~kris/9p

9hist

36c043ee48e7c920c3aa367b10c4a55495bc7907 — David du Colombier 35 years ago d44ee85
Plan 9 from Bell Labs 1990-09-28
M gnot/dat.h => gnot/dat.h +0 -15
@@ 339,20 339,6 @@ struct Proc
	ulong	pc;			/* DEBUG only */
};

struct MMU
{
	ulong	va;
	ulong	pa;
	int	pid;
};

#define NMMU 16
struct MMUCache
{
	ulong	next;
	MMU	mmu[NMMU];
};

#define	NERR	15
#define	NNOTE	5
#define	NFD	100


@@ 376,7 362,6 @@ struct User
	short	nnote;
	short	notified;		/* sysnoted is due */
	int	(*notify)(void*, char*);
	MMUCache mc;
	void	*ureg;
};


M gnot/main.c => gnot/main.c +0 -1
@@ 155,7 155,6 @@ userinit(void)
	k = kmap(p->upage);
	up = (User*)VA(k);
	up->p = p;
	up->mc.next = 0;
	kunmap(k);

	/*

A gnot/malloc.h => gnot/malloc.h +15 -0
@@ 0,0 1,15 @@
struct tbl_entry {
	struct tbl_entry *next;		/* free list */
	int *data;			/* data */
};

struct table {
	int size;			/* # entries */
	struct tbl_entry *entries;	/* the entries */
	struct tbl_entry *free;		/* the free list */
};

void *tbl_alloc(struct table *, int);
void tbl_free(struct table *, void *);
int tbl_index(struct table *, void *);
void *tbl_data(struct table *, int);

M gnot/mmu.c => gnot/mmu.c +0 -39
@@ 12,17 12,6 @@ struct
	KMap	arena[4*1024*1024/BY2PG];	/* kernel mmu maps up to 4MB */
}kmapalloc;

void
putxmmu(ulong tlbvirt, ulong tlbphys, int pid)
{
	if(pid != u->p->pid)
		panic("putxmmu %ld %ld\n", pid, u->p->pid);
	if(tlbvirt&KZERO)
		panic("putmmu");
	tlbphys |= VTAG(tlbvirt)<<24;
	UMAP[(tlbvirt&0x003FE000L)>>2] = tlbphys;
}

/*
 * Called splhi, not in Running state
 */


@@ 39,18 28,6 @@ mapstack(Proc *p)
	putkmmu(tlbvirt, tlbphys);
	flushmmu();
	u = (User*)USERADDR;

	/*
 	 *  preload the MMU with the last (up to) NMMU user entries
	 *  previously faulted into it for this process.
	 */
	if(u->mc.next >= NMMU){
		u->mc.next &= NMMU - 1;
		for(i = u->mc.next; i < NMMU; i++)
			putxmmu(u->mc.mmu[i].va, u->mc.mmu[i].pa, u->mc.mmu[i].pid);
	}
	for(i = 0; i < u->mc.next; i++)
		putxmmu(u->mc.mmu[i].va, u->mc.mmu[i].pa, u->mc.mmu[i].pid);
}

void


@@ 67,14 44,6 @@ putmmu(ulong tlbvirt, ulong tlbphys)
{
	if(tlbvirt&KZERO)
		panic("putmmu");
	if(u){
		MMU *mp;
		mp = &(u->mc.mmu[u->mc.next&(NMMU-1)]);
		mp->pa = tlbphys;
		mp->va = tlbvirt;
		mp->pid = u->p->pid;
		u->mc.next++;
	}
	tlbphys |= VTAG(tlbvirt)<<24;
	UMAP[(tlbvirt&0x003FE000L)>>2] = tlbphys;
}


@@ 88,14 57,6 @@ flushmmu(void)
}

void
clearmmucache(void)
{
	if(u == 0)
		panic("flushmmucache");
	u->mc.next = 0;
}

void
kmapinit(void)
{
	KMap *k;

M gnot/proc.c => gnot/proc.c +0 -1
@@ 621,7 621,6 @@ kproc(char *name, void (*func)(void *), void *arg)
	/*
	 * Save time: only copy u-> data and useful stack
	 */
	clearmmucache();
	memcpy(up, u, sizeof(User));
	n = USERADDR+BY2PG - (ulong)&lastvar;
	n = (n+32) & ~(BY2WD-1);	/* be safe & word align */

M gnot/stream.c => gnot/stream.c +35 -28
@@ 878,6 878,28 @@ stringread(Chan *c, uchar *buf, long n, char *str)
}

/*
 *  return the stream id
 */
long
streamctlread(Chan *c, void *vbuf, long n)
{
	uchar *buf = vbuf;
	char num[32];
	Stream *s;

	s = c->stream;
	if(STREAMTYPE(c->qid) == Sctlqid){
		sprint(num, "%d", s->id);
		return stringread(c, buf, n, num);
	} else {
		if(CHDIR & c->qid)
			return devdirread(c, vbuf, n, 0, 0, streamgen);
		else
			panic("streamctlread");
	}
}

/*
 *  return true if there is an output buffer available
 */
static int


@@ 895,28 917,16 @@ streamread(Chan *c, void *vbuf, long n)
	Block *bp;
	Stream *s;
	Queue *q;
	long rv = 0;
	int left, i, x;
	int left, i;
	uchar *buf = vbuf;
	char num[32];

	s = c->stream;
	switch(STREAMTYPE(c->qid)){
	case Sdataqid:
		break;
	case Sctlqid:
		sprint(num, "%d", s->id);
		return stringread(c, buf, n, num);
	default:
		if(CHDIR & c->qid)
			return devdirread(c, vbuf, n, 0, 0, streamgen);
		else
			panic("streamread");
	}
	if(STREAMTYPE(c->qid) != Sdataqid)
		return streamctlread(c, vbuf, n);

	/*
	 *  one reader at a time
	 */
	s = c->stream;
	qlock(&s->rdlock);
	if(waserror()){
		qunlock(&s->rdlock);


@@ 974,10 984,15 @@ streamread(Chan *c, void *vbuf, long n)
 *  This routing is entrered with s->wrlock'ed and must unlock.
 */
static long
streamctlwrite(Stream *s, void *a, long n)
streamctlwrite(Chan *c, void *a, long n)
{
	Qinfo *qi;
	Block *bp;
	Stream *s;

	if(STREAMTYPE(c->qid) != Sctlqid)
		panic("streamctlwrite %lux", c->qid);
	s = c->stream;

	/*
	 *  package


@@ 1040,15 1055,8 @@ streamwrite(Chan *c, void *a, long n, int docopy)
	/*
	 *  decode the qid
	 */
	switch(STREAMTYPE(c->qid)){
	case Sdataqid:
		break;
	case Sctlqid:
		n = streamctlwrite(s, a, n);
		goto out;
	default:
		panic("bad stream qid\n");
	}
	if(STREAMTYPE(c->qid) != Sdataqid)
		return streamctlwrite(c, a, n);

	/*
	 *  No writes allowed on hungup channels


@@ 1057,7 1065,7 @@ streamwrite(Chan *c, void *a, long n, int docopy)
	if(q->other->flag & QHUNGUP)
		error(0, Ehungup);

	if((GLOBAL(a) && !docopy) || n==0){
	if(!docopy && GLOBAL(a)){
		/*
		 *  `a' is global to the whole system, just create a
		 *  pointer to it and pass it on.


@@ 1094,7 1102,6 @@ streamwrite(Chan *c, void *a, long n, int docopy)
			}
		}
	}
out:
	return n;
}


M gnot/sturp.c => gnot/sturp.c +63 -35
@@ 33,6 33,7 @@ struct urpstat {
} urpstat;

struct Urp {
	QLock;
	short	state;		/* flags */
	Rendez	r;		/* process waiting for close */



@@ 51,11 52,11 @@ struct Urp {
	int	maxout;		/* maximum outstanding unacked blocks */
	int	maxblock;	/* max block size */
	int	next;		/* next block to send */
	int	tofree;		/* first block to be freed (unacked is first not to) */
	int	unechoed;	/* first unechoed block */
	int	unacked;	/* first unacked block */
	int	nxb;		/* next xb to use */
	Block	*xb[8];		/* the xmit window buffer */
	QLock	xl[8];
	ulong	timer;		/* timeout for xmit */
	int	rexmit;



@@ 96,7 97,6 @@ struct Urp {
#define CLOSING		0x10

Urp	*urp;
Lock	urpalloc;

/*
 *  predeclared


@@ 112,7 112,7 @@ static void	sendblock(Urp*, int);
static void	rcvack(Urp*, int);
static void	flushinput(Urp*);
static void	sendctl(Urp*, int);
static void	sendack(Urp*, int);
static void	sendack(Urp*);
static void	sendrej(Urp*);
static void	initoutput(Urp*, int);
static void	initinput(Urp*, int);


@@ 139,14 139,15 @@ urpopen(Queue *q, Stream *s)
	/*
	 *  find a free urp structure
	 */
	lock(&urpalloc);
	for(up = urp; up < &urp[conf.nurp]; up++)
	for(up = urp; up < &urp[conf.nurp]; up++){
		qlock(up);
		if(up->state == 0)
			break;
		qunlock(up);
	}
	if(up == &urp[conf.nurp]){
		q->ptr = 0;
		WR(q)->ptr = 0;
		unlock(&urpalloc);
		error(0, Egreg);
	}



@@ 154,7 155,7 @@ urpopen(Queue *q, Stream *s)
	up->rq = q;
	up->wq = q->other;
	up->state = OPEN;
	unlock(&urpalloc);
	qunlock(up);
	initinput(up, 0);
	initoutput(up, 0);



@@ 339,8 340,12 @@ urpciput(Queue *q, Block *bp)

	case SEQ+0: case SEQ+1: case SEQ+2: case SEQ+3:
	case SEQ+4: case SEQ+5: case SEQ+6: case SEQ+7:
		qlock(&up->ack);
		i = ctl & Nmask;
		if(!QFULL(q->next))
			sendctl(up, up->lastecho = ECHO+i);
		up->iseq = i;
		sendack(up, ECHO);
		qunlock(&up->ack);
		break;
	}
}


@@ 510,8 515,11 @@ urpiput(Queue *q, Block *bp)
		/*
		 *  acknowledge receipt
		 */
		qlock(&up->ack);
		up->iseq = i;
		sendack(up, ECHO);
		if(!QFULL(q->next))
			sendctl(up, up->lastecho = ECHO|i);
		qunlock(&up->ack);
		break;
	}
}


@@ 591,7 599,8 @@ output(Urp *up)
	int n;
	int i;

	qlock(&up->xmit);
	if(!canqlock(&up->xmit))
		return;

	if(waserror()){
		print("urp output error\n");


@@ 656,26 665,22 @@ output(Urp *up)
	}

	/*
	 *  free any blocks that can be freed
	 */
	while(up->tofree != up->unacked){
		if(up->xb[up->tofree] == 0)
			urpvomit("output2", up);
		else
			freeb(up->xb[up->tofree]);
		up->xb[up->tofree] = 0;
		up->tofree = NEXT(up->tofree);
	}

	/*
	 *  if there's a window open, push some blocks out
	 *
	 *  the lock is to synchronize with acknowledges that free
	 *  blocks.
	 */
	while(WINDOW(up)>0 && up->next!=up->nxb){
		sendblock(up, up->next);
		i = up->next;
		qlock(&up->xl[i]);
		if(waserror()){
			qunlock(&up->xl[i]);
			nexterror();
		}
		sendblock(up, i);
		qunlock(&up->xl[i]);
		up->next = NEXT(up->next);
		poperror();
	}
out:
	qunlock(&up->xmit);


@@ 708,10 713,9 @@ static void
sendrej(Urp *up)
{
	Queue *q = up->wq;

	flushinput(up);
	qlock(&up->ack);
	if(!QFULL(up->rq->next) && (up->lastecho&~Nmask)==ECHO){
	if((up->lastecho&~Nmask) == ECHO){
		DPRINT("REJ %d\n", up->iseq);
		sendctl(up, up->lastecho = REJ|up->iseq);
	}


@@ 722,13 726,31 @@ sendrej(Urp *up)
 *  send an acknowledge
 */
static void
sendack(Urp *up, int type)
sendack(Urp *up)
{
	Block *bp;

	qlock(&up->ack);
	if(!QFULL(up->rq->next) && (up->lastecho&Nmask)!=up->iseq)
		sendctl(up, up->lastecho = type|up->iseq);
	/*
	 *  check the precondition for acking
	 */
	if(QFULL(up->rq->next) || (up->lastecho&Nmask)==up->iseq)
		return;

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

	/*
	 *  check again now that we've locked
	 */
	if(QFULL(up->rq->next) || (up->lastecho&Nmask)==up->iseq){
		qunlock(&up->ack);
		return;
	}

	/*
	 *  send the ack
	 */
	sendctl(up, up->lastecho = ECHO|up->iseq);
	qunlock(&up->ack);
}



@@ 792,8 814,16 @@ rcvack(Urp *up, int msg)
	 *  release any acknowledged blocks
	 */
	if(IN(seqno, up->unacked, up->next)){
		for(; up->unacked != next; up->unacked = NEXT(up->unacked))
		for(; up->unacked != next; up->unacked = NEXT(up->unacked)){
			i = up->unacked;
			qlock(&up->xl[i]);
			if(up->xb[i])
				freeb(up->xb[i]);
			else
				urpvomit("rcvack", up);
			up->xb[i] = 0;
			qunlock(&up->xl[i]);
		}
	}

	switch(msg & 0370){


@@ 849,7 879,6 @@ initoutput(Urp *up, int window)
{
	int i;

	qlock(&up->xmit);
	/*
	 *  set output window
	 */


@@ 862,7 891,6 @@ initoutput(Urp *up, int window)
	/*
	 *  set sequence varialbles
	 */
	up->tofree = 1;
	up->unechoed = 1;
	up->unacked = 1;
	up->next = 1;


@@ 873,9 901,11 @@ initoutput(Urp *up, int window)
	 *  free any outstanding blocks
	 */
	for(i = 0; i < 8; i++){
		qlock(&up->xl[i]);
		if(up->xb[i])
			freeb(up->xb[i]);
		up->xb[i] = 0;
		qunlock(&up->xl[i]);
	}

	/*


@@ 883,7 913,6 @@ initoutput(Urp *up, int window)
	 */
	up->state |= INITING;
	up->timer = NOW + MSrexmit;
	qunlock(&up->xmit);
	sendctl(up, INIT1);
}



@@ 916,7 945,6 @@ todo(void *arg)
	return (up->state&INITING)
	? NOW>up->timer					/* time to INIT1 */
	: ((up->unacked!=up->next && NOW>up->timer)	/* time to ENQ */
	  || up->tofree != up->unacked
	  || WINDOW(up)>0 && up->next!=up->nxb
	  || (!QFULL(up->rq->next) && up->iseq!=(up->lastecho&7))); /* time to ECHO */
}


@@ 938,7 966,7 @@ urpkproc(void *arg)
		if(up->state & HUNGUP)
			break;
		if(!QFULL(up->rq->next))
			sendack(up, ECHO);
			sendack(up);
		output(up);
		sleep(&up->rq->r, todo, up);
	}

M gnot/sysfile.c => gnot/sysfile.c +3 -3
@@ 31,12 31,12 @@ fdtochan(int fd, int mode)

	if(fd<0 || NFD<=fd || (c=u->fd[fd])==0)
		error(0, Ebadfd);
	if(mode<0 || c->mode == 2)
	if(mode<0 || c->mode==ORDWR)
		return c;
	if((mode&16) && c->mode==0)
	if((mode&OTRUNC) && c->mode==OREAD)
    err:
		error(0, Ebadusefd);
	if((mode&~16) != c->mode)
	if((mode&~OTRUNC) != c->mode)
		goto err;
	return c;
}

M gnot/sysproc.c => gnot/sysproc.c +0 -2
@@ 41,7 41,6 @@ sysfork(ulong *arg)
	/*
	 * Save time: only copy u-> data and useful stack
	 */
	clearmmucache();
	memcpy((void*)upa, u, sizeof(User));
	n = USERADDR+BY2PG - (ulong)&lastvar;
	n = (n+32) & ~(BY2WD-1);	/* be safe & word align */


@@ 362,7 361,6 @@ sysexec(ulong *arg)
	unlock(o);

	flushmmu();
	clearmmucache();
	((Ureg*)UREGADDR)->pc = exec.entry;
	sp = (ulong*)(USTKTOP - ssize);
	*--sp = nargs;

M port/devcons.c => port/devcons.c +23 -14
@@ 36,6 36,18 @@ struct IOQ{
IOQ	kbdq;		/* qlock to getc; interrupt putc's */
IOQ	lineq;		/* lock to getc; interrupt putc's */

#define SYSLOGMAGIC	0x23456789
#define SYSLOG		((Syslog *)(UNCACHED | KZERO | 0x1B00))
typedef struct Syslog	Syslog;
struct Syslog
{
	ulong	magic;
	char	*start;
	char	*next;
	char	buf[2*BY2PG - 3*BY2WD];
};


void
printinit(void)
{


@@ 55,6 67,7 @@ printinit(void)
	unlock(&lineq);

	duartinit();
	sysloginit();		/* must be at the end of printinit */
}

/*


@@ 164,12 177,15 @@ panic(char *fmt, ...)
{
	char buf[PRINTSIZE];
	int n;
	Syslog *s;

	strcpy(buf, "panic: ");
	n = doprint(buf+7, buf+sizeof(buf), fmt, (&fmt+1)) - buf;
	buf[n] = '\n';
	putstrn(buf, n+1);
	dumpstack();
	s = SYSLOG;
	print("start/next is %lux/%lux\n", s->start, s->next);
	exit();
}



@@ 598,30 614,23 @@ consuserstr(Error *e, char *buf)
/*
 *  kernel based system log, passed between crashes
 */
#define SYSLOGMAGIC	0x23456789
#define SYSLOG		((Syslog *)(UNCACHED | KZERO | 0x1B00))
typedef struct Syslog	Syslog;
struct Syslog
{
	ulong	magic;
	char	*start;
	char	*next;
	char	buf[BY2PG - 3*BY2WD];
};

void
sysloginit(void)
{
	Syslog *s;
	char *p;
	char *start, *next;

	s = SYSLOG;
	if(s->magic!=SYSLOGMAGIC || s->next>=&s->buf[sizeof(s->buf)]
	|| s->start>=&s->buf[sizeof(s->buf)] || s->next<s->buf){
	next = s->next;
	start = s->start;
	if(s->magic!=SYSLOGMAGIC || next>=&s->buf[sizeof(s->buf)]
	|| start>=&s->buf[sizeof(s->buf)] || next<s->buf){
		s->start = s->buf;
		s->next = s->buf;
		s->magic = SYSLOGMAGIC;
	}
	print("start/next is %lux/%lux was %lux/%lux\n", s->start, s->next,
		start, next);
}

void

M port/devkprof.c => port/devkprof.c +2 -0
@@ 157,6 157,8 @@ kprofwrite(Chan *c, char *a, long n)
void
kproftimer(ulong pc)
{
	extern ulong splpc;

	timerbuf[0]++;
	if(KTZERO<=pc && pc<KTZERO+MAXPC){
		pc -= KTZERO;

M port/pgrp.c => port/pgrp.c +1 -0
@@ 103,6 103,7 @@ loop:
	if(m = mountalloc.free){		/* assign = */
		mountalloc.free = m->next;
		m->ref = 1;
		m->next = 0;
		m->mountid = ++mountalloc.mountid;
		unlock(&mountalloc);
		return m;

M power/main.c => power/main.c +0 -1
@@ 47,7 47,6 @@ main(void)
	active.machs = 1;
	confinit();
	arginit();
	sysloginit();
	lockinit();
	printinit();
	tlbinit();