From 2a898c74fd025a804879fbb782ea10adb0c08d69 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sat, 28 Jul 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-07-28 --- gnot/clock.c | 24 +++++++++----- gnot/devdk.c | 16 +++++++--- gnot/devmnt.c | 1 - gnot/errno.h | 1 + gnot/page.c | 13 +++++--- gnot/proc.c | 11 +++++-- gnot/sturp.c | 84 ++++++++++++++++++++++++++++++------------------- port/devbit.c | 4 +-- port/page.c | 14 ++++++--- port/proc.c | 1 - port/sturp.c | 86 +++++++++++++++++---------------------------------- power/clock.c | 24 +++++++++----- 12 files changed, 152 insertions(+), 127 deletions(-) diff --git a/gnot/clock.c b/gnot/clock.c index 0877c0e92c3b0a60010ea15918aaef913782b4d3..854be58349d1cfc8d70555f8c7b0a8fe392e259b 100644 --- a/gnot/clock.c +++ b/gnot/clock.c @@ -87,13 +87,15 @@ delay(int ms) ; } +#define NA 10 void clock(Ureg *ur) { - int i; + int i, n; Alarm *a; void (*f)(void*); Proc *p; + Alarm *alist[NA]; SYNCREG[1] = 0x5F; /* clear interrupt */ m->ticks++; @@ -106,16 +108,22 @@ clock(Ureg *ur) if(m->alarm){ a = m->alarm; a->dt--; - while(a && a->dt<=0){ - f = a->f; /* avoid race with cancel */ - if(f) - (*f)(a); + for(n = 0; a && a->dt<=0 && nalarm, 0, a); - a->busy = 0; a = m->alarm; } - } - unlock(&m->alarmlock); + unlock(&m->alarmlock); + + /* execute alarm functions outside the lock */ + for(i = 0; i < n; i++){ + f = alist[i]->f; /* avoid race with cancel */ + if(f) + (*f)(alist[i]); + alist[i]->busy = 0; + } + } else + unlock(&m->alarmlock); } kbdclock(); mouseclock(); diff --git a/gnot/devdk.c b/gnot/devdk.c index 88599861ed9b0178e491ba31402c32f01b3732c7..bacd0cc2f866576bc36e86cc3ffe21e54f078b6c 100644 --- a/gnot/devdk.c +++ b/gnot/devdk.c @@ -456,6 +456,7 @@ dkmuxconfig(Dk *dp, Block *bp) */ dp->restart = 1; n = getfields((char *)bp->rptr, fields, 4, ' '); + strcpy(dp->name, "dk"); switch(n){ case 4: strncpy(dp->name, fields[3], sizeof(dp->name)); @@ -494,7 +495,7 @@ dkmuxconfig(Dk *dp, Block *bp) /* * start a process to deal with it */ - sprint(buf, "**csckproc%d**", dp->ncsc); + sprint(buf, "csckproc%d", dp->ncsc); kproc(buf, dkcsckproc, dp); poperror(); @@ -503,7 +504,7 @@ dkmuxconfig(Dk *dp, Block *bp) */ if(dktimeron == 0){ dktimeron = 1; - kproc("**dktimer**", dktimer, 0); + kproc("dktimer", dktimer, 0); } } @@ -592,8 +593,10 @@ dkattach(char *spec) Dk *dp; /* - * find a multiplexor with the same name + * find a multiplexor with the same name (default dk) */ + if(*spec == 0) + spec = "dk"; for(dp = dk; dp < &dk[Ndk]; dp++){ qlock(dp); if(dp->wq && strcmp(spec, dp->name)==0) { @@ -859,8 +862,10 @@ dkmesg(Dk *dp, int type, int srv, int p0, int p1) if(dp->csc == 0) return -1; - if(waserror()) + if(waserror()){ + print("dkmesg: error\n"); return -1; + } d.type = type; d.srv = srv; d.param0l = p0; @@ -1477,7 +1482,8 @@ dktimer(void *a) Dk *dp; Line *lp; - waserror(); + while(waserror()) + print("dktimer: error\n"); for(;;){ /* diff --git a/gnot/devmnt.c b/gnot/devmnt.c index c96f567a91dad05afe95d1d46a88913cf1dd2b3c..239b2b253383fbeb890e71a0eda588606e89c1e2 100644 --- a/gnot/devmnt.c +++ b/gnot/devmnt.c @@ -291,7 +291,6 @@ mntattach(char *spec) mh = mhalloc(); if(waserror()){ mhfree(mh); - mqfree(q); close(c); nexterror(); } diff --git a/gnot/errno.h b/gnot/errno.h index f569775960d22f6307d687a57ff826844e296c87..ee070d757d339a590130a6765dd747ff37150b39 100644 --- a/gnot/errno.h +++ b/gnot/errno.h @@ -50,6 +50,7 @@ enum{ Enobitmap, /* out of bitmap descriptors */ Enobitstore, /* out of bitmap storage */ Ebadbitmap, /* unallocated bitmap */ + Ebadfont, /* unallocated font */ Eshortmsg, /* short message */ Ebadmsg, /* format error or mismatch in message */ Ebadcnt, /* read count greater than requested */ diff --git a/gnot/page.c b/gnot/page.c index cd6e44462a5e3c7a8d9c2eb23cb0127873342bf0..e0164e6422dff0e2be3e66857d5b00669bd46ddf 100644 --- a/gnot/page.c +++ b/gnot/page.c @@ -560,10 +560,14 @@ growpte(Orig *o, ulong n) lock(&ptealloc); lock(o); if(o->pte){ - if(o->npte == n) - panic("growpte pointless"); + if(o->npte == n){ + print("growpte pointless\n"); + goto Return; + } p = (PTEA*)(o->pte - 1); if(o->npte > n){ + print("growpte shrink"); + goto Return; nfree = o->npte - n; p->n -= nfree; o->npte -= nfree; @@ -589,9 +593,7 @@ growpte(Orig *o, ulong n) p->n = n; o->npte = n-1; } - unlock(o); - unlock(&ptealloc); - return; + goto Return; } n++; compactpte(o, n); @@ -602,6 +604,7 @@ growpte(Orig *o, ulong n) p->o = o; o->pte = p+1; o->npte = n-1; + Return: unlock(o); unlock(&ptealloc); } diff --git a/gnot/proc.c b/gnot/proc.c index eed82727919e996223972847a5452ceee822cd95..d86d46c3cbc8c19176619eedb4cdf59faae0ad06 100644 --- a/gnot/proc.c +++ b/gnot/proc.c @@ -575,6 +575,7 @@ kproc(char *name, void (*func)(void *), void *arg) int lastvar; /* used to compute stack address */ User *up; KMap *k; + static Pgrp *kpgrp; /* * Kernel stack @@ -612,12 +613,16 @@ kproc(char *name, void (*func)(void *), void *arg) p->mach = m; m->proc = p; spllo(); - strncpy(p->text, name, sizeof p->text); (*func)(arg); pexit(0, 1); } - p->pgrp = u->p->pgrp; - incref(p->pgrp); + if(kpgrp == 0){ + kpgrp = newpgrp(); + strcpy(kpgrp->user, "bootes"); + } + p->pgrp = kpgrp; + incref(kpgrp); + sprint(p->text, "%s.%.6s", name, u->p->pgrp->user); p->nchild = 0; p->parent = 0; memset(p->time, 0, sizeof(p->time)); diff --git a/gnot/sturp.c b/gnot/sturp.c index a6879dc8ccef1fbff799e5511a68737309705caa..929461944bf8e7a86514ce7601e185e79b26bae6 100644 --- a/gnot/sturp.c +++ b/gnot/sturp.c @@ -11,7 +11,7 @@ enum { Nmask= 0x7, }; -#define DPRINT if(q->flag&QDEBUG)kprint +#define DPRINT /*if(q->flag&QDEBUG)kprint*/ typedef struct Urp Urp; @@ -116,6 +116,7 @@ static void sendrej(Urp*); static void initoutput(Urp*, int); static void initinput(Urp*, int); static void urpkproc(void *arg); +static void urptimer(Alarm*); static void urpvomit(char*, Urp*); Qinfo urpinfo = { urpciput, urpoput, urpopen, urpclose, "urp" }; @@ -125,6 +126,7 @@ urpreset(void) { newqinfo(&urpinfo); urp = (Urp *)ialloc(conf.nurp*sizeof(Urp), 0); + alarm(500, urptimer, 0); } static void @@ -160,17 +162,22 @@ urpopen(Queue *q, Stream *s) /* * start the ack/(re)xmit process */ - if(up->kstarted == 0){ - up->kstarted = 1; - sprint(name, "**urp%d**", up - urp); - kproc(name, urpkproc, up); - } + sprint(name, "urp%d", up - urp); + kproc(name, urpkproc, up); } /* * Shut down the connection and kill off the kernel process */ static int +isdead(void *a) +{ + Urp *up; + + up = (Urp *)a; + return up->kstarted==0; +} +static int isflushed(void *a) { Urp *up; @@ -199,7 +206,7 @@ urpclose(Queue *q) tsleep(&up->r, isflushed, up, 2*60*1000); /* - * kill off the kernel process + * tell kernel process to die */ up->state |= HUNGUP; wakeup(&up->rq->r); @@ -223,10 +230,13 @@ urpclose(Queue *q) } qunlock(&up->xmit); - if(up->kstarted == 0){ - DPRINT("urpclose %ux\n", up); - up->state = 0; - } + /* + * wait for kernel process to die + */ + while(up->kstarted) + sleep(&up->r, isdead, up); + + up->state = 0; } /* @@ -607,9 +617,7 @@ output(Urp *up) sendctl(up, INIT1); up->timer = now + MSrexmit; } - qunlock(&up->xmit); - poperror(); - return; + goto out; } /* @@ -653,9 +661,7 @@ output(Urp *up) up->timer = NOW + MSrexmit; up->state &= ~REJECTING; sendctl(up, ENQ); - qunlock(&up->xmit); - poperror(); - return; + goto out; } /* @@ -676,6 +682,7 @@ output(Urp *up) up->next = NEXT(up->next); poperror(); } +out: qunlock(&up->xmit); poperror(); } @@ -941,39 +948,54 @@ todo(void *arg) static void urpkproc(void *arg) { - Urp *up; Queue *q; + Urp *up; up = (Urp *)arg; - q = up->wq; + up->kstarted = 1; if(waserror()){ print("urpkproc error %ux\n", up); - up->state = 0; up->kstarted = 0; wakeup(&up->r); return; } for(;;){ - if(up->state & (HUNGUP|CLOSING)){ - if(isflushed(up)) - wakeup(&up->r); - if(up->state & HUNGUP) - break; - } - if(up->state == 0){ - DPRINT("urpkproc: %ux->state == 0\n", up); + if(up->state & HUNGUP) break; - } if(!QFULL(up->rq->next)) sendack(up); output(up); - tsleep(&up->rq->r, todo, up, MSrexmit/2); + sleep(&up->rq->r, todo, up); } - up->state = 0; up->kstarted = 0; + wakeup(&up->r); + poperror(); DPRINT("urpkproc %ux\n", up); } +/* + * timer to wakeup urpkproc's for retransmissions + */ +static void +urptimer(Alarm *a) +{ + Urp *up; + Urp *last; + Queue *q; + + cancel(a); + alarm(500, urptimer, 0); + for(up = urp, last = &urp[conf.nurp]; up < last; up++){ + if(up->state==0) + continue; + if(up->unacked!=up->next && NOW>up->timer){ + q = up->rq; + if(q) + wakeup(&q->r); + } + } +} + /* * urp got very confused, complain */ diff --git a/port/devbit.c b/port/devbit.c index bd217e8f98912d5d0bacd94789bc2af8bba17f9e..f324a3567cb318a521a6795a642c35773402a0fe 100644 --- a/port/devbit.c +++ b/port/devbit.c @@ -61,7 +61,7 @@ struct{ Cursor arrow = { - {0, 0}, + {1, 1}, {0xFF, 0xE0, 0xFF, 0xE0, 0xFF, 0xC0, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x80, 0xFF, 0xC0, 0xFF, 0xE0, 0xE7, 0xF0, 0xE3, 0xF8, 0xC1, 0xFC, 0x00, 0xFE, @@ -657,7 +657,7 @@ bitwrite(Chan *c, void *va, long n) v = GSHORT(p+1); f = &bit.font[v]; if(v<0 || v>=conf.nfont || f->bits==0) - error(0, Ebadbitmap); + error(0, Ebadfont); f->bits = 0; m -= 3; p += 3; diff --git a/port/page.c b/port/page.c index d284ee0592394791b3f993dac68716e5c6ac318b..82b7bd028f772dadcadbdd4123ed945e064e3554 100644 --- a/port/page.c +++ b/port/page.c @@ -560,10 +560,15 @@ growpte(Orig *o, ulong n) lock(&ptealloc); lock(o); if(o->pte){ - if(o->npte == n) - panic("growpte pointless"); + if(o->npte == n){ +if(u && u->p) print("%s: ", u->p->text); + print("growpte pointless\n"); + goto Return; + } p = (PTEA*)(o->pte - 1); if(o->npte > n){ + print("growpte shrink"); + goto Return; nfree = o->npte - n; p->n -= nfree; o->npte -= nfree; @@ -589,9 +594,7 @@ growpte(Orig *o, ulong n) p->n = n; o->npte = n-1; } - unlock(o); - unlock(&ptealloc); - return; + goto Return; } n++; compactpte(o, n); @@ -602,6 +605,7 @@ growpte(Orig *o, ulong n) p->o = o; o->pte = p+1; o->npte = n-1; + Return: unlock(o); unlock(&ptealloc); } diff --git a/port/proc.c b/port/proc.c index e94fc65960ae39adb5f09e61cbae06fdf4bdfea7..a68f9eb1f4c72ce8f6b0c082a91ca4a6a7707f11 100644 --- a/port/proc.c +++ b/port/proc.c @@ -299,7 +299,6 @@ void twakeme(Alarm *a) { wakeup((Rendez*)(a->arg)); - cancel(a); } int diff --git a/port/sturp.c b/port/sturp.c index e8a412e9dc84befc9d2934d7ebbe6ea5ad336a0d..929461944bf8e7a86514ce7601e185e79b26bae6 100644 --- a/port/sturp.c +++ b/port/sturp.c @@ -67,12 +67,6 @@ struct Urp { #define IN(x, f, n) (f<=n ? (x>=f && x=f)) #define NEXT(x) (((x)+1)&Nmask) -/* - * Alarm for urptiming - */ -Alarm *urptiming; -Lock urptlock; - /* * Protocol control bytes */ @@ -132,6 +126,7 @@ urpreset(void) { newqinfo(&urpinfo); urp = (Urp *)ialloc(conf.nurp*sizeof(Urp), 0); + alarm(500, urptimer, 0); } static void @@ -167,28 +162,22 @@ urpopen(Queue *q, Stream *s) /* * start the ack/(re)xmit process */ - if(up->kstarted == 0){ - up->kstarted = 1; - sprint(name, "urp%d", up - urp); - kproc(name, urpkproc, up); - } - - /* - * start the urptimer if it isn't already - */ - if(urptiming==0){ - if(canlock(&urptlock)){ - if(urptiming == 0) - urptiming = alarm(500, urptimer, 0); - unlock(&urptlock); - } - } + sprint(name, "urp%d", up - urp); + kproc(name, urpkproc, up); } /* * Shut down the connection and kill off the kernel process */ static int +isdead(void *a) +{ + Urp *up; + + up = (Urp *)a; + return up->kstarted==0; +} +static int isflushed(void *a) { Urp *up; @@ -217,7 +206,7 @@ urpclose(Queue *q) tsleep(&up->r, isflushed, up, 2*60*1000); /* - * kill off the kernel process + * tell kernel process to die */ up->state |= HUNGUP; wakeup(&up->rq->r); @@ -241,10 +230,13 @@ urpclose(Queue *q) } qunlock(&up->xmit); - if(up->kstarted == 0){ - DPRINT("urpclose %ux\n", up); - up->state = 0; - } + /* + * wait for kernel process to die + */ + while(up->kstarted) + sleep(&up->r, isdead, up); + + up->state = 0; } /* @@ -607,17 +599,6 @@ output(Urp *up) int n; int i; - /* - * start the urptimer if it isn't already - */ - if(urptiming==0){ - if(canlock(&urptlock)){ - if(urptiming == 0) - urptiming = alarm(500, urptimer, 0); - unlock(&urptlock); - } - } - if(!canqlock(&up->xmit)) return; @@ -636,9 +617,7 @@ output(Urp *up) sendctl(up, INIT1); up->timer = now + MSrexmit; } - qunlock(&up->xmit); - poperror(); - return; + goto out; } /* @@ -682,9 +661,7 @@ output(Urp *up) up->timer = NOW + MSrexmit; up->state &= ~REJECTING; sendctl(up, ENQ); - qunlock(&up->xmit); - poperror(); - return; + goto out; } /* @@ -705,6 +682,7 @@ output(Urp *up) up->next = NEXT(up->next); poperror(); } +out: qunlock(&up->xmit); poperror(); } @@ -970,36 +948,28 @@ todo(void *arg) static void urpkproc(void *arg) { - Urp *up; Queue *q; + Urp *up; up = (Urp *)arg; - q = up->wq; + up->kstarted = 1; if(waserror()){ print("urpkproc error %ux\n", up); - up->state = 0; up->kstarted = 0; wakeup(&up->r); return; } for(;;){ - if(up->state & (HUNGUP|CLOSING)){ - if(isflushed(up)) - wakeup(&up->r); - if(up->state & HUNGUP) - break; - } - if(up->state == 0){ - DPRINT("urpkproc: %ux->state == 0\n", up); + if(up->state & HUNGUP) break; - } if(!QFULL(up->rq->next)) sendack(up); output(up); sleep(&up->rq->r, todo, up); } - up->state = 0; up->kstarted = 0; + wakeup(&up->r); + poperror(); DPRINT("urpkproc %ux\n", up); } @@ -1014,7 +984,7 @@ urptimer(Alarm *a) Queue *q; cancel(a); - urptiming = 0; + alarm(500, urptimer, 0); for(up = urp, last = &urp[conf.nurp]; up < last; up++){ if(up->state==0) continue; diff --git a/power/clock.c b/power/clock.c index 0ad8e1c9e27d04f2548fdbb3d98c9d728ae3faf8..ae2b78a5dcad3af6d268205021086be6b266b124 100644 --- a/power/clock.c +++ b/power/clock.c @@ -135,13 +135,15 @@ clockinit(void) m->ticks = 0; } +#define NA 10 void clock(ulong n) { - int i; + int i, na; Alarm *a; void (*f)(void*); Proc *p; + Alarm *alist[NA]; if(n&INTR2){ i = *CLRTIM0; @@ -170,16 +172,22 @@ clock(ulong n) if(m->alarm){ a = m->alarm; a->dt--; - while(a && a->dt<=0){ - f = a->f; /* avoid race with cancel */ - if(f) - (*f)(a); + for(na = 0; a && a->dt<=0 && naalarm, 0, a); - a->busy = 0; a = m->alarm; } - } - unlock(&m->alarmlock); + unlock(&m->alarmlock); + + /* execute alarm functions outside the lock */ + for(i = 0; i < na; i++){ + f = alist[i]->f; /* avoid race with cancel */ + if(f) + (*f)(alist[i]); + alist[i]->busy = 0; + } + } else + unlock(&m->alarmlock); } return; }