~kris/9p

9hist

a0a8ac297122fb9dbf2a74750dd208687da1561b — David du Colombier 35 years ago dba21a3
Plan 9 from Bell Labs 1990-11-06
9 files changed, 197 insertions(+), 52 deletions(-)

M gnot/clock.c
M gnot/dat.h
M gnot/devproc.c
M gnot/fns.h
M gnot/pgrp.c
M gnot/proc.c
M gnot/sysfile.c
M power/clock.c
M power/devhotrod.c
M gnot/clock.c => gnot/clock.c +5 -4
@@ 106,14 106,15 @@ clock(Ureg *ur)
			p->time[p->insyscall]++;
	}
	if(canlock(&m->alarmlock)){
		if(m->alarm){
			a = m->alarm;
			a->dt--;
			for(n = 0; a && a->dt<=0 && n<NA; n++){
		a = m->alarm;
		if(a){
			for(n=0; a && a->dt<=0 && n<NA; n++){
				alist[n] = a;
				delete(&m->alarm, 0, a);
				a = m->alarm;
			}
			if(a)
				a->dt--;
			unlock(&m->alarmlock);

			/*  execute alarm functions outside the lock */

M gnot/dat.h => gnot/dat.h +5 -1
@@ 103,6 103,7 @@ struct Chan
	union {
		Stream	*stream;	/* for stream channels */
		void	*aux;
		ulong	pgrpid;		/* for #p/notepg */
	};
	Chan	*mchan;			/* channel to mounted server */
	ulong	mqid;			/* qid of root of mount point */


@@ 278,10 279,12 @@ struct Pgrp
{
	Ref;				/* also used as a lock when mounting */
	Pgrp	*next;
	int	index;			/* index in pgrp table */
	ulong	pgrpid;
	char	user[NAMELEN];
	int	nmtab;			/* highest active mount table entry, +1 */
	int	nenv;			/* highest active env table entry, +1 */
	Lock	debug;			/* single access via devproc.c */
	Mtab	*mtab;
	Envp	*etab;
};


@@ 499,7 502,8 @@ struct Service
	Service *next;
	QLock	alock;
	int	die;
	Chan	*c;
	Chan	*inc;
	Chan	*outc;
	char	name[NAMELEN];
};


M gnot/devproc.c => gnot/devproc.c +33 -1
@@ 12,6 12,7 @@ enum{
	Qctl,
	Qmem,
	Qnote,
	Qnotepg,
	Qproc,
	Qstatus,
	Qtext,


@@ 21,6 22,7 @@ Dirtab procdir[]={
	"ctl",		Qctl,		0,			0600,
	"mem",		Qmem,		0,			0600,
	"note",		Qnote,		0,			0600,
	"notepg",	Qnotepg,	0,			0200,
	"proc",		Qproc,		sizeof(Proc),		0600,
	"status",	Qstatus,	NAMELEN+12+6*12,	0600,
	"text",		Qtext,		0,			0600,


@@ 108,6 110,7 @@ Chan *
procopen(Chan *c, int omode)
{
	Proc *p;
	Pgrp *pg;
	Orig *o;
	Chan *tc;



@@ 117,6 120,7 @@ procopen(Chan *c, int omode)
		goto done;
	}
	p = proctab(SLOT(c->qid));
	pg = p->pgrp;
	if((p->pid&PIDMASK) != PID(c->qid))
    Died:
		error(0, Eprocdied);


@@ 146,11 150,18 @@ procopen(Chan *c, int omode)
	case Qctl:
	case Qnote:
		break;

	case Qnotepg:
		if(omode != OWRITE)
			error(0, Eperm);
		c->pgrpid = (pg->pgrpid<<PIDSHIFT)|((pg->index+1)<<QSHIFT);
		break;

	case Qdir:
	case Qmem:
	case Qproc:
	case Qstatus:
		if(omode!=OREAD)
		if(omode != OREAD)
			error(0, Eperm);
		break;
	default:


@@ 347,12 358,33 @@ long
procwrite(Chan *c, void *va, long n)
{
	Proc *p;
	Pgrp *pg;
	User *up;
	KMap *k;
	char buf[ERRLEN];

	if(c->qid & CHDIR)
		error(0, Eisdir);

	/*
	 * Special case: don't worry about process, just use remembered group
	 */
	if(QID(c->qid) == Qnotepg){
		pg = pgrptab(SLOT(c->pgrpid));
		lock(&pg->debug);
		if(waserror()){
			unlock(&pg->debug);
			nexterror();
		}
		if((pg->pgrpid&PIDMASK) != PID(c->pgrpid)){
			unlock(&pg->debug);
  	  		goto Died;
		}
		pgrpnote(pg, va, n, NUser);
		unlock(&pg->debug);
		return n;
	}

	p = proctab(SLOT(c->qid));
	lock(&p->debug);
	if(waserror()){

M gnot/fns.h => gnot/fns.h +14 -9
@@ 19,6 19,7 @@ long	clrfpintr(void);
int	compactpte(Orig*, ulong);
void	confinit(void);
Env	*copyenv(Env*, int);
Chan	*createdir(Chan*);
int	decref(Ref*);
void	delay(int);
void	delete(List**, List*, List*);


@@ 29,7 30,7 @@ void	devdir(Chan*, long, char*, long, long, Dir*);
long	devdirread(Chan*, char*, long, Dirtab*, int, Devgen*);
Devgen	devgen;
int	devno(int, int);
Chan*	devopen(Chan*, int, Dirtab*, int, Devgen*);
Chan	*devopen(Chan*, int, Dirtab*, int, Devgen*);
void	devstat(Chan*, char*, Dirtab*, int, Devgen*);
int	devwalk(Chan*, char*, Dirtab*, int, Devgen*);
void	duartbaud(int);


@@ 47,7 48,7 @@ void	error(Chan*, int);
void	exit(void);
void	fault(Ureg*, FFrame*);
void	fdclose(int);
Chan*	fdtochan(int, int);
Chan	*fdtochan(int, int);
void	filsys(Chan*, char*, long);
void	firmware(void);
void	flowctl(Queue*);


@@ 81,7 82,7 @@ void	kbdclock(void);
void	kmapinit(void);
KMap	*kmap(Page*);
int	kprint(char*, ...);
Proc	*kproc(char*, void(*)(void*), void*);
void	*kproc(char*, void(*)(void*), void*);
void	kunmap(KMap*);
void	lock(Lock*);
void	lockinit(void);


@@ 107,19 108,21 @@ char	*nextelem(char*, char*);
void	notify(Ureg*);
void	nullput(Queue*, Block*);
int	openmode(ulong);
Block*	padb(Block*, int);
Block	*padb(Block*, int);
void	pageinit(void);
void	panic(char*, ...);
void	pexit(char*, int);
void	pgrpcpy(Pgrp*, Pgrp*);
void	pgrpinit(void);
void	pgrpnote(Pgrp*, char*, long, int);
Pgrp	*pgrptab(int);
int	postnote(Proc*, int, char*, int);
int	pprint(char*, ...);
void	printinit(void);
void	printslave(void);
void	procinit0(void);
Proc	*proctab(int);
Queue*	pushq(Stream*, Qinfo*);
Queue	*pushq(Stream*, Qinfo*);
void	putbq(Blist*, Block*);
void	putkmmu(ulong, ulong);
void	putmmu(ulong, ulong);


@@ 146,9 149,9 @@ long	seconds(void);
Seg	*seg(Proc*, ulong);
int	segaddr(Seg*, ulong, ulong);
void	serviceinit(void);
void	service(char*, Chan*, void (*)(Chan*, char*, long));
void	service(char*, Chan*, Chan*, void (*)(Chan*, char*, long));
int	setlabel(Label*);
char*	skipslash(char*);
char	*skipslash(char*);
void	sleep(Rendez*, int(*)(void*), void*);
int	splhi(void);
int	spllo(void);


@@ 162,7 165,7 @@ int	streamexit(Stream*, int);
void	streaminit(void);
long	streamread(Chan*, void*, long);
long	streamwrite(Chan*, void*, long, int);
Stream*	streamnew(ushort, ushort, ushort, Qinfo*, int);
Stream	*streamnew(ushort, ushort, ushort, Qinfo*, int);
void	streamopen(Chan*, Qinfo*);
int	streamparse(char*, Block*);
void	streamstat(Chan*, char*, char*);


@@ 172,13 175,15 @@ int	tas(char*);
void	touser(void);
void	tsleep(Rendez*, int (*)(void*), void*, int);
void	twakeme(Alarm*);
long	unionread(Chan*, void*, long);
void	unlock(Lock*);
void	usepage(Page*, int);
void	userinit(void);
void	validaddr(ulong, ulong, int);
void*	vmemchr(void*, int, int);
void	*vmemchr(void*, int, int);
void	wakeme(Alarm*);
void	wakeup(Rendez*);
Chan	*walk(Chan*, char*, int);

#define	waserror()	(u->nerrlab++, setlabel(&u->errlab[u->nerrlab-1]))
#define	poperror()	u->nerrlab--

M gnot/pgrp.c => gnot/pgrp.c +42 -1
@@ 7,6 7,7 @@

struct{
	Lock;
	Pgrp	*arena;
	Pgrp	*free;
	ulong	pgrpid;
}pgrpalloc;


@@ 24,10 25,12 @@ pgrpinit(void)
	Pgrp *p;
	Mount *m;

	pgrpalloc.free = ialloc(conf.npgrp*sizeof(Pgrp), 0);
	pgrpalloc.arena = ialloc(conf.npgrp*sizeof(Pgrp), 0);
	pgrpalloc.free = pgrpalloc.arena;

	p = pgrpalloc.free;
	for(i=0; i<conf.npgrp; i++,p++){
		p->index = i;
		p->next = p+1;
		p->mtab = ialloc(conf.nmtab*sizeof(Mtab), 0);
		p->etab = ialloc(conf.npgenv*sizeof(Envp*), 0);


@@ 43,6 46,43 @@ pgrpinit(void)
}

Pgrp*
pgrptab(int i)
{
	return &pgrpalloc.arena[i];
}

void
pgrpnote(Pgrp *pg, char *a, long n, int flag)
{
	int i;
	Proc *p;
	char buf[ERRLEN];

	if(n >= ERRLEN-1)
		error(0, Etoobig);
	if(n>=4 && strncmp(a, "sys:", 4)==0)
		error(0, Ebadarg);
	memcpy(buf, a, n);
	buf[n] = 0;
	p = proctab(0);
	for(i=0; i<conf.nproc; i++, p++){
		if(p->pgrp == pg){
			lock(&p->debug);
			if(p->pid==0 || p->pgrp!=pg){
				unlock(&p->debug);
				continue;
			}
			if(waserror()){
				unlock(&p->debug);
				continue;
			}
			postnote(p, 0, buf, flag);
			unlock(&p->debug);
		}
	}
}

Pgrp*
newpgrp(void)
{
	Pgrp *p;


@@ 76,6 116,7 @@ closepgrp(Pgrp *p)
	Envp *ep;

	if(decref(p) == 0){
		p->pgrpid = -1;
		m = p->mtab;
		for(i=0; i<p->nmtab; i++,m++)
			if(m->c){

M gnot/proc.c => gnot/proc.c +21 -20
@@ 58,13 58,13 @@ schedinit(void)		/* never returns */
	/*
	 * At init time:  wait for a process on the run queue.
	 */
	for (;;) {
	for(;;){
		spllo();
		while (runq.head == 0)
			/* idle loop */;
		splhi();
		lock(&runq);
		if (runq.head != 0)
		if(runq.head != 0)
			break;
		unlock(&runq);
	}


@@ 84,7 84,7 @@ schedinit(void)		/* never returns */
	 * to have a process on it.
	 */
	p = runq.head;
	if ((runq.head = p->rnext) == 0)
	if((runq.head = p->rnext) == 0)
		runq.tail = 0;
	unlock(&runq);



@@ 108,7 108,7 @@ restore(void)
	u->p->mach = m;
	m->proc = u->p;
	u->p->state = Running;
	if (p->state == Moribund) {
	if(p->state == Moribund){
		p->pid = 0;
		unlock(&p->debug);		/* set in pexit */
		p->upage->ref--;


@@ 127,16 127,16 @@ void
save(Balu *balu)
{
	fpsave(&u->fpsave);
	if (u->fpsave.type) {
	if(u->fpsave.type){
		if(u->fpsave.size > sizeof u->fpsave.junk)
			panic("fpsize %d max %d\n", u->fpsave.size, sizeof u->fpsave.junk);
		fpregsave(u->fpsave.reg);
		u->p->fpstate = FPactive;
		m->fpstate = FPdirty;
	}
	if (BALU->cr0 != 0xFFFFFFFF)	/* balu busy */
	if(BALU->cr0 != 0xFFFFFFFF)	/* balu busy */
		memcpy(balu, BALU, sizeof *balu);
	else {
	else{
		balu->cr0 = 0xFFFFFFFF;
		BALU->cr0 = 0xFFFFFFFF;
	}


@@ 166,7 166,7 @@ sched(void)
	/*
	 * Look for a new process to be run.
	 */
	for (;;) {
	for (;;){
		spllo();

		/*


@@ 174,9 174,9 @@ sched(void)
		 * to do, start saving some of the process state.
		 */
		while (runq.head == 0)
			if (p->state == Running)
			if(p->state == Running)
				return;
			else if (!saved) {
			else if(!saved){
				save(&balu);
				saved = 1;
			}


@@ 188,7 188,7 @@ sched(void)
		 */
		splhi();
		lock(&runq);
		if (runq.head != 0)
		if(runq.head != 0)
			break;
		unlock(&runq);
	}


@@ 199,7 199,7 @@ sched(void)
	 * save our state before we jump to schedinit.  If this process was running, put
	 * it on the run queue.
	 */
	if (p->state == Running) {
	if(p->state == Running){
		p->state = Ready;
		p->rnext = 0;
		runq.tail->rnext = p;


@@ 211,9 211,9 @@ sched(void)
	 * pc and sp.  We have to jump to schedinit() because we are going to remap the
	 * stack.
	 */
	if (!saved)
	if(!saved)
		save(&balu);
	if (setlabel(&p->sched) == 0)
	if(setlabel(&p->sched) == 0)
		gotolabel(&m->sched);

	/*


@@ 225,18 225,18 @@ sched(void)
	/*
	 * Jumped to by schedinit.  Restore the process state.
	 */
	if (p->fpstate != m->fpstate)
		if (p->fpstate == FPinit) {
	if(p->fpstate != m->fpstate)
		if(p->fpstate == FPinit){
			initfp = 0;
			fprestore((FPsave *) &initfp);
			m->fpstate = FPinit;
		}
		else {
		else{
			fpregrestore(u->fpsave.reg);
			fprestore(&u->fpsave);
			m->fpstate = FPdirty;
		}
	if (balu.cr0 != 0xFFFFFFFF)	/* balu busy */
	if(balu.cr0 != 0xFFFFFFFF)	/* balu busy */
		memcpy(BALU, &balu, sizeof balu);

	/*


@@ 250,11 250,12 @@ ready(Proc *p)
{
	int s;

	if (p->spin) {
	s = splhi();
	if(p->spin){
		p->state = Running;
		splx(s);
		return;
	}
	s = splhi();
	lock(&runq);
	p->rnext = 0;
	if(runq.tail)

M gnot/sysfile.c => gnot/sysfile.c +6 -5
@@ 512,12 512,13 @@ sysfwstat(ulong *arg)
long
sysfilsys(ulong *arg)
{
	Chan *c;
	Chan *cin, *cout;

	c = fdtochan(arg[0], -1);
	validaddr(arg[1], 1, 0);
	if((c->qid&CHDIR) || (c->mode&ORDWR)!=ORDWR)
	cin = fdtochan(arg[0], OREAD);
	cout = fdtochan(arg[1], OWRITE);
	validaddr(arg[2], 1, 0);
	if((cin->qid&CHDIR) || (cout->qid&CHDIR))
		error(0, Ebadarg);
	service((char *)arg[1], c, filsys);
	service((char *)arg[2], cin, cout, filsys);
	return 0;
}

M power/clock.c => power/clock.c +7 -6
@@ 181,18 181,19 @@ clock(ulong n, ulong pc)
			exit();
		}
		if(canlock(&m->alarmlock)){
			if(m->alarm){
				a = m->alarm;
				a->dt--;
				for(na = 0; a && a->dt<=0 && na<NA; na++){
					alist[na] = a;
			a = m->alarm;
			if(a){
				for(n=0; a && a->dt<=0 && n<NA; n++){
					alist[n] = a;
					delete(&m->alarm, 0, a);
					a = m->alarm;
				}
				if(a)
					a->dt--;
				unlock(&m->alarmlock);
	
				/*  execute alarm functions outside the lock */
				for(i = 0; i < na; i++){
				for(i = 0; i < n; i++){
					f = alist[i]->f;	/* avoid race with cancel */
					if(f)
						(*f)(alist[i]);

M power/devhotrod.c => power/devhotrod.c +64 -5
@@ 10,6 10,7 @@

typedef struct Hotrod	Hotrod;
typedef struct Device	Device;
typedef struct Printbuf	Printbuf;

enum {
	Vmevec=		0xd2,		/* vme vector for interrupts */


@@ 18,6 19,16 @@ enum {
};

/*
 *  circular 2 pointer queue for hotrod prnt's
 */
struct Printbuf {
	char	*rptr;
	char	*wptr;
	char	*lim;
	char	buf[4*1024];
};

/*
 *  the hotrod fiber interface responds to 1MB
 *  of either user or supervisor accesses at:
 *  	0x30000000 to 0x300FFFFF  in	A32 space


@@ 31,14 42,18 @@ struct Device {
struct Hotrod {
	QLock;

	Device	*addr;
	int	vec;
	char	name[NAMELEN];
	Device		*addr;		/* address of the device */
	int		vec;		/* vme interrupt vector */
	char		name[NAMELEN];	/* hot rod name */
	Printbuf	pbuf;		/* circular queue for hotrod print's */
	int		kprocstarted;
	Rendez		r;
};

Hotrod hotrod[Nhotrod];

static void hotrodintr(int);
void	hotrodintr(int);
void	hotrodkproc(void *a);

int
hotrodgen(Chan *c, Dirtab *tab, int ntab, int i, Dir *dp)


@@ 79,6 94,7 @@ hotrodinit(void)
Chan*
hotrodattach(char *spec)
{
	Hotrod *hp;
	int i;
	Chan *c;



@@ 86,6 102,10 @@ hotrodattach(char *spec)
	if(i >= Nhotrod)
		error(0, Ebadarg);

	hp = &hotrod[i];
	if(hp->kprocstarted == 0)
		kproc(hp->name, hotrodkproc, hp);

	c = devattach('H', spec);
	c->dev = i;
	c->qid = CHDIR;


@@ 113,6 133,17 @@ hotrodstat(Chan *c, char *dp)
Chan*
hotrodopen(Chan *c, int omode)
{
	Device *dp;
	Hotrod *hp;

	/*
	 *  Remind hotrod where the print buffer is.  The address we store
	 *  is the address of the printbuf in VME A32 space.
	 */
	hp = &hotrod[c->dev];
	dp = hp->addr;
	dp->mem[256*1024/sizeof(ulong)] = (((ulong)&hp->pbuf) - KZERO) | (SLAVE<<28);

	if(c->qid == CHDIR){
		if(omode != OREAD)
			error(0, Eperm);


@@ 238,7 269,7 @@ hotroderrstr(Error *e, char *buf)
	rooterrstr(e, buf);
}

static void
void
hotrodintr(int vec)
{
	Hotrod *hp;


@@ 250,3 281,31 @@ hotrodintr(int vec)
		return;
	}
}

/*
 *  print hotrod processor messages on the console
 */
void
hotrodkproc(void *a)
{
	Hotrod	*hp = a;
	char	*p;

	hp->kprocstarted = 1;
	hp->pbuf.rptr = hp->pbuf.wptr = hp->pbuf.buf;
	hp->pbuf.lim = &hp->pbuf.buf[sizeof(hp->pbuf.buf)];

	for(;;){
		p = hp->pbuf.wptr;
		if(p != hp->pbuf.rptr){
			if(p > hp->pbuf.rptr){
				putstrn(hp->pbuf.rptr, p - hp->pbuf.rptr);
			} else {
				putstrn(hp->pbuf.rptr, hp->pbuf.lim - hp->pbuf.rptr);
				putstrn(hp->pbuf.buf, hp->pbuf.wptr - hp->pbuf.buf);
			}
			hp->pbuf.rptr = p;
		}
		tsleep(&(hp->r), return0, 0, 1000);
	}
}