kernel: move duplicated random.c to port
This commit is contained in:
parent
5377a19447
commit
7f04d86dfb
15 changed files with 10 additions and 839 deletions
|
@ -36,6 +36,7 @@ PORT=\
|
|||
taslock.$O\
|
||||
tod.$O\
|
||||
xalloc.$O\
|
||||
random.$O\
|
||||
|
||||
OBJ=\
|
||||
l.$O\
|
||||
|
@ -47,7 +48,6 @@ OBJ=\
|
|||
i8259.$O\
|
||||
main.$O\
|
||||
mmu.$O\
|
||||
random.$O\
|
||||
trap.$O\
|
||||
$CONF.root.$O\
|
||||
$CONF.rootc.$O\
|
||||
|
|
|
@ -34,6 +34,7 @@ PORT=\
|
|||
taslock.$O\
|
||||
tod.$O\
|
||||
xalloc.$O\
|
||||
random.$O\
|
||||
|
||||
OBJ=\
|
||||
l.$O\
|
||||
|
@ -45,7 +46,6 @@ OBJ=\
|
|||
main.$O\
|
||||
mmu.$O\
|
||||
power.$O\
|
||||
random.$O\
|
||||
sa1110dma.$O\
|
||||
screen.$O\
|
||||
trap.$O\
|
||||
|
|
|
@ -1,138 +0,0 @@
|
|||
#include "u.h"
|
||||
#include "../port/lib.h"
|
||||
#include "mem.h"
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
|
||||
struct Rb
|
||||
{
|
||||
QLock;
|
||||
Rendez producer;
|
||||
Rendez consumer;
|
||||
ulong randomcount;
|
||||
uchar buf[128];
|
||||
uchar *ep;
|
||||
uchar *rp;
|
||||
uchar *wp;
|
||||
uchar next;
|
||||
uchar wakeme;
|
||||
ushort bits;
|
||||
ulong randn;
|
||||
} rb;
|
||||
|
||||
static int
|
||||
rbnotfull(void*)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = rb.rp - rb.wp;
|
||||
return i != 1 && i != (1 - sizeof(rb.buf));
|
||||
}
|
||||
|
||||
static int
|
||||
rbnotempty(void*)
|
||||
{
|
||||
return rb.wp != rb.rp;
|
||||
}
|
||||
|
||||
static void
|
||||
genrandom(void*)
|
||||
{
|
||||
up->basepri = PriNormal;
|
||||
up->priority = up->basepri;
|
||||
|
||||
for(;;){
|
||||
for(;;)
|
||||
if(++rb.randomcount > 100000)
|
||||
break;
|
||||
if(anyhigher())
|
||||
sched();
|
||||
if(!rbnotfull(0))
|
||||
sleep(&rb.producer, rbnotfull, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* produce random bits in a circular buffer
|
||||
*/
|
||||
static void
|
||||
randomclock(void)
|
||||
{
|
||||
if(rb.randomcount == 0 || !rbnotfull(0))
|
||||
return;
|
||||
|
||||
rb.bits = (rb.bits<<2) ^ rb.randomcount;
|
||||
rb.randomcount = 0;
|
||||
|
||||
rb.next++;
|
||||
if(rb.next != 8/2)
|
||||
return;
|
||||
rb.next = 0;
|
||||
|
||||
*rb.wp ^= rb.bits;
|
||||
if(rb.wp+1 == rb.ep)
|
||||
rb.wp = rb.buf;
|
||||
else
|
||||
rb.wp = rb.wp+1;
|
||||
|
||||
if(rb.wakeme)
|
||||
wakeup(&rb.consumer);
|
||||
}
|
||||
|
||||
void
|
||||
randominit(void)
|
||||
{
|
||||
addclock0link(randomclock, 1000/HZ);
|
||||
rb.ep = rb.buf + sizeof(rb.buf);
|
||||
rb.rp = rb.wp = rb.buf;
|
||||
kproc("genrandom", genrandom, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* consume random bytes from a circular buffer
|
||||
*/
|
||||
ulong
|
||||
randomread(void *xp, ulong n)
|
||||
{
|
||||
uchar *e, *p;
|
||||
ulong x;
|
||||
|
||||
p = xp;
|
||||
|
||||
if(waserror()){
|
||||
qunlock(&rb);
|
||||
nexterror();
|
||||
}
|
||||
|
||||
qlock(&rb);
|
||||
for(e = p + n; p < e; ){
|
||||
if(rb.wp == rb.rp){
|
||||
rb.wakeme = 1;
|
||||
wakeup(&rb.producer);
|
||||
sleep(&rb.consumer, rbnotempty, 0);
|
||||
rb.wakeme = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* beating clocks will be precictable if
|
||||
* they are synchronized. Use a cheap pseudo
|
||||
* random number generator to obscure any cycles.
|
||||
*/
|
||||
x = rb.randn*1103515245 ^ *rb.rp;
|
||||
*p++ = rb.randn = x;
|
||||
|
||||
if(rb.rp+1 == rb.ep)
|
||||
rb.rp = rb.buf;
|
||||
else
|
||||
rb.rp = rb.rp+1;
|
||||
}
|
||||
qunlock(&rb);
|
||||
poperror();
|
||||
|
||||
wakeup(&rb.producer);
|
||||
|
||||
return n;
|
||||
}
|
|
@ -39,6 +39,7 @@ PORT=\
|
|||
taslock.$O\
|
||||
tod.$O\
|
||||
xalloc.$O\
|
||||
random.$O\
|
||||
|
||||
OBJ=\
|
||||
l.$O\
|
||||
|
@ -52,7 +53,6 @@ OBJ=\
|
|||
fpimem.$O\
|
||||
main.$O\
|
||||
mmu.$O\
|
||||
random.$O\
|
||||
trap.$O\
|
||||
$CONF.root.$O\
|
||||
$CONF.rootc.$O\
|
||||
|
|
|
@ -1,138 +0,0 @@
|
|||
#include "u.h"
|
||||
#include "../port/lib.h"
|
||||
#include "mem.h"
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
|
||||
struct Rb
|
||||
{
|
||||
QLock;
|
||||
Rendez producer;
|
||||
Rendez consumer;
|
||||
ulong randomcount;
|
||||
uchar buf[128];
|
||||
uchar *ep;
|
||||
uchar *rp;
|
||||
uchar *wp;
|
||||
uchar next;
|
||||
uchar wakeme;
|
||||
ushort bits;
|
||||
ulong randn;
|
||||
} rb;
|
||||
|
||||
static int
|
||||
rbnotfull(void*)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = rb.rp - rb.wp;
|
||||
return i != 1 && i != (1 - sizeof(rb.buf));
|
||||
}
|
||||
|
||||
static int
|
||||
rbnotempty(void*)
|
||||
{
|
||||
return rb.wp != rb.rp;
|
||||
}
|
||||
|
||||
static void
|
||||
genrandom(void*)
|
||||
{
|
||||
up->basepri = PriNormal;
|
||||
up->priority = up->basepri;
|
||||
|
||||
for(;;){
|
||||
for(;;)
|
||||
if(++rb.randomcount > 100000)
|
||||
break;
|
||||
if(anyhigher())
|
||||
sched();
|
||||
if(!rbnotfull(0))
|
||||
sleep(&rb.producer, rbnotfull, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* produce random bits in a circular buffer
|
||||
*/
|
||||
static void
|
||||
randomclock(void)
|
||||
{
|
||||
if(rb.randomcount == 0 || !rbnotfull(0))
|
||||
return;
|
||||
|
||||
rb.bits = (rb.bits<<2) ^ rb.randomcount;
|
||||
rb.randomcount = 0;
|
||||
|
||||
rb.next++;
|
||||
if(rb.next != 8/2)
|
||||
return;
|
||||
rb.next = 0;
|
||||
|
||||
*rb.wp ^= rb.bits;
|
||||
if(rb.wp+1 == rb.ep)
|
||||
rb.wp = rb.buf;
|
||||
else
|
||||
rb.wp = rb.wp+1;
|
||||
|
||||
if(rb.wakeme)
|
||||
wakeup(&rb.consumer);
|
||||
}
|
||||
|
||||
void
|
||||
randominit(void)
|
||||
{
|
||||
addclock0link(randomclock, 1000/HZ);
|
||||
rb.ep = rb.buf + sizeof(rb.buf);
|
||||
rb.rp = rb.wp = rb.buf;
|
||||
kproc("genrandom", genrandom, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* consume random bytes from a circular buffer
|
||||
*/
|
||||
ulong
|
||||
randomread(void *xp, ulong n)
|
||||
{
|
||||
uchar *e, *p;
|
||||
ulong x;
|
||||
|
||||
p = xp;
|
||||
|
||||
if(waserror()){
|
||||
qunlock(&rb);
|
||||
nexterror();
|
||||
}
|
||||
|
||||
qlock(&rb);
|
||||
for(e = p + n; p < e; ){
|
||||
if(rb.wp == rb.rp){
|
||||
rb.wakeme = 1;
|
||||
wakeup(&rb.producer);
|
||||
sleep(&rb.consumer, rbnotempty, 0);
|
||||
rb.wakeme = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* beating clocks will be predictable if
|
||||
* they are synchronized. Use a cheap pseudo
|
||||
* random number generator to obscure any cycles.
|
||||
*/
|
||||
x = rb.randn*1103515245 ^ *rb.rp;
|
||||
*p++ = rb.randn = x;
|
||||
|
||||
if(rb.rp+1 == rb.ep)
|
||||
rb.rp = rb.buf;
|
||||
else
|
||||
rb.rp = rb.rp+1;
|
||||
}
|
||||
qunlock(&rb);
|
||||
poperror();
|
||||
|
||||
wakeup(&rb.producer);
|
||||
|
||||
return n;
|
||||
}
|
|
@ -36,6 +36,7 @@ PORT=\
|
|||
taslock.$O\
|
||||
tod.$O\
|
||||
xalloc.$O\
|
||||
random.$O\
|
||||
|
||||
OBJ=\
|
||||
l.$O\
|
||||
|
@ -44,7 +45,6 @@ OBJ=\
|
|||
i8259.$O\
|
||||
main.$O\
|
||||
mmu.$O\
|
||||
random.$O\
|
||||
raven.$O\
|
||||
trap.$O\
|
||||
$CONF.root.$O\
|
||||
|
|
|
@ -1,138 +0,0 @@
|
|||
#include "u.h"
|
||||
#include "../port/lib.h"
|
||||
#include "mem.h"
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
|
||||
struct Rb
|
||||
{
|
||||
QLock;
|
||||
Rendez producer;
|
||||
Rendez consumer;
|
||||
ulong randomcount;
|
||||
uchar buf[1024];
|
||||
uchar *ep;
|
||||
uchar *rp;
|
||||
uchar *wp;
|
||||
uchar next;
|
||||
uchar wakeme;
|
||||
ushort bits;
|
||||
ulong randn;
|
||||
} rb;
|
||||
|
||||
static int
|
||||
rbnotfull(void*)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = rb.rp - rb.wp;
|
||||
return i != 1 && i != (1 - sizeof(rb.buf));
|
||||
}
|
||||
|
||||
static int
|
||||
rbnotempty(void*)
|
||||
{
|
||||
return rb.wp != rb.rp;
|
||||
}
|
||||
|
||||
static void
|
||||
genrandom(void*)
|
||||
{
|
||||
up->basepri = PriNormal;
|
||||
up->priority = up->basepri;
|
||||
|
||||
for(;;){
|
||||
for(;;)
|
||||
if(++rb.randomcount > 100000)
|
||||
break;
|
||||
if(anyhigher())
|
||||
sched();
|
||||
if(!rbnotfull(0))
|
||||
sleep(&rb.producer, rbnotfull, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* produce random bits in a circular buffer
|
||||
*/
|
||||
static void
|
||||
randomclock(void)
|
||||
{
|
||||
if(rb.randomcount == 0 || !rbnotfull(0))
|
||||
return;
|
||||
|
||||
rb.bits = (rb.bits<<2) ^ rb.randomcount;
|
||||
rb.randomcount = 0;
|
||||
|
||||
rb.next++;
|
||||
if(rb.next != 8/2)
|
||||
return;
|
||||
rb.next = 0;
|
||||
|
||||
*rb.wp ^= rb.bits;
|
||||
if(rb.wp+1 == rb.ep)
|
||||
rb.wp = rb.buf;
|
||||
else
|
||||
rb.wp = rb.wp+1;
|
||||
|
||||
if(rb.wakeme)
|
||||
wakeup(&rb.consumer);
|
||||
}
|
||||
|
||||
void
|
||||
randominit(void)
|
||||
{
|
||||
addclock0link(randomclock, 1000/HZ);
|
||||
rb.ep = rb.buf + sizeof(rb.buf);
|
||||
rb.rp = rb.wp = rb.buf;
|
||||
kproc("genrandom", genrandom, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* consume random bytes from a circular buffer
|
||||
*/
|
||||
ulong
|
||||
randomread(void *xp, ulong n)
|
||||
{
|
||||
uchar *e, *p;
|
||||
ulong x;
|
||||
|
||||
p = xp;
|
||||
|
||||
if(waserror()){
|
||||
qunlock(&rb);
|
||||
nexterror();
|
||||
}
|
||||
|
||||
qlock(&rb);
|
||||
for(e = p + n; p < e; ){
|
||||
if(rb.wp == rb.rp){
|
||||
rb.wakeme = 1;
|
||||
wakeup(&rb.producer);
|
||||
sleep(&rb.consumer, rbnotempty, 0);
|
||||
rb.wakeme = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* beating clocks will be precictable if
|
||||
* they are synchronized. Use a cheap pseudo
|
||||
* random number generator to obscure any cycles.
|
||||
*/
|
||||
x = rb.randn*1103515245 ^ *rb.rp;
|
||||
*p++ = rb.randn = x;
|
||||
|
||||
if(rb.rp+1 == rb.ep)
|
||||
rb.rp = rb.buf;
|
||||
else
|
||||
rb.rp = rb.rp+1;
|
||||
}
|
||||
qunlock(&rb);
|
||||
poperror();
|
||||
|
||||
wakeup(&rb.producer);
|
||||
|
||||
return n;
|
||||
}
|
|
@ -39,6 +39,7 @@ PORT=\
|
|||
taslock.$O\
|
||||
tod.$O\
|
||||
xalloc.$O\
|
||||
random.$O\
|
||||
|
||||
OBJ=\
|
||||
l.$O\
|
||||
|
@ -51,7 +52,6 @@ OBJ=\
|
|||
fpimem.$O\
|
||||
main.$O\
|
||||
mmu.$O\
|
||||
random.$O\
|
||||
trap.$O\
|
||||
$CONF.root.$O\
|
||||
$CONF.rootc.$O\
|
||||
|
|
|
@ -1,138 +0,0 @@
|
|||
#include "u.h"
|
||||
#include "../port/lib.h"
|
||||
#include "mem.h"
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
|
||||
struct Rb
|
||||
{
|
||||
QLock;
|
||||
Rendez producer;
|
||||
Rendez consumer;
|
||||
ulong randomcount;
|
||||
uchar buf[128];
|
||||
uchar *ep;
|
||||
uchar *rp;
|
||||
uchar *wp;
|
||||
uchar next;
|
||||
uchar wakeme;
|
||||
ushort bits;
|
||||
ulong randn;
|
||||
} rb;
|
||||
|
||||
static int
|
||||
rbnotfull(void*)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = rb.rp - rb.wp;
|
||||
return i != 1 && i != (1 - sizeof(rb.buf));
|
||||
}
|
||||
|
||||
static int
|
||||
rbnotempty(void*)
|
||||
{
|
||||
return rb.wp != rb.rp;
|
||||
}
|
||||
|
||||
static void
|
||||
genrandom(void*)
|
||||
{
|
||||
up->basepri = PriNormal;
|
||||
up->priority = up->basepri;
|
||||
|
||||
for(;;){
|
||||
for(;;)
|
||||
if(++rb.randomcount > 100000)
|
||||
break;
|
||||
if(anyhigher())
|
||||
sched();
|
||||
if(!rbnotfull(0))
|
||||
sleep(&rb.producer, rbnotfull, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* produce random bits in a circular buffer
|
||||
*/
|
||||
static void
|
||||
randomclock(void)
|
||||
{
|
||||
if(rb.randomcount == 0 || !rbnotfull(0))
|
||||
return;
|
||||
|
||||
rb.bits = (rb.bits<<2) ^ rb.randomcount;
|
||||
rb.randomcount = 0;
|
||||
|
||||
rb.next++;
|
||||
if(rb.next != 8/2)
|
||||
return;
|
||||
rb.next = 0;
|
||||
|
||||
*rb.wp ^= rb.bits;
|
||||
if(rb.wp+1 == rb.ep)
|
||||
rb.wp = rb.buf;
|
||||
else
|
||||
rb.wp = rb.wp+1;
|
||||
|
||||
if(rb.wakeme)
|
||||
wakeup(&rb.consumer);
|
||||
}
|
||||
|
||||
void
|
||||
randominit(void)
|
||||
{
|
||||
addclock0link(randomclock, 1000/HZ);
|
||||
rb.ep = rb.buf + sizeof(rb.buf);
|
||||
rb.rp = rb.wp = rb.buf;
|
||||
kproc("genrandom", genrandom, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* consume random bytes from a circular buffer
|
||||
*/
|
||||
ulong
|
||||
randomread(void *xp, ulong n)
|
||||
{
|
||||
uchar *e, *p;
|
||||
ulong x;
|
||||
|
||||
p = xp;
|
||||
|
||||
if(waserror()){
|
||||
qunlock(&rb);
|
||||
nexterror();
|
||||
}
|
||||
|
||||
qlock(&rb);
|
||||
for(e = p + n; p < e; ){
|
||||
if(rb.wp == rb.rp){
|
||||
rb.wakeme = 1;
|
||||
wakeup(&rb.producer);
|
||||
sleep(&rb.consumer, rbnotempty, 0);
|
||||
rb.wakeme = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* beating clocks will be predictable if
|
||||
* they are synchronized. Use a cheap pseudo
|
||||
* random number generator to obscure any cycles.
|
||||
*/
|
||||
x = rb.randn*1103515245 ^ *rb.rp;
|
||||
*p++ = rb.randn = x;
|
||||
|
||||
if(rb.rp+1 == rb.ep)
|
||||
rb.rp = rb.buf;
|
||||
else
|
||||
rb.rp = rb.rp+1;
|
||||
}
|
||||
qunlock(&rb);
|
||||
poperror();
|
||||
|
||||
wakeup(&rb.producer);
|
||||
|
||||
return n;
|
||||
}
|
|
@ -37,12 +37,12 @@ PORT=\
|
|||
taslock.$O\
|
||||
tod.$O\
|
||||
xalloc.$O\
|
||||
random.$O\
|
||||
|
||||
OBJ=\
|
||||
l.$O\
|
||||
main.$O\
|
||||
mmu.$O\
|
||||
random.$O\
|
||||
clock.$O\
|
||||
arch.$O\
|
||||
trap.$O\
|
||||
|
|
|
@ -1,138 +0,0 @@
|
|||
#include "u.h"
|
||||
#include "../port/lib.h"
|
||||
#include "mem.h"
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
|
||||
struct Rb
|
||||
{
|
||||
QLock;
|
||||
Rendez producer;
|
||||
Rendez consumer;
|
||||
ulong randomcount;
|
||||
uchar buf[128];
|
||||
uchar *ep;
|
||||
uchar *rp;
|
||||
uchar *wp;
|
||||
uchar next;
|
||||
uchar wakeme;
|
||||
ushort bits;
|
||||
ulong randn;
|
||||
} rb;
|
||||
|
||||
static int
|
||||
rbnotfull(void*)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = rb.rp - rb.wp;
|
||||
return i != 1 && i != (1 - sizeof(rb.buf));
|
||||
}
|
||||
|
||||
static int
|
||||
rbnotempty(void*)
|
||||
{
|
||||
return rb.wp != rb.rp;
|
||||
}
|
||||
|
||||
static void
|
||||
genrandom(void*)
|
||||
{
|
||||
up->basepri = PriNormal;
|
||||
up->priority = up->basepri;
|
||||
|
||||
for(;;){
|
||||
for(;;)
|
||||
if(++rb.randomcount > 100000)
|
||||
break;
|
||||
if(anyhigher())
|
||||
sched();
|
||||
if(!rbnotfull(0))
|
||||
sleep(&rb.producer, rbnotfull, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* produce random bits in a circular buffer
|
||||
*/
|
||||
static void
|
||||
randomclock(void)
|
||||
{
|
||||
if(rb.randomcount == 0 || !rbnotfull(0))
|
||||
return;
|
||||
|
||||
rb.bits = (rb.bits<<2) ^ rb.randomcount;
|
||||
rb.randomcount = 0;
|
||||
|
||||
rb.next++;
|
||||
if(rb.next != 8/2)
|
||||
return;
|
||||
rb.next = 0;
|
||||
|
||||
*rb.wp ^= rb.bits;
|
||||
if(rb.wp+1 == rb.ep)
|
||||
rb.wp = rb.buf;
|
||||
else
|
||||
rb.wp = rb.wp+1;
|
||||
|
||||
if(rb.wakeme)
|
||||
wakeup(&rb.consumer);
|
||||
}
|
||||
|
||||
void
|
||||
randominit(void)
|
||||
{
|
||||
addclock0link(randomclock, 1000/HZ);
|
||||
rb.ep = rb.buf + sizeof(rb.buf);
|
||||
rb.rp = rb.wp = rb.buf;
|
||||
kproc("genrandom", genrandom, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* consume random bytes from a circular buffer
|
||||
*/
|
||||
ulong
|
||||
randomread(void *xp, ulong n)
|
||||
{
|
||||
uchar *e, *p;
|
||||
ulong x;
|
||||
|
||||
p = xp;
|
||||
|
||||
if(waserror()){
|
||||
qunlock(&rb);
|
||||
nexterror();
|
||||
}
|
||||
|
||||
qlock(&rb);
|
||||
for(e = p + n; p < e; ){
|
||||
if(rb.wp == rb.rp){
|
||||
rb.wakeme = 1;
|
||||
wakeup(&rb.producer);
|
||||
sleep(&rb.consumer, rbnotempty, 0);
|
||||
rb.wakeme = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* beating clocks will be predictable if
|
||||
* they are synchronized. Use a cheap pseudo
|
||||
* random number generator to obscure any cycles.
|
||||
*/
|
||||
x = rb.randn*1103515245 ^ *rb.rp;
|
||||
*p++ = rb.randn = x;
|
||||
|
||||
if(rb.rp+1 == rb.ep)
|
||||
rb.rp = rb.buf;
|
||||
else
|
||||
rb.rp = rb.rp+1;
|
||||
}
|
||||
qunlock(&rb);
|
||||
poperror();
|
||||
|
||||
wakeup(&rb.producer);
|
||||
|
||||
return n;
|
||||
}
|
|
@ -41,6 +41,7 @@ PORT=\
|
|||
taslock.$O\
|
||||
tod.$O\
|
||||
xalloc.$O\
|
||||
random.$O\
|
||||
|
||||
OBJ=\
|
||||
l.$O\
|
||||
|
@ -51,7 +52,6 @@ OBJ=\
|
|||
main.$O\
|
||||
memory.$O\
|
||||
mmu.$O\
|
||||
random.$O\
|
||||
syscallfmt.$O\
|
||||
trap.$O\
|
||||
$CONF.root.$O\
|
||||
|
|
|
@ -5,14 +5,13 @@
|
|||
#include "fns.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
|
||||
struct Rb
|
||||
{
|
||||
QLock;
|
||||
Rendez producer;
|
||||
Rendez consumer;
|
||||
ulong randomcount;
|
||||
uchar buf[1024];
|
||||
uchar buf[128];
|
||||
uchar *ep;
|
||||
uchar *rp;
|
||||
uchar *wp;
|
||||
|
@ -85,7 +84,7 @@ void
|
|||
randominit(void)
|
||||
{
|
||||
/* Frequency close but not equal to HZ */
|
||||
addclock0link(randomclock, 13);
|
||||
addclock0link(randomclock, MS2HZ+3);
|
||||
rb.ep = rb.buf + sizeof(rb.buf);
|
||||
rb.rp = rb.wp = rb.buf;
|
||||
kproc("genrandom", genrandom, 0);
|
|
@ -37,13 +37,13 @@ PORT=\
|
|||
taslock.$O\
|
||||
tod.$O\
|
||||
xalloc.$O\
|
||||
random.$O\
|
||||
|
||||
OBJ=\
|
||||
l.$O\
|
||||
clock.$O\
|
||||
main.$O\
|
||||
mmu.$O\
|
||||
random.$O\
|
||||
trap.$O\
|
||||
$CONF.root.$O\
|
||||
$CONF.rootc.$O\
|
||||
|
|
|
@ -1,138 +0,0 @@
|
|||
#include "u.h"
|
||||
#include "../port/lib.h"
|
||||
#include "mem.h"
|
||||
#include "dat.h"
|
||||
#include "fns.h"
|
||||
#include "../port/error.h"
|
||||
|
||||
|
||||
struct Rb
|
||||
{
|
||||
QLock;
|
||||
Rendez producer;
|
||||
Rendez consumer;
|
||||
ulong randomcount;
|
||||
uchar buf[1024];
|
||||
uchar *ep;
|
||||
uchar *rp;
|
||||
uchar *wp;
|
||||
uchar next;
|
||||
uchar wakeme;
|
||||
ushort bits;
|
||||
ulong randn;
|
||||
} rb;
|
||||
|
||||
static int
|
||||
rbnotfull(void*)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = rb.rp - rb.wp;
|
||||
return i != 1 && i != (1 - sizeof(rb.buf));
|
||||
}
|
||||
|
||||
static int
|
||||
rbnotempty(void*)
|
||||
{
|
||||
return rb.wp != rb.rp;
|
||||
}
|
||||
|
||||
static void
|
||||
genrandom(void*)
|
||||
{
|
||||
up->basepri = PriNormal;
|
||||
up->priority = up->basepri;
|
||||
|
||||
for(;;){
|
||||
for(;;)
|
||||
if(++rb.randomcount > 100000)
|
||||
break;
|
||||
if(anyhigher())
|
||||
sched();
|
||||
if(!rbnotfull(0))
|
||||
sleep(&rb.producer, rbnotfull, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* produce random bits in a circular buffer
|
||||
*/
|
||||
static void
|
||||
randomclock(void)
|
||||
{
|
||||
if(rb.randomcount == 0 || !rbnotfull(0))
|
||||
return;
|
||||
|
||||
rb.bits = (rb.bits<<2) ^ rb.randomcount;
|
||||
rb.randomcount = 0;
|
||||
|
||||
rb.next++;
|
||||
if(rb.next != 8/2)
|
||||
return;
|
||||
rb.next = 0;
|
||||
|
||||
*rb.wp ^= rb.bits;
|
||||
if(rb.wp+1 == rb.ep)
|
||||
rb.wp = rb.buf;
|
||||
else
|
||||
rb.wp = rb.wp+1;
|
||||
|
||||
if(rb.wakeme)
|
||||
wakeup(&rb.consumer);
|
||||
}
|
||||
|
||||
void
|
||||
randominit(void)
|
||||
{
|
||||
addclock0link(randomclock, 1000/HZ);
|
||||
rb.ep = rb.buf + sizeof(rb.buf);
|
||||
rb.rp = rb.wp = rb.buf;
|
||||
kproc("genrandom", genrandom, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* consume random bytes from a circular buffer
|
||||
*/
|
||||
ulong
|
||||
randomread(void *xp, ulong n)
|
||||
{
|
||||
uchar *e, *p;
|
||||
ulong x;
|
||||
|
||||
p = xp;
|
||||
|
||||
if(waserror()){
|
||||
qunlock(&rb);
|
||||
nexterror();
|
||||
}
|
||||
|
||||
qlock(&rb);
|
||||
for(e = p + n; p < e; ){
|
||||
if(rb.wp == rb.rp){
|
||||
rb.wakeme = 1;
|
||||
wakeup(&rb.producer);
|
||||
sleep(&rb.consumer, rbnotempty, 0);
|
||||
rb.wakeme = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* beating clocks will be precictable if
|
||||
* they are synchronized. Use a cheap pseudo
|
||||
* random number generator to obscure any cycles.
|
||||
*/
|
||||
x = rb.randn*1103515245 ^ *rb.rp;
|
||||
*p++ = rb.randn = x;
|
||||
|
||||
if(rb.rp+1 == rb.ep)
|
||||
rb.rp = rb.buf;
|
||||
else
|
||||
rb.rp = rb.rp+1;
|
||||
}
|
||||
qunlock(&rb);
|
||||
poperror();
|
||||
|
||||
wakeup(&rb.producer);
|
||||
|
||||
return n;
|
||||
}
|
Loading…
Reference in a new issue