M gnot/proc.c => gnot/proc.c +27 -0
@@ 411,8 411,35 @@ pexit(char *s, int freemem)
}
out:
if(!freemem){
+ /*
+ * weird thing: keep at most NBROKEN around
+ */
+ #define NBROKEN 4
+ static struct{
+ Lock;
+ int n;
+ Proc *p[NBROKEN];
+ }broken;
+ int b;
+
+ lock(&broken);
+ if(broken.n == NBROKEN){
+ ready(broken.p[0]);
+ memcpy(&broken.p[0], &broken.p[1], sizeof(Proc*)*(NBROKEN-1));
+ --broken.n;
+ }
+ broken.p[broken.n++] = c;
+ unlock(&broken);
c->state = Broken;
sched(); /* until someone lets us go */
+ lock(&broken);
+ for(b=0; b<NBROKEN; b++)
+ if(broken.p[b] == c){
+ broken.n--;
+ memcpy(&broken.p[b], &broken.p[b+1], sizeof(Proc*)*(NBROKEN-(b+1)));
+ break;
+ }
+ unlock(&broken);
freesegs(-1);
closepgrp(c->pgrp);
close(u->dot);
M port/devdk.c => port/devdk.c +5 -1
@@ 417,7 417,11 @@ dkoput(Queue *q, Block *bp)
bp->rptr[0] = line;
bp->rptr[1] = line>>8;
- PUTNEXT(dp->wq, bp);
+ if(QFULL(dp->wq->next)){
+ print("dk wq full\n");
+ freeb(bp);
+ } else
+ PUTNEXT(dp->wq, bp);
}
/*
M port/proc.c => port/proc.c +27 -0
@@ 410,8 410,35 @@ pexit(char *s, int freemem)
}
out:
if(!freemem){
+ /*
+ * weird thing: keep at most NBROKEN around
+ */
+ #define NBROKEN 4
+ static struct{
+ Lock;
+ int n;
+ Proc *p[NBROKEN];
+ }broken;
+ int b;
+
+ lock(&broken);
+ if(broken.n == NBROKEN){
+ ready(broken.p[0]);
+ memcpy(&broken.p[0], &broken.p[1], sizeof(Proc*)*(NBROKEN-1));
+ --broken.n;
+ }
+ broken.p[broken.n++] = c;
+ unlock(&broken);
c->state = Broken;
sched(); /* until someone lets us go */
+ lock(&broken);
+ for(b=0; b<NBROKEN; b++)
+ if(broken.p[b] == c){
+ broken.n--;
+ memcpy(&broken.p[b], &broken.p[b+1], sizeof(Proc*)*(NBROKEN-(b+1)));
+ break;
+ }
+ unlock(&broken);
freesegs(-1);
closepgrp(c->pgrp);
close(u->dot);
M port/stream.c => port/stream.c +11 -0
@@ 70,7 70,9 @@ dumpqueues(void)
Queue *q;
int count;
Block *bp;
+ Bclass *bcp;
+ print("\n");
for(q = qlist; q < qlist + conf.nqueue; q++, q++){
if(!(q->flag & QINUSE))
continue;
@@ 81,6 83,15 @@ dumpqueues(void)
count++;
print(" WR count %d len %d\n", count, WR(q)->len);
}
+ print("\n");
+ for(bcp=bclass; bcp<&bclass[Nclass-1]; bcp++){
+ lock(bcp);
+ for(count = 0, bp = bcp->first; bp; count++, bp = bp->next)
+ ;
+ unlock(bcp);
+ print("%d blocks of size %d\n", count, bcp->size);
+ }
+ print("\n");
}
/*
M port/sturp.c => port/sturp.c +18 -7
@@ 166,7 166,7 @@ isflushed(void *a)
Urp *up;
up = (Urp *)a;
- return (up->state&HUNGUP) || (up->unechoed==up->next && up->wq->len==0);
+ return (up->state&HUNGUP) || (up->unechoed==up->nxb && up->wq->len==0);
}
static int
isdead(void *a)
@@ 188,25 188,36 @@ urpclose(Queue *q)
/*
* wait for all outstanding messages to drain, tell kernel
* process we're closing.
+ *
+ * if 2 minutes elapse, give it up
*/
up->state |= CLOSING;
- tsleep(&up->r, isflushed, up, 60*1000);
+ tsleep(&up->r, isflushed, up, 2*60*1000);
/*
- * ack all outstanding messages
+ * kill off the kernel process
*/
- qlock(&up->xmit);
up->state |= HUNGUP;
+ wakeup(&up->rq->r);
+
+ qlock(&up->xmit);
+ /*
+ * ack all outstanding messages
+ */
i = up->next - 1;
if(i < 0)
i = 7;
rcvack(up, ECHO+i);
- qunlock(&up->xmit);
/*
- * kill off the kernel process
+ * free all staged but unsent messages
*/
- wakeup(&up->rq->r);
+ for(i = 0; i < 7; i++)
+ if(up->xb[i]){
+ freeb(up->xb[i]);
+ up->xb[i] = 0;
+ }
+ qunlock(&up->xmit);
if(up->kstarted == 0)
up->state = 0;