From a0a8ac297122fb9dbf2a74750dd208687da1561b Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 6 Nov 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-11-06 --- gnot/clock.c | 9 ++++--- gnot/dat.h | 6 ++++- gnot/devproc.c | 34 ++++++++++++++++++++++- gnot/fns.h | 23 +++++++++------- gnot/pgrp.c | 43 ++++++++++++++++++++++++++++- gnot/proc.c | 41 ++++++++++++++-------------- gnot/sysfile.c | 11 ++++---- power/clock.c | 13 ++++----- power/devhotrod.c | 69 +++++++++++++++++++++++++++++++++++++++++++---- 9 files changed, 197 insertions(+), 52 deletions(-) diff --git a/gnot/clock.c b/gnot/clock.c index 9f79da37e5b8c97d7391bbc7caba2f0c3581a627..5d59299dadb2445071d908061bf8b066ade4b4ec 100644 --- a/gnot/clock.c +++ b/gnot/clock.c @@ -106,14 +106,15 @@ clock(Ureg *ur) p->time[p->insyscall]++; } if(canlock(&m->alarmlock)){ - if(m->alarm){ - a = m->alarm; - a->dt--; - for(n = 0; a && a->dt<=0 && nalarm; + if(a){ + for(n=0; a && a->dt<=0 && nalarm, 0, a); a = m->alarm; } + if(a) + a->dt--; unlock(&m->alarmlock); /* execute alarm functions outside the lock */ diff --git a/gnot/dat.h b/gnot/dat.h index 211fe8045a5a436675b1bbab5ca697fc7f84b342..da5ac3e9225a860e066756fffbee47626e28a61f 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -103,6 +103,7 @@ struct Chan union { Stream *stream; /* for stream channels */ void *aux; + ulong pgrpid; /* for #p/notepg */ }; Chan *mchan; /* channel to mounted server */ ulong mqid; /* qid of root of mount point */ @@ -278,10 +279,12 @@ struct Pgrp { Ref; /* also used as a lock when mounting */ Pgrp *next; + int index; /* index in pgrp table */ ulong pgrpid; char user[NAMELEN]; int nmtab; /* highest active mount table entry, +1 */ int nenv; /* highest active env table entry, +1 */ + Lock debug; /* single access via devproc.c */ Mtab *mtab; Envp *etab; }; @@ -499,7 +502,8 @@ struct Service Service *next; QLock alock; int die; - Chan *c; + Chan *inc; + Chan *outc; char name[NAMELEN]; }; diff --git a/gnot/devproc.c b/gnot/devproc.c index f20ee7308d545e2cd873f6e8f48a30af6603d58d..9160c06aece3a8a86bdb9f4e5773d5fd66d9c705 100644 --- a/gnot/devproc.c +++ b/gnot/devproc.c @@ -12,6 +12,7 @@ enum{ Qctl, Qmem, Qnote, + Qnotepg, Qproc, Qstatus, Qtext, @@ -21,6 +22,7 @@ Dirtab procdir[]={ "ctl", Qctl, 0, 0600, "mem", Qmem, 0, 0600, "note", Qnote, 0, 0600, + "notepg", Qnotepg, 0, 0200, "proc", Qproc, sizeof(Proc), 0600, "status", Qstatus, NAMELEN+12+6*12, 0600, "text", Qtext, 0, 0600, @@ -108,6 +110,7 @@ Chan * procopen(Chan *c, int omode) { Proc *p; + Pgrp *pg; Orig *o; Chan *tc; @@ -117,6 +120,7 @@ procopen(Chan *c, int omode) goto done; } p = proctab(SLOT(c->qid)); + pg = p->pgrp; if((p->pid&PIDMASK) != PID(c->qid)) Died: error(0, Eprocdied); @@ -146,11 +150,18 @@ procopen(Chan *c, int omode) case Qctl: case Qnote: break; + + case Qnotepg: + if(omode != OWRITE) + error(0, Eperm); + c->pgrpid = (pg->pgrpid<index+1)<qid & CHDIR) error(0, Eisdir); + + /* + * Special case: don't worry about process, just use remembered group + */ + if(QID(c->qid) == Qnotepg){ + pg = pgrptab(SLOT(c->pgrpid)); + lock(&pg->debug); + if(waserror()){ + unlock(&pg->debug); + nexterror(); + } + if((pg->pgrpid&PIDMASK) != PID(c->pgrpid)){ + unlock(&pg->debug); + goto Died; + } + pgrpnote(pg, va, n, NUser); + unlock(&pg->debug); + return n; + } + p = proctab(SLOT(c->qid)); lock(&p->debug); if(waserror()){ diff --git a/gnot/fns.h b/gnot/fns.h index 312be9bc05aa476e5423be0aa41c4ea9e96443f8..b03dce77bb7b02c38dd9545d126dc747fc5aa3eb 100644 --- a/gnot/fns.h +++ b/gnot/fns.h @@ -19,6 +19,7 @@ long clrfpintr(void); int compactpte(Orig*, ulong); void confinit(void); Env *copyenv(Env*, int); +Chan *createdir(Chan*); int decref(Ref*); void delay(int); void delete(List**, List*, List*); @@ -29,7 +30,7 @@ void devdir(Chan*, long, char*, long, long, Dir*); long devdirread(Chan*, char*, long, Dirtab*, int, Devgen*); Devgen devgen; int devno(int, int); -Chan* devopen(Chan*, int, Dirtab*, int, Devgen*); +Chan *devopen(Chan*, int, Dirtab*, int, Devgen*); void devstat(Chan*, char*, Dirtab*, int, Devgen*); int devwalk(Chan*, char*, Dirtab*, int, Devgen*); void duartbaud(int); @@ -47,7 +48,7 @@ void error(Chan*, int); void exit(void); void fault(Ureg*, FFrame*); void fdclose(int); -Chan* fdtochan(int, int); +Chan *fdtochan(int, int); void filsys(Chan*, char*, long); void firmware(void); void flowctl(Queue*); @@ -81,7 +82,7 @@ void kbdclock(void); void kmapinit(void); KMap *kmap(Page*); int kprint(char*, ...); -Proc *kproc(char*, void(*)(void*), void*); +void *kproc(char*, void(*)(void*), void*); void kunmap(KMap*); void lock(Lock*); void lockinit(void); @@ -107,19 +108,21 @@ char *nextelem(char*, char*); void notify(Ureg*); void nullput(Queue*, Block*); int openmode(ulong); -Block* padb(Block*, int); +Block *padb(Block*, int); void pageinit(void); void panic(char*, ...); void pexit(char*, int); void pgrpcpy(Pgrp*, Pgrp*); void pgrpinit(void); +void pgrpnote(Pgrp*, char*, long, int); +Pgrp *pgrptab(int); int postnote(Proc*, int, char*, int); int pprint(char*, ...); void printinit(void); void printslave(void); void procinit0(void); Proc *proctab(int); -Queue* pushq(Stream*, Qinfo*); +Queue *pushq(Stream*, Qinfo*); void putbq(Blist*, Block*); void putkmmu(ulong, ulong); void putmmu(ulong, ulong); @@ -146,9 +149,9 @@ long seconds(void); Seg *seg(Proc*, ulong); int segaddr(Seg*, ulong, ulong); void serviceinit(void); -void service(char*, Chan*, void (*)(Chan*, char*, long)); +void service(char*, Chan*, Chan*, void (*)(Chan*, char*, long)); int setlabel(Label*); -char* skipslash(char*); +char *skipslash(char*); void sleep(Rendez*, int(*)(void*), void*); int splhi(void); int spllo(void); @@ -162,7 +165,7 @@ int streamexit(Stream*, int); void streaminit(void); long streamread(Chan*, void*, long); long streamwrite(Chan*, void*, long, int); -Stream* streamnew(ushort, ushort, ushort, Qinfo*, int); +Stream *streamnew(ushort, ushort, ushort, Qinfo*, int); void streamopen(Chan*, Qinfo*); int streamparse(char*, Block*); void streamstat(Chan*, char*, char*); @@ -172,13 +175,15 @@ int tas(char*); void touser(void); void tsleep(Rendez*, int (*)(void*), void*, int); void twakeme(Alarm*); +long unionread(Chan*, void*, long); void unlock(Lock*); void usepage(Page*, int); void userinit(void); void validaddr(ulong, ulong, int); -void* vmemchr(void*, int, int); +void *vmemchr(void*, int, int); void wakeme(Alarm*); void wakeup(Rendez*); +Chan *walk(Chan*, char*, int); #define waserror() (u->nerrlab++, setlabel(&u->errlab[u->nerrlab-1])) #define poperror() u->nerrlab-- diff --git a/gnot/pgrp.c b/gnot/pgrp.c index 6354a6447f33d19f2accf73f4757ccb38358f4e8..9fea02ce5a3c53cb75f7adc17ecbfb93037a517b 100644 --- a/gnot/pgrp.c +++ b/gnot/pgrp.c @@ -7,6 +7,7 @@ struct{ Lock; + Pgrp *arena; Pgrp *free; ulong pgrpid; }pgrpalloc; @@ -24,10 +25,12 @@ pgrpinit(void) Pgrp *p; Mount *m; - pgrpalloc.free = ialloc(conf.npgrp*sizeof(Pgrp), 0); + pgrpalloc.arena = ialloc(conf.npgrp*sizeof(Pgrp), 0); + pgrpalloc.free = pgrpalloc.arena; p = pgrpalloc.free; for(i=0; iindex = i; p->next = p+1; p->mtab = ialloc(conf.nmtab*sizeof(Mtab), 0); p->etab = ialloc(conf.npgenv*sizeof(Envp*), 0); @@ -42,6 +45,43 @@ pgrpinit(void) m->next = 0; } +Pgrp* +pgrptab(int i) +{ + return &pgrpalloc.arena[i]; +} + +void +pgrpnote(Pgrp *pg, char *a, long n, int flag) +{ + int i; + Proc *p; + char buf[ERRLEN]; + + if(n >= ERRLEN-1) + error(0, Etoobig); + if(n>=4 && strncmp(a, "sys:", 4)==0) + error(0, Ebadarg); + memcpy(buf, a, n); + buf[n] = 0; + p = proctab(0); + for(i=0; ipgrp == pg){ + lock(&p->debug); + if(p->pid==0 || p->pgrp!=pg){ + unlock(&p->debug); + continue; + } + if(waserror()){ + unlock(&p->debug); + continue; + } + postnote(p, 0, buf, flag); + unlock(&p->debug); + } + } +} + Pgrp* newpgrp(void) { @@ -76,6 +116,7 @@ closepgrp(Pgrp *p) Envp *ep; if(decref(p) == 0){ + p->pgrpid = -1; m = p->mtab; for(i=0; inmtab; i++,m++) if(m->c){ diff --git a/gnot/proc.c b/gnot/proc.c index 8a768894bf0086a84dd7306fc33d8c866c41ed19..e6043ecad8c58538529867c0fcd85ee6674b5631 100644 --- a/gnot/proc.c +++ b/gnot/proc.c @@ -58,13 +58,13 @@ schedinit(void) /* never returns */ /* * At init time: wait for a process on the run queue. */ - for (;;) { + for(;;){ spllo(); while (runq.head == 0) /* idle loop */; splhi(); lock(&runq); - if (runq.head != 0) + if(runq.head != 0) break; unlock(&runq); } @@ -84,7 +84,7 @@ schedinit(void) /* never returns */ * to have a process on it. */ p = runq.head; - if ((runq.head = p->rnext) == 0) + if((runq.head = p->rnext) == 0) runq.tail = 0; unlock(&runq); @@ -108,7 +108,7 @@ restore(void) u->p->mach = m; m->proc = u->p; u->p->state = Running; - if (p->state == Moribund) { + if(p->state == Moribund){ p->pid = 0; unlock(&p->debug); /* set in pexit */ p->upage->ref--; @@ -127,16 +127,16 @@ void save(Balu *balu) { fpsave(&u->fpsave); - if (u->fpsave.type) { + if(u->fpsave.type){ if(u->fpsave.size > sizeof u->fpsave.junk) panic("fpsize %d max %d\n", u->fpsave.size, sizeof u->fpsave.junk); fpregsave(u->fpsave.reg); u->p->fpstate = FPactive; m->fpstate = FPdirty; } - if (BALU->cr0 != 0xFFFFFFFF) /* balu busy */ + if(BALU->cr0 != 0xFFFFFFFF) /* balu busy */ memcpy(balu, BALU, sizeof *balu); - else { + else{ balu->cr0 = 0xFFFFFFFF; BALU->cr0 = 0xFFFFFFFF; } @@ -166,7 +166,7 @@ sched(void) /* * Look for a new process to be run. */ - for (;;) { + for (;;){ spllo(); /* @@ -174,9 +174,9 @@ sched(void) * to do, start saving some of the process state. */ while (runq.head == 0) - if (p->state == Running) + if(p->state == Running) return; - else if (!saved) { + else if(!saved){ save(&balu); saved = 1; } @@ -188,7 +188,7 @@ sched(void) */ splhi(); lock(&runq); - if (runq.head != 0) + if(runq.head != 0) break; unlock(&runq); } @@ -199,7 +199,7 @@ sched(void) * save our state before we jump to schedinit. If this process was running, put * it on the run queue. */ - if (p->state == Running) { + if(p->state == Running){ p->state = Ready; p->rnext = 0; runq.tail->rnext = p; @@ -211,9 +211,9 @@ sched(void) * pc and sp. We have to jump to schedinit() because we are going to remap the * stack. */ - if (!saved) + if(!saved) save(&balu); - if (setlabel(&p->sched) == 0) + if(setlabel(&p->sched) == 0) gotolabel(&m->sched); /* @@ -225,18 +225,18 @@ sched(void) /* * Jumped to by schedinit. Restore the process state. */ - if (p->fpstate != m->fpstate) - if (p->fpstate == FPinit) { + if(p->fpstate != m->fpstate) + if(p->fpstate == FPinit){ initfp = 0; fprestore((FPsave *) &initfp); m->fpstate = FPinit; } - else { + else{ fpregrestore(u->fpsave.reg); fprestore(&u->fpsave); m->fpstate = FPdirty; } - if (balu.cr0 != 0xFFFFFFFF) /* balu busy */ + if(balu.cr0 != 0xFFFFFFFF) /* balu busy */ memcpy(BALU, &balu, sizeof balu); /* @@ -250,11 +250,12 @@ ready(Proc *p) { int s; - if (p->spin) { + s = splhi(); + if(p->spin){ p->state = Running; + splx(s); return; } - s = splhi(); lock(&runq); p->rnext = 0; if(runq.tail) diff --git a/gnot/sysfile.c b/gnot/sysfile.c index db5af7689e5bd550ea330443f7593ec5b65dd911..05fb55717594923a0e71d0c5e7c7635e2da529fe 100644 --- a/gnot/sysfile.c +++ b/gnot/sysfile.c @@ -512,12 +512,13 @@ sysfwstat(ulong *arg) long sysfilsys(ulong *arg) { - Chan *c; + Chan *cin, *cout; - c = fdtochan(arg[0], -1); - validaddr(arg[1], 1, 0); - if((c->qid&CHDIR) || (c->mode&ORDWR)!=ORDWR) + cin = fdtochan(arg[0], OREAD); + cout = fdtochan(arg[1], OWRITE); + validaddr(arg[2], 1, 0); + if((cin->qid&CHDIR) || (cout->qid&CHDIR)) error(0, Ebadarg); - service((char *)arg[1], c, filsys); + service((char *)arg[2], cin, cout, filsys); return 0; } diff --git a/power/clock.c b/power/clock.c index 78671a3e57cfa808d99f21b098066ffd6ad56811..802ba629feb8a50071e3d0ded46d9dc9260313a4 100644 --- a/power/clock.c +++ b/power/clock.c @@ -181,18 +181,19 @@ clock(ulong n, ulong pc) exit(); } if(canlock(&m->alarmlock)){ - if(m->alarm){ - a = m->alarm; - a->dt--; - for(na = 0; a && a->dt<=0 && naalarm; + if(a){ + for(n=0; a && a->dt<=0 && nalarm, 0, a); a = m->alarm; } + if(a) + a->dt--; unlock(&m->alarmlock); /* execute alarm functions outside the lock */ - for(i = 0; i < na; i++){ + for(i = 0; i < n; i++){ f = alist[i]->f; /* avoid race with cancel */ if(f) (*f)(alist[i]); diff --git a/power/devhotrod.c b/power/devhotrod.c index b90036b9d45d62878b7134a2846221823a2be7ee..8230e20101158cd2ebfbd420e1be92ea41bb8c4a 100644 --- a/power/devhotrod.c +++ b/power/devhotrod.c @@ -10,6 +10,7 @@ typedef struct Hotrod Hotrod; typedef struct Device Device; +typedef struct Printbuf Printbuf; enum { Vmevec= 0xd2, /* vme vector for interrupts */ @@ -17,6 +18,16 @@ enum { Nhotrod= 2, }; +/* + * circular 2 pointer queue for hotrod prnt's + */ +struct Printbuf { + char *rptr; + char *wptr; + char *lim; + char buf[4*1024]; +}; + /* * the hotrod fiber interface responds to 1MB * of either user or supervisor accesses at: @@ -31,14 +42,18 @@ struct Device { struct Hotrod { QLock; - Device *addr; - int vec; - char name[NAMELEN]; + Device *addr; /* address of the device */ + int vec; /* vme interrupt vector */ + char name[NAMELEN]; /* hot rod name */ + Printbuf pbuf; /* circular queue for hotrod print's */ + int kprocstarted; + Rendez r; }; Hotrod hotrod[Nhotrod]; -static void hotrodintr(int); +void hotrodintr(int); +void hotrodkproc(void *a); int hotrodgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp) @@ -79,6 +94,7 @@ hotrodinit(void) Chan* hotrodattach(char *spec) { + Hotrod *hp; int i; Chan *c; @@ -86,6 +102,10 @@ hotrodattach(char *spec) if(i >= Nhotrod) error(0, Ebadarg); + hp = &hotrod[i]; + if(hp->kprocstarted == 0) + kproc(hp->name, hotrodkproc, hp); + c = devattach('H', spec); c->dev = i; c->qid = CHDIR; @@ -113,6 +133,17 @@ hotrodstat(Chan *c, char *dp) Chan* hotrodopen(Chan *c, int omode) { + Device *dp; + Hotrod *hp; + + /* + * Remind hotrod where the print buffer is. The address we store + * is the address of the printbuf in VME A32 space. + */ + hp = &hotrod[c->dev]; + dp = hp->addr; + dp->mem[256*1024/sizeof(ulong)] = (((ulong)&hp->pbuf) - KZERO) | (SLAVE<<28); + if(c->qid == CHDIR){ if(omode != OREAD) error(0, Eperm); @@ -238,7 +269,7 @@ hotroderrstr(Error *e, char *buf) rooterrstr(e, buf); } -static void +void hotrodintr(int vec) { Hotrod *hp; @@ -250,3 +281,31 @@ hotrodintr(int vec) return; } } + +/* + * print hotrod processor messages on the console + */ +void +hotrodkproc(void *a) +{ + Hotrod *hp = a; + char *p; + + hp->kprocstarted = 1; + hp->pbuf.rptr = hp->pbuf.wptr = hp->pbuf.buf; + hp->pbuf.lim = &hp->pbuf.buf[sizeof(hp->pbuf.buf)]; + + for(;;){ + p = hp->pbuf.wptr; + if(p != hp->pbuf.rptr){ + if(p > hp->pbuf.rptr){ + putstrn(hp->pbuf.rptr, p - hp->pbuf.rptr); + } else { + putstrn(hp->pbuf.rptr, hp->pbuf.lim - hp->pbuf.rptr); + putstrn(hp->pbuf.buf, hp->pbuf.wptr - hp->pbuf.buf); + } + hp->pbuf.rptr = p; + } + tsleep(&(hp->r), return0, 0, 1000); + } +}