~kris/9p

9hist

ec7bb12cf39e0df52405a8d77cdb38692bce4611 — David du Colombier 32 years ago cd9ee40
Plan 9 from Bell Labs 1994-03-22
M carrera/dat.h => carrera/dat.h +2 -2
@@ 24,8 24,7 @@ typedef struct Ureg	Ureg;
struct Lock
{
	ulong	key;			/* semaphore (non-zero = locked) */
	ulong	pc;
	void	*upa;
	ulong	sr;
};

struct Label


@@ 48,6 47,7 @@ struct Conf
	ulong	base1;		/* base of bank 1 */
	ulong	copymode;	/* 0 is copy on write, 1 is copy on reference */
	int	monitor;
	ulong	ialloc;		/* bytes available for interrupt time allocation */
};

/*

M carrera/l.s => carrera/l.s +2 -8
@@ 8,7 8,7 @@
#define	WAIT		NOOP; NOOP
#define	NOOP4		NOOP; NOOP; NOOP; NOOP

#define	ERET		NOOP4;NOOP4;WORD	$0x42000018;NOOP4;NOOP4
#define	ERET		NOOP4;NOOP4;NOOP4;WORD $0x42000018;NOOP4;NOOP4;NOOP4

#define	CONST(x,r)	MOVW $((x)&0xffff0000), r; OR  $((x)&0xffff), r



@@ 103,7 103,6 @@ TEXT	touser(SB), $-4
	WAIT
	MOVW	R1, SP
	MOVW	R2, M(EPC)
	NOOP4
	ERET

TEXT	firmware(SB), $0


@@ 358,12 357,10 @@ utlbcom:
	NOOP4
	BGEZ	R26, utlindex
	TLBWR
	NOOP4
	ERET
utlindex:
	MOVW	R0,(R0)
	TLBWI
	NOOP4
	ERET

stlbm:


@@ 426,12 423,11 @@ sysrestore:
	MOVW	0x0C(SP), R26		/* old pc */
	MOVW	0x10(SP), SP
	MOVW	R26, M(EPC)
	NOOP4
	ERET

notsys:
	JAL	trap(SB)

	RDBGSV
restore:
	JAL	restregs(SB)
	MOVW	0x28(SP), R31


@@ 440,7 436,6 @@ restore:
	MOVW	0x40(SP), R(USER)
	MOVW	0x10(SP), SP
	MOVW	R26, M(EPC)
	NOOP4
	ERET

waskernel:


@@ 455,7 450,6 @@ waskernel:
	MOVW	0x28(SP), R31
	ADDU	$UREGSIZE, SP
	MOVW	R26, M(EPC)
	NOOP4
	ERET

TEXT	forkret(SB), $0

M carrera/main.c => carrera/main.c +7 -4
@@ 42,6 42,7 @@ main(void)
{
	tlbinit();
	ioinit(1);		/* Very early to establish IO mappings */
	rdbginit();
	arginit();
	confinit();
	savefpregs(&initfp);


@@ 61,7 62,6 @@ main(void)
	chandevreset();
	swapinit();
	userinit();
	rdbginit();
	schedinit();
}



@@ 155,6 155,11 @@ machinit(void)

	active.exiting = 0;
	active.machs = 1;

	/* Setup call back ring buffer */
	m->cbin = m->calls;
	m->cbout = m->calls;
	m->cbend = &m->calls[NCALLBACK];
}

/*


@@ 331,7 336,6 @@ init0(void)
	up->slash = namec("#/", Atodir, 0, 0);
	up->dot = clone(up->slash, 0);

	iallocinit();
	chandevinit();

	if(!waserror()){


@@ 440,6 444,7 @@ confinit(void)
	conf.base1 = 0;

	conf.upages = (conf.npage*70)/100;
	conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG;

	conf.nmach = 1;



@@ 499,8 504,6 @@ rdbginit(void)
	uchar *vec;
	ulong jba;

	return;	/* Not installed now */

	/* Only interested in the PC */
	Mipsjmpbuf.pc = 0x8001C020;


M carrera/mem.h => carrera/mem.h +2 -1
@@ 13,7 13,8 @@
#define	BY2PG		4096			/* bytes per page */
#define	WD2PG		(BY2PG/BY2WD)		/* words per page */
#define	PGSHIFT		12			/* log(BY2PG) */
#define	PGROUND(s)	(((s)+(BY2PG-1))&~(BY2PG-1))
#define ROUND(s, sz)	(((s)+(sz-1))&~(sz-1))
#define PGROUND(s)	ROUND(s, BY2PG)

#define	MAXMACH		1			/* max # cpus system can run */
#define	KSTACK		4096			/* Size of kernel stack */

M carrera/trap.c => carrera/trap.c +13 -2
@@ 102,6 102,8 @@ ptlb(ulong phys)
	return buf[k];
}

ulong *XDBG = (ulong*)0x80020018;

static void
kpteprint(Ureg *ur)
{


@@ 271,17 273,20 @@ trap(Ureg *ur)
		}
	}


XDBG[0] = 7;
	splhi();
	if(!user)
		return;
XDBG[0] = 8;

	notify(ur);
XDBG[0] = 9;
	if(up->fpstate == FPinactive) {
		restfpregs(&up->fpsave, up->fpsave.fpstatus&~FPEXPMASK);
		up->fpstate = FPactive;
		ur->status |= CU1;
	}
XDBG[0] = 10;
}

void


@@ 291,9 296,11 @@ intr(Ureg *ur)
	ulong cause = ur->cause;
	ulong isr, vec;

XDBG[0] = 0;
	m->intr++;
	cause &= INTR7|INTR6|INTR5|INTR4|INTR3|INTR2|INTR1|INTR0;

XDBG[0] = 1;
	if(cause & INTR3) {
		devint = IO(uchar, Intcause);
		switch(devint) {


@@ 320,6 327,7 @@ intr(Ureg *ur)
		}
		cause &= ~INTR3;
	}
XDBG[0] = 2;
	if(cause & INTR2) {
		isr = IO(ulong, R4030Isr);
		if(isr) {


@@ 331,6 339,7 @@ intr(Ureg *ur)
		}
		cause &= ~INTR2;
	}
XDBG[0] = 3;
	if(cause & INTR4) {
		devint = IO(uchar, I386ack);
		vec = devint&~0x7;


@@ 355,15 364,17 @@ intr(Ureg *ur)
		}
		cause &= ~INTR4;
	}
XDBG[0] = 4;
	if(cause & INTR7) {
		clock(ur);
		cause &= ~INTR7;
	}

XDBG[0] = 5;
	if(cause) {
		iprint("cause %lux\n", cause);
		exit(1);
	}
XDBG[0] = 6;
}

char*

M pc/dat.h => pc/dat.h +2 -1
@@ 25,7 25,7 @@ extern  void	(*kprofp)(ulong);
struct Lock
{
	ulong	key;
	ulong	pc;
	ulong	sr;
};

struct Label


@@ 82,6 82,7 @@ struct Conf
	ulong	ldepth;		/* screen depth */
	ulong	maxx;		/* screen width */
	ulong	maxy;		/* screen length */
	ulong	ialloc;		/* max interrupt time allocation in bytes */
};

/*

M pc/fns.h => pc/fns.h +1 -0
@@ 38,6 38,7 @@ ushort	ins(int);
void	inss(int, void*, int);
ulong	inl(int);
void	insl(int, void*, int);
int	iprint(char*, ...);
int	isaconfig(char*, int, ISAConf*);
ulong	isamem(int);
void	kbdinit(void);

M pc/kbd.c => pc/kbd.c +3 -2
@@ 505,7 505,7 @@ kbdintr(Ureg *ur, void *arg)
 *  set up a ps2 mouse
 */
static void
ps2mouse(int frominit)
ps2mouse(void)
{
	int x;



@@ 566,7 566,7 @@ mousectl(char *arg)
			break;
		}
	} else if(strcmp(field[0], "ps2") == 0){
		ps2mouse(0);
		ps2mouse();
	} else if(strcmp(field[0], "accelerated") == 0){
		switch(mousetype){
		case MousePS2:


@@ 623,6 623,7 @@ kbdinit(void)
		ccc = inb(Data);

	/* enable kbd xfers and interrupts */
	/* disable mouse */
	ccc &= ~Ckbddis;
	ccc |= Csf | Ckbdint | Cscs1 | Cmousedis;
	if(outready() < 0)

M pc/main.c => pc/main.c +1 -1
@@ 119,7 119,6 @@ init0(void)
	up->slash = namec("#/", Atodir, 0, 0);
	up->dot = clone(up->slash, 0);

	iallocinit();
	chandevinit();

	if(!waserror()){


@@ 387,6 386,7 @@ confinit(void)
	if(pcnt < 10)
		pcnt = 70;
	conf.upages = (conf.npage*pcnt)/100;
	conf.ialloc = ((conf.npage-conf.upages)/2)*BY2PG;

	conf.nproc = 30 + ((conf.npage*BY2PG)/MB)*5;
	conf.monitor = 1;

M pc/mem.h => pc/mem.h +2 -1
@@ 12,7 12,8 @@
#define	BY2PG		4096			/* bytes per page */
#define	WD2PG		(BY2PG/BY2WD)		/* words per page */
#define	PGSHIFT		12			/* log(BY2PG) */
#define PGROUND(s)	(((s)+(BY2PG-1))&~(BY2PG-1))
#define ROUND(s, sz)	(((s)+(sz-1))&~(sz-1))
#define PGROUND(s)	ROUND(s, BY2PG)

#define	MAXMACH		1			/* max # cpus system can run */


M port/alloc.c => port/alloc.c +21 -33
@@ 118,9 118,6 @@ xinit(void)
	conf.base1 = (ulong)KADDR(conf.base1);
	conf.npage0 = (ulong)KADDR(conf.npage0);
	conf.npage1 = (ulong)KADDR(conf.npage1);

	/* setup initial memory allocations for interrupt time */
	qinit();
}

/*


@@ 162,7 159,7 @@ xallocz(ulong size, int zero)
	size += BY2V + sizeof(Xhdr);
	size &= ~(BY2V-1);

	lock(&xlists);
	ilock(&xlists);
	l = &xlists.table;
	for(h = *l; h; h = h->link) {
		if(h->size >= size) {


@@ 174,7 171,7 @@ xallocz(ulong size, int zero)
				h->link = xlists.flist;
				xlists.flist = h;
			}
			unlock(&xlists);
			iunlock(&xlists);
			p = KADDR(p);
			if(zero)
				memset(p, 0, size);


@@ 184,16 181,10 @@ xallocz(ulong size, int zero)
		}
		l = &h->link;
	}
	unlock(&xlists);
	iunlock(&xlists);
	return nil;
}

void*
xalloc(ulong size)
{
	return xallocz(size, 1);
}

void
xfree(void *p)
{


@@ 217,7 208,7 @@ xhole(ulong addr, ulong size)
		return;

	top = addr + size;
	lock(&xlists);
	ilock(&xlists);
	l = &xlists.table;
	for(h = *l; h; h = h->link) {
		if(h->top == addr) {


@@ 231,7 222,7 @@ xhole(ulong addr, ulong size)
				c->link = xlists.flist;
				xlists.flist = c;
			}
			unlock(&xlists);
			iunlock(&xlists);
			return;
		}
		if(h->addr > addr)


@@ 241,12 232,12 @@ xhole(ulong addr, ulong size)
	if(h && top == h->addr) {
		h->addr -= size;
		h->size += size;
		unlock(&xlists);
		iunlock(&xlists);
		return;
	}

	if(xlists.flist == nil) {
		unlock(&xlists);
		iunlock(&xlists);
		print("xfree: no free holes, leaked %d bytes\n", size);
		return;
	}


@@ 258,11 249,11 @@ xhole(ulong addr, ulong size)
	h->size = size;
	h->link = *l;
	*l = h;
	unlock(&xlists);
	iunlock(&xlists);
}

void*
malloc(ulong size)
mallocz(ulong size, int zero)
{
	ulong next;
	int pow, n;


@@ 275,21 266,22 @@ malloc(ulong size)
	return nil;
good:
	/* Allocate off this list */
	lock(&arena);
	ilock(&arena);
	bp = arena.btab[pow];
	if(bp) {
		arena.btab[pow] = bp->next;
		unlock(&arena);
		iunlock(&arena);

		if(bp->magic != 0)
			panic("malloc %lux %lux", bp->magic, bp->pc);

		bp->magic = Magic2n;
		bp->pc = getcallerpc(((uchar*)&size) - sizeof(size));
		memset(bp->data, 0,  size);

		if(zero)
			memset(bp->data, 0,  size);
		return  bp->data;
	}
	unlock(&arena);
	iunlock(&arena);

	size = sizeof(Bucket)+(1<<pow);
	size += BY2V;


@@ 303,7 295,7 @@ good:

		next = (ulong)bp+size;
		nbp = (Bucket*)next;
		lock(&arena);
		ilock(&arena);
		arena.btab[pow] = nbp;
		arena.nbuck[pow] += n;
		for(n -= 2; n; n--) {


@@ 313,7 305,7 @@ good:
			nbp = nbp->next;
		}
		nbp->size = pow;
		unlock(&arena);
		iunlock(&arena);
	}
	else {
		bp = xalloc(size);


@@ 325,7 317,7 @@ good:

	bp->size = pow;
	bp->magic = Magic2n;
	bp->pc = getcallerpc(((uchar*)&size) - sizeof(size));

	return bp->data;
}



@@ 335,15 327,11 @@ smalloc(ulong size)
	char *s;
	void *p;
	int attempt;
	Bucket *bp;

	for(attempt = 0; attempt < 1000; attempt++) {
		p = malloc(size);
		if(p != nil) {
			bp = (Bucket*)((ulong)p - bdatoff);
			bp->pc = getcallerpc(((uchar*)&size) - sizeof(size));
		if(p != nil)
			return p;
		}
		s = up->psstate;
		up->psstate = "Malloc";
		qlock(&arena.rq);


@@ 379,11 367,11 @@ free(void *ptr)
		panic("free %lux %lux", bp->magic, bp->pc);

	bp->magic = 0;
	lock(&arena);
	ilock(&arena);
	l = &arena.btab[bp->size];
	bp->next = *l;
	*l = bp;
	unlock(&arena);
	iunlock(&arena);
	if(arena.r.p)
		wakeup(&arena.r);
}

M port/portdat.h => port/portdat.h +1 -1
@@ 122,12 122,12 @@ struct Block
{
	Block*	next;
	Block*	list;
	int	size;			/* power of 2 allocation list */
	uchar*	rp;			/* first unconsumed byte */
	uchar*	wp;			/* first empty byte */
	uchar*	lim;			/* 1 past the end of the buffer */
	uchar*	base;			/* start of the buffer */
	uchar	flag;
	uchar	intr;
};
#define BLEN(s)	((s)->wp - (s)->rp)


M port/portfns.h => port/portfns.h +6 -2
@@ 81,6 81,7 @@ void		flushmmu(void);
void		forkchild(Proc*, Ureg*);
void		forkret(void);
void		free(void*);
void		freeb(Block*);
int		freebroken(void);
void		freechan(Chan*);
void		freepte(Segment*, Pte*);


@@ 96,6 97,8 @@ void		hwcursmove(int, int);
void		hwcursset(ulong*, ulong*, int, int);
void		iallocinit(void);
long		ibrk(ulong, int);
void		ilock(Lock*);
void		iunlock(Lock*);
int		incref(Ref*);
void		initscsi(void);
void		initseg(void);


@@ 124,7 127,8 @@ void		lockinit(void);
Page*		lookpage(Image*, ulong);
int		m3mouseputc(int);
void		machinit(void);
void*		malloc(ulong);
#define		malloc(s)	mallocz(s, 1)
void*		mallocz(ulong, int);
void		mbbpt(Point);
void		mbbrect(Rectangle);
void		mfreeseg(Segment*, ulong, int);


@@ 258,7 262,7 @@ void		wakeup(Rendez*);
Chan*		walk(Chan*, char*, int);
void		wlock(RWlock*);
void		wunlock(RWlock*);
void*		xalloc(ulong);
#define		xalloc(s)	xallocz(s, 1)
void*		xallocz(ulong, int);
void		xfree(void*);
void		xhole(ulong, ulong);

M port/proc.c => port/proc.c +0 -4
@@ 44,10 44,6 @@ char *statename[] =
void
schedinit(void)		/* never returns */
{
	m->cbin = m->calls;
	m->cbout = m->calls;
	m->cbend = &m->calls[NCALLBACK];

	setlabel(&m->sched);
	if(up) {
		m->proc = 0;

M port/qio.c => port/qio.c +62 -164
@@ 5,23 5,11 @@
#include	"fns.h"
#include	"../port/error.h"


enum
{
	Minpow	= 7,
	Maxpow	= 16,
};

struct Pool
struct
{
	Lock;
	Block*	list;
	int	had;
	int	have;
	int	want;
	int	goal;
};
Pool	pool[Maxpow];
	ulong	bytes;
} ialloc;

/*
 *  IO queues


@@ 79,143 67,65 @@ checkb(Block *b, char *msg)
		panic("checkb 4 %s %lux %lux", msg, b->wp, b->lim);
}

void
poison(Block *b)
{
	b->next = (void*)0xdeadbabe;
	b->rp = (void*)0xdeadbabe;
	b->wp = (void*)0xdeadbabe;
	b->lim = (void*)0xdeadbabe;
	b->base = (void*)0xdeadbabe;
}

/*
 *  Manage interrupt level memory allocation.
 *  interrupt time allocation
 */
static void
iallocmgr(void)
Block*
iallocb(int size)
{
	int pow;

	attention = 0;
	spllo();
	for(pow = Minpow; pow <= Maxpow; pow++) {
		p = &pool[pow];

		/* Low pass filter */
		delta = 3 * (p->had - p->have);
		delta = (delta/2) + p->want;

		if(delta < 0) {
			lock(p);
			p->have -= delta;
			bp = p->list;
			while(delta--)
				p->list = p->list->next;
			unlock(p);
			spllo();
			while(bp) {
				next = bp->next;
				free(bp);
				bp = next;
			}
			splhi();
		}
		else {
			spllo();
			n = 0;
			s = sizeof(Block)+(1<<pow)+(BY2V-1);
			while(delta--) {
				b = malloc(s);
				if(b == 0)
					break;
				addr = (ulong)b;
				addr = (addr+sizeof(Block)+(BY2V-1)) & ~(BY2V-1);
				b->base = (uchar*)addr;
				b->rp = b->base;
				b->wp = b->base;
				b->lim = ((uchar*)b)+size;
				b->size = pow;
				n++;
			}
			spllo();
			lock(p);
			unlock(p);
			splhi();
		}
		p->had = p->have;
		p->want = 0;		
	Block *b;
	ulong addr;

	size = sizeof(Block) + size + (BY2V-1);
	if(ialloc.bytes > conf.ialloc){
iprint("whoops %d/%d\n", ialloc.bytes, conf.ialloc);
		return 0;
	}
}
	b = mallocz(size, 0);
	if(b == 0){
iprint("malloc %d/%d\n", ialloc.bytes, conf.ialloc);
		return 0;
	}
	memset(b, 0, sizeof(Block));

void
qinit(void)
{
}
	addr = (ulong)b;
	addr = ROUND(addr + sizeof(Block), BY2V);
	b->base = (uchar*)addr;
	b->rp = b->base;
	b->wp = b->base;
	b->lim = ((uchar*)b) + size;
	b->intr = 1;

void
ixsummary(void)
{
	int pow;
	Pool *p;
	lock(&ialloc);
	ialloc.bytes += b->lim - b->base;
	unlock(&ialloc);

	print("size	have/goal\n");
	for(pow = Minpow; pow <= Maxpow; pow++){
		cl = &pool[pow];
		print("%d	%d/%d\n", 1<<pow, p->have, p->goal);
	}
	print("\n");
	return b;
}

/*
 *  interrupt time allocation
 */
Block*
iallocb(int size)
void
freeb(Block *b)
{
	int pow;
	Block *bp;

	for(pow = Minpow; pow < Maxpow; pow++)
		if(size >= (1<<pow))
			break;
	if(b->intr){
		ilock(&ialloc);
		ialloc.bytes -= b->lim - b->base;
		iunlock(&ialloc);
	}

	if(pow == Maxpow)
		return 0;
	/* poison the block in case someone is still holding onto it */
	b->next = (void*)0xdeadbabe;
	b->rp = (void*)0xdeadbabe;
	b->wp = (void*)0xdeadbabe;
	b->lim = (void*)0xdeadbabe;
	b->base = (void*)0xdeadbabe;

	p = &pool[pow];
	lock(p);
	bp = p->list;
	if(p == 0) {
		p->want++;
		unlock(p);
		if(attention == 0) {
			attention++;
			newcallback(iallocmgr);
		}
		return 0;
	}
	p->have--;
	p->list = bp->next;
	unlock(p);
	bp->wp = b->base;
	bp->rp = b->base;
	bp->list = 0;
	bp->next = 0;
	return bp;
	free(b);
}

void
ifreeb(Block *bp)
ixsummary(void)
{
	Pool *p;

	p = &pool[bp->size];
	lock(p);
	bp->next = p->list;
	p->list = bp;
	p->have++;
	unlock(p);
	print("ialloc %d/%d\n", ialloc.bytes, conf.ialloc);
}

/*


@@ 227,13 137,14 @@ allocb(int size)
	Block *b;
	ulong addr;

	size += sizeof(Block) + 7;
	b = malloc(size);
	size = sizeof(Block) + size + (BY2V-1);
	b = mallocz(size, 0);
	if(b == 0)
		exhausted("Blocks");
	memset(b, 0, sizeof(Block));

	addr = (ulong)b;
	addr = (addr + sizeof(Block) + 7) & ~7;
	addr = ROUND(addr + sizeof(Block), BY2V);
	b->base = (uchar*)addr;
	b->rp = b->base;
	b->wp = b->base;


@@ 243,8 154,7 @@ allocb(int size)
}

/*
 *  Interrupt level copy out of a queue, return # bytes copied.  If drop is
 *  set, any bytes left in a block afer a consume are discarded.
 *  Interrupt level copy out of a queue, return # bytes copied.
 */
int
qconsume(Queue *q, void *vp, int len)


@@ 287,10 197,8 @@ checkb(b, "qconsume 1");

checkb(b, "qconsume 2");
	/* discard the block if we're done with it */
	if((q->state & Qmsg) || len == n) {
		poison(b);
		ifree(b);
	}
	if((q->state & Qmsg) || len == n)
		freeb(b);
	return len;
}



@@ 300,9 208,7 @@ qpass(Queue *q, Block *b)
	int s, i, len, dowakeup;

	s = splhi();

	len = BLEN(b);

	/* sync with qread */
	dowakeup = 0;
	lock(q);


@@ 318,23 224,15 @@ qpass(Queue *q, Block *b)
		if(len <= 0 || (q->state & Qmsg)){
			unlock(q);
			wakeup(&q->rr);
			free(b);
			freeb(b);
			splx(s);
			return i;
		}

		/* queue anything that's left */
		dowakeup = 1;
		b->rp += i;
	}

	/* no waiting receivers, room in buffer? */
	if(q->len >= q->limit){
		unlock(q);
		splx(s);
		return -1;
	}

	/* save in buffer */
	if(q->bfirst)
		q->blast->next = b;


@@ 519,7 417,8 @@ qread(Queue *q, void *vp, int len)
			q->syncbuf = vp;
			unlock(q);
			splx(x);
			sleep(&q->rr, filled, q);
			while(q->syncbuf != 0)
				sleep(&q->rr, filled, q);
			len = q->synclen;
			poperror();
			qunlock(&q->rlock);


@@ 528,7 427,8 @@ qread(Queue *q, void *vp, int len)
			q->state |= Qstarve;
			unlock(q);
			splx(x);
			sleep(&q->rr, notempty, q);
			while(q->bfirst == 0)
				sleep(&q->rr, notempty, q);
		}
	}
checkb(b, "qread 1");


@@ 556,8 456,7 @@ checkb(b, "qread 1");
checkb(b, "qread 2");
	/* free it or put what's left on the queue */
	if(b->rp >= b->wp || (q->state&Qmsg)) {
		poison(b);
		free(b);
		freeb(b);
	} else {
		x = splhi();
		lock(q);


@@ 637,7 536,7 @@ qwrite(Queue *q, void *vp, int len, int nowait)
		/* flow control */
		while(!qnotfull(q)){
			if(nowait){
				free(b);
				freeb(b);
				qunlock(&q->wlock);
				poperror();
				return len;


@@ 664,7 563,7 @@ checkb(b, "qwrite");
			q->synclen = n;
			q->syncbuf = 0;
			dowakeup = 1;
			free(b);
			freeb(b);
		} else {
			/* we guessed right, queue it */
			if(q->bfirst)


@@ 720,8 619,7 @@ qclose(Queue *q)
	/* free queued blocks */
	while(bfirst){
		b = bfirst->next;
		poison(bfirst);
		free(bfirst);
		freeb(bfirst);
		bfirst = b;
	}


M port/qlock.c => port/qlock.c +4 -0
@@ 10,6 10,8 @@ qlock(QLock *q)
{
	Proc *p, *mp;

if(up==0) { iprint("QLOCK at ilevel PC=%lux\n", getcallerpc(0)); for(;;); }

	lock(&q->use);
	if(!q->locked) {
		q->locked = 1;


@@ 48,6 50,8 @@ qunlock(QLock *q)
{
	Proc *p;

if(up==0) { iprint("QUNLOCK at ilevel PC=%lux\n", getcallerpc(0)); for(;;); }

	lock(&q->use);
	p = q->head;
	if(p) {

M port/systab.h => port/systab.h +3 -6
@@ 26,7 26,7 @@ Syscall sysrfork;
Syscall syswrite;
Syscall syspipe;
Syscall syscreate;
Syscall syspath;
Syscall sysfd2path;
Syscall sysbrk_;
Syscall sysremove;
Syscall syswstat;


@@ 41,7 41,6 @@ Syscall sysrendezvous;
Syscall sysunmount;
Syscall syswait;
Syscall ;
Syscall /* make sure port/portdat.h has nsyscall defined correctly!!! */;
Syscall	sysdeath;

Syscall *systab[]={


@@ 68,7 67,7 @@ Syscall *systab[]={
	[WRITE]		syswrite,
	[PIPE]		syspipe,
	[CREATE]	syscreate,
	[PATH]		syspath,
	[FD2PATH]	sysfd2path,
	[BRK_]		sysbrk_,
	[REMOVE]	sysremove,
	[WSTAT]		syswstat,


@@ 83,7 82,6 @@ Syscall *systab[]={
	[UNMOUNT]	sysunmount,
	[WAIT]		syswait,

/* make sure port/portdat.h has NSYSCALL defined correctly!!! */
};

char *sysctab[]={


@@ 110,7 108,7 @@ char *sysctab[]={
	[WRITE]		"Write",
	[PIPE]		"Pipe",
	[CREATE]	"Create",
	[PATH]		"Path",
	[FD2PATH]	"Fd2path",
	[BRK_]		"Brk",
	[REMOVE]	"Remove",
	[WSTAT]		"Wstat",


@@ 125,5 123,4 @@ char *sysctab[]={
	[UNMOUNT]	"Unmount",
	[WAIT]		"Wait",

/* make sure port/portdat.h has NSYSCALL defined correctly!!! */
};

M port/taslock.c => port/taslock.c +27 -2
@@ 10,6 10,22 @@ lock(Lock *l)
{
	if(tas(&l->key) == 0)
		return;

	for(;;){
		while(l->key)
			;
		if(tas(&l->key) == 0)
			return;
	}
}

void
ilock(Lock *l)
{
	l->sr = splhi();
	if(tas(&l->key) == 0)
		return;

	for(;;){
		while(l->key)
			;


@@ 23,13 39,22 @@ canlock(Lock *l)
{
	if(tas(&l->key))
		return 0;
	l->pc = getcallerpc(((uchar*)&l) - sizeof(l));

	return 1;
}

void
unlock(Lock *l)
{
	l->pc = 0;
	l->key = 0;
}

void
iunlock(Lock *l)
{
	ulong sr;

	sr = l->sr;
	l->key = 0;
	splx(sr);
}

M power/main.c => power/main.c +0 -1
@@ 190,7 190,6 @@ init0(void)
	up->slash = namec("#/", Atodir, 0, 0);
	up->dot = clone(up->slash, 0);

	iallocinit();
	chandevinit();

	if(!waserror()){