~kris/9p

9hist

638268bdde463182044b2a62a3aeec02b5ab597d — David du Colombier 36 years ago ff43c31
Plan 9 from Bell Labs 1990-08-14
M gnot/chan.c => gnot/chan.c +1 -1
@@ 447,7 447,7 @@ namec(char *name, int amode, int omode, ulong perm)
		mntok = 0;
		if(!((ulong)name & KZERO))
			validaddr((ulong)(name+1), 2, 0);
		if(name[1]=='|' || ('A'<=name[1] && name[1]<='Z'))
		if(name[1]=='|' || name[1]=='M')
			error(0, Enonexist);
		t = devno(name[1], 1);
		if(t == -1)

M gnot/dat.h => gnot/dat.h +2 -0
@@ 80,6 80,8 @@ struct Alarm
};

#define	CHDIR	0x80000000L
#define	CHAPPEND 0x40000000L
#define	CHEXCL	0x20000000L
#define	QPATH	0x0000FFFFL
struct Chan
{

M gnot/devcons.c => gnot/devcons.c +48 -21
@@ 17,7 17,7 @@ static struct

typedef struct IOQ	IOQ;

#define	NQ	1024
#define	NQ	2048
struct IOQ{
	union{
		Lock;


@@ 100,8 100,9 @@ putstrn(char *str, long n)
}

int
cangetc(IOQ *q)
cangetc(void *arg)
{
	IOQ *q = (IOQ *)arg;
	int n = q->in - q->out;
	if (n < 0)
		n += sizeof(q->buf);


@@ 109,14 110,16 @@ cangetc(IOQ *q)
}

int
canputc(IOQ *q)
canputc(void *arg)
{
	IOQ *q = (IOQ *)arg;
	return sizeof(q->buf)-cangetc(q)-1;
}

int
isbrkc(IOQ *q)
isbrkc(void *arg)
{
	IOQ *q = (IOQ *)arg;
	uchar *p;

	for(p=q->out; p!=q->in; ){


@@ 352,21 355,25 @@ enum{
	Qtime,
	Quser,
	Qklog,
	Qmsec,
	Qclock,
};

Dirtab consdir[]={
	"cons",		Qcons,		0,	0600,
	"cputime",	Qcputime,	72,	0600,
	"null",		Qnull,		0,	0600,
	"pgrpid",	Qpgrpid,	12,	0600,
	"pid",		Qpid,		12,	0600,
	"ppid",		Qppid,		12,	0600,
	"rcons",	Qrcons,		0,	0600,
	"rs232",	Qrs232,		0,	0600,
	"rs232ctl",	Qrs232ctl,	0,	0600,
	"time",		Qtime,		12,	0600,
	"user",		Quser,		0,	0600,
	"klog",		Qklog,		0,	0400,
	"cons",		Qcons,		0,		0600,
	"cputime",	Qcputime,	6*NUMSIZE,	0600,
	"null",		Qnull,		0,		0600,
	"pgrpid",	Qpgrpid,	NUMSIZE,	0600,
	"pid",		Qpid,		NUMSIZE,	0600,
	"ppid",		Qppid,		NUMSIZE,	0600,
	"rcons",	Qrcons,		0,		0600,
	"rs232",	Qrs232,		0,		0600,
	"rs232ctl",	Qrs232ctl,	0,		0600,
	"time",		Qtime,		NUMSIZE,	0600,
	"user",		Quser,		0,		0600,
	"klog",		Qklog,		0,		0400,
	"msec",		Qmsec,		NUMSIZE,	0400,
	"clock",	Qclock,		2*NUMSIZE,	0400,
};

#define	NCONS	(sizeof consdir/sizeof(Dirtab))


@@ 520,7 527,7 @@ consread(Chan *c, void *buf, long n)
			nexterror();
		}
		while(!cangetc(&lineq)){
			sleep(&kbdq.r, (int(*)(void*))isbrkc, &kbdq);
			sleep(&kbdq.r, isbrkc, &kbdq);
			do{
				lock(&lineq);
				ch = getc(&kbdq);


@@ 567,12 574,13 @@ consread(Chan *c, void *buf, long n)
			nexterror();
		}
		while(!cangetc(&rs232iq))
			sleep(&rs232iq.r, (int(*)(void*))cangetc, &rs232iq);
			sleep(&rs232iq.r, cangetc, &rs232iq);
		for(i=0; i<n; i++){
			if((ch=getc(&rs232iq)) == -1)
				break;
			*cbuf++ = ch;
		}
		poperror();
		qunlock(&rs232iq);
		return i;



@@ 606,7 614,20 @@ consread(Chan *c, void *buf, long n)
		return readnum(c->offset, buf, n, u->p->parentpid, NUMSIZE);

	case Qtime:
		return readnum(c->offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), 12);
		return readnum(c->offset, buf, n, boottime+TK2SEC(MACHP(0)->ticks), NUMSIZE);

	case Qmsec:
		return readnum(c->offset, buf, n, TK2MS(MACHP(0)->ticks), NUMSIZE);
	case Qclock:
		k = c->offset;
		if(k >= 2*NUMSIZE)
			return 0;
		if(k+n > 2*NUMSIZE)
			n = 2*NUMSIZE - k;
		readnum(0, tmp, NUMSIZE, MACHP(0)->ticks, NUMSIZE);
		readnum(0, tmp+NUMSIZE, NUMSIZE, HZ, NUMSIZE);
		memcpy(buf, tmp+k, n);
		return n;

	case Quser:
		return readstr(c->offset, buf, n, u->p->pgrp->user);


@@ 621,12 642,13 @@ consread(Chan *c, void *buf, long n)
			nexterror();
		}
		while(!cangetc(&klogq))
			sleep(&klogq.r, (int(*)(void*))cangetc, &klogq);
			sleep(&klogq.r, cangetc, &klogq);
		for(i=0; i<n; i++){
			if((ch=getc(&klogq)) == -1)
				break;
			*cbuf++ = ch;
		}
		poperror();
		qunlock(&klogq);
		return i;



@@ 664,10 686,14 @@ conswrite(Chan *c, void *va, long n)

	case Qrs232:
		qlock(&rs232oq);
		if(waserror()){
			qunlock(&rs232oq);
			nexterror();
		}
		l = n;
		while(--l >= 0) {
			while (putc(&rs232oq, *a) < 0)
				sleep(&rs232oq.r, (int(*)(void*))canputc, &rs232oq);
				sleep(&rs232oq.r, canputc, &rs232oq);
			a++;
			if(rs232oq.state == 0){
				splhi();


@@ 678,6 704,7 @@ conswrite(Chan *c, void *va, long n)
				spllo();
			}
		}
		poperror();
		qunlock(&rs232oq);
		break;


M gnot/devdk.c => gnot/devdk.c +10 -4
@@ 6,8 6,9 @@
#include	"io.h"
#include	"errno.h"

#define NOW (MACHP(0)->ticks)
#define DPRINT if(0)
#define	DPRINT	if(0)	/*kprint*/

#define	NOW	(MACHP(0)->ticks)

enum {
	/*


@@ 477,6 478,8 @@ dkmuxconfig(Dk *dp, Block *bp)
		dp->lines = 16;
		error(0, Ebadarg);
	}
	DPRINT("dkmuxconfig: ncsc=%d, lines=%d, restart=%d, name=\"%s\"\n",
		dp->ncsc, dp->lines, dp->restart, dp->name);

	/*
	 *  open a stream for the csc and push urp onto it


@@ 495,7 498,7 @@ dkmuxconfig(Dk *dp, Block *bp)
	/*
	 *  start a process to deal with it
	 */
	sprint(buf, "csckproc%d", dp->ncsc);
	sprint(buf, "csc.%s.%d", dp->name, dp->ncsc);
	kproc(buf, dkcsckproc, dp);
	poperror();



@@ 1316,8 1319,11 @@ dkcsckproc(void *a)
	/*
	 *  tell datakit we've rebooted. It should close all channels.
	 */
	if(dp->restart)
	if(dp->restart) {
		DPRINT("dkcsckproc: restart %s\n", dp->name);
		dkmesg(dp, T_ALIVE, D_RESTART, 0, 0);
	}
	DPRINT("dkcsckproc: closeall %s\n", dp->name);
	dkmesg(dp, T_CHG, D_CLOSEALL, 0, 0);

	/*

M gnot/fault.c => gnot/fault.c +3 -3
@@ 79,6 79,7 @@ fault(Ureg *ur, FFrame *f)
			panic("prefetch pagefault");
	}else
		panic("prefetch format");
	addr &= VAMASK;
	badvaddr = addr;
	addr &= ~(BY2PG-1);
	user = !(ur->sr&SUPER);


@@ 99,7 100,7 @@ fault(Ureg *ur, FFrame *f)
			}
			u->p->state = MMUing;
			dumpregs(ur);
			panic("fault");
			panic("fault: 0x%lux", badvaddr);
			exit();
		}
		s = &u->p->seg[SSEG];


@@ 108,15 109,14 @@ fault(Ureg *ur, FFrame *f)
		/* grow stack */
		o = s->o;
		n = o->npte;
		lock(o);
		if(waserror()){
			unlock(o);
			pprint("can't allocate stack page\n");
			goto cant;
		}
		growpte(o, (s->maxva-addr)>>PGSHIFT);
		poperror();
		/* stacks grown down, sigh */
		lock(o);
		memcpy(o->pte+(o->npte-n), o->pte, n*sizeof(PTE));
		memset(o->pte, 0, (o->npte-n)*sizeof(PTE));
		unlock(o);

M gnot/fns.h => gnot/fns.h +1 -0
@@ 49,6 49,7 @@ void	flushcpucache(void);
void	flushmmu(void);
void	forkmod(Seg*, Seg*, Proc*);
void	freeb(Block*);
void	freenextmod(PTE*);
void	freepage(Orig*);
void	freepte(Orig*);
void	freesegs(int);

M gnot/mem.h => gnot/mem.h +6 -4
@@ 18,10 18,11 @@
/*
 * Time
 */
#define	MS2HZ		(1000/60)		/* millisec per clock tick */
#define	TK2SEC(t)	((t)/60)		/* ticks to seconds */
#define	TK2MS(t)	(((t)*1000)/60)		/* ticks to milliseconds */
#define	MS2TK(t)	(((t)*60)/1000)		/* milliseconds to ticks */
#define	HZ		(60)			/* clock frequency */
#define	MS2HZ		(1000/HZ)		/* millisec per clock tick */
#define	TK2SEC(t)	((t)/HZ)		/* ticks to seconds */
#define	TK2MS(t)	(((t)*1000)/HZ)		/* ticks to milliseconds */
#define	MS2TK(t)	(((t)*HZ)/1000)		/* milliseconds to ticks */

/*
 * SR bits


@@ 59,6 60,7 @@
 * MMU
 */

#define	VAMASK	0xCFFFFFFF	/* clear balu bits in address */
#define	KUSEG	0x00000000
#define KSEG	0x80000000


M gnot/page.c => gnot/page.c +25 -42
@@ 311,16 311,13 @@ loop:
			o->mqid = -1;
			o->mchan = 0;
		}
		lock(o);
		if(u && u->p && waserror()){
			unlock(o);
			unlock(&origalloc);
			nexterror();
		}
		growpte(o, npte);
		if(u && u->p)
			poperror();
		unlock(o);
		unlock(&origalloc);
		return o;
	}


@@ 515,15 512,8 @@ segaddr(Seg *s, ulong min, ulong max)
		 * Grow
		 */
		/* BUG: check spill onto other segments */
		lock(o);
		if(waserror()){
			unlock(o);
			nexterror();
		}
		if(o->va+BY2PG*o->npte < max)
			growpte(o, (max-o->va)>>PGSHIFT);
		unlock(o);
		poperror();
		s->maxva = max;
		return 1;
	}


@@ 568,6 558,10 @@ freepte(Orig *o)	/* o is locked */
	p->o = 0;
}

/*
 * o is locked.  this will always do a grow; if n<=o->npte someone
 * else got here first and we can just return.
 */
void
growpte(Orig *o, ulong n)
{


@@ 575,43 569,30 @@ growpte(Orig *o, ulong n)
	ulong nfree;

	lock(&ptealloc);
	lock(o);
	if(o->pte){
		if(o->npte == n){
if(u && u->p) print("%s: ", u->p->text);
			print("growpte pointless\n");
		if(o->npte >= n)
			goto Return;
		}
		p = (PTEA*)(o->pte - 1);
		if(o->npte > n){
			print("growpte shrink");
			goto Return;
			nfree = o->npte - n;
			p->n -= nfree;
			o->npte -= nfree;
			p += p->n;
			p->o = 0;
			p->n = nfree;
		n++;
		if(p+p->n == ptealloc.free){
			if(!compactpte(o, n - p->n))
				goto Trouble;
			p = (PTEA*)(o->pte - 1);
			ptealloc.free += n - p->n;
		}else{
			n++;
			if(p+p->n == ptealloc.free){
				if(!compactpte(o, n - p->n))
					goto Trouble;
				p = (PTEA*)(o->pte - 1);
				ptealloc.free += n - p->n;
			}else{
				if(!compactpte(o, n))
					goto Trouble;
				p = ptealloc.free;
				ptealloc.free += n;
				memcpy(p+1, o->pte, o->npte*sizeof(PTE));
				p->o = o;
				((PTEA*)(o->pte-1))->o = 0;
				o->pte = p+1;
			}
			memset(p+1+o->npte, 0, (n-(1+o->npte))*sizeof(PTE));
			p->n = n;
			o->npte = n-1;
			if(!compactpte(o, n))
				goto Trouble;
			p = ptealloc.free;
			ptealloc.free += n;
			memcpy(p+1, o->pte, o->npte*sizeof(PTE));
			p->o = o;
			((PTEA*)(o->pte-1))->o = 0;
			o->pte = p+1;
		}
		memset(p+1+o->npte, 0, (n-(1+o->npte))*sizeof(PTE));
		p->n = n;
		o->npte = n-1;
		goto Return;
	}
	n++;


@@ 626,10 607,12 @@ if(u && u->p) print("%s: ", u->p->text);
	o->npte = n-1;
    Return:
	unlock(&ptealloc);
	unlock(o);
	return;

    Trouble:
	unlock(&ptealloc);
	unlock(o);
	if(u && u->p)
		error(0, Enovmem);
	panic("growpte fails %d %lux %d\n", n, o->va, o->npte);

M gnot/screen.c => gnot/screen.c +1 -2
@@ 65,8 65,7 @@ screenputc(int c)
		bitblt(&screen, Pt(0, out.pos.y), &screen,
		    Rect(0, out.pos.y, screen.r.max.x, out.pos.y+2*defont0.height), 0);
	}else if(c == '\t'){
		nx = out.pos.x + (8-(out.pos.x/out.bwid&7))*out.bwid;
		out.pos.x = nx;
		out.pos.x += (8-((out.pos.x-MINX)/out.bwid&7))*out.bwid;
		if(out.pos.x >= screen.r.max.x)
			screenputc('\n');
	}else if(c == '\b'){

M gnot/sturp.c => gnot/sturp.c +1 -3
@@ 771,10 771,8 @@ sendblock(Urp *up, int bn)
	 *  message 1, the BOT and the data
	 */
	bp = up->xb[bn];
	if(bp == 0){
		urpvomit("sendblock", up);
	if(bp == 0)
		return;
	}
	m = allocb(1);
	m->rptr = m->lim - 1;
	m->wptr = m->lim;

M port/devbit.c => port/devbit.c +14 -0
@@ 973,11 973,24 @@ bitfree(Bitmap *bp)
	bit.free = bp;
}

QLock	bitlock;

Bitmap *
id2bit(int k)
{
	Bitmap *bp;
	bp = &bit.map[k];
	if(k<0 || k>=conf.nbitmap || bp->ldepth < 0)
		error(0, Ebadbitmap);
	return bp;
}

void
bitcompact(void)
{
	ulong *p1, *p2;

	qlock(&bitlock);
	p1 = p2 = bit.words;
	while(p2 < bit.wfree){
		if(p2[1] == 0){


@@ 992,6 1005,7 @@ bitcompact(void)
		p1 += 2 + p1[0];
	}
	bit.wfree = p1;
	qunlock(&bitlock);
}

void

M port/fault.c => port/fault.c +1 -2
@@ 43,15 43,14 @@ fault(Ureg *ur, int user, int code)
		/* grow stack */
		o = s->o;
		n = o->npte;
		lock(o);
		if(waserror()){
			unlock(o);
			pprint("can't allocate stack page\n");
			goto cant;
		}
		growpte(o, (s->maxva-addr)>>PGSHIFT);
		poperror();
		/* stacks grown down, sigh */
		lock(o);
		memcpy(o->pte+(o->npte-n), o->pte, n*sizeof(PTE));
		memset(o->pte, 0, (o->npte-n)*sizeof(PTE));
		unlock(o);

M port/page.c => port/page.c +25 -42
@@ 339,16 339,13 @@ o->nmod = 0;
			o->mqid = -1;
			o->mchan = 0;
		}
		lock(o);
		if(u && u->p && waserror()){
			unlock(o);
			unlock(&origalloc);
			nexterror();
		}
		growpte(o, npte);
		if(u && u->p)
			poperror();
		unlock(o);
		unlock(&origalloc);
		return o;
	}


@@ 547,15 544,8 @@ segaddr(Seg *s, ulong min, ulong max)
		 * Grow
		 */
		/* BUG: check spill onto other segments */
		lock(o);
		if(waserror()){
			unlock(o);
			nexterror();
		}
		if(o->va+BY2PG*o->npte < max)
			growpte(o, (max-o->va)>>PGSHIFT);
		unlock(o);
		poperror();
		s->maxva = max;
		return 1;
	}


@@ 601,6 591,10 @@ freepte(Orig *o)	/* o is locked */
	p->o = 0;
}

/*
 * o is locked.  this will always do a grow; if n<=o->npte someone
 * else got here first and we can just return.
 */
void
growpte(Orig *o, ulong n)
{


@@ 608,43 602,30 @@ growpte(Orig *o, ulong n)
	ulong nfree;

	lock(&ptealloc);
	lock(o);
	if(o->pte){
		if(o->npte == n){
if(u && u->p) print("%s: ", u->p->text);
			print("growpte pointless\n");
		if(o->npte >= n)
			goto Return;
		}
		p = (PTEA*)(o->pte - 1);
		if(o->npte > n){
			print("growpte shrink");
			goto Return;
			nfree = o->npte - n;
			p->n -= nfree;
			o->npte -= nfree;
			p += p->n;
			p->o = 0;
			p->n = nfree;
		n++;
		if(p+p->n == ptealloc.free){
			if(!compactpte(o, n - p->n))
				goto Trouble;
			p = (PTEA*)(o->pte - 1);
			ptealloc.free += n - p->n;
		}else{
			n++;
			if(p+p->n == ptealloc.free){
				if(!compactpte(o, n - p->n))
					goto Trouble;
				p = (PTEA*)(o->pte - 1);
				ptealloc.free += n - p->n;
			}else{
				if(!compactpte(o, n))
					goto Trouble;
				p = ptealloc.free;
				ptealloc.free += n;
				memcpy(p+1, o->pte, o->npte*sizeof(PTE));
				p->o = o;
				((PTEA*)(o->pte-1))->o = 0;
				o->pte = p+1;
			}
			memset(p+1+o->npte, 0, (n-(1+o->npte))*sizeof(PTE));
			p->n = n;
			o->npte = n-1;
			if(!compactpte(o, n))
				goto Trouble;
			p = ptealloc.free;
			ptealloc.free += n;
			memcpy(p+1, o->pte, o->npte*sizeof(PTE));
			p->o = o;
			((PTEA*)(o->pte-1))->o = 0;
			o->pte = p+1;
		}
		memset(p+1+o->npte, 0, (n-(1+o->npte))*sizeof(PTE));
		p->n = n;
		o->npte = n-1;
		goto Return;
	}
	n++;


@@ 659,10 640,12 @@ if(u && u->p) print("%s: ", u->p->text);
	o->npte = n-1;
    Return:
	unlock(&ptealloc);
	unlock(o);
	return;

    Trouble:
	unlock(&ptealloc);
	unlock(o);
	if(u && u->p)
		error(0, Enovmem);
	panic("growpte fails %d %lux %d\n", n, o->va, o->npte);

M port/sturp.c => port/sturp.c +2 -3
@@ 771,10 771,8 @@ sendblock(Urp *up, int bn)
	 *  message 1, the BOT and the data
	 */
	bp = up->xb[bn];
	if(bp == 0){
		urpvomit("sendblock", up);
	if(bp == 0)
		return;
	}
	m = allocb(1);
	m->rptr = m->lim - 1;
	m->wptr = m->lim;


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