From da139e8eaa9ca35b6a5b9f7eed941eadb685cfa5 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 9 Jun 2000 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2000-06-09 --- alphapc/random.c | 138 +++++++++++++++++++++++++++++++++++++++++++++ carrera/random.c | 138 +++++++++++++++++++++++++++++++++++++++++++++ mpc/random.c | 138 +++++++++++++++++++++++++++++++++++++++++++++ pc/main.c | 6 +- pc/random.c | 138 +++++++++++++++++++++++++++++++++++++++++++++ port/cache.c | 3 + port/devcons.c | 144 ++--------------------------------------------- port/portfns.h | 2 + 8 files changed, 566 insertions(+), 141 deletions(-) create mode 100644 alphapc/random.c create mode 100644 carrera/random.c create mode 100644 mpc/random.c create mode 100644 pc/random.c diff --git a/alphapc/random.c b/alphapc/random.c new file mode 100644 index 0000000000000000000000000000000000000000..cf9eb1d054608a5a63c47eb48ed459b739b8a6d3 --- /dev/null +++ b/alphapc/random.c @@ -0,0 +1,138 @@ +#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; +} + +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); +} + +static void +randominit(void) +{ + addclock0link(randomclock); + rb.ep = rb.buf + sizeof(rb.buf); + rb.rp = rb.wp = rb.buf; + kproc("genrandom", genrandom, 0); +} + +/* + * consume random bytes from a circular buffer + */ +static 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; +} diff --git a/carrera/random.c b/carrera/random.c new file mode 100644 index 0000000000000000000000000000000000000000..cf9eb1d054608a5a63c47eb48ed459b739b8a6d3 --- /dev/null +++ b/carrera/random.c @@ -0,0 +1,138 @@ +#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; +} + +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); +} + +static void +randominit(void) +{ + addclock0link(randomclock); + rb.ep = rb.buf + sizeof(rb.buf); + rb.rp = rb.wp = rb.buf; + kproc("genrandom", genrandom, 0); +} + +/* + * consume random bytes from a circular buffer + */ +static 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; +} diff --git a/mpc/random.c b/mpc/random.c new file mode 100644 index 0000000000000000000000000000000000000000..cf9eb1d054608a5a63c47eb48ed459b739b8a6d3 --- /dev/null +++ b/mpc/random.c @@ -0,0 +1,138 @@ +#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; +} + +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); +} + +static void +randominit(void) +{ + addclock0link(randomclock); + rb.ep = rb.buf + sizeof(rb.buf); + rb.rp = rb.wp = rb.buf; + kproc("genrandom", genrandom, 0); +} + +/* + * consume random bytes from a circular buffer + */ +static 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; +} diff --git a/pc/main.c b/pc/main.c index 627ba2d4305cd98eab95471495ac281a6ee1481b..3823b523c0fd80955cf79f2368dd49f281287580 100644 --- a/pc/main.c +++ b/pc/main.c @@ -395,14 +395,14 @@ confinit(void) /* * Hack for the big boys. Only good while physmem < 4GB. - * Give the kernel a max. of 16MB + enough to allocate the + * Give the kernel fixed max + enough to allocate the * page pool. * This is an overestimate as conf.upages < conf.npages. * The patch of nimage is a band-aid, scanning the whole * page list in imagereclaim just takes too long. */ - if(kpages > (16*MB + conf.npage*sizeof(Page))/BY2PG){ - kpages = (16*MB + conf.npage*sizeof(Page))/BY2PG; + if(kpages > (32*MB + conf.npage*sizeof(Page))/BY2PG){ + kpages = (32*MB + conf.npage*sizeof(Page))/BY2PG; conf.nimage = 2000; kpages += (conf.nproc*KSTACK)/BY2PG; } diff --git a/pc/random.c b/pc/random.c new file mode 100644 index 0000000000000000000000000000000000000000..282e8c99a29b625dc7be4b2b37f564c2ed8bf11b --- /dev/null +++ b/pc/random.c @@ -0,0 +1,138 @@ +#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); + 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; +} diff --git a/port/cache.c b/port/cache.c index ba5c1e8b59a077ae055f55307082548c35277129..e6efeda7e4f9e11a7010a499ac88c19d90164a0c 100644 --- a/port/cache.c +++ b/port/cache.c @@ -110,8 +110,11 @@ cinit(void) cache.head = xalloc(sizeof(Mntcache)*NFILE); m = cache.head; + /* a better algorithm would be nice */ if(conf.npage*BY2PG > 200*MB) maxcache = 10*MAXCACHE; + if(conf.npage*BY2PG > 400*MB) + maxcache = 50*MAXCACHE; for(i = 0; i < NFILE-1; i++) { m->next = m+1; diff --git a/port/devcons.c b/port/devcons.c index 27e71fe6ed3e48fbb70df08ce6764fede52d16ee..a2dc10be607d888fdab2ebcba5dac43afb4df2f5 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -29,8 +29,6 @@ static struct char sysname[NAMELEN]; vlong fasthz; -static ulong randomread(void*, ulong); -static void randominit(void); static void seedrand(void); static int readtime(ulong, char*, int); static int readbintime(char*, int); @@ -911,158 +909,28 @@ Dev consdevtab = { devwstat, }; -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 ulong randn; static void seedrand(void) { - randomread((void*)&rb.randn, sizeof(rb.randn)); + randomread((void*)&randn, sizeof(randn)); } int nrand(int n) { - if(rb.randn == 0) + if(randn == 0) seedrand(); - rb.randn = rb.randn*1103515245 + 12345 + MACHP(0)->ticks; - return (rb.randn>>16) % n; + randn = randn*1103515245 + 12345 + MACHP(0)->ticks; + return (randn>>16) % n; } int rand(void) { nrand(1); - return rb.randn; -} - - -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; -} - -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); -} - -static void -randominit(void) -{ - addclock0link(randomclock); - rb.ep = rb.buf + sizeof(rb.buf); - rb.rp = rb.wp = rb.buf; - kproc("genrandom", genrandom, 0); -} - -/* - * consume random bytes from a circular buffer - */ -static 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; + return randn; } static uvlong uvorder = 0x0001020304050607ULL; diff --git a/port/portfns.h b/port/portfns.h index 025338d6d862bff99b29ff068ce861ef079c101b..4a512183e12ac4708acd4dd8244d507d88275a88 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -250,6 +250,8 @@ int qwrite(Queue*, void*, int); void qsetlimit(Queue*, int); void qnoblock(Queue*, int); int rand(void); +void randominit(void); +ulong randomread(void*, ulong); void rdb(void); int readnum(ulong, char*, ulong, ulong, int); int readstr(ulong, char*, ulong, char*);