~kris/9p

9hist

1e9f8fab0a15fa6ab54455d7c64b7391ebbd4af3 — David du Colombier 36 years ago 3afa7e7
Plan 9 from Bell Labs 1990-03-09
6 files changed, 167 insertions(+), 48 deletions(-)

M port/devmnt.c
M port/devproc.c
M port/proc.c
M port/sysproc.c
M power/dat.h
M power/devbit.c
M port/devmnt.c => port/devmnt.c +34 -16
@@ 553,7 553,7 @@ mntxmit(Mnt *m, Mnthdr *mh)
{
	ulong n;
	Mntbuf *mbr, *mbw;
	Chan *mntpt;
	Chan *mntpt, *msg;
	int isbit;

	mbr = mballoc();


@@ 564,23 564,38 @@ mntxmit(Mnt *m, Mnthdr *mh)
		nexterror();
	}
	n = convS2M(&mh->thdr, mbw->buf);
	qlock(m);
	if(m->msg == 0){
		qunlock(m);
		error(0, Eshutdown);
	}
	isbit = 0;
	if(devchar[m->msg->type] == 'b')
		isbit = 1;
	if(!isbit)
		qlock(m->msg);
	/*
	 * Avoid qlock for bit, to maximize parallelism
	 */
	if(isbit){
		lock(&m->use);		/* spin rather than sleep */
		if((msg = m->msg) == 0){
			unlock(&m->use);
			error(0, Eshutdown);
		}
		incref(msg);
		unlock(&m->use);
	}else{
		qlock(m);
		if((msg = m->msg) == 0){
			qunlock(m);
			error(0, Eshutdown);
		}
		qlock(msg);
	}
	if(waserror()){
		qunlock(m);
		if(!isbit)
			qunlock(m->msg);
		if(isbit)
			close(msg);
		else{
			qunlock(m);
			qunlock(msg);
		}
		nexterror();
	}
	if((*devtab[m->msg->type].write)(m->msg, mbw->buf, n) != n){
	if((*devtab[msg->type].write)(msg, mbw->buf, n) != n){
		pprint("short write in mntxmit\n");
		error(0, Egreg);
	}


@@ 588,10 603,13 @@ mntxmit(Mnt *m, Mnthdr *mh)
	/*
	 * Read response
	 */
	n = (*devtab[m->msg->type].read)(m->msg, mbr->buf, BUFSIZE);
	qunlock(m);
	if(!isbit)
		qunlock(m->msg);
	n = (*devtab[msg->type].read)(msg, mbr->buf, BUFSIZE);
	if(isbit)
		close(msg);
	else{
		qunlock(m);
		qunlock(msg);
	}
	poperror();

	if(convM2S(mbr->buf, &mh->rhdr, n) == 0){

M port/devproc.c => port/devproc.c +7 -0
@@ 82,6 82,7 @@ procreset(void)
Chan*
procattach(char *spec)
{
	Chan *c;
	return devattach('p', spec);
}



@@ 110,6 111,11 @@ procopen(Chan *c, int omode)
	Orig *o;
	Chan *tc;

	if(c->qid == CHDIR){
		if(omode != OREAD)
			error(0, Eperm);
		goto done;
	}
	p = proctab(SLOT(c->qid));
	if((p->pid&PIDMASK) != PID(c->qid))
    Died:


@@ 156,6 162,7 @@ procopen(Chan *c, int omode)
	 */
	if(p->state != Dead)
		c->qid |= (p->pid&PIDMASK)<<PIDSHIFT;
   done:
	c->mode = omode;
	c->flag |= COPEN;
	c->offset = 0;

M port/proc.c => port/proc.c +75 -25
@@ 165,6 165,9 @@ loop:
		unlock(&procalloc);
		p->mach = 0;
		p->qnext = 0;
		p->kid = 0;
		p->sib = 0;
		p->pop = 0;
		p->nchild = 0;
		p->child = 0;
		p->exiting = 0;


@@ 339,65 342,66 @@ pexit(char *s, int freemem)
{
	char status[64];
	ulong mypid;
	Proc *p;
	Proc *p, *c, *k, *l;
	Waitmsg w;
	int n;
	Chan *c;
	Chan *ch;
	ulong *up, *ucp, *wp;

	mypid = u->p->pid;
	c = u->p;
	mypid = c->pid;
	if(s)
		strcpy(status, s);
	else
		status[0] = 0;
	if(freemem){
		freesegs(-1);
		closepgrp(u->p->pgrp);
		closepgrp(c->pgrp);
		close(u->dot);
	}
	for(n=0; n<=u->maxfd; n++)
		if(c = u->fd[n])	/* assign = */
			close(c);
		if(ch = u->fd[n])	/* assign = */
			close(ch);
	/*
	 * Any of my children exiting?
	 */
	while(u->p->nchild){
		lock(&u->p->wait.queue);
		if(canlock(&u->p->wait.use)){	/* no child is exiting */
			u->p->exiting = 1;
			unlock(&u->p->wait.use);
			unlock(&u->p->wait.queue);
	while(c->nchild){
		lock(&c->wait.queue);
		if(canlock(&c->wait.use)){	/* no child is exiting */
			c->exiting = 1;
			unlock(&c->wait.use);
			unlock(&c->wait.queue);
			break;
		}else{				/* must wait for child */
			unlock(&u->p->wait.queue);
			unlock(&c->wait.queue);
			pwait(0);
		}
	}

	u->p->time[TReal] = MACHP(0)->ticks - u->p->time[TReal];
	c->time[TReal] = MACHP(0)->ticks - c->time[TReal];
	/*
	 * Tell my parent
	 */
	p = u->p->parent;
	p = c->parent;
	if(p == 0)
		goto out;
	qlock(&p->wait);
	lock(&p->wait.queue);
	if(p->pid==u->p->parentpid && !p->exiting){
	if(p->pid==c->parentpid && !p->exiting){
		w.pid = mypid;
		strcpy(w.msg, status);
		wp = &w.time[TUser];
		up = &u->p->time[TUser];
		ucp = &u->p->time[TCUser];
		up = &c->time[TUser];
		ucp = &c->time[TCUser];
		*wp++ = (*up++ + *ucp++)*MS2HZ;
		*wp++ = (*up++ + *ucp  )*MS2HZ;
		*wp   = (*up           )*MS2HZ;
		p->child = u->p;
		p->child = c;
		/*
		 * Pass info through back door, to avoid huge Proc's
		 */
		p->waitmsg = (Waitmsg*)(u->p->upage->pa|(((ulong)&w)&(BY2PG-1))|KZERO);
		u->p->state = Exiting;
		p->waitmsg = (Waitmsg*)(c->upage->pa|(((ulong)&w)&(BY2PG-1))|KZERO);
		c->state = Exiting;
		if(p->state == Inwait)
			ready(p);
		unlock(&p->wait.queue);


@@ 408,15 412,61 @@ pexit(char *s, int freemem)
	}
   out:
	if(!freemem){
		u->p->state = Broken;
		c->state = Broken;
		sched();		/* until someone lets us go */
		freesegs(-1);
		closepgrp(u->p->pgrp);
		closepgrp(c->pgrp);
		close(u->dot);
	}

	/*
	 * Rearrange inheritance hierarchy
	 * 1. my children's pop is now my pop
	 */
	lock(&c->kidlock);
	p = c->pop;
	if(k = c->kid)		/* assign = */
		do{
			k->pop = p;
			k = k->sib;
		}while(k != c->kid);

	/*
	 * 2. cut me from pop's tree
	 */
	if(p == 0)	/* init process only; fix pops */
		goto done;
	lock(&p->kidlock);
	k = p->kid;
	while(k->sib != c)
		k = k->sib;
	if(k == c)
		p->kid = 0;
	else{
		if(p->kid == c)
			p->kid = c->sib;
		k->sib = c->sib;
	}

	/*
	 * 3. pass my children (pop's grandchildren) to pop
	 */
	if(k = c->kid){		/* assign = */
		if(p->kid == 0)
			p->kid = k;
		else{
			l = k->sib;
			k->sib = p->kid->sib;
			p->kid->sib = l;
		}
	}
	unlock(&p->kidlock);
    done:
	unlock(&c->kidlock);

	lock(&procalloc);	/* sched() can't do this */
	lock(&u->p->debug);	/* sched() can't do this */
	u->p->state = Moribund;
	lock(&c->debug);	/* sched() can't do this */
	c->state = Moribund;
	sched();	/* never returns */
}


M port/sysproc.c => port/sysproc.c +15 -0
@@ 105,6 105,20 @@ sysfork(ulong *arg)
		if(c = u->fd[n])	/* assign = */
			incref(c);
	/*
	 * Committed.  Link into hierarchy
	 */
	lock(&p->kidlock);
	lock(&u->p->kidlock);
	if(u->p->kid == 0){
		p->sib = p;
		u->p->kid = p;
	}else{
		p->sib = u->p->kid->sib;
		u->p->kid->sib = p;
	}
	unlock(&u->p->kidlock);
	unlock(&p->kidlock);
	/*
	 * Sched
	 */
	if(setlabel(&p->sched)){


@@ 115,6 129,7 @@ sysfork(ulong *arg)
		spllo();
		return 0;
	}
	p->pop = u->p;
	p->parent = u->p;
	p->parentpid = u->p->pid;
	p->pgrp = u->p->pgrp;

M power/dat.h => power/dat.h +5 -0
@@ 81,6 81,7 @@ struct Bitmsg
	ulong	cmd;
	ulong	addr;
	ulong	count;
	ulong	rcount;
};

#define	CHDIR	0x80000000L


@@ 301,6 302,10 @@ struct Proc
	Page	*upage;			/* BUG: should be unlinked from page list */
	Seg	seg[NSEG];
	ulong	pid;
	Lock	kidlock;		/* access to kid and sib */
	Proc	*pop;			/* some ascendant */
	Proc	*kid;			/* some descendant */
	Proc	*sib;			/* non-ascendant relatives (circular list) */
	int	nchild;
	QLock	wait;			/* exiting children to be waited for */
	Waitmsg	*waitmsg;

M power/devbit.c => power/devbit.c +31 -7
@@ 16,6 16,7 @@ static struct
}bit;

#define	BITADDR	((Bitmsg**)(KZERO+0x7C))
#define	BITHOLD	((ulong*)(KZERO+0x78))
#define	BITINTR	((char*)(UNCACHED|0x17c12001))

enum


@@ 25,23 26,27 @@ enum
	WRITE,
};

long	hold, wait, hang;

void
bitsend(Bitmsg *bp, ulong cmd, void *addr, ulong count)
{
	do wait++; while(*BITADDR);
	bp->cmd = cmd;
	bp->addr = (ulong)addr;
	bp->count = count;
	if(*BITADDR)
		panic("bitsend");
/* print("%d %lux %d ", cmd, addr, count); /**/
	*BITADDR = bp;
	wbflush();
	do hold++; while(*BITHOLD);
	*BITINTR = 0x20;
	do; while(*BITADDR);
/* print("done\n");  /**/
}

void
bitreset(void)
{
	*BITHOLD = 0;
	*BITADDR = 0;
	qlock(&bit);
	qunlock(&bit);


@@ 94,7 99,6 @@ bitopen(Chan *c, int omode)
	qlock(&bit);
	if(bit.open){
		qunlock(&bit);
print("multiple bit open\n");
		error(0, Einuse);
	}
	bitsend(bp, RESET, 0, 0);


@@ 135,6 139,7 @@ bitread(Chan *c, void *buf, long n)
	int docpy;

	bp = &((User*)(u->p->upage->pa|KZERO))->bit;
	bp->rcount = 0;
	switch(c->qid){
	case 1:
		if(n > sizeof bit.buf)


@@ 148,11 153,21 @@ bitread(Chan *c, void *buf, long n)
			docpy = 1;
		}
		qunlock(&bit);
		do
			n = bp->count;
		while(n == 0);
		do{
			n = bp->rcount;
			hang++;
		}while(n == 0);
		if(docpy)
			memcpy(buf, bit.buf, n);
if(0 && n > 512){
	int i;
	char *cp=buf;
	for(i=9; i<n; i++)
		if(cp[i] != cp[i-1]){
			print("r %d %x %x\n", i, cp[i-1], cp[i]);
			break;
		}
}
		return n;
	}
	error(0, Egreg);


@@ 169,6 184,15 @@ bitwrite(Chan *c, void *buf, long n)
	case 1:
		if(n > sizeof bit.buf)
			error(0, Egreg);
if(0 && n > 512){
	int i;
	char *cp=buf;
	for(i=15; i<n; i++)
		if(cp[i] != cp[i-1]){
			print("w %d %x %x\n", i, cp[i-1], cp[i]);
			break;
		}
}
		qlock(&bit);
		if((((ulong)buf)&(KSEGM|3)) == KSEG0)
			bitsend(bp, WRITE, buf, n);