From dba21a3700ba82ec0ca646f253781ac543da6a2d Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 4 Nov 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-11-04 --- gnot/chan.c | 12 ++++++++---- gnot/dat.h | 14 ++++++++++++++ gnot/devdk.c | 2 +- gnot/fns.h | 5 ++++- gnot/main.c | 2 ++ gnot/proc.c | 31 ++++++++++++++++++++++--------- gnot/stream.c | 4 ++++ gnot/sysfile.c | 13 +++++++++++++ gnot/trap.c | 3 ++- port/chan.c | 12 ++++++++---- port/devdk.c | 2 +- port/devpipe.c | 29 ++++++++++++++--------------- port/stream.c | 4 ++++ 13 files changed, 97 insertions(+), 36 deletions(-) diff --git a/gnot/chan.c b/gnot/chan.c index 335371736d213e8bb51ab77f3d26e5680214d6ab..d98f8ee526e64f0d72e1523dc4878489d61289f7 100644 --- a/gnot/chan.c +++ b/gnot/chan.c @@ -14,19 +14,23 @@ struct{ int incref(Ref *r) { + int x; + lock(r); - r->ref++; + x = ++r->ref; unlock(r); - return r->ref; + return x; } int decref(Ref *r) { + int x; + lock(r); - r->ref--; + x = --r->ref; unlock(r); - return r->ref; + return x; } void diff --git a/gnot/dat.h b/gnot/dat.h index b3525e01f23a076714747d4bbb3ae4927b00619c..211fe8045a5a436675b1bbab5ca697fc7f84b342 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -31,6 +31,7 @@ typedef struct Queue Queue; typedef struct Ref Ref; typedef struct Rendez Rendez; typedef struct Seg Seg; +typedef struct Service Service; typedef struct Stream Stream; typedef struct Ureg Ureg; typedef struct User User; @@ -149,6 +150,7 @@ struct Conf int nurp; /* max urp conversations */ int nasync; /* number of async protocol modules */ int npipe; /* number of pipes */ + int nservice; /* number of services */ }; struct Dev @@ -490,6 +492,18 @@ enum { Streambhi= 32, /* block count high water mark */ }; +#define NSTUB 32 +struct Service +{ + Ref; + Service *next; + QLock alock; + int die; + Chan *c; + char name[NAMELEN]; +}; + + #define PRINTSIZE 256 extern Mach *m; diff --git a/gnot/devdk.c b/gnot/devdk.c index dcc0a268a499f59beae941fcd401102cdefe04c3..0727297a45bf67112e3daf70eed3ba2b66d13e5f 100644 --- a/gnot/devdk.c +++ b/gnot/devdk.c @@ -377,9 +377,9 @@ dkstopen(Queue *q, Stream *s) error(0, Ehungup); } unlock(dp); + lp->rq = q; if(lp->state==Lclosed) lp->state = Lopened; - lp->rq = q; } /* diff --git a/gnot/fns.h b/gnot/fns.h index 8999502e7e8388d5116aed3d5fada970e7f50d02..312be9bc05aa476e5423be0aa41c4ea9e96443f8 100644 --- a/gnot/fns.h +++ b/gnot/fns.h @@ -48,6 +48,7 @@ void exit(void); void fault(Ureg*, FFrame*); void fdclose(int); Chan* fdtochan(int, int); +void filsys(Chan*, char*, long); void firmware(void); void flowctl(Queue*); void flushcpucache(void); @@ -80,7 +81,7 @@ void kbdclock(void); void kmapinit(void); KMap *kmap(Page*); int kprint(char*, ...); -void kproc(char*, void(*)(void*), void*); +Proc *kproc(char*, void(*)(void*), void*); void kunmap(KMap*); void lock(Lock*); void lockinit(void); @@ -144,6 +145,8 @@ void screenputc(int); long seconds(void); Seg *seg(Proc*, ulong); int segaddr(Seg*, ulong, ulong); +void serviceinit(void); +void service(char*, Chan*, void (*)(Chan*, char*, long)); int setlabel(Label*); char* skipslash(char*); void sleep(Rendez*, int(*)(void*), void*); diff --git a/gnot/main.c b/gnot/main.c index a6fcdec9aa901fdf366d365fc5c626e8c81f72ae..85fb44765081a99234e0687da1ad80079a576f08 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -46,6 +46,7 @@ main(void) alarminit(); chandevreset(); streaminit(); + serviceinit(); pageinit(); kmapinit(); userinit(); @@ -326,4 +327,5 @@ confinit(void) conf.nurp = 32; conf.nasync = 1; conf.npipe = conf.nstream/2; + conf.nservice = conf.nproc/5; } diff --git a/gnot/proc.c b/gnot/proc.c index 9462c7e3c981ebd94dc3c182d29aee41e385b066..8a768894bf0086a84dd7306fc33d8c866c41ed19 100644 --- a/gnot/proc.c +++ b/gnot/proc.c @@ -688,7 +688,13 @@ DEBUG(void) } } -void +/* + * create a kernel process. if func is nonzero put the process in the kernel + * process group, have it call func, and exit. + * + * otherwise, the new process stays in the same process group and returns. + */ +Proc * kproc(char *name, void (*func)(void *), void *arg) { Proc *p; @@ -733,15 +739,21 @@ kproc(char *name, void (*func)(void *), void *arg) */ if(setlabel(&p->sched)){ restore(); - (*func)(arg); - pexit(0, 1); + if(func){ + (*func)(arg); + pexit(0, 1); + } else + return 0; } - if(kpgrp == 0){ - kpgrp = newpgrp(); - strcpy(kpgrp->user, "bootes"); - } - p->pgrp = kpgrp; - incref(kpgrp); + if(func){ + if(kpgrp == 0){ + kpgrp = newpgrp(); + strcpy(kpgrp->user, "bootes"); + } + p->pgrp = kpgrp; + } else + p->pgrp = u->p->pgrp; + incref(p->pgrp); sprint(p->text, "%s.%.6s", name, u->p->pgrp->user); p->nchild = 0; p->parent = 0; @@ -749,4 +761,5 @@ kproc(char *name, void (*func)(void *), void *arg) p->time[TReal] = MACHP(0)->ticks; ready(p); flushmmu(); + return p; } diff --git a/gnot/stream.c b/gnot/stream.c index 367a86acf4e2e8697cd95119330fa96acc8f6a49..4a7bccc8fb8a4a16a6526a0d47bd52e1bd317d41 100644 --- a/gnot/stream.c +++ b/gnot/stream.c @@ -752,10 +752,14 @@ streamexit(Stream *s, int locked) Queue *q; Queue *nq; int rv; + char *name; if(!locked) lock(s); if(s->inuse == 1){ + if(s->opens != 0) + print("streamexit %d %s\n", s->opens, s->devq->info->name); + /* * ascend the stream freeing the queues */ diff --git a/gnot/sysfile.c b/gnot/sysfile.c index c45fbe353aed5cb48bcd41d4dbd6e784b931556a..db5af7689e5bd550ea330443f7593ec5b65dd911 100644 --- a/gnot/sysfile.c +++ b/gnot/sysfile.c @@ -508,3 +508,16 @@ sysfwstat(ulong *arg) (*devtab[c->type].wstat)(c, (char*)arg[1]); return 0; } + +long +sysfilsys(ulong *arg) +{ + Chan *c; + + c = fdtochan(arg[0], -1); + validaddr(arg[1], 1, 0); + if((c->qid&CHDIR) || (c->mode&ORDWR)!=ORDWR) + error(0, Ebadarg); + service((char *)arg[1], c, filsys); + return 0; +} diff --git a/gnot/trap.c b/gnot/trap.c index a70fd95ddffa99e057e51f06f321f1e43a15211d..9f7dc7925e7a4ec8d8f97ab260c89a5f42453884 100644 --- a/gnot/trap.c +++ b/gnot/trap.c @@ -200,7 +200,7 @@ typedef long Syscall(ulong*); Syscall sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, syslasterr, syswait; Syscall sysopen, sysclose, sysread, syswrite, sysseek, syserrstr, sysaccess, sysstat, sysfstat; Syscall sysdup, syschdir, sysforkpgrp, sysbind, sysmount, syspipe, syscreate, sysuserstr; -Syscall sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted; +Syscall sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted, sysfilsys; Syscall *systab[]={ sysr1, @@ -233,6 +233,7 @@ Syscall *systab[]={ sysfwstat, sysnotify, sysnoted, + sysfilsys, }; long diff --git a/port/chan.c b/port/chan.c index 335371736d213e8bb51ab77f3d26e5680214d6ab..d98f8ee526e64f0d72e1523dc4878489d61289f7 100644 --- a/port/chan.c +++ b/port/chan.c @@ -14,19 +14,23 @@ struct{ int incref(Ref *r) { + int x; + lock(r); - r->ref++; + x = ++r->ref; unlock(r); - return r->ref; + return x; } int decref(Ref *r) { + int x; + lock(r); - r->ref--; + x = --r->ref; unlock(r); - return r->ref; + return x; } void diff --git a/port/devdk.c b/port/devdk.c index dcc0a268a499f59beae941fcd401102cdefe04c3..0727297a45bf67112e3daf70eed3ba2b66d13e5f 100644 --- a/port/devdk.c +++ b/port/devdk.c @@ -377,9 +377,9 @@ dkstopen(Queue *q, Stream *s) error(0, Ehungup); } unlock(dp); + lp->rq = q; if(lp->state==Lclosed) lp->state = Lopened; - lp->rq = q; } /* diff --git a/port/devpipe.c b/port/devpipe.c index c213aeb57863341a463519e99372e9888b8d03bc..c06096092f07aece864346f1d7da1d41facc455e 100644 --- a/port/devpipe.c +++ b/port/devpipe.c @@ -75,8 +75,10 @@ pipeattach(char *spec) } p = pipealloc.free; pipealloc.free = p->next; - if(incref(p) != 1) + if(++(p->ref) != 1){ + print("pipattach pipe half %d ref %d\n", p - pipealloc.pipe, p->ref); panic("pipeattach"); + } unlock(&pipealloc); c->qid = CHDIR|STREAMQID(2*(p - pipealloc.pipe), 0); @@ -200,19 +202,6 @@ pipewstat(Chan *c, char *db) error(0, Eperm); } -void -pipeexit(Pipe *p) -{ - if(decref(p) < 0) - panic("pipeexit"); - if(p->ref == 0){ - lock(&pipealloc); - p->next = pipealloc.free; - pipealloc.free = p; - unlock(&pipealloc); - } -} - void pipeclose(Chan *c) { @@ -230,7 +219,17 @@ pipeclose(Chan *c) streamclose(c); /* close this stream */ streamexit(remote, 0); /* release stream for other half of pipe */ } - pipeexit(p); + + lock(p); + if(--(p->ref) < 0) + panic("pipeexit"); + if(p->ref == 0){ + lock(&pipealloc); + p->next = pipealloc.free; + pipealloc.free = p; + unlock(&pipealloc); + } + unlock(p); } long diff --git a/port/stream.c b/port/stream.c index 367a86acf4e2e8697cd95119330fa96acc8f6a49..4a7bccc8fb8a4a16a6526a0d47bd52e1bd317d41 100644 --- a/port/stream.c +++ b/port/stream.c @@ -752,10 +752,14 @@ streamexit(Stream *s, int locked) Queue *q; Queue *nq; int rv; + char *name; if(!locked) lock(s); if(s->inuse == 1){ + if(s->opens != 0) + print("streamexit %d %s\n", s->opens, s->devq->info->name); + /* * ascend the stream freeing the queues */