M gnot/mmu.c => gnot/mmu.c +9 -3
@@ 143,9 143,13 @@ KMap*
kmap(Page *pg)
{
KMap *k;
- int s;
+ int s = 0;
- s = splhi();
+ if(u) {
+ s = u->p->state;
+ u->p->state = MMUing;
+ }
+
lock(&kmapalloc);
k = kmapalloc.free;
if(k == 0){
@@ 154,10 158,12 @@ kmap(Page *pg)
}
kmapalloc.free = k->next;
unlock(&kmapalloc);
- splx(s);
k->pa = pg->pa;
putkmmu(k->va, PPN(k->pa) | PTEVALID | PTEKERNEL);
+ if(s)
+ u->p->state = s;
+
return k;
}
M pc/main.c => pc/main.c +3 -3
@@ 181,14 181,14 @@ confinit(void)
conf.maxialloc = 2*1024*1024;
mul = 1;
- conf.nproc = 10 + 10*mul;
+ conf.nproc = 10 + 20*mul;
conf.npgrp = conf.nproc/2;
conf.nseg = conf.nproc*3;
conf.npagetab = (conf.nseg*14)/10;
conf.nswap = conf.nproc*80;
conf.nimage = 50;
conf.nalarm = 1000;
- conf.nchan = 4*conf.nproc;
+ conf.nchan = 6*conf.nproc;
conf.nenv = 4*conf.nproc;
conf.nenvchar = 8000*mul;
conf.npgenv = 200*mul;
@@ 198,7 198,7 @@ confinit(void)
conf.nmntbuf = conf.nmntdev+3;
conf.nmnthdr = 2*conf.nmntdev;
conf.nsrv = 16*mul; /* was 32 */
- conf.nbitmap = 256*mul;
+ conf.nbitmap = 512*mul;
conf.nbitbyte = conf.nbitmap*1024*screenbits();
conf.nfont = 10*mul;
conf.nnoifc = 1;
M port/devdk.c => port/devdk.c +1 -1
@@ 1469,7 1469,7 @@ dkcsckproc(void *a)
case T_RESTART: /* datakit reboot */
if(line >=0 && line<dp->lines)
- dp->lines=line+1;
+ dp->lines = line+1;
break;
default:
M port/devlance.c => port/devlance.c +27 -10
@@ 183,7 183,9 @@ static SoftLance l;
* predeclared
*/
static void lancekproc(void *);
-static void lancestart(int);
+static void lancestart(int, int);
+static void lancedump(void);
+
/*
* lance stream module definition
*/
@@ 228,7 230,7 @@ lancestclose(Queue *q)
qlock(&l);
l.prom--;
if(l.prom == 0)
- lancestart(0);
+ lancestart(0, 1);
qunlock(&l);
}
qlock(et);
@@ 266,7 268,7 @@ lanceoput(Queue *q, Block *bp )
qlock(&l);
l.prom++;
if(l.prom == 1)
- lancestart(PROM);
+ lancestart(PROM, 1);
qunlock(&l);
}
freeb(bp);
@@ 283,13 285,15 @@ lanceoput(Queue *q, Block *bp )
* only one transmitter at a time
*/
qlock(&l.tlock);
+ if(waserror()){
+ qunlock(&l.tlock);
+ nexterror();
+ }
/*
* Wait till we get an output buffer
*/
- if(TSUCC(l.tc) == l.tl){
- sleep(&l.tr, isobuf, (void *)0);
- }
+ sleep(&l.tr, isobuf, (void *)0);
p = &l.tp[l.tc];
/*
@@ 335,6 339,7 @@ lanceoput(Queue *q, Block *bp )
*l.rdp = INEA|TDMD; /**/
wbflush();
qunlock(&l.tlock);
+ poperror();
}
/*
@@ 377,7 382,7 @@ lancereset(void)
* It may be used to restart a dead lance.
*/
static void
-lancestart(int mode)
+lancestart(int mode, int dolock)
{
int i;
Etherpkt *p;
@@ 388,8 393,10 @@ lancestart(int mode)
* wait till both receiver and transmitter are
* quiescent
*/
- qlock(&l.tlock);
- qlock(&l.rlock);
+ if(dolock){
+ qlock(&l.tlock);
+ qlock(&l.rlock);
+ }
lancereset();
l.rl = 0;
@@ 509,7 516,7 @@ lanceattach(char *spec)
if(l.kstarted == 0){
kproc("lancekproc", lancekproc, 0);/**/
l.kstarted = 1;
- lancestart(0);
+ lancestart(0, 1);
}
return devattach('l', spec);
}
@@ 625,6 632,7 @@ lanceintr(void)
int i;
ushort csr;
Lancemem *lm = LANCEMEM;
+ static int misses;
csr = *l.rdp;
@@ 638,6 646,8 @@ lanceintr(void)
*/
if(csr & (BABL|MISS|MERR)){
print("lance err %ux\n", csr);
+ if(csr & MISS)
+ lancedump();
}
if(csr & IDON){
@@ 650,6 660,7 @@ lanceintr(void)
* look for rcv'd packets, just wakeup the input process
*/
if(l.rl!=l.rc && (MPus(lm->rmr[l.rl].flags) & OWN)==0){
+ misses = 0;
wakeup(&l.rr);
}
@@ 757,3 768,9 @@ stage:
sleep(&l.rr, isinput, 0);
}
}
+
+static void
+lancedump(void)
+{
+ print("l.rl %d l.rc %d l.tl %d l.tc %d\n", l.rl, l.rc, l.tl, l.tc);
+}
M port/devsrv.c => port/devsrv.c +72 -169
@@ 4,27 4,26 @@
#include "dat.h"
#include "fns.h"
#include "errno.h"
-#include "devtab.h"
-#include "fcall.h"
-void *calloc(unsigned, unsigned);
-void free(void *);
+#include "devtab.h"
-/* This structure holds the contents of a directory entry. Entries are kept
- * in a linked list.
- */
-typedef struct Entry Entry;
-struct Entry {
+typedef struct Srv Srv;
+struct Srv{
Lock;
- Entry *next; /* next entry */
- Entry **back; /* entry pointer */
- Entry *parent; /* parent directory */
- Dir dir; /* dir structure */
- union{
- Chan *chan; /* if not a subdirectory */
- Entry *entries; /* directory entries */
- };
-};
+ char *name;
+ Chan **chan;
+}srv;
+
+int
+srvgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp)
+{
+ if(s >= conf.nsrv)
+ return -1;
+ if(srv.chan[s] == 0)
+ return 0;
+ devdir(c, (Qid){s, 0}, &srv.name[s*NAMELEN], 0, 0666, dp);
+ return 1;
+}
void
srvinit(void)
@@ 34,92 33,40 @@ srvinit(void)
void
srvreset(void)
{
-}
-
-Entry *
-srvalloc(int mode){
- Entry *e;
- static Lock qidlock;
- static nextqid;
-
- e = calloc(1, sizeof(Entry));
- e->dir.atime = e->dir.mtime = seconds();
- lock(&qidlock); /* for qid allocation */
- e->dir.qid = (Qid){mode|nextqid++, 0};
- unlock(&qidlock);
- return e;
+ srv.chan = ialloc(conf.nsrv*sizeof(Chan*), 0);
+ srv.name = ialloc(conf.nsrv*NAMELEN, 0);
}
Chan *
srvattach(char *spec)
{
- Chan *c;
- static Lock rootlock;
- static Entry *root;
-
- lock(&rootlock);
- if(root==0){
- root = srvalloc(CHDIR);
- root->dir.mode = CHDIR | 0777;
- }
- unlock(&rootlock);
- c = devattach('s', spec);
- c->qid = root->dir.qid;
- c->aux = root;
- return c;
+ return devattach('s', spec);
}
Chan *
srvclone(Chan *c, Chan *nc)
{
- nc = devclone(c, nc);
- return nc;
+ return devclone(c, nc);
}
int
srvwalk(Chan *c, char *name)
{
- Entry *dir, *e;
-
- isdir(c);
- if(strcmp(name, ".") == 0)
- return 1;
- if((dir=c->aux) == 0)
- panic("bad aux pointer in srvwalk");
- if(strcmp(name, "..") == 0)
- e = dir->parent;
- else{
- lock(dir);
- for(e=dir->entries; e; e=e->next)
- if (strcmp(name, e->dir.name) == 0)
- break;
- unlock(dir);
- }
- if(e==0){
- strncpy(u->error, errstrtab[Enonexist], NAMELEN);
- return 0;
- }
- c->qid = e->dir.qid;
- c->aux = e;
- return 1;
+ return devwalk(c, name, 0, 0, srvgen);
}
void
srvstat(Chan *c, char *db)
{
- Entry *e;
-
- e = c->aux;
- convD2M(&e->dir, db);
+ devstat(c, db, 0, 0, srvgen);
}
Chan *
srvopen(Chan *c, int omode)
{
- Entry *e;
Chan *f;
- if(c->qid.path & CHDIR){
+ if(c->qid.path == CHDIR){
if(omode != OREAD)
error(Eisdir);
c->mode = omode;
@@ 127,78 74,77 @@ srvopen(Chan *c, int omode)
c->offset = 0;
return c;
}
- if((e=c->aux) == 0)
- error(Egreg);
- if((f=e->chan) == 0)
+ lock(&srv);
+ if(waserror()){
+ unlock(&srv);
+ nexterror();
+ }
+ f = srv.chan[c->qid.path];
+ if(f == 0)
error(Eshutdown);
- if(omode & OTRUNC)
+ if(omode&OTRUNC)
error(Eperm);
if(omode!=f->mode && f->mode!=ORDWR)
error(Eperm);
close(c);
incref(f);
+ unlock(&srv);
+ poperror();
return f;
}
void
srvcreate(Chan *c, char *name, int omode, ulong perm)
{
- Entry *parent, *e;
+ int j, i;
- parent = c->aux;
- isdir(c);
- lock(parent);
- if (waserror()){
- unlock(parent);
+ if(omode != OWRITE)
+ error(Eperm);
+ lock(&srv);
+ if(waserror()){
+ unlock(&srv);
nexterror();
}
- for(e=parent->entries; e; e=e->next)
- if(strcmp(name, e->dir.name) == 0)
+ j = -1;
+ for(i=0; i<conf.nsrv; i++){
+ if(srv.chan[i] == 0){
+ if(j == -1)
+ j = i;
+ }else if(strcmp(name, &srv.name[i*NAMELEN]) == 0)
error(Einuse);
- e = srvalloc(perm & CHDIR);
- e->parent = parent;
- strcpy(e->dir.name, name);
- e->dir.mode = perm & parent->dir.mode;
- strcpy(e->dir.gid, parent->dir.gid);
- if(e->next = parent->entries) /* assign = */
- e->next->back = &e->next;
- e->back = &parent->entries;
- *e->back = e;
- parent->dir.mtime = e->dir.mtime;
- unlock(parent);
+ }
+ if(j == -1)
+ error(Enosrv);
+ srv.chan[j] = c;
+ unlock(&srv);
poperror();
- c->qid = e->dir.qid;
- c->aux = e;
+ strcpy(&srv.name[j*NAMELEN], name);
+ c->qid.path = j;
c->flag |= COPEN;
- c->mode = omode;
+ c->mode = OWRITE;
}
void
srvremove(Chan *c)
{
- Entry *e;
+ Chan *f;
- e = c->aux;
- if(e->parent == 0)
+ if(c->qid.path == CHDIR)
error(Eperm);
- lock(e->parent);
+ lock(&srv);
if(waserror()){
- unlock(e->parent);
+ unlock(&srv);
nexterror();
}
- if(e->dir.mode & CHDIR){
- if (e->entries != 0)
- error(Eperm);
- }else{
- if(e->chan == 0)
- error(Eshutdown);
- close(e->chan);
- }
- if(*e->back = e->next) /* assign = */
- e->next->back = e->back;
- unlock(e->parent);
+ f = srv.chan[c->qid.path];
+ if(f == 0)
+ error(Eshutdown);
+ if(strcmp(&srv.name[c->qid.path*NAMELEN], "boot") == 0)
+ error(Eperm);
+ srv.chan[c->qid.path] = 0;
+ unlock(&srv);
poperror();
- free(e);
+ close(f);
}
void
@@ 212,72 158,29 @@ srvclose(Chan *c)
{
}
-/* A directory is being read. The entries must be synthesized. e points
- * to a list of entries in this directory. Count is the size to be
- * read.
- */
-int
-srvdirentry(Entry *e, char *a, long count){
- Dir dir;
- int n;
-
- n = 0;
- while(n!=count && e!=0){
- n += convD2M(&e->dir, a + n);
- e = e->next;
- }
- return n;
-}
-
long
srvread(Chan *c, void *va, long n, ulong offset)
{
- Entry *dir, *e;
-
- dir = c->aux;
isdir(c);
- if(n <= 0)
- return 0;
- if(offset%DIRLEN || n%DIRLEN)
- error(Ebaddirread);
- lock(dir);
- for(e=dir->entries; e; e=e->next)
- if(offset <= 0){
- n = srvdirentry(e, va, n);
- unlock(dir);
- c->offset += n;
- return n;
- }else
- offset -= DIRLEN;
- unlock(dir);
- return 0;
+ return devdirread(c, va, n, 0, 0, srvgen);
}
long
srvwrite(Chan *c, void *va, long n, ulong offset)
{
- Entry *e;
int i, fd;
char buf[32];
- e = c->aux;
- if(e->dir.mode & CHDIR)
- panic("write to directory");
- lock(e);
- if(waserror()){
- unlock(e);
- nexterror();
- }
- if(e->chan)
+ i = c->qid.path;
+ if(srv.chan[i] != c) /* already been written to */
error(Egreg);
if(n >= sizeof buf)
error(Egreg);
memmove(buf, va, n); /* so we can NUL-terminate */
buf[n] = 0;
fd = strtoul(buf, 0, 0);
- e->chan = fdtochan(fd, -1);
- incref(e->chan);
- unlock(e);
- poperror();
+ fdtochan(fd, -1); /* error check only */
+ srv.chan[i] = u->p->fgrp->fd[fd];
+ incref(u->p->fgrp->fd[fd]);
return n;
}
D port/filsys.c => port/filsys.c +0 -250
@@ 1,250 0,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "errno.h"
-
-#include "devtab.h"
-
-#include "fcall.h"
-
-#define PRINT print
-
-enum {
- Rreadhlen = 8, /* number of chars in Rread message hdr */
-};
-
-typedef struct Ftrans Ftrans;
-
-struct Ftrans{
- long fid;
- Chan *c;
- Chan *pc;
-};
-
-static Ftrans *fsyshash;
-static Lock fsyslock;
-
-static void fsysnewchan(Chan *, long, Chan *);
-static Chan *fsyschan(Chan *, long);
-static int fsyserr(void);
-
-void
-filsysinit(void)
-{
- fsyshash = ialloc(conf.nfsyschan * sizeof(Ftrans), 0);
-}
-
-void
-filsys(Chan *protoc, char *msg, long msgn)
-{
- Fcall r, t, *rf, *tf;
- Chan *c, *c0;
- long fid, n;
-
- if(!convM2S(msg, &r, msgn)){
- error(Ebadmsg);
- }
- rf = &r;
- tf = &t;
- if(waserror()){
- tf->type = Rerror;
- strncpy(tf->ename, u->error, sizeof(tf->ename));
- goto Errret;
- }
- fid = rf->fid;
- if(rf->type != Tattach)
- c = fsyschan(protoc, fid);
- switch(rf->type){
- case Tattach:
- c = clone(u->slash, 0);
- fsysnewchan(protoc, fid, c);
- break;
- case Tclone:
- c0 = clone(c, 0);
- c0 = domount(c0);
- fsysnewchan(protoc, rf->newfid, c0);
- break;
- case Twalk:
- if((c0 = walk(c, rf->name, 1)) == 0)
- error(Enonexist);
- if(c != c0)
- fsysnewchan(protoc, fid, c0);
- tf->qid = c0->qid;
- break;
- case Topen:
- c0 = (*devtab[c->type].open)(c, rf->mode);
- if(c != c0)
- fsysnewchan(protoc, fid, c0);
- if(rf->mode & OCEXEC)
- c0->flag |= CCEXEC;
- break;
- case Tcreate:
- if((c->flag&(CMOUNT|CCREATE)) == CMOUNT)
- c0 = createdir(c);
- (*devtab[c->type].create)(c, rf->name, rf->mode, rf->perm);
- if(rf->mode & OCEXEC)
- c->flag |= CCEXEC;
- break;
- case Tread:
- qlock(c);
- if(waserror()){
- qunlock(c);
- nexterror();
- }
- n = rf->count;
- tf->count = 0;
- /* overwrite the input msg -- assumes buffer is big enough */
- tf->data = msg+Rreadhlen;
- if(c->qid.path&CHDIR){
- n -= n%DIRLEN;
- if(c->offset%DIRLEN || n==0)
- error(Ebaddirread);
- }
- if((c->qid.path&CHDIR) && (c->flag&CMOUNT))
- n = unionread(c, tf->data, n);
- else
- n = (*devtab[c->type].read)(c, tf->data, n);
- c->offset += n;
- qunlock(c);
- poperror();
- tf->count = n;
- break;
- case Twrite:
- qlock(c);
- if(waserror()){
- qunlock(c);
- nexterror();
- }
- if(c->qid.path & CHDIR)
- error(Eisdir);
- n = rf->count;
- tf->count = 0;
- n = (*devtab[c->type].write)(c, rf->data, n);
- c->offset += n;
- qunlock(c);
- poperror();
- tf->count = n;
- break;
- case Tclunk:
- close(c);
- fsysnewchan(protoc, rf->fid, 0);
- break;
- case Tremove:
- (*devtab[c->type].remove)(c);
- break;
- case Tstat:
- (*devtab[c->type].stat)(c, tf->stat);
- break;
- case Twstat:
- (*devtab[c->type].wstat)(c, rf->stat);
- break;
- case Tflush:
- /* really, this message has to be handled by caller */
- break;
- default:
- error(Ebadmsg);
- }
- poperror();
- tf->type = rf->type+1;
- Errret:
- tf->fid = rf->fid;
- tf->tag = rf->tag;
- /* assume can reuse msg buf */
- n = convS2M(tf, msg);
- qlock(protoc);
- if(waserror()){
- qunlock(protoc);
- nexterror();
- }
- (*devtab[protoc->type].write)(protoc, msg, n);
- qunlock(protoc);
- poperror();
-}
-
-/*
- * hash table discipline: linear probe
- * a fid of 0 means 'free'; a fid of -1 means 'deleted'
- * use a function as per Knuth
- * only a function of fid, but protoc checked for match
- */
-static int
-fhash(long fid)
-{
- long x;
-
- x = fid*29128;
- if(x < 0)
- x = -x;
- x %= 262143;
- return x % conf.nfsyschan;
-}
-
-/*
- * Register channel c for fid (if c!= 0).
- * If c==0, unregister.
- * The protoc argument is used to disambiguate
- * identical fids from different attaches.
- */
-static void
-fsysnewchan(Chan *protoc, long fid, Chan *c)
-{
- int i, m;
- Ftrans *f, *fstop, *fend;
-
- i = fhash(fid);
- f = fsyshash+i;
- m = conf.nfsyschan;
- fstop = f+(i+m-1)%m;
- fend = fsyshash+m;
- lock(&fsyslock);
- while(f != fstop){
- if(f->fid == fid && f->pc == protoc){
- if(c)
- f->c = c;
- else
- f->fid = -1;
- break;
- }
- if(f->fid <= 0){
- f->c = c;
- f->fid = fid;
- f->pc = protoc;
- break;
- }
- if(++f == fend)
- f = fsyshash;
- }
- unlock(&fsyslock);
- if(f == fstop)
- error(Enofilsys);
-}
-
-/* Return the channel registered for fid */
-static Chan*
-fsyschan(Chan *protoc, long fid)
-{
- int i, m;
- Ftrans *f, *fstop, *fend;
-
- i = fhash(fid);
- f = fsyshash+i;
- if(f->fid == fid && f->pc == protoc)
- return f->c;
- m = conf.nfsyschan;
- fstop = f;
- if(++f == fend)
- f = fsyshash;
- fend = fsyshash+m;
- while(f != fstop){
- if(f->fid == fid && f->pc == protoc)
- return f->c;
- if(f->fid == 0)
- break;
- if(++f == fend)
- f = fsyshash;
- }
- error(Egreg);
-}
-
D port/service.c => port/service.c +0 -222
@@ 1,222 0,0 @@
-#include "u.h"
-#include "lib.h"
-#include "mem.h"
-#include "dat.h"
-#include "fns.h"
-#include "errno.h"
-
-#include "fcall.h"
-
-#define BUFSIZE (MAXFDATA+500) /* BUG */
-typedef struct Buffer Buffer;
-struct Buffer
-{
- Buffer *next;
- char buf[BUFSIZE];
-};
-
-struct Servalloc {
- Lock;
- Service *all;
- Service *freel;
- Buffer *ball;
- Buffer *bfreel;
-} servalloc;
-
-
-/*
- * allocate the taks force structures and put them
- * on the free list
- */
-void
-serviceinit(void)
-{
- Service *s;
- Buffer *b;
-
- servalloc.all = ialloc(conf.nservice * sizeof(Service), 0);
- servalloc.freel = servalloc.all;
- for(s = servalloc.all; s < &servalloc.all[conf.nservice-1]; s++)
- s->next = s+1;
-
- servalloc.ball = ialloc(2*conf.nservice * sizeof(Service), 0);
- servalloc.bfreel = servalloc.ball;
- for(b = servalloc.ball; b < &servalloc.ball[2*conf.nservice-1]; b++)
- b->next = b+1;
-}
-
-/*
- * Add a process to a service
- */
-static Proc *
-reinforce(Service *s)
-{
- int i;
- Proc *p;
-
- /*
- * don't start one up if we already have too many,
- * return our own process number
- */
- lock(s);
- if(s->ref == NSTUB){
- unlock(s);
- return u->p;
- }
- s->ref++;
- unlock(s);
-
- /*
- * create it
- */
- return kproc(s->name, 0, 0);
-}
-
-/*
- * resign from a service
- */
-static void
-resign(Service *s)
-{
- int i;
-
- print("%lux resigning\n", u->p);
- if(decref(s) == 0){
- print("freeing service\n");
- close(s->inc);
- close(s->outc);
- lock(&servalloc);
- s->next = servalloc.freel;
- servalloc.freel = s;
- unlock(&servalloc);
- }
- pexit(0, 1);
-}
-
-/*
- * Create a service of kernel processes to handle file system requests.
- * (*doit)() is a function that handles that event. Service
- * dynamicly creates new processes (up to MAXTASK) to ensure that 1 process
- * is always awaiting while others are doing.
- */
-void
-service(char *name, Chan *cin, Chan *cout, void (*doit)(Chan*, char*, long))
-{
- void *a;
- Service *s;
- Buffer *b;
- long n;
-
- b = 0;
-
- /*
- * allocate a service
- */
- lock(&servalloc);
- s = servalloc.freel;
- if(s == 0)
- panic("no more services");
- servalloc.freel = s->next;
- unlock(&servalloc);
- memset(s, 0, sizeof(Service));
- if(name==0 || *name==0)
- strcpy(name, "filsys");
- else
- strncpy(s->name, name, sizeof(s->name));
- s->inc = cin;
- s->outc = cout;
- s->die = 0;
- incref(cin);
- incref(cout);
-
- if(waserror()){
- /*
- * tell everyone else to die
- */
- s->die = 1;
-
- /*
- * wake up the next guy
- */
- qunlock(&s->alock);
-
- /*
- * free the buffer if we have one
- */
- if(b){
- lock(&servalloc);
- b->next = servalloc.bfreel;
- servalloc.bfreel = b;
- unlock(&servalloc);
- }
- resign(s);
- }
-
- /*
- * Create the first process in the service. The
- * caller returns.
- */
- if(reinforce(s)){
- poperror();
- return;
- }
-
- /*
- * first process enters the infinite loop
- */
- for(;;){
- b = 0;
- qlock(&s->alock);
-
- /*
- * if there's more than 1 process waiting, we're
- * superfluous
- */
- if(s->die || s->alock.head && s->alock.head!=s->alock.tail){
- qunlock(&s->alock);
- resign(s);
- }
-
- /*
- * get a buffer
- */
- lock(&servalloc);
- b = servalloc.bfreel;
- if(b == 0){
- print("no serv buffers\n");
- unlock(&servalloc);
- continue;
- }
- servalloc.bfreel = b->next;
- unlock(&servalloc);
-
- /*
- * wait for something to happen
- */
- n = (*devtab[cin->type].read)(cin, b->buf, sizeof(b->buf));
- if(n <= 0)
- error(Ehungup);
-
- /*
- * create a new process if none are waiting to
- * take over
- */
- if(s->alock.head == 0)
- if(reinforce(s) == 0)
- continue;
- qunlock(&s->alock);
-
- /*
- * process an event
- */
- (*doit)(cout, b->buf, n);
-
- /*
- * release the buffer
- */
- lock(&servalloc);
- b->next = servalloc.bfreel;
- servalloc.bfreel = b;
- unlock(&servalloc);
- }
-}