From fe68274bb8cac7ae435a941858cd312124d49016 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 10 Sep 1995 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1995-09-10 --- pc/clock.c | 1 + port/devcons.c | 106 ++++++++++++++++++++++++++++++++++++++++++++++++- port/portdat.h | 1 + port/portfns.h | 1 + port/proc.c | 4 +- 5 files changed, 111 insertions(+), 2 deletions(-) diff --git a/pc/clock.c b/pc/clock.c index 95c66e5078906f964de973115085f18116b519a3..3c6592acbabbe5c4ff1ad9288b2dcb619334f225 100644 --- a/pc/clock.c +++ b/pc/clock.c @@ -44,6 +44,7 @@ clock(Ureg *ur, void *arg) hardclock(); uartclock(); mouseclock(); + randomclock(); if(up && up->state == Running){ if(anyready()) diff --git a/port/devcons.c b/port/devcons.c index 455a731e4c31383c47b09ecea8ddfaf44753c714..902b0a1fb155a914fdf5e377e86c64a5f7776502 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -27,9 +27,11 @@ static struct int ctlpoff; } kbd; - char sysname[NAMELEN]; +static ulong randomread(uchar*, ulong); +static void randomreset(void); + void printinit(void) { @@ -330,6 +332,7 @@ enum{ Qpgrpid, Qpid, Qppid, + Qrandom, Qswap, Qsysname, Qsysstat, @@ -356,6 +359,7 @@ Dirtab consdir[]={ "pgrpid", {Qpgrpid}, NUMSIZE, 0444, "pid", {Qpid}, NUMSIZE, 0444, "ppid", {Qppid}, NUMSIZE, 0444, + "random", {Qrandom}, 0, 0664, "swap", {Qswap}, 0, 0664, "sysname", {Qsysname}, 0, 0664, "sysstat", {Qsysstat}, 0, 0666, @@ -406,6 +410,7 @@ readstr(ulong off, char *buf, ulong n, char *str) void consreset(void) { + randomreset(); } void @@ -642,6 +647,9 @@ consread(Chan *c, void *buf, long n, ulong offset) case Qsysname: return readstr(offset, buf, n, sysname); + case Qrandom: + return randomread(buf, n); + default: print("consread %lux\n", c->qid); error(Egreg); @@ -879,3 +887,99 @@ setterm(char *f) sprint(buf, f, conffile); ksetenv("terminal", buf); } + +static struct +{ + QLock; + Rendez r; + uchar buf[4096]; + uchar *ep; + uchar *rp; + uchar *wp; + uchar next; + uchar bits; + uchar wakeme; +} rb; + +ulong randomcount; + +void +randomreset(void) +{ + rb.ep = rb.buf + sizeof(rb.buf); + rb.rp = rb.wp = rb.buf; +} + +/* + * produce random bits in a circular buffer + */ +void +randomclock(void) +{ + int i; + uchar *p; + + i = rb.rp - rb.wp; + if(i == 1 || i == (1 - sizeof(rb.buf))) + return; + + rb.bits = (rb.bits<<2) ^ randomcount; + rb.next += 2; + if(rb.next != 8) + return; + + rb.next = 0; + *rb.wp ^= rb.bits; + p = rb.wp+1; + if(p == rb.ep) + p = rb.buf; + rb.wp = p; + + if(rb.wakeme) + wakeup(&rb.r); +} + +static int +notempty(void*) +{ + return rb.wp != rb.rp; +} + +/* + * consume random bytes from a circular buffer + */ +static ulong +randomread(uchar *p, ulong n) +{ + int i, sofar; + uchar *e; + + if(waserror()){ + qunlock(&rb); + nexterror(); + } + + qlock(&rb); + for(sofar = 0; sofar < n; sofar += i){ + i = rb.wp - rb.rp; + if(i == 0){ + rb.wakeme = 1; + sleep(&rb.r, notempty, 0); + rb.wakeme = 0; + continue; + } + if(i < 0) + i = rb.ep - rb.rp; + if(i > n) + i = n; + memmove(p + sofar, rb.rp, i); + e = rb.rp + i; + if(e == rb.ep) + e = rb.buf; + rb.rp = e; + } + qunlock(&rb); + poperror(); + + return n; +} diff --git a/port/portdat.h b/port/portdat.h index 282b3f9d84cb74222d2bd2d5a6dea2b9267180a5..ffd35fae23cfeee1040db2133a8b501f0efab2b8 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -704,3 +704,4 @@ extern int nsyscall; extern Physseg physseg[]; extern ulong crasharea; extern ulong crashend; +extern ulong randomcount; diff --git a/port/portfns.h b/port/portfns.h index 631c0642dcee438eb4cfc35891f7ff3a59ab7f8d..d026f815a5fe981ac3ba95c37dd48d4181193fa0 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -216,6 +216,7 @@ long qiwrite(Queue*, void*, int); long qwrite(Queue*, void*, int); void qsetlimit(Queue*, int); void qnoblock(Queue*, int); +void randomclock(void); int readnum(ulong, char*, ulong, ulong, int); int readstr(ulong, char*, ulong, char*); void ready(Proc*); diff --git a/port/proc.c b/port/proc.c index d387e1aaa1bda50e6f597d705a9d34226635afc9..c8fd00b6afb07f5aa432c5c84186f6a4da4bed55 100644 --- a/port/proc.c +++ b/port/proc.c @@ -47,6 +47,8 @@ char *statename[] = "Rendez", }; +ulong randomcount; + /* * Always splhi()'ed. */ @@ -183,7 +185,7 @@ loop: * or one that hasn't moved in a while (load balancing). */ spllo(); - for(;;){ + for(randomcount++;;randomcount++){ /* * Once a second we look for a long waiting process * in the lowest priority queue to make sure nothing