~kris/9p

9hist

b289cd8b27e92b1ed3a777a6afb140228d1f662c — David du Colombier 34 years ago 0f159a0
Plan 9 from Bell Labs 1992-06-20
M port/alloc.c => port/alloc.c +33 -22
@@ 13,7 13,7 @@ enum
	Maxpow		= 16,
	Nhole		= 128,
	Magichole	= 0xDeadBabe,
	Magic2n		= 0xBadC0c0a,
	Magic2n		= 0xFeedBeef,
};

typedef struct Hole Hole;


@@ 56,7 56,8 @@ struct Bucket
struct Arena
{
	Lock;
	Bucket	*btab[Maxpow];	
	Bucket	*btab[Maxpow];
	int	nbuck[Maxpow];
};

static Arena	arena;


@@ 226,32 227,13 @@ xhole(ulong addr, ulong size)
	unlock(&xlists);
}

void
xsummary(void)
{
	int i;
	Hole *h;

	i = 0;
	for(h = xlists.flist; h; h = h->link)
		i++;

	print("%d holes free\n", i);
	i = 0;
	for(h = xlists.table; h; h = h->link) {
		print("%.8lux %.8lux %d\n", h->addr, h->top, h->size);
		i += h->size;
	}
	print("%d bytes free\n", i);
}

void*
malloc(ulong size)
{
	int pow;
	Bucket *bp;

	for(pow = 1; pow < Maxpow; pow++)
	for(pow = 3; pow < Maxpow; pow++)
		if(size <= (1<<pow))
			goto good;



@@ 272,6 254,7 @@ good:
		memset(bp->data, 0,  size);
		return  bp->data;
	}
	arena.nbuck[pow]++;
	unlock(&arena);
	size = sizeof(Bucket)+(1<<pow);
	bp = xalloc(size);


@@ 310,3 293,31 @@ free(void *ptr)
	*l = bp;
	unlock(&arena);
}

void
xsummary(void)
{
	Hole *h;
	Bucket *k;
	int i, nfree;

	i = 0;
	for(h = xlists.flist; h; h = h->link)
		i++;

	print("%d holes free\n", i);
	i = 0;
	for(h = xlists.table; h; h = h->link) {
		print("%.8lux %.8lux %d\n", h->addr, h->top, h->size);
		i += h->size;
	}
	print("%d bytes free\n", i);
	for(i = 3; i < Maxpow; i++) {
		if(arena.btab[i] == 0 && arena.nbuck[i] == 0)
			continue;
		nfree = 0;
		for(k = arena.btab[i]; k; k = k->next)
			nfree++;
		print("%8d %4d %4d\n", 1<<i, arena.nbuck[i], nfree);
	}
}

M port/chan.c => port/chan.c +31 -39
@@ 5,9 5,11 @@
#include	"fns.h"
#include	"../port/error.h"

struct{
struct
{
	Lock;
	Chan	*free;
	int	fid;
}chanalloc;

int


@@ 38,22 40,6 @@ decref(Ref *r)
}

void
chaninit(void)
{
	int i;
	Chan *c;

	chanalloc.free = ialloc(conf.nchan*sizeof(Chan), 0);

	c = chanalloc.free;
	for(i=0; i<conf.nchan-1; i++,c++){
		c->fid = i;
		c->next = c+1;
	}
	c->next = 0;
}

void
chandevreset(void)
{
	int i;


@@ 75,30 61,36 @@ Chan*
newchan(void)
{
	Chan *c;
	int nfid;

	for(;;) {
		lock(&chanalloc);
		if(c = chanalloc.free) {
			chanalloc.free = c->next;
			/* if you get an error before associating with a dev,
			   close calls rootclose, a nop */
			c->type = 0;
			c->flag = 0;
			c->ref = 1;
			unlock(&chanalloc);
			c->dev = 0;
			c->offset = 0;
			c->mnt = 0;
			c->stream = 0;
			c->aux = 0;
			c->mchan = 0;
			c->mqid = (Qid){0, 0};
			return c;
		}
		unlock(&chanalloc);
		resrcwait("no chans\n");
	SET(nfid);

	lock(&chanalloc);
	c = chanalloc.free;
	if(c)
		chanalloc.free = c->next;
	else
		nfid = ++chanalloc.fid;
	unlock(&chanalloc);

	if(c == 0) {
		c = smalloc(sizeof(Chan));
		c->fid = nfid;
	}
	return 0;	/* not reached */

	/* if you get an error before associating with a dev,
	   close calls rootclose, a nop */
	c->type = 0;
	c->flag = 0;
	c->ref = 1;
	c->dev = 0;
	c->offset = 0;
	c->mnt = 0;
	c->stream = 0;
	c->aux = 0;
	c->mchan = 0;
	c->mqid = (Qid){0, 0};
	return c;
}

void

M port/devarp.c => port/devarp.c +2 -2
@@ 94,8 94,8 @@ arpreset(void)
{
	Arpcache *ap, *ep;

	arp = (Arpcache *)ialloc(sizeof(Arpcache) * conf.arp, 0);
	arphash = (Arpcache **)ialloc(sizeof(Arpcache *) * Arphashsize, 0);
	arp = xalloc(sizeof(Arpcache) * conf.arp);
	arphash = (Arpcache **)xalloc(sizeof(Arpcache *) * Arphashsize);

	ep = &arp[conf.arp];
	for(ap = arp; ap < ep; ap++) {

M port/devconc.c => port/devconc.c +1 -1
@@ 285,7 285,7 @@ concdevstclose(Queue *q)
	q->ptr = 0;
	q->other->ptr = 0;
	dp->rq = 0;
	streamexit(cp->s, 0);
	streamexit(cp->s);
	qunlock(cp);
}


M port/devcons.c => port/devcons.c +0 -6
@@ 234,15 234,9 @@ echo(Rune r, char *buf, int n)
		case 'd':
			consdebug();
			return;
		case 'm':
			mntdump();
			return;
		case 'p':
			procdump();
			return;
		case 'q':
			dumpqueues();
			return;
		case 'r':
			exit();
			break;

M port/devkprof.c => port/devkprof.c +1 -1
@@ 42,7 42,7 @@ kprofreset(void)
	kprof.maxpc = (ulong)etext;
	kprof.nbuf = (kprof.maxpc-kprof.minpc) >> LRES;
	n = kprof.nbuf*SZ;
	kprof.buf = ialloc(n, 0);
	kprof.buf = xalloc(n);
	kproftab[0].length = n;
	if(SZ != sizeof kprof.buf[0])
		panic("kprof size");

M port/devmnt.c => port/devmnt.c +64 -92
@@ 7,8 7,6 @@
#include	"devtab.h"

typedef struct Mntrpc Mntrpc;
typedef struct Mnt Mnt;

struct Mntrpc
{
	Mntrpc	*list;		/* Free/pending list */


@@ 40,11 38,11 @@ struct Mnt
struct Mntalloc
{
	Lock;
	Mnt	*mntfree;
	Mnt	*mntarena;
	Mnt	*list;		/* Mount devices in used */
	Mnt	*mntfree;	/* Free list */
	Mntrpc	*rpcfree;
	Mntrpc	*rpcarena;
	int	id;
	int	rpctag;
}mntalloc;

#define MAXRPC		(MAXFDATA+MAXMSG)


@@ 71,6 69,7 @@ void	mntpntfree(Mnt*);
enum
{
	Tagspace = 1,
	Tagfls = 0x8000,
	Tagend = 0xfffe,

	ALIGN = 256,		/* Vme block mode alignment */


@@ 79,39 78,8 @@ enum
void
mntreset(void)
{
	Mnt *me, *md;
	Mntrpc *re, *rd;
	ushort tag;
	ulong p;
	int i;

	mntalloc.mntarena = ialloc(conf.nmntdev*sizeof(Mnt), 0);
	mntalloc.mntfree = mntalloc.mntarena;
	me = &mntalloc.mntfree[conf.nmntdev];

	mntalloc.rpcfree = ialloc(conf.nmntbuf*sizeof(Mntrpc), 0);
	mntalloc.rpcarena = mntalloc.rpcfree;
	re = &mntalloc.rpcfree[conf.nmntbuf];

	/*
	 *  Align mount buffers to 256 byte boundaries
	 *  so we can use burst mode vme transfers
	 */
	tag = Tagspace;
	for(rd = mntalloc.rpcfree; rd < re; rd++) {
		rd->list = rd+1;
		rd->request.tag = tag++;
		rd->rpc = iallocspan(MAXRPC, ALIGN, 0);
	}
	re[-1].list = 0;
	for(md = mntalloc.mntfree; md < me; md++){
		md->list = md+1;
		md->flushbase = tag;
		md->flushtag = tag;
	}
	me[-1].list = 0;

	mntalloc.id = 1;
	mntalloc.rpctag = Tagspace;
}

void


@@ 122,7 90,7 @@ mntinit(void)
Chan*
mntattach(char *muxattach)
{
	Mnt *m, *e;
	Mnt *m;
	Chan *c;
	struct bogus{
		Chan	*chan;


@@ 131,11 99,14 @@ mntattach(char *muxattach)
	}bogus;

	bogus = *((struct bogus *)muxattach);
	e = &mntalloc.mntarena[conf.nmntdev];
	for(m = mntalloc.mntarena; m < e; m++) {
		if(m->c == bogus.chan && m->id) {
	c = bogus.chan;

	lock(&mntalloc);
	for(m = mntalloc.list; m; m = m->list) {
		if(m->c == c && m->id) {
			lock(m);
			if(m->id && m->ref > 0 && m->c == bogus.chan) {
			if(m->id && m->ref > 0 && m->c == c) {
				unlock(&mntalloc);
				m->ref++;
				unlock(m);
				return mattach(m, bogus.spec, bogus.serv);


@@ 143,29 114,36 @@ mntattach(char *muxattach)
			unlock(m);	
		}
	}
	lock(&mntalloc);
	if(mntalloc.mntfree == 0) {
		unlock(&mntalloc);
		exhausted("mount devices");
	}
	m = mntalloc.mntfree;
	mntalloc.mntfree = m->list;	
	if(m != 0)
		mntalloc.mntfree = m->list;	
	else {
		m = malloc(sizeof(Mnt));
		if(m == 0) {
			unlock(&mntalloc);
			exhausted("mount devices");
		}
		m->flushbase = Tagfls;
		m->flushtag = Tagfls;
	}
	m->list = mntalloc.list;
	mntalloc.list = m;
	m->id = mntalloc.id++;
	lock(m);
	unlock(&mntalloc);

	m->ref = 1;
	m->queue = 0;
	m->rip = 0;
	m->c = bogus.chan;
	m->c = c;
	m->c->flag |= CMSG;
	m->blocksize = MAXFDATA;


	switch(devchar[m->c->type]) {
	default:
		m->mux = 0;
		break;
	case 'H':			/* Cyclone */
	case 'C':			/* Cyclone */
		m->mux = 1;
		break;
	}


@@ 195,7 173,7 @@ mattach(Mnt *m, char *spec, char *serv)
	lock(&mntalloc);
	c->dev = mntalloc.id++;
	unlock(&mntalloc);
	c->mntindex = m-mntalloc.mntarena;
	c->mntptr = m;

	if(waserror()){
		mntfree(r);


@@ 442,7 420,18 @@ mntdoclunk(Mnt *m, Mntrpc *r)
void
mntpntfree(Mnt *m)
{
	Mnt *f, **l;

	lock(&mntalloc);
	l = &mntalloc.list;
	for(f = *l; f; f = f->list) {
		if(f == m) {
			*l = m->list;
			break;
		}
		l = &f->list;
	}

	m->list = mntalloc.mntfree;
	mntalloc.mntfree = m;
	unlock(&mntalloc);


@@ 538,17 527,21 @@ mntrdwr(int type, Chan *c, void *buf, long n, ulong offset)
void
mountrpc(Mnt *m, Mntrpc *r)
{
	r->reply.tag = 0;		/* safety checks */
	r->reply.tag = 0;		/* poison the old values */
	r->reply.type = 4;

	mountio(m, r);
	if(r->reply.type == Rerror)
		error(r->reply.ename);

	if(r->reply.type == Rflush)
		error(Eintr);

	if(r->reply.type != r->request.type+1) {
		print("devmnt: mismatched reply 0x%lux T%d R%d tags req %d fls %d rep %d\n",
		r, r->request.type, r->reply.type, r->request.tag, r->flushtag, r->reply.tag);
		print("mnt: mismatched reply 0x%lux T%d R%d tags req %d fls %d rep %d\n",
				r, r->request.type, r->reply.type, r->request.tag, 
				r->flushtag, r->reply.tag);

		error(Emountrpc);
	}
}


@@ 744,19 737,23 @@ mntralloc(void)
{
	Mntrpc *new;

	for(;;) {
		lock(&mntalloc);
		if(new = mntalloc.rpcfree) {
			mntalloc.rpcfree = new->list;
	lock(&mntalloc);
	new = mntalloc.rpcfree;
	if(new != 0)
		mntalloc.rpcfree = new->list;
	else {
		new = xalloc(sizeof(Mntrpc)+MAXRPC);
		if(new == 0) {
			unlock(&mntalloc);
			new->done = 0;
			new->flushed = 0;
			return new;
			exhausted("mount rpc buffer");
		}
		unlock(&mntalloc);
		resrcwait("no mount buffers");
		new->rpc = (char*)new+sizeof(Mntrpc);
		new->request.tag = mntalloc.rpctag++;
	}
	return 0;		/* not reached */
	unlock(&mntalloc);
	new->done = 0;
	new->flushed = 0;
	return new;
}

void


@@ 793,9 790,9 @@ mntchk(Chan *c)
{
	Mnt *m;

	m = &mntalloc.mntarena[c->mntindex];
	m = c->mntptr;
	/* Was it closed and reused ? */
	if(m->id == 0 || m->id >= c->dev)
	if(m->id == 0 || m->id >= c->dev)	/* Sanity check */
		error(Eshutdown);
	return m;
}


@@ 814,28 811,3 @@ rpcattn(Mntrpc *r)
{
	return r->done || r->m->rip == 0;
}

void
mntdump(void)
{
	Mnt *me, *m;
	Mntrpc *re, *r;

	me = &mntalloc.mntarena[conf.nmntdev];
	for(m = mntalloc.mntarena; m < me; m++) {
		if(m->ref == 0)
			continue;
		print("mount %d: mux %d queue %lux rip 0x%lux %d %s\n", 
			m->id, m->mux, m->queue, m->rip,
			m->rip ? m->rip->pid : 0, m->rip ? m->rip->text : "no");
	}
	print("rpcfree 0x%lux\n", mntalloc.rpcfree);
	re = &mntalloc.rpcarena[conf.nmntbuf];
	for(r = mntalloc.rpcarena; r < re; r++) 
		print("%.8lux %.8lux T%d R%d tags req %d fls %d rep %d d %d f %d\n",
			r, r->list, r->request.type, r->reply.type,
			r->request.tag, r->flushtag, r->reply.tag, 
			r->done, r->flushed);

}


M port/devscc.c => port/devscc.c +4 -3
@@ 298,6 298,7 @@ sccsetup0(SCC *sp)
	sp->sticky[5] = TxEna | Tx8bits;
	sccwrreg(sp, 5, 0);
}

void
sccsetup(void *addr, ulong freq)
{


@@ 309,13 310,13 @@ sccsetup(void *addr, ulong freq)
	/*
	 *  allocate a structure, set port addresses, and setup the line
	 */
	sp = ialloc(sizeof(SCC), 0);
	sp = xalloc(sizeof(SCC));
	scc[nscc] = sp;
	sp->ptr = &dev->ptra;
	sp->data = &dev->dataa;
	sp->freq = freq;
	sccsetup0(sp);
	sp = ialloc(sizeof(SCC), 0);
	sp = xalloc(sizeof(SCC));
	scc[nscc+1] = sp;
	sp->ptr = &dev->ptrb;
	sp->data = &dev->datab;


@@ 647,7 648,7 @@ sccreset(void)
	int i;
	Dirtab *dp;

	sccdir = ialloc(2 * nscc * sizeof(Dirtab), 0);
	sccdir = xalloc(2 * nscc * sizeof(Dirtab));
	dp = sccdir;
	for(i = 0; i < nscc; i++){
		/* 2 directory entries per port */

M port/devsrv.c => port/devsrv.c +3 -2
@@ 7,7 7,7 @@

#include	"devtab.h"

typedef struct	Srv Srv;
typedef struct Srv Srv;
struct Srv{
	char	name[NAMELEN];
	char	owner[NAMELEN];


@@ 196,8 196,8 @@ srvwrite(Chan *c, void *va, long n, ulong offset)
	memmove(buf, va, n);	/* so we can NUL-terminate */
	buf[n] = 0;
	fd = strtoul(buf, 0, 0);
	f = u->p->fgrp;

	f = u->p->fgrp;
	lock(f);
	if(waserror()){
		unlock(f);


@@ 218,6 218,7 @@ srvwrite(Chan *c, void *va, long n, ulong offset)
	i = c->qid.path;
	if(srv[i].chan != c)	/* already been written to */
		error(Egreg);

	srv[i].chan = c1;
	unlock(&srvlk);
	poperror();

M port/page.c => port/page.c +2 -34
@@ 8,13 8,6 @@
#define PGHFUN(x, y)	(((ulong)x^(ulong)y)%PGHSIZE)
#define	pghash(s)	palloc.hash[PGHFUN(s->image, p->daddr)]

struct Ptealloc
{
	Lock;
	Pte	*free;
	int	pages;
}ptealloclk;

static	Lock pglock;
struct	Palloc palloc;



@@ 361,31 354,10 @@ Pte*
ptealloc(void)
{
	Pte *new;
	int i, n;
	KMap *k;

	lock(&ptealloclk);
	while(ptealloclk.free == 0) {
		unlock(&ptealloclk);

		k = kmap(newpage(1, 0, 0));
		new = (Pte*)VA(k);
		n = (BY2PG/sizeof(Pte))-1;
		for(i = 0; i < n; i++)
			new[i].next = &new[i+1];

		lock(&ptealloclk);
		ptealloclk.pages++;
		new[i].next = ptealloclk.free;
		ptealloclk.free = new;
	}

	new = ptealloclk.free;
	ptealloclk.free = new->next;
	unlock(&ptealloclk);
	new = smalloc(sizeof(Pte));
	new->first = &new->pages[PTEPERTAB];
	new->last = new->pages;

	return new;
}



@@ 410,11 382,7 @@ freepte(Segment *s, Pte *p)
				*pg = 0;
			}
	}

	lock(&ptealloclk);
	p->next = ptealloclk.free;
	ptealloclk.free = p;
	unlock(&ptealloclk);
	free(p);
}

/* Multiplex a hardware lock for per page manipulations */

M port/portdat.h => port/portdat.h +3 -1
@@ 15,6 15,7 @@ typedef struct IOQ	IOQ;
typedef struct KIOQ	KIOQ;
typedef struct List	List;
typedef struct Mount	Mount;
typedef struct Mnt	Mnt;
typedef struct Mhead	Mhead;
typedef struct Netinf	Netinf;
typedef struct Netprot	Netprot;


@@ 158,7 159,7 @@ struct Chan
	union {
		void	*aux;
		Qid	pgrpid;		/* for #p/notepg */
		int	mntindex;	/* for devmnt */
		Mnt	*mntptr;	/* for devmnt */
	};
	Chan	*mchan;			/* channel to mounted server */
	Qid	mqid;			/* qid of root of mount point */


@@ 608,6 609,7 @@ struct Queue
struct Stream
{
	QLock;				/* structure lock */
	Stream	*next;
	short	inuse;			/* number of processes in stream */
	short	opens;			/* number of processes with stream open */
	ushort	hread;			/* number of reads after hangup */

M port/portfns.h => port/portfns.h +0 -3
@@ 15,7 15,6 @@ int	canqlock(QLock*);
void	chandevinit(void);
void	chandevreset(void);
void	chanfree(Chan*);
void	chaninit(void);
void	checkalarms(void);
void	clock(Ureg*);
Chan*	clone(Chan*, Chan*);


@@ 75,7 74,6 @@ int	freebroken(void);
void	freechan(Chan*);
void	freepte(Segment*, Pte*);
void	freesegs(int);
void	freewaitq(Waitq*);
Block*	getb(Blist*);
int	getc(IOQ*);
void	getcolor(ulong, ulong*, ulong*, ulong*);


@@ 139,7 137,6 @@ Pgrp*	newpgrp(void);
Proc*	newproc(void);
void	newqinfo(Qinfo*);
Segment*	newseg(int, ulong, ulong);
Waitq*	newwaitq(void);
char*	nextelem(char*, char*);
void	nexterror(void);
int	nodelims(Stream*);

M port/proc.c => port/proc.c +11 -47
@@ 65,6 65,7 @@ schedinit(void)		/* never returns */
		else
		if(p->state == Moribund) {
			p->pid = 0;
			p->state = Dead;
			/* 
			 * Holding locks from pexit:
			 * 	procalloc, debug, palloc


@@ 79,8 80,6 @@ schedinit(void)		/* never returns */
			unlock(&palloc);
			qunlock(&p->debug);
			unlock(&procalloc);

			p->state = Dead;
		}
		p->mach = 0;
	}


@@ 399,7 398,6 @@ postnote(Proc *p, int dolock, char *n, int flag)
		up = u;
	USED(k);


	if(flag!=NUser && (up->notify==0 || up->notified))
		up->nnote = 0;	/* force user's hand */



@@ 527,7 525,7 @@ pexit(char *exitstr, int freemem)
		if((p = c->parent) == 0)
			panic("boot process died");
			
		wq = newwaitq();
		wq = smalloc(sizeof(Waitq));
		readnum(0, wq->w.pid, NUMSIZE, c->pid, NUMSIZE);
		utime = c->time[TUser] + c->time[TCUser];
		stime = c->time[TSys] + c->time[TCSys];


@@ 545,7 543,8 @@ pexit(char *exitstr, int freemem)

		lock(&p->exl);
		/* My parent still alive, processes are limited to 128 Zombies to
		 * prevent badly written daemon consuming all the wait records */
		 * prevent a badly written daemon lots of wait records
		 */
		if(p->pid == c->parentpid && p->state != Broken && p->nwait < 128) {	
			p->nchild--;
			p->time[TCUser] += utime;


@@ 560,7 559,7 @@ pexit(char *exitstr, int freemem)
		}
		else {
			unlock(&p->exl);
			freewaitq(wq);
			free(wq);
		}
	}



@@ 580,7 579,7 @@ pexit(char *exitstr, int freemem)

	for(f = c->waitq; f; f = next) {
		next = f->next;
		freewaitq(f);
		free(f);
	}

	/*


@@ 637,15 636,13 @@ pwait(Waitmsg *w)
	if(w)
		memmove(w, &wq->w, sizeof(Waitmsg));
	cpid = atoi(wq->w.pid);
	freewaitq(wq);
	free(wq);
	return cpid;
}

Proc*
proctab(int i)
{
if((i < 0) || (i >= conf.nproc))
    panic("proctab(%d)\n", i);
	return &procalloc.arena[i];
}



@@ 660,7 657,8 @@ procdump(void)
		if(p->state != Dead){
			print("%d:%s %s upc %lux %s ut %ld st %ld r %lux qpc %lux\n",
				p->pid, p->text, p->user, p->pc, 
				statename[p->state], p->time[0], p->time[1], p->r, p->qlockpc);
				statename[p->state], p->time[0],
				p->time[1], p->r, p->qlockpc);
		}
	}
}


@@ 754,10 752,12 @@ procctl(Proc *p)
	case Proc_exitme:
		spllo();	/* pexit has locks in it */
		pexit("Killed", 1);

	case Proc_traceme:
		if(u->nnote == 0)
			return;
		/* No break */

	case Proc_stopme:
		p->procctl = 0;
		state = p->psstate;


@@ 800,39 800,3 @@ exhausted(char *resource)
	sprint(buf, "no free %s", resource);
	error(buf);
}

Waitq *
newwaitq(void)
{
	Waitq *wq, *e, *f;

	for(;;) {
		lock(&waitqalloc);
		if(wq = waitqalloc.free) {
			waitqalloc.free = wq->next;
			unlock(&waitqalloc);
			return wq;
		}
		unlock(&waitqalloc);

		wq = (Waitq*)VA(kmap(newpage(0, 0, 0)));
		e = &wq[(BY2PG/sizeof(Waitq))-1];
		for(f = wq; f < e; f++)
			f->next = f+1;

		lock(&waitqalloc);
		e->next = waitqalloc.free;
		waitqalloc.free = wq;
		unlock(&waitqalloc);
	}
	return 0;		/* not reached */
}

void
freewaitq(Waitq *wq)
{
	lock(&waitqalloc);
	wq->next = waitqalloc.free;
	waitqalloc.free = wq;
	unlock(&waitqalloc);
}

M ss/dat.h => ss/dat.h +0 -13
@@ 59,30 59,19 @@ struct Conf
{
	int	nmach;		/* processors */
	int	nproc;		/* processes */
	int	npgrp;		/* process groups */
	ulong	npage0;		/* total physical pages of memory, bank 0 */
	ulong	npage1;		/* total physical pages of memory, bank 1 */
	ulong	base0;		/* base of bank 0 */
	ulong	base1;		/* base of bank 1 */
	ulong	npage;		/* total physical pages of memory */
	ulong	nseg;		/* number of segments */
	ulong	nimage;		/* number of page cache image headers */
	ulong 	npagetab;	/* number of pte tables */
	ulong	nswap;		/* number of swap blocks */
	ulong	upages;		/* number of user pages */
	int	nalarm;		/* alarms */
	int	nchan;		/* channels */
	int	nenv;		/* distinct environment values */
	int	nenvchar;	/* environment text storage */
	int	npgenv;		/* environment files per process group */
	int	nmtab;		/* mounted-upon channels per process group */
	int	nmount;		/* mounts */
	int	nmntdev;	/* mounted devices (devmnt.c) */
	int	nmntbuf;	/* buffers for devmnt.c messages */
	int	nmnthdr;	/* headers for devmnt.c messages */
	int	nstream;	/* streams */
	int	nqueue;		/* stream queues */
	int	nblock;		/* stream blocks */
	int	nsrv;		/* public servers (devsrv.c) */
	int	nbitmap;	/* bitmap structs (devbit.c) */
	int	nbitbyte;	/* bytes of bitmap data (devbit.c) */


@@ 91,8 80,6 @@ struct Conf
	int	nurp;		/* max urp conversations */
	int	nasync;		/* number of async protocol modules */
	int	npipe;		/* number of pipes */
	int	nservice;	/* number of services */
	int	nfsyschan;	/* number of filsys open channels */
	int	copymode;	/* 0 is copy on write, 1 is copy on reference */
	ulong	ipif;		/* Ip protocol interfaces */
	ulong	ip;		/* Ip conversations per interface */

M ss/main.c => ss/main.c +2 -17
@@ 35,7 35,6 @@ main(void)
	intrinit();
	procinit0();
	initseg();
	chaninit();
	chandevreset();
	streaminit();
	userinit();


@@ 206,28 205,16 @@ confinit(void)

	conf.upages = 1400;

	mul = 1;
	if(conf.npage1 > 0)
		mul = 2;
	mul = conf.upages/700;

	conf.nproc = 50*mul;
	conf.npgrp = 12*mul;
	conf.nseg = conf.nproc*4;
	conf.npagetab = conf.nseg*2;
	conf.nswap = 4096;
	conf.nimage = 50;
	conf.nalarm = 1000;
	conf.nchan = 200*mul;
	conf.nenv = 100*mul;
	conf.nenvchar = 8000*mul;
	conf.npgenv = 200*mul;
	conf.nmtab = 50*mul;
	conf.nmount = 80*mul;
	conf.nmntdev = 10*mul;
	conf.nmntbuf = conf.nmntdev+3;
	conf.nmnthdr = 2*conf.nmntdev;
	conf.nstream = 40 + 32*mul;
	conf.nqueue = 5 * conf.nstream;
	conf.nblock = 24 * conf.nstream;
	conf.nsrv = 16*mul;			/* was 32 */
	conf.nbitmap = 300*mul;
	conf.nbitbyte = 300*1024*mul;


@@ 236,8 223,6 @@ confinit(void)
	conf.nurp = 32;
	conf.nasync = 1;
	conf.npipe = conf.nstream/2;
	conf.nservice = 3*mul;			/* was conf.nproc/5 */
	conf.nfsyschan = 31 + conf.nchan/20;
	conf.copymode = 0;		/* copy on write */
	conf.ipif = 8;
	conf.ip = 64;

M ss/trap.c => ss/trap.c +5 -4
@@ 376,16 376,16 @@ syscall(Ureg *aur)
	ret = -1;
	if(!waserror()){
		if(r7 >= sizeof systab/BY2WD){
			pprint("bad sys call number %d pc %lux\n", r7, ((Ureg*)UREGADDR)->pc);
			pprint("bad sys call number %d pc %lux\n", r7, ur->pc);
			msg = "sys: bad sys call";
	    Bad:
			postnote(u->p, 1, msg, NDebug);
			error(Ebadarg);
		}
		if(sp & (BY2WD-1)){
			pprint("odd sp in sys call pc %lux sp %lux\n", ((Ureg*)UREGADDR)->pc, ((Ureg*)UREGADDR)->sp);
			pprint("odd sp in sys call pc %lux sp %lux\n", ur->pc, ur->sp);
			msg = "sys: odd stack";
			goto Bad;
			postnote(u->p, 1, msg, NDebug);
			error(Ebadarg);
		}
		if(sp<(USTKTOP-BY2PG) || sp>(USTKTOP-(1+MAXSYSARG)*BY2WD))
			validaddr(sp, ((1+MAXSYSARG)*BY2WD), 0);


@@ 393,6 393,7 @@ syscall(Ureg *aur)
		ret = (*systab[r7])((ulong*)(sp+1*BY2WD));
		poperror();
	}

	ur->pc += 4;
	ur->npc = ur->pc+4;
	u->nerrlab = 0;