M gnot/dat.h => gnot/dat.h +1 -5
@@ 325,10 325,6 @@ struct Proc
Seg seg[NSEG];
ulong bssend; /* initial top of bss seg */
ulong pid;
- Lock kidlock; /* access to kid and sib */
- Proc *pop; /* some ascendant */
- Proc *kid; /* some descendant */
- Proc *sib; /* non-ascendant relatives (circular list) */
int nchild;
QLock wait; /* exiting children to be waited for */
ulong waitmsg;
@@ 361,7 357,7 @@ struct MMUCache
MMU mmu[NMMU];
};
-#define NERR 15
+#define NERR 20
#define NNOTE 5
#define NFD 100
struct User
M gnot/devmnt.c => gnot/devmnt.c +60 -26
@@ 49,7 49,8 @@ struct Mnthdr
{
Mnthdr *next; /* in free list or writers list */
Mnthdr *prev; /* in writers list only */
- int writing; /* flag: in writers list */
+ short active;
+ short flushing; /* a Tflush has been sent */
Fcall thdr;
Fcall rhdr;
Rendez r;
@@ 122,6 123,7 @@ loop:
lock(&mnthdralloc);
if(mh = mnthdralloc.free){ /* assign = */
mnthdralloc.free = mh->next;
+ mh->flushing = 0;
unlock(&mnthdralloc);
return mh;
}
@@ 138,6 140,9 @@ loop:
void
mhfree(Mnthdr *mh)
{
+ if(mh->flushing)
+ return;
+ mh->active = 0;
lock(&mnthdralloc);
mh->next = mnthdralloc.free;
mnthdralloc.free = mh;
@@ 601,22 606,49 @@ mntwunlink(MntQ *q, Mnthdr *w) /* queue is locked and w is a writer */
if(q->writer)
q->writer->prev = 0;
}
- w->writing = 0;
}
+/*
+ * m->q is unlocked. Send Tflush message to flush omh->tag.
+ * Cut off all errors. Caller will free omh
+ */
void
-mnterrdequeue(MntQ *q, Mnthdr *mh) /* queue is unlocked */
+mntflush(Mnt *m, Mnthdr *omh) /* queue is unlocked */
+{
+ Mnthdr *mh;
+
+ if(omh->thdr.type == Tflush)
+ return;
+
+ mh = mhalloc();
+ if(waserror()){
+ omh->flushing = 0;
+ mhfree(mh);
+ return; /* no more errors please */
+ }
+ mh->thdr.type = Tflush;
+ mh->thdr.oldtag = omh->thdr.tag;
+ mntxmit(m, mh);
+ omh->flushing = 0;
+ mhfree(mh);
+ poperror();
+}
+
+void
+mnterrdequeue(Mnt *m, Mnthdr *mh) /* queue is unlocked */
{
Mnthdr *w;
+ MntQ *q;
+ mh->flushing = 1;
+ q = m->q;
qlock(q);
/* take self from queue if necessary */
if(q->reader == u->p){ /* advance a writer to reader */
w = q->writer;
if(w){
+ mntwunlink(q, w);
q->reader = w->p;
- q->writer = w->next;
- q->writer->prev = 0;
wakeup(&w->r);
}else{
q->reader = 0;
@@ 625,7 657,7 @@ mnterrdequeue(MntQ *q, Mnthdr *mh) /* queue is unlocked */
}else
mntwunlink(q, mh);
qunlock(q);
-
+ mntflush(m, mh);
}
int
@@ 641,11 673,11 @@ mntxmit(Mnt *m, Mnthdr *mh)
Mntbuf *mbw, *t;
Mnthdr *w, *ow;
MntQ *q;
- int qlocked, tag;
+ int qlocked, tag, written;
mh->mbr = mballoc();
mbw = mballoc();
- if(waserror()){
+ if(waserror()){ /* 1 */
mbfree(mh->mbr);
mbfree(mbw);
nexterror();
@@ 663,7 695,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
goto Normal;
incref(q);
- if(waserror()){
+ if(waserror()){ /* 2 */
mqfree(q);
nexterror();
}
@@ 677,7 709,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
*/
n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE);
mqfree(q);
- poperror();
+ poperror(); /* 2 */
if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){
print("format error in mntxmit\n");
@@ 712,7 744,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
memcpy(mh->thdr.data, mh->rhdr.data, mh->rhdr.count);
mbfree(mh->mbr);
mbfree(mbw);
- poperror();
+ poperror(); /* 1 */
return;
Normal:
@@ 720,13 752,14 @@ mntxmit(Mnt *m, Mnthdr *mh)
incref(q);
qlock(q);
qlocked = 1;
- if(waserror()){
+ if(waserror()){ /* 2 */
if(qlocked)
qunlock(q);
mqfree(q);
nexterror();
}
mh->readreply = 0;
+ mh->active = 1;
if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n) != n){
print("short write in mntxmit\n");
error(Eshortmsg);
@@ 736,14 769,15 @@ mntxmit(Mnt *m, Mnthdr *mh)
Read:
qunlock(q);
qlocked = 0;
- if(waserror()){
- mnterrdequeue(q, mh);
+ if(waserror()){ /* 3 */
+ mnterrdequeue(m, mh);
nexterror();
}
n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE);
- poperror();
+ poperror(); /* 3 */
if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){
- mnterrdequeue(q, mh);
+ print("bad reply message\n");
+ mnterrdequeue(m, mh);
error(Ebadmsg);
}
/*
@@ 755,13 789,12 @@ mntxmit(Mnt *m, Mnthdr *mh)
if(tag == mh->thdr.tag){ /* it's mine */
q->reader = 0;
if(w = q->writer){ /* advance a writer to reader */
+ mntwunlink(q, w);
q->reader = w->p;
- q->writer = w->next;
- if(q->writer)
- q->writer->prev = 0;
w->readreply = 1;
wakeup(&w->r);
}
+ mh->active = 0;
qunlock(q);
qlocked = 0;
goto Respond;
@@ 774,10 807,8 @@ mntxmit(Mnt *m, Mnthdr *mh)
goto Read;
}
w = &mnthdralloc.arena[tag];
- if(!w->writing){
- print("reply not writing\n");
+ if(w->flushing || !w->active) /* nothing to do; mntflush will clean up */
goto Read;
- }
t = mh->mbr;
mh->mbr = w->mbr;
w->mbr = t;
@@ 791,14 822,13 @@ mntxmit(Mnt *m, Mnthdr *mh)
/* put self in queue */
mh->next = q->writer;
mh->prev = 0;
- mh->writing = 1;
if(q->writer)
q->writer->prev = mh;
q->writer = mh;
qunlock(q);
qlocked = 0;
if(waserror()){ /* interrupted sleep */
- mnterrdequeue(q, mh);
+ mnterrdequeue(m, mh);
nexterror();
}
sleep(&mh->r, mntreadreply, mh);
@@ 807,6 837,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
qlocked = 1;
if(q->reader == u->p) /* i got promoted */
goto Read;
+ mh->active = 0;
qunlock(q);
qlocked = 0;
goto Respond;
@@ 814,11 845,14 @@ mntxmit(Mnt *m, Mnthdr *mh)
Respond:
mqfree(q);
- poperror();
+ poperror(); /* 2 */
if(mh->rhdr.type == Rerror){
if(m->mntpt)
errors(mh->rhdr.ename);
error(Eshutdown);
+ }else if(mh->rhdr.type != mh->thdr.type+1){
+ print("bad type %d not %d in mntxmit\n", mh->rhdr.type, mh->thdr.type+1);
+ error(Ebadmsg);
}
/*
* Copy out on read
@@ 830,7 864,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
}
mbfree(mh->mbr);
mbfree(mbw);
- poperror();
+ poperror(); /* 1 */
}
mntdump()
M gnot/proc.c => gnot/proc.c +1 -47
@@ 281,9 281,6 @@ loop:
unlock(&procalloc);
p->mach = 0;
p->qnext = 0;
- p->kid = 0;
- p->sib = 0;
- p->pop = 0;
p->nchild = 0;
p->child = 0;
p->exiting = 0;
@@ 350,7 347,7 @@ sleep1(Rendez *r, int (*f)(void*), void *arg)
*/
p = u->p;
if(r->p)
- print("double sleep %d %d\n", r->p->pid, p->pid);
+ print("double sleep %lux %d %d\n", r, r->p->pid, p->pid);
p->r = r;
p->wokeup = 0;
p->state = Wakeme;
@@ 567,50 564,7 @@ pexit(char *s, int freemem)
close(u->dot);
}
- /*
- * Rearrange inheritance hierarchy
- * 1. my children's pop is now my pop
- */
- lock(&c->kidlock);
- p = c->pop;
- if(k = c->kid) /* assign = */
- do{
- k->pop = p;
- k = k->sib;
- }while(k != c->kid);
-
- /*
- * 2. cut me from pop's tree
- */
- if(p == 0) /* init process only; fix pops */
- goto done;
- lock(&p->kidlock);
- k = p->kid;
- while(k->sib != c)
- k = k->sib;
- if(k == c)
- p->kid = 0;
- else{
- if(p->kid == c)
- p->kid = c->sib;
- k->sib = c->sib;
- }
-
- /*
- * 3. pass my children (pop's grandchildren) to pop
- */
- if(k = c->kid){ /* assign = */
- if(p->kid == 0)
- p->kid = k;
- else{
- l = k->sib;
- k->sib = p->kid->sib;
- p->kid->sib = l;
- }
- }
- unlock(&p->kidlock);
done:
- unlock(&c->kidlock);
lock(&procalloc); /* sched() can't do this */
lock(&c->debug); /* sched() can't do this */
M gnot/sysproc.c => gnot/sysproc.c +0 -15
@@ 112,20 112,6 @@ sysfork(ulong *arg)
if(c = u->fd[n]) /* assign = */
incref(c);
/*
- * Committed. Link into hierarchy
- */
- lock(&p->kidlock);
- lock(&u->p->kidlock);
- if(u->p->kid == 0){
- p->sib = p;
- u->p->kid = p;
- }else{
- p->sib = u->p->kid->sib;
- u->p->kid->sib = p;
- }
- unlock(&u->p->kidlock);
- unlock(&p->kidlock);
- /*
* Sched
*/
if(setlabel(&p->sched)){
@@ 133,7 119,6 @@ sysfork(ulong *arg)
restore();
return 0;
}
- p->pop = u->p;
p->parent = u->p;
p->parentpid = u->p->pid;
p->pgrp = u->p->pgrp;
M port/devmnt.c => port/devmnt.c +60 -26
@@ 49,7 49,8 @@ struct Mnthdr
{
Mnthdr *next; /* in free list or writers list */
Mnthdr *prev; /* in writers list only */
- int writing; /* flag: in writers list */
+ short active;
+ short flushing; /* a Tflush has been sent */
Fcall thdr;
Fcall rhdr;
Rendez r;
@@ 122,6 123,7 @@ loop:
lock(&mnthdralloc);
if(mh = mnthdralloc.free){ /* assign = */
mnthdralloc.free = mh->next;
+ mh->flushing = 0;
unlock(&mnthdralloc);
return mh;
}
@@ 138,6 140,9 @@ loop:
void
mhfree(Mnthdr *mh)
{
+ if(mh->flushing)
+ return;
+ mh->active = 0;
lock(&mnthdralloc);
mh->next = mnthdralloc.free;
mnthdralloc.free = mh;
@@ 601,22 606,49 @@ mntwunlink(MntQ *q, Mnthdr *w) /* queue is locked and w is a writer */
if(q->writer)
q->writer->prev = 0;
}
- w->writing = 0;
}
+/*
+ * m->q is unlocked. Send Tflush message to flush omh->tag.
+ * Cut off all errors. Caller will free omh
+ */
void
-mnterrdequeue(MntQ *q, Mnthdr *mh) /* queue is unlocked */
+mntflush(Mnt *m, Mnthdr *omh) /* queue is unlocked */
+{
+ Mnthdr *mh;
+
+ if(omh->thdr.type == Tflush)
+ return;
+
+ mh = mhalloc();
+ if(waserror()){
+ omh->flushing = 0;
+ mhfree(mh);
+ return; /* no more errors please */
+ }
+ mh->thdr.type = Tflush;
+ mh->thdr.oldtag = omh->thdr.tag;
+ mntxmit(m, mh);
+ omh->flushing = 0;
+ mhfree(mh);
+ poperror();
+}
+
+void
+mnterrdequeue(Mnt *m, Mnthdr *mh) /* queue is unlocked */
{
Mnthdr *w;
+ MntQ *q;
+ mh->flushing = 1;
+ q = m->q;
qlock(q);
/* take self from queue if necessary */
if(q->reader == u->p){ /* advance a writer to reader */
w = q->writer;
if(w){
+ mntwunlink(q, w);
q->reader = w->p;
- q->writer = w->next;
- q->writer->prev = 0;
wakeup(&w->r);
}else{
q->reader = 0;
@@ 625,7 657,7 @@ mnterrdequeue(MntQ *q, Mnthdr *mh) /* queue is unlocked */
}else
mntwunlink(q, mh);
qunlock(q);
-
+ mntflush(m, mh);
}
int
@@ 641,11 673,11 @@ mntxmit(Mnt *m, Mnthdr *mh)
Mntbuf *mbw, *t;
Mnthdr *w, *ow;
MntQ *q;
- int qlocked, tag;
+ int qlocked, tag, written;
mh->mbr = mballoc();
mbw = mballoc();
- if(waserror()){
+ if(waserror()){ /* 1 */
mbfree(mh->mbr);
mbfree(mbw);
nexterror();
@@ 663,7 695,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
goto Normal;
incref(q);
- if(waserror()){
+ if(waserror()){ /* 2 */
mqfree(q);
nexterror();
}
@@ 677,7 709,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
*/
n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE);
mqfree(q);
- poperror();
+ poperror(); /* 2 */
if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){
print("format error in mntxmit\n");
@@ 712,7 744,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
memcpy(mh->thdr.data, mh->rhdr.data, mh->rhdr.count);
mbfree(mh->mbr);
mbfree(mbw);
- poperror();
+ poperror(); /* 1 */
return;
Normal:
@@ 720,13 752,14 @@ mntxmit(Mnt *m, Mnthdr *mh)
incref(q);
qlock(q);
qlocked = 1;
- if(waserror()){
+ if(waserror()){ /* 2 */
if(qlocked)
qunlock(q);
mqfree(q);
nexterror();
}
mh->readreply = 0;
+ mh->active = 1;
if((*devtab[q->msg->type].write)(q->msg, mbw->buf, n) != n){
print("short write in mntxmit\n");
error(Eshortmsg);
@@ 736,14 769,15 @@ mntxmit(Mnt *m, Mnthdr *mh)
Read:
qunlock(q);
qlocked = 0;
- if(waserror()){
- mnterrdequeue(q, mh);
+ if(waserror()){ /* 3 */
+ mnterrdequeue(m, mh);
nexterror();
}
n = (*devtab[q->msg->type].read)(q->msg, mh->mbr->buf, BUFSIZE);
- poperror();
+ poperror(); /* 3 */
if(convM2S(mh->mbr->buf, &mh->rhdr, n) == 0){
- mnterrdequeue(q, mh);
+ print("bad reply message\n");
+ mnterrdequeue(m, mh);
error(Ebadmsg);
}
/*
@@ 755,13 789,12 @@ mntxmit(Mnt *m, Mnthdr *mh)
if(tag == mh->thdr.tag){ /* it's mine */
q->reader = 0;
if(w = q->writer){ /* advance a writer to reader */
+ mntwunlink(q, w);
q->reader = w->p;
- q->writer = w->next;
- if(q->writer)
- q->writer->prev = 0;
w->readreply = 1;
wakeup(&w->r);
}
+ mh->active = 0;
qunlock(q);
qlocked = 0;
goto Respond;
@@ 774,10 807,8 @@ mntxmit(Mnt *m, Mnthdr *mh)
goto Read;
}
w = &mnthdralloc.arena[tag];
- if(!w->writing){
- print("reply not writing\n");
+ if(w->flushing || !w->active) /* nothing to do; mntflush will clean up */
goto Read;
- }
t = mh->mbr;
mh->mbr = w->mbr;
w->mbr = t;
@@ 791,14 822,13 @@ mntxmit(Mnt *m, Mnthdr *mh)
/* put self in queue */
mh->next = q->writer;
mh->prev = 0;
- mh->writing = 1;
if(q->writer)
q->writer->prev = mh;
q->writer = mh;
qunlock(q);
qlocked = 0;
if(waserror()){ /* interrupted sleep */
- mnterrdequeue(q, mh);
+ mnterrdequeue(m, mh);
nexterror();
}
sleep(&mh->r, mntreadreply, mh);
@@ 807,6 837,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
qlocked = 1;
if(q->reader == u->p) /* i got promoted */
goto Read;
+ mh->active = 0;
qunlock(q);
qlocked = 0;
goto Respond;
@@ 814,11 845,14 @@ mntxmit(Mnt *m, Mnthdr *mh)
Respond:
mqfree(q);
- poperror();
+ poperror(); /* 2 */
if(mh->rhdr.type == Rerror){
if(m->mntpt)
errors(mh->rhdr.ename);
error(Eshutdown);
+ }else if(mh->rhdr.type != mh->thdr.type+1){
+ print("bad type %d not %d in mntxmit\n", mh->rhdr.type, mh->thdr.type+1);
+ error(Ebadmsg);
}
/*
* Copy out on read
@@ 830,7 864,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
}
mbfree(mh->mbr);
mbfree(mbw);
- poperror();
+ poperror(); /* 1 */
}
mntdump()
M port/proc.c => port/proc.c +0 -46
@@ 166,9 166,6 @@ loop:
unlock(&procalloc);
p->mach = 0;
p->qnext = 0;
- p->kid = 0;
- p->sib = 0;
- p->pop = 0;
p->nchild = 0;
p->child = 0;
p->exiting = 0;
@@ 477,50 474,7 @@ pexit(char *s, int freemem)
close(u->dot);
}
- /*
- * Rearrange inheritance hierarchy
- * 1. my children's pop is now my pop
- */
- lock(&c->kidlock);
- p = c->pop;
- if(k = c->kid) /* assign = */
- do{
- k->pop = p;
- k = k->sib;
- }while(k != c->kid);
-
- /*
- * 2. cut me from pop's tree
- */
- if(p == 0) /* init process only; fix pops */
- goto done;
- lock(&p->kidlock);
- k = p->kid;
- while(k->sib != c)
- k = k->sib;
- if(k == c)
- p->kid = 0;
- else{
- if(p->kid == c)
- p->kid = c->sib;
- k->sib = c->sib;
- }
-
- /*
- * 3. pass my children (pop's grandchildren) to pop
- */
- if(k = c->kid){ /* assign = */
- if(p->kid == 0)
- p->kid = k;
- else{
- l = k->sib;
- k->sib = p->kid->sib;
- p->kid->sib = l;
- }
- }
- unlock(&p->kidlock);
done:
- unlock(&c->kidlock);
lock(&procalloc); /* sched() can't do this */
lock(&c->debug); /* sched() can't do this */
M port/sysproc.c => port/sysproc.c +0 -15
@@ 111,20 111,6 @@ sysfork(ulong *arg)
if(c = u->fd[n]) /* assign = */
incref(c);
/*
- * Committed. Link into hierarchy
- */
- lock(&p->kidlock);
- lock(&u->p->kidlock);
- if(u->p->kid == 0){
- p->sib = p;
- u->p->kid = p;
- }else{
- p->sib = u->p->kid->sib;
- u->p->kid->sib = p;
- }
- unlock(&u->p->kidlock);
- unlock(&p->kidlock);
- /*
* Sched
*/
if(setlabel(&p->sched)){
@@ 135,7 121,6 @@ sysfork(ulong *arg)
spllo();
return 0;
}
- p->pop = u->p;
p->parent = u->p;
p->parentpid = u->p->pid;
p->pgrp = u->p->pgrp;
M power/dat.h => power/dat.h +1 -5
@@ 316,10 316,6 @@ struct Proc
Page *upage; /* BUG: should be unlinked from page list */
Seg seg[NSEG];
ulong pid;
- Lock kidlock; /* access to kid and sib */
- Proc *pop; /* some ascendant */
- Proc *kid; /* some descendant */
- Proc *sib; /* non-ascendant relatives (circular list) */
int nchild;
QLock wait; /* exiting children to be waited for */
ulong waitmsg;
@@ 339,7 335,7 @@ struct Proc
};
-#define NERR 15
+#define NERR 20
#define NFD 100
#define NNOTE 5
struct User