M gnot/chan.c => gnot/chan.c +8 -4
@@ 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
M gnot/dat.h => gnot/dat.h +14 -0
@@ 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;
M gnot/devdk.c => gnot/devdk.c +1 -1
@@ 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;
}
/*
M gnot/fns.h => gnot/fns.h +4 -1
@@ 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*);
M gnot/main.c => gnot/main.c +2 -0
@@ 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;
}
M gnot/proc.c => gnot/proc.c +22 -9
@@ 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;
}
M gnot/stream.c => gnot/stream.c +4 -0
@@ 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
*/
M gnot/sysfile.c => gnot/sysfile.c +13 -0
@@ 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;
+}
M gnot/trap.c => gnot/trap.c +2 -1
@@ 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
M port/chan.c => port/chan.c +8 -4
@@ 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
M port/devdk.c => port/devdk.c +1 -1
@@ 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;
}
/*
M port/devpipe.c => port/devpipe.c +14 -15
@@ 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);
@@ 201,19 203,6 @@ pipewstat(Chan *c, char *db)
}
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)
{
Stream *remote;
@@ 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
M port/stream.c => port/stream.c +4 -0
@@ 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
*/