~kris/9p

9hist

916bb539005a999b8769d5176f1e95c7bd0cf55d — David du Colombier 36 years ago 6906627
Plan 9 from Bell Labs 1990-04-03
M gnot/dat.h => gnot/dat.h +6 -2
@@ 43,7 43,7 @@ struct List

struct Lock
{
	char	key[1];			/* addr of sync bus semaphore */
	char	key;			/* addr of sync bus semaphore */
	ulong	pc;
};



@@ 390,6 390,7 @@ struct Blist {
 */
struct Queue {
	Blist;
	int	nb;		/* number of blocks in queue */
	int	flag;
	Qinfo	*info;		/* line discipline definition */
	Queue	*other;		/* opposite direction, same line discipline */


@@ 426,6 427,8 @@ struct Stream {
#define STREAMQID(i,t)	(((i)<<5)|(t))
#define PUTNEXT(q,b)	(*(q)->next->put)((q)->next, b)
#define BLEN(b)		((b)->wptr - (b)->rptr)
#define QFULL(q)	((q)->flag & QHIWAT)
#define FLOWCTL(q)	{ if(QFULL(q)) flowctl(q); }

/*
 *  stream file qid's & high water mark


@@ 435,7 438,8 @@ enum {
	Sdataqid = Shighqid,
	Sctlqid = Sdataqid-1,
	Slowqid = Sctlqid,
	Streamhi= (8*1024),	/* stream high water mark */
	Streamhi= (9*1024),	/* byte count high water mark */
	Streambhi= 16,		/* block count high water mark */
};

#define	PRINTSIZE	256

M gnot/devdk.c => gnot/devdk.c +3 -5
@@ 417,11 417,7 @@ dkoput(Queue *q, Block *bp)
	bp->rptr[0] = line;
	bp->rptr[1] = line>>8;

	if(dp->wq->len >= Streamhi){
		print("dkoput free\n");
		freeb(bp);
	} else
		PUTNEXT(dp->wq, bp);
	PUTNEXT(dp->wq, bp);
}

/*


@@ 1132,6 1128,8 @@ dklisten(Chan *c)
		 */
		if(ts == lp->timestamp){
			print("dklisten: repeat timestamp %d\n", lineno);
			if(lp->state != Lconnected)
				dkanswer(c, lineno, DKbusy);
			continue;
		}
	

M gnot/devpipe.c => gnot/devpipe.c +1 -2
@@ 154,8 154,7 @@ pipeerrstr(Error *e, char *buf)
static void
pipeiput(Queue *q, Block *bp)
{
	if(q->next->len >= Streamhi)
		flowctl(q);
	FLOWCTL(q);
	PUTNEXT(q, bp);
}


M gnot/lock.c => gnot/lock.c +23 -9
@@ 4,6 4,15 @@
#include "dat.h"
#include "fns.h"

#define PCOFF -2

/*
 *  N.B.  Ken's compiler generates a TAS instruction for the sequence:
 *
 *  	if(l->key >= 0){
 *		l->key |= 0x80;
 *		...
 */
void
lock(Lock *l)
{


@@ 12,24 21,29 @@ lock(Lock *l)
	/*
	 * Try the fast grab first
	 */
    	if(tas(l->key) == 0){
		l->pc = ((ulong*)&l)[-1];
    	if(l->key >= 0){
		l->key |= 0x80;
		l->pc = ((ulong*)&i)[PCOFF];
		return;
	}
	for(i=0; i<10000000; i++)
    		if(tas(l->key) == 0){
			l->pc = ((ulong*)&l)[-1];
    		if(l->key >= 0){
			l->key |= 0x80;
			l->pc = ((ulong*)&i)[PCOFF];
			return;
	}
	l->key[0] = 0;
	panic("lock loop %lux pc %lux held by pc %lux\n", l, ((ulong*)&l)[-1], l->pc);
	l->key = 0;
	panic("lock loop %lux pc %lux held by pc %lux\n", l, ((ulong*)&i)[PCOFF], l->pc);
}

int
canlock(Lock *l)
{
	if(tas(l->key) == 0){
		l->pc = ((ulong*)&l)[-1];
	int i;

	if(l->key >= 0){
		l->key |= 0x80;
		l->pc = ((ulong*)&i)[PCOFF];
		return 1;
	}
	return 0;


@@ 39,7 53,7 @@ void
unlock(Lock *l)
{
	l->pc = 0;
	l->key[0] = 0;
	l->key = 0;
}

void

M gnot/stream.c => gnot/stream.c +16 -11
@@ 145,10 145,9 @@ allocb(ulong size)
	lock(bcp);
	while(bcp->first == 0){
		unlock(bcp);
		if(loop++ > 10){
		if(loop++ == 10){
			dumpqueues();
			dumpstack();
			panic("waiting for blocks\n");
			print("waiting for blocks\n");
		}
		qlock(bcp);
		tsleep(&bcp->r, isblock, (void *)bcp, 250);


@@ 230,12 229,14 @@ allocq(Qinfo *qi)
	q->r.p = 0;
	q->info = qi;
	q->put = qi->iput;
	q->len = q->nb = 0;
	wq = q->other = q + 1;

	wq->r.p = 0;
	wq->info = qi;
	wq->put = qi->oput;
	wq->other = q;
	wq->len = wq->nb = 0;

	unlock(q);



@@ 323,14 324,16 @@ putq(Queue *q, Block *bp)
	else
		q->first = bp;
	q->len += BLEN(bp);
	q->nb++;
	delim = bp->flags & S_DELIM;
	while(bp->next) {
		bp = bp->next;
		q->len += BLEN(bp);
		q->nb++;
		delim |= bp->flags & S_DELIM;
	}
	q->last = bp;
	if(q->len >= Streamhi)
	if(q->len >= Streamhi || q->nb >= Streambhi)
		q->flag |= QHIWAT;
	unlock(q);
	return delim;


@@ 387,7 390,8 @@ getq(Queue *q)
		if(q->first == 0)
			q->last = 0;
		q->len -= BLEN(bp);
		if((q->flag&QHIWAT) && q->len < Streamhi/2){
		q->nb--;
		if((q->flag&QHIWAT) && q->len < Streamhi/2 && q->nb < Streambhi){
			wakeup(&q->other->next->other->r);
			q->flag &= ~QHIWAT;
		}


@@ 762,14 766,16 @@ stputq(Queue *q, Block *bp)
		else
			q->first = bp;
		q->len += BLEN(bp);
		q->nb++;
		delim = bp->flags & S_DELIM;
		while(bp->next) {
			bp = bp->next;
			q->len += BLEN(bp);
			q->nb++;
			delim |= bp->flags & S_DELIM;
		}
		q->last = bp;
		if(q->len >= Streamhi){
		if(q->len >= Streamhi || q->nb >= Streambhi){
			q->flag |= QHIWAT;
			delim = 1;
		}


@@ 938,13 944,12 @@ notfull(void *arg)
	Queue *q;

	q = (Queue *)arg;
	return q->len < Streamhi;
	return !QFULL(q->next);
}
void
flowctl(Queue *q)
{
	if(q->next->len >= Streamhi)
		sleep(&q->r, notfull, q->next);
	sleep(&q->r, notfull, q->next);
}

/*


@@ 996,7 1001,7 @@ streamwrite(Chan *c, void *a, long n, int docopy)
		 *  `a' is global to the whole system, just create a
		 *  pointer to it and pass it on.
		 */
		flowctl(q);
		FLOWCTL(q);
		bp = allocb(0);
		bp->rptr = bp->base = (uchar *)a;
		bp->wptr = bp->lim = (uchar *)a+n;


@@ 1009,7 1014,7 @@ streamwrite(Chan *c, void *a, long n, int docopy)
		 *  system buffers and pass the buffers on.
		 */
		for(rem = n; ; rem -= i) {
			flowctl(q);
			FLOWCTL(q);
			bp = allocb(rem);
			i = bp->lim - bp->wptr;
			if(i >= rem){

M gnot/sturp.c => gnot/sturp.c +7 -9
@@ 253,7 253,7 @@ urpciput(Queue *q, Block *bp)
	/*
	 *  take care of any data
	 */
	if(BLEN(bp)>0 && q->next->len<Streamhi)
	if(BLEN(bp)>0 && !QFULL(q->next))
		PUTNEXT(q, bp);
	else
		freeb(bp);


@@ 311,7 311,7 @@ urpciput(Queue *q, Block *bp)
	case SEQ+4: case SEQ+5: case SEQ+6: case SEQ+7:
		qlock(&up->ack);
		i = ctl & Nmask;
		if(q->next->len < Streamhi)
		if(!QFULL(q->next))
			sendctl(up, up->lastecho = ECHO+i);
		up->iseq = i;
		qunlock(&up->ack);


@@ 479,7 479,7 @@ urpiput(Queue *q, Block *bp)
		 */
		qlock(&up->ack);
		up->iseq = i;
		if(q->next->len < Streamhi)
		if(!QFULL(q->next))
			sendctl(up, up->lastecho = ECHO|i);
		qunlock(&up->ack);
		break;


@@ 622,7 622,7 @@ sendctl(Urp *up, int ctl)
{
	Block *bp;

	if(up->wq->next->len > Streamhi)
	if(QFULL(up->wq->next))
		return;
	bp = allocb(1);
	bp->wptr = bp->lim;


@@ 658,7 658,7 @@ sendack(Urp *up)
	/*
	 *  check the precondition for acking
	 */
	if(up->rq->next->len>=Streamhi || (up->lastecho&Nmask)==up->iseq)
	if(QFULL(up->rq->next) || (up->lastecho&Nmask)==up->iseq)
		return;

	if(!canqlock(&up->ack))


@@ 667,7 667,7 @@ sendack(Urp *up)
	/*
	 *  check again now that we've locked
	 */
	if(up->rq->next->len>=Streamhi || (up->lastecho&Nmask)==up->iseq){
	if(QFULL(up->rq->next) || (up->lastecho&Nmask)==up->iseq){
		qunlock(&up->ack);
		return;
	}


@@ 689,7 689,7 @@ sendblock(Urp *up, int bn)
	int n;

	up->timer = NOW + MSrexmit;
	if(up->wq->next->len > Streamhi)
	if(QFULL(up->wq->next))
		return;

	/*


@@ 804,8 804,6 @@ initoutput(Urp *up, int window)
	up->maxblock = window/4;
	if(up->maxblock < 64)
		up->maxblock = 64;
	if(up->maxblock > Streamhi/4)
		up->maxblock = Streamhi/4;
	up->maxblock -= 4;
	up->maxout = 3;


M port/devdk.c => port/devdk.c +2 -0
@@ 1128,6 1128,8 @@ dklisten(Chan *c)
		 */
		if(ts == lp->timestamp){
			print("dklisten: repeat timestamp %d\n", lineno);
			if(lp->state != Lconnected)
				dkanswer(c, lineno, DKbusy);
			continue;
		}
	

M port/devpipe.c => port/devpipe.c +6 -2
@@ 11,7 11,7 @@
static void pipeiput(Queue*, Block*);
static void pipeoput(Queue*, Block*);
static void pipestclose(Queue *);
Qinfo pipeinfo = { pipeiput, pipeoput, 0, pipestclose, "process" };
Qinfo pipeinfo = { pipeiput, pipeoput, 0, pipestclose, "pipe" };

void
pipeinit(void)


@@ 154,7 154,7 @@ pipeerrstr(Error *e, char *buf)
static void
pipeiput(Queue *q, Block *bp)
{
	flowctl(q);
	FLOWCTL(q);
	PUTNEXT(q, bp);
}



@@ 168,6 168,10 @@ pipeoput(Queue *q, Block *bp)
	lock(q);
	if(q->next)
		pipeiput(q->next, bp);
	else{
		print("pipeoput losing block\n");
		freeb(bp);
	}
	unlock(q);
}


M port/stream.c => port/stream.c +18 -12
@@ 58,7 58,7 @@ Bclass bclass[Nclass]={
	{ 0 },
	{ 68 },
	{ 260 },
	{ 4096 },
	{ 1024 },
};

/*


@@ 145,10 145,9 @@ allocb(ulong size)
	lock(bcp);
	while(bcp->first == 0){
		unlock(bcp);
		if(loop++ > 10){
		if(loop++ == 10){
			dumpqueues();
			dumpstack();
			panic("waiting for blocks\n");
			print("waiting for blocks\n");
		}
		qlock(bcp);
		tsleep(&bcp->r, isblock, (void *)bcp, 250);


@@ 230,12 229,14 @@ allocq(Qinfo *qi)
	q->r.p = 0;
	q->info = qi;
	q->put = qi->iput;
	q->len = q->nb = 0;
	wq = q->other = q + 1;

	wq->r.p = 0;
	wq->info = qi;
	wq->put = qi->oput;
	wq->other = q;
	wq->len = wq->nb = 0;

	unlock(q);



@@ 323,14 324,16 @@ putq(Queue *q, Block *bp)
	else
		q->first = bp;
	q->len += BLEN(bp);
	q->nb++;
	delim = bp->flags & S_DELIM;
	while(bp->next) {
		bp = bp->next;
		q->len += BLEN(bp);
		q->nb++;
		delim |= bp->flags & S_DELIM;
	}
	q->last = bp;
	if(q->len >= Streamhi)
	if(q->len >= Streamhi || q->nb >= Streambhi)
		q->flag |= QHIWAT;
	unlock(q);
	return delim;


@@ 369,6 372,7 @@ putbq(Blist *q, Block *bp)
		q->last = bp;
	q->first = bp;
	q->len += BLEN(bp);
	q->nb++;
	unlock(q);
}



@@ 387,7 391,8 @@ getq(Queue *q)
		if(q->first == 0)
			q->last = 0;
		q->len -= BLEN(bp);
		if((q->flag&QHIWAT) && q->len < Streamhi/2){
		q->nb--;
		if((q->flag&QHIWAT) && q->len < Streamhi/2 && q->nb < Streambhi){
			wakeup(&q->other->next->other->r);
			q->flag &= ~QHIWAT;
		}


@@ 762,14 767,16 @@ stputq(Queue *q, Block *bp)
		else
			q->first = bp;
		q->len += BLEN(bp);
		q->nb++;
		delim = bp->flags & S_DELIM;
		while(bp->next) {
			bp = bp->next;
			q->len += BLEN(bp);
			q->nb++;
			delim |= bp->flags & S_DELIM;
		}
		q->last = bp;
		if(q->len >= Streamhi){
		if(q->len >= Streamhi || q->nb >= Streambhi){
			q->flag |= QHIWAT;
			delim = 1;
		}


@@ 938,13 945,12 @@ notfull(void *arg)
	Queue *q;

	q = (Queue *)arg;
	return q->len < Streamhi;
	return !QFULL(q->next);
}
void
flowctl(Queue *q)
{
	if(q->next->len >= Streamhi)
		sleep(&q->r, notfull, q->next);
	sleep(&q->r, notfull, q->next);
}

/*


@@ 996,7 1002,7 @@ streamwrite(Chan *c, void *a, long n, int docopy)
		 *  `a' is global to the whole system, just create a
		 *  pointer to it and pass it on.
		 */
		flowctl(q);
		FLOWCTL(q);
		bp = allocb(0);
		bp->rptr = bp->base = (uchar *)a;
		bp->wptr = bp->lim = (uchar *)a+n;


@@ 1009,7 1015,7 @@ streamwrite(Chan *c, void *a, long n, int docopy)
		 *  system buffers and pass the buffers on.
		 */
		for(rem = n; ; rem -= i) {
			flowctl(q);
			FLOWCTL(q);
			bp = allocb(rem);
			i = bp->lim - bp->wptr;
			if(i >= rem){

M port/sturp.c => port/sturp.c +21 -12
@@ 207,6 207,9 @@ urpclose(Queue *q)
	 *  kill off the kernel process
	 */
	wakeup(&up->rq->r);

	if(up->kstarted == 0)
		up->state = 0;
}

/*


@@ 253,7 256,7 @@ urpciput(Queue *q, Block *bp)
	/*
	 *  take care of any data
	 */
	if(BLEN(bp)>0 && q->next->len<Streamhi)
	if(BLEN(bp)>0 && !QFULL(q->next))
		PUTNEXT(q, bp);
	else
		freeb(bp);


@@ 311,7 314,7 @@ urpciput(Queue *q, Block *bp)
	case SEQ+4: case SEQ+5: case SEQ+6: case SEQ+7:
		qlock(&up->ack);
		i = ctl & Nmask;
		if(q->next->len < Streamhi)
		if(!QFULL(q->next))
			sendctl(up, up->lastecho = ECHO+i);
		up->iseq = i;
		qunlock(&up->ack);


@@ 479,7 482,7 @@ urpiput(Queue *q, Block *bp)
		 */
		qlock(&up->ack);
		up->iseq = i;
		if(q->next->len < Streamhi)
		if(!QFULL(q->next))
			sendctl(up, up->lastecho = ECHO|i);
		qunlock(&up->ack);
		break;


@@ 572,14 575,16 @@ output(Urp *up)
	 *  fill the transmit buffers
	 */
	q = up->wq;
	for(bp = getq(q); bp && up->xb[up->nxb]==0; up->nxb = NEXT(up->nxb)){
	for(bp = getq(q); q->first && up->xb[up->nxb]==0; up->nxb = NEXT(up->nxb)){
		if(bp == 0)
			bp = getq(q);
		if(BLEN(bp) > up->maxblock){
			nbp = up->xb[up->nxb] = allocb(0);
			nbp->rptr = bp->rptr;
			nbp->wptr = bp->rptr = bp->rptr + up->maxblock;
		} else {
			up->xb[up->nxb] = bp;
			bp = getq(q);
			bp = 0;
		}
	}
	if(bp)


@@ 622,7 627,7 @@ sendctl(Urp *up, int ctl)
{
	Block *bp;

	if(up->wq->next->len > Streamhi)
	if(QFULL(up->wq->next))
		return;
	bp = allocb(1);
	bp->wptr = bp->lim;


@@ 658,7 663,7 @@ sendack(Urp *up)
	/*
	 *  check the precondition for acking
	 */
	if(up->rq->next->len>=Streamhi || (up->lastecho&Nmask)==up->iseq)
	if(QFULL(up->rq->next) || (up->lastecho&Nmask)==up->iseq)
		return;

	if(!canqlock(&up->ack))


@@ 667,7 672,7 @@ sendack(Urp *up)
	/*
	 *  check again now that we've locked
	 */
	if(up->rq->next->len>=Streamhi || (up->lastecho&Nmask)==up->iseq){
	if(QFULL(up->rq->next) || (up->lastecho&Nmask)==up->iseq){
		qunlock(&up->ack);
		return;
	}


@@ 689,7 694,7 @@ sendblock(Urp *up, int bn)
	int n;

	up->timer = NOW + MSrexmit;
	if(up->wq->next->len > Streamhi)
	if(QFULL(up->wq->next))
		return;

	/*


@@ 804,8 809,6 @@ initoutput(Urp *up, int window)
	up->maxblock = window/4;
	if(up->maxblock < 64)
		up->maxblock = 64;
	if(up->maxblock > Streamhi/4)
		up->maxblock = Streamhi/4;
	up->maxblock -= 4;
	up->maxout = 3;



@@ 870,6 873,12 @@ urpkproc(void *arg)

	up = (Urp *)arg;

	if(waserror()){
		up->state = 0;
		up->kstarted = 0;
		wakeup(&up->r);
		return;
	}
	for(;;){
		if(up->state & (HUNGUP|CLOSING)){
			if(isflushed(up))


@@ 881,6 890,6 @@ urpkproc(void *arg)
		output(up);
		tsleep(&up->rq->r, todo, up, MSrexmit/2);
	}
	up->kstarted = 0;
	up->state = 0;
	up->kstarted = 0;
}

M power/dat.h => power/dat.h +5 -1
@@ 407,6 407,7 @@ struct Blist {
 */
struct Queue {
	Blist;
	int	nb;		/* number of blocks in queue */
	int	flag;
	Qinfo	*info;		/* line discipline definition */
	Queue	*other;		/* opposite direction, same line discipline */


@@ 443,6 444,8 @@ struct Stream {
#define STREAMQID(i,t)	(((i)<<5)|(t))
#define PUTNEXT(q,b)	(*(q)->next->put)((q)->next, b)
#define BLEN(b)		((b)->wptr - (b)->rptr)
#define QFULL(q)	((q)->flag & QHIWAT)
#define FLOWCTL(q)	{ if(QFULL(q)) flowctl(q); }

/*
 *  stream file qid's & high water mark


@@ 452,7 455,8 @@ enum {
	Sdataqid = Shighqid,
	Sctlqid = Sdataqid-1,
	Slowqid = Sctlqid,
	Streamhi= (9*1024),	/* stream high water mark */
	Streamhi= (9*1024),	/* byte count high water mark */
	Streambhi= 16,		/* block count high water mark */
};

#define	PRINTSIZE	256

M power/devhs.c => power/devhs.c +5 -5
@@ 158,7 158,6 @@ hsvmeattach(char *spec)
		error(0, Ebadarg);
	hp = &hsvme[i];
	hsvmerestart(hp);
	print("hsvme [%d] csr %ux\n", i, hp->addr->csr);

	c = devattach('h', spec);
	c->dev = i;


@@ 466,6 465,7 @@ hsvmekproc(void *arg)
	Hsvme *hp;
	Device *addr;
	unsigned int c;
	int miss;

	hp = (Hsvme *)arg;
	addr = hp->addr;


@@ 485,15 485,14 @@ hsvmekproc(void *arg)
		}

		/*
		 *  let the fifo fill a bit
		 *  if we loop many times without finding a character, sleep
		 */
		delay(1);

		for(miss = 0; miss < 10; miss++){
		/*
		 *  0xFFFF means an empty fifo
		 */
		while ((c = addr->data) != 0xFFFF) {
/*			print(" %.2uo<-\n", c); /**/
			miss = 0;
			if(c & CHNO){
				c &= 0x1FF;
				if(hp->chan == c)


@@ 518,6 517,7 @@ hsvmekproc(void *arg)
					upstream(hp, 0);
			}
		}
		}
		qunlock(hp);

		/*