From 6affaa48b03cee73b8c4b312d63d1efb8d7315e7 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 2 Jun 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-06-02 --- gnot/fns.h | 1 - gnot/main.c | 1 - pc/devuart.c | 15 ---- pc/main.c | 1 - port/alarm.c | 211 ++++++++++--------------------------------------- port/devcons.c | 4 +- port/devip.c | 10 +-- port/devscc.c | 1 - port/fault.c | 1 + port/pgrp.c | 5 +- port/portdat.h | 18 +++-- port/portfns.h | 7 -- port/proc.c | 58 ++++++-------- port/taslock.c | 17 ++-- power/main.c | 16 ++-- ss/fns.h | 1 - ss/main.c | 1 - 17 files changed, 101 insertions(+), 267 deletions(-) diff --git a/gnot/fns.h b/gnot/fns.h index 18731ec317746749c073c4f18670a59242a56ef0..75b6db193e635c2f82f86fd48389d22fefe89983 100644 --- a/gnot/fns.h +++ b/gnot/fns.h @@ -36,7 +36,6 @@ void procrestore(Proc*); void procsave(Proc*); void procsetup(Proc*); void putkmmu(ulong, ulong); -void restartprint(Alarm*); void restfpregs(FPsave*); void screeninit(void); void screenputc(int); diff --git a/gnot/main.c b/gnot/main.c index 1c691617dce1c10ebe3191ee40069c40e3275cab..70631d263dc9725b5f02615796cf4a06a57a4727 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -50,7 +50,6 @@ main(void) initseg(); grpinit(); chaninit(); - alarminit(); chandevreset(); streaminit(); /* serviceinit(); /**/ diff --git a/pc/devuart.c b/pc/devuart.c index a26ad64def7efa6d117f29a7757bbff56e2c4a22..45ab9fcedc22221315bfe84a8a2e1c09fc84a5bf 100644 --- a/pc/devuart.c +++ b/pc/devuart.c @@ -70,7 +70,6 @@ struct Uart /* stream interface */ Queue *wq; /* write queue */ Rendez r; /* kproc waiting for input */ - Alarm *a; /* alarm for waking the kernel process */ int kstarted; /* kproc started */ /* error statistics */ @@ -401,7 +400,6 @@ uartspecial(int port, IOQ *oq, IOQ *iq, int baud) } } -static void uarttimer(Alarm*); static int uartputc(IOQ *, int); static void uartstopen(Queue*, Stream*); static void uartstclose(Queue*); @@ -416,19 +414,6 @@ Qinfo uartinfo = "uart" }; -/* - * create a helper process per port - */ -static void -uarttimer(Alarm *a) -{ - Uart *up = a->arg; - - cancel(a); - up->a = 0; - wakeup(&up->iq->r); -} - static void uartstopen(Queue *q, Stream *s) { diff --git a/pc/main.c b/pc/main.c index 6c981aa2a166b2cda17422bd6f393bdc6c14b68f..3e793e7fafd5b7e01032e214b37ff0282e9f281a 100644 --- a/pc/main.c +++ b/pc/main.c @@ -32,7 +32,6 @@ main(void) initseg(); grpinit(); chaninit(); - alarminit(); chandevreset(); streaminit(); swapinit(); diff --git a/port/alarm.c b/port/alarm.c index 9976a507404561e93e17d68cb2b88fc305a82490..7287bc62b70af39ca88a67a3c72e5730e50f884f 100644 --- a/port/alarm.c +++ b/port/alarm.c @@ -5,93 +5,14 @@ #include "fns.h" #include "io.h" -struct { - Lock; - Alarm *tab; /* table of all alarm structures */ - void *list; /* busy alarms */ - Rendez r; -} alarmalloc; - Alarms alarms; - -Alarm* -alarm(int ms, void (*f)(Alarm*), void *arg) -{ - Alarm *a, *w, *pw; - int s; - - if(ms < 0) - ms = 0; - a = newalarm(); - a->when = MACHP(0)->ticks+MS2TK(ms); - a->f = f; - a->arg = arg; - s = splhi(); - lock(&alarmalloc); - pw = 0; - for(w=alarmalloc.list; w; pw=w, w=w->next){ - if(w->when > a->when) - break; - } - insert(&alarmalloc.list, pw, a); - unlock(&alarmalloc); - splx(s); - return a; -} +Rendez alarmr; +Talarm talarm; -void -cancel(Alarm *a) -{ - a->f = 0; -} - -Alarm* -newalarm(void) -{ - int i; - Alarm *a; - - for(i=0,a=alarmalloc.tab; ibusy==0 && a->f==0 && canlock(a)){ - if(a->busy){ - unlock(a); - continue; - } - a->f = 0; - a->arg = 0; - a->busy = 1; - unlock(a); - return a; - } - panic("newalarm"); - return 0; /* not reached */ -} - -/* allocate locks here since you can't allocate them at interrupt time (on the SGI) */ -void -alarminit(void) -{ - int i; - - alarmalloc.tab = ialloc(conf.nalarm*sizeof(Alarm), 0); - for(i=0; iticks; - - s = splhi(); - lock(&alarmalloc); - a = alarmalloc.list; - if(a){ - for(n=0; a && a->when<=now && nerror); - } else { - for(i = 0; i < n; i++){ - f = alist[i]->f; /* avoid race with cancel */ - if(f) - (*f)(alist[i]); - alist[i]->busy = 0; - } - poperror(); - } - }else{ - unlock(&alarmalloc); - splx(s); - } - qlock(&alarms); while((rp = alarms.head) && rp->alarm <= now){ if(rp->alarm != 0L){ @@ -151,7 +38,7 @@ alarmkproc(void *arg) } qunlock(&alarms); - sleep(&alarmalloc.r, return0, 0); + sleep(&alarmr, return0, 0); } } @@ -161,90 +48,78 @@ alarmkproc(void *arg) void checkalarms(void) { - ulong now; Proc *p; - Alarm *a; + ulong now; - a = alarmalloc.list; p = alarms.head; now = MACHP(0)->ticks; - if((a && a->when <= now) || (p && p->alarm <= now)) - wakeup(&alarmalloc.r); + if(p && p->alarm <= now) + wakeup(&alarmr); + + if(talarm.list == 0 || canlock(&talarm) == 0) + return; + + for(;;) { + p = talarm.list; + if(p == 0) + break; + + if(p->twhen == 0) { + talarm.list = p->tlink; + continue; + } + if(now < p->twhen) + break; + talarm.list = p->tlink; + wakeup(p->trend); + } + + unlock(&talarm); } ulong procalarm(ulong time) { - Proc **l, *f; + Proc **l, *f, *p; ulong when, old; - old = TK2MS(u->p->alarm - MACHP(0)->ticks); - if(time == 0){ - u->p->alarm = 0; + p = u->p; + old = TK2MS(p->alarm - MACHP(0)->ticks); + if(time == 0) { + p->alarm = 0; return old; } - when = MS2TK(time); - when += MACHP(0)->ticks; + when = MS2TK(time)+MACHP(0)->ticks; qlock(&alarms); l = &alarms.head; - for(f = *l; f; f = f->palarm){ - if(u->p == f){ + for(f = *l; f; f = f->palarm) { + if(p == f){ *l = f->palarm; break; } l = &f->palarm; } - u->p->palarm = 0; - if(alarms.head){ + p->palarm = 0; + if(alarms.head) { l = &alarms.head; - for(f = *l; f; f = f->palarm){ - if(f->alarm > when){ - u->p->palarm = f; - *l = u->p; + for(f = *l; f; f = f->palarm) { + if(f->alarm > when) { + p->palarm = f; + *l = p; goto done; } l = &f->palarm; } - *l = u->p; + *l = p; } else - alarms.head = u->p; + alarms.head = p; done: - u->p->alarm = when; + p->alarm = when; qunlock(&alarms); return old; } - -/* - * Insert new into list after where - */ -void -insert(List **head, List *where, List *new) -{ - if(where == 0){ - new->next = *head; - *head = new; - }else{ - new->next = where->next; - where->next = new; - } - -} - -/* - * Delete old from list. where->next is known to be old. - */ -void -delete(List **head, List *where, List *old) -{ - if(where == 0){ - *head = old->next; - return; - } - where->next = old->next; -} - diff --git a/port/devcons.c b/port/devcons.c index 37b74d34b8ae44561844ee805adfb23ee9079c3e..6f1575f3ea86ef77e84ac92c4dc68372cf3c6a75 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -513,10 +513,8 @@ consread(Chan *c, void *buf, long n, ulong offset) do{ lock(&lineq); ch = getc(&kbdq); - if(raw){ - unlock(&lineq); + if(raw) goto Default; - } switch(ch){ case '\b': if(lineq.in != lineq.out){ diff --git a/port/devip.c b/port/devip.c index cfec8649029ee0eb88a55d40c181c7a1dff2d9f3..62df1310a8d6f1c185e542fc2d297308c1811e37 100644 --- a/port/devip.c +++ b/port/devip.c @@ -1048,7 +1048,7 @@ bsdoput(Queue *q, Block *bp) } /* collect into a single block */ - lock(q); + qlock(&q->rlock); if(q->first == 0) q->first = pullup(bp, blen(bp)); else{ @@ -1058,7 +1058,7 @@ bsdoput(Queue *q, Block *bp) } bp = q->first; if(bp == 0){ - unlock(q); + qunlock(&q->rlock); bsdclose(q); return; } @@ -1066,12 +1066,12 @@ bsdoput(Queue *q, Block *bp) /* look for 2 nulls to indicate stderr port and local user */ luser = memchr(bp->rptr, 0, BLEN(bp)); if(luser == 0){ - unlock(q); + qunlock(&q->rlock); return; } luser++; if(memchr(luser, 0, bp->wptr - luser) == 0){ - unlock(q); + qunlock(&q->rlock); return; } @@ -1084,5 +1084,5 @@ bsdoput(Queue *q, Block *bp) q->first = 0; bp->flags |= S_DELIM; PUTNEXT(q, bp); - unlock(q); + qunlock(&q->rlock); } diff --git a/port/devscc.c b/port/devscc.c index 44bd2e393a0f6fd6a9741ce9fa22bd8a88a43cf9..c2a3a12ca101dec7522926ba9ade1b8ed90b5e03 100644 --- a/port/devscc.c +++ b/port/devscc.c @@ -103,7 +103,6 @@ struct SCC /* stream interface */ Queue *wq; /* write queue */ Rendez r; /* kproc waiting for input */ - Alarm *a; /* alarm for waking the kernel process */ int kstarted; /* kproc started */ /* idiot flow control */ diff --git a/port/fault.c b/port/fault.c index 5ac2c395bac84ffb5ed2514e578ec0f22039689a..67edff17f5563ef5a43e36a1a40680f3164bf171 100644 --- a/port/fault.c +++ b/port/fault.c @@ -17,6 +17,7 @@ fault(ulong addr, int read) sps = u->p->psstate; u->p->psstate = "Fault"; + spllo(); m->pfault++; for(;;) { diff --git a/port/pgrp.c b/port/pgrp.c index 34db395f41d692b80c1abe6da2a68696b6d6fec7..9ebdda50b120f98319f5f26b690e636e65db12b5 100644 --- a/port/pgrp.c +++ b/port/pgrp.c @@ -199,9 +199,8 @@ resrcwait(char *reason) } if(u == 0) panic("resrcwait"); - u->p->state = Wakeme; - alarm(1000, wakeme, u->p); - sched(); + + tsleep(&u->p->sleep, return0, 0, 1000); u->p->psstate = p; } diff --git a/port/portdat.h b/port/portdat.h index aa4d14963256ac4f8d83812d98b7a1ac2e8e0bee..3285881db57735e54a7f1a334d7764dea8a17a54 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -1,4 +1,3 @@ -typedef struct Alarm Alarm; typedef struct Alarms Alarms; typedef struct Block Block; typedef struct Blist Blist; @@ -35,6 +34,7 @@ typedef struct Rendez Rendez; typedef struct RWlock RWlock; typedef struct Segment Segment; typedef struct Stream Stream; +typedef struct Talarm Talarm; typedef struct Waitq Waitq; typedef int Devgen(Chan*, Dirtab*, int, int, Dir*); @@ -71,14 +71,10 @@ struct RWlock int readers; /* Count of readers in lock */ }; -struct Alarm +struct Talarm { - List; Lock; - int busy; - ulong when; /* may underflow in clock(); must be signed */ - void (*f)(void*); - void *arg; + Proc *list; }; struct Alarms @@ -550,7 +546,7 @@ struct Proc ulong pc; /* DEBUG only */ Rendez *r; /* rendezvous point slept on */ - Rendez sleep; /* place for tsleep/syssleep/debug */ + Rendez sleep; /* place for syssleep/debug */ int notepending; /* note issued but not acted on */ int kp; /* true if a kernel process */ Proc *palarm; /* Next alarm time */ @@ -561,6 +557,11 @@ struct Proc ulong rendtag; /* Tag for rendezvous */ ulong rendval; /* Value for rendezvous */ Proc *rendhash; /* Hash list for tag values */ + + ulong twhen; + Rendez *trend; + Proc *tlink; + /* * machine specific MMU goo */ @@ -696,6 +697,7 @@ extern int nrdy; extern char sysname[NAMELEN]; extern int cpuserver; extern Ref noteidalloc; +extern Talarm talarm; #define CHDIR 0x80000000L #define CHAPPEND 0x40000000L diff --git a/port/portfns.h b/port/portfns.h index 34e8d009e1db9a1f7a4a574a80d5a0bc84dd6e4a..a7cc2c5704b4a8d979b59a23de7bb1db1ca795e4 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -1,5 +1,3 @@ -Alarm* alarm(int, void (*)(Alarm*), void*); -void alarminit(void); void alarmkproc(void*); Block* allocb(ulong); int anyready(void); @@ -9,7 +7,6 @@ int blen(Block *); int bround(Block *, int); void buzz(int, int); void cachepage(Page*, Image*); -void cancel(Alarm*); int cangetc(void*); int canlock(Lock*); int canpage(Proc*); @@ -73,7 +70,6 @@ void firmware(void); int fixfault(Segment*, ulong, int, int); void flowctl(Queue*, Block*); void flushmmu(void); -void freealarm(Alarm*); void freeb(Block*); int freebroken(void); void freechan(Chan*); @@ -133,7 +129,6 @@ long netread(Chan*, void*, long, ulong, Network*); void netstat(Chan*, char*, Network*); int netwalk(Chan*, char*, Network*); void netwstat(Chan*, char*, Network*); -Alarm* newalarm(void); Chan* newchan(void); Egrp* newegrp(void); Fgrp* newfgrp(void); @@ -236,7 +231,6 @@ void swapinit(void); long syscall(Ureg*); void tcpinit(void); void tsleep(Rendez*, int (*)(void*), void*, int); -void twakeme(Alarm*); void uncachepage(Page*); long unionread(Chan*, void*, long); void unlock(Lock*); @@ -246,7 +240,6 @@ void userinit(void); ulong userpc(void); void validaddr(ulong, ulong, int); void* vmemchr(void*, int, int); -void wakeme(Alarm*); void wakeup(Rendez*); void rlock(RWlock*); void runlock(RWlock*); diff --git a/port/proc.c b/port/proc.c index 387f5590916f4c2436580340d38728ee0e82759e..22bc3032c9bb9c20a797f2404b69627ba2c0e8f7 100644 --- a/port/proc.c +++ b/port/proc.c @@ -317,29 +317,32 @@ sleep(Rendez *r, int (*f)(void*), void *arg) } void -tsleep(Rendez *r, int (*f)(void*), void *arg, int ms) +tsleep(Rendez *r, int (*fn)(void*), void *arg, int ms) { - Alarm *a; - Proc *p; - int s; + ulong when; + Proc *p, *f, **l, **i; p = u->p; - sleep1(r, f, arg); - if(p->notepending == 0){ - a = alarm(ms, twakeme, r); - sched(); /* notepending may go true while asleep */ - cancel(a); - } - if(p->notepending){ - p->notepending = 0; - s = splhi(); - lock(r); - if(r->p == p) - r->p = 0; - unlock(r); - splx(s); - error(Eintr); + when = MS2TK(ms)+MACHP(0)->ticks; + i = &talarm.list; + + lock(&talarm); + l = &talarm.list; + for(f = talarm.list; f; f = f->tlink) { + if(f == p) + *l = p->tlink; + if(f->twhen && f->twhen < when) + i = &f->tlink; + l = &f->tlink; } + p->trend = r; + p->twhen = when; + p->tlink = *i; + *i = p; + unlock(&talarm); + + sleep(r, fn, arg); + p->twhen = 0; } void @@ -356,29 +359,12 @@ wakeup(Rendez *r) if(p->state != Wakeme) panic("wakeup: state"); p->r = 0; -if((p->sched.pc&KZERO) != KZERO){ - spllo(); - panic("wakeup"); -} ready(p); } unlock(r); splx(s); } -void -wakeme(Alarm *a) -{ - ready((Proc*)(a->arg)); - cancel(a); -} - -void -twakeme(Alarm *a) -{ - wakeup((Rendez*)(a->arg)); -} - int postnote(Proc *p, int dolock, char *n, int flag) { diff --git a/port/taslock.c b/port/taslock.c index 3092e8519a865f35a5fd127f2e195b648f907e1d..d61a72302defbf0be59d0aa4c4b4d367d52e3de1 100644 --- a/port/taslock.c +++ b/port/taslock.c @@ -5,6 +5,9 @@ #include "fns.h" #include "../port/error.h" +ulong spinner; +ulong spinpc; + void lock(Lock *l) { @@ -13,10 +16,12 @@ lock(Lock *l) ulong pc; pc = getcallerpc(((uchar*)&l) - sizeof(l)); -if(l == 0){ -print("pc= %lux", pc); -for(;;); -} + if (tas(&ll->key) == 0){ + if(u) + u->p->hasspin = 1; + ll->pc = pc; + return; + } for(i = 0; i < 1000000; i++){ if (tas(&ll->key) == 0){ if(u) @@ -24,8 +29,8 @@ for(;;); ll->pc = pc; return; } - if(u && u->p->state == Running) - sched(); +spinner++; +spinpc = pc; } i = l->key; l->key = 0; diff --git a/power/main.c b/power/main.c index 0522bc565006aed8add9defa6e70aba7dd27556a..6ce6b0b336363406f6ad434c096d6754100ce49f 100644 --- a/power/main.c +++ b/power/main.c @@ -56,7 +56,6 @@ main(void) grpinit(); chaninit(); clockinit(); - alarminit(); ioboardinit(); chandevreset(); streaminit(); @@ -600,7 +599,7 @@ confinit(void) * we do this because the arguments are in memory that may be allocated * to processes or kernel buffers. */ -#define SYSENV "netaddr=" +#define IPADDRENV "netaddr=" void arginit(void) { @@ -614,16 +613,13 @@ arginit(void) /* * get the system name from the environment */ - if(*sysname == 0){ - for(argv = _env; *argv; argv++){ - if(strncmp(*argv, SYSENV, sizeof(SYSENV)-1)==0){ - strcpy(sysname, (*argv) + sizeof(SYSENV)-1); - break; - } + strcpy(envbuf, IPADDRENV); + for(argv = _env; *argv; argv++){ + if(strncmp(*argv, IPADDRENV, sizeof(IPADDRENV)-1)==0){ + strcat(envbuf, (*argv) + sizeof(IPADDRENV)-1); + break; } } - strcpy(envbuf, SYSENV); - strcat(envbuf, sysname); env[0] = envbuf; env[1] = 0; diff --git a/ss/fns.h b/ss/fns.h index 1e98b5b154c5b9bfaea58d7116778fb074b9f667..fcc7487280a0ccc54622680998277b83333abd6a 100644 --- a/ss/fns.h +++ b/ss/fns.h @@ -55,7 +55,6 @@ void putwD(ulong, ulong); void putwE16(ulong, ulong); void putwE(ulong, ulong); void systemreset(void); -void restartprint(Alarm*); void restfpregs(FPsave*); void screeninit(void); void screenputc(int); diff --git a/ss/main.c b/ss/main.c index e9ca1a15266bc8e4a28d204123ad95f5a7e4cb2a..7f6e58b5620f28a3fff23933fbfacb075ebb771c 100644 --- a/ss/main.c +++ b/ss/main.c @@ -36,7 +36,6 @@ main(void) initseg(); grpinit(); chaninit(); - alarminit(); chandevreset(); streaminit(); pageinit();