plan 9 kernel history: overview | file list | diff list

1991/0926/port/proc.c (diff list | history)

1991/0919/sys/src/9/port/proc.c:18,231991/0926/sys/src/9/port/proc.c:18,29 (short | long | prev | next)
Remove Zombie, MMUing, Exiting, Inwait states.
rsc Mon Mar 20 17:14:17 2006
1990/0227    
	Proc	*free; 
}procalloc; 
 
1991/0926    
struct 
{ 
	Lock; 
	Waitq	*free; 
}waitqalloc; 
 
1991/0420    
typedef struct 
1990/0227    
{ 
	Lock; 
1991/0919/sys/src/9/port/proc.c:30,431991/0926/sys/src/9/port/proc.c:36,45
1990/0227    
char *statename[]={	/* BUG: generate automatically */ 
	"Dead", 
	"Moribund", 
	"Zombie", 
	"Ready", 
	"Scheding", 
	"Running", 
	"Queueing", 
	"MMUing", 
	"Exiting", 
	"Inwait", 
	"Wakeme", 
	"Broken", 
1991/0705    
	"Stopped", 
1991/0919/sys/src/9/port/proc.c:227,2391991/0926/sys/src/9/port/proc.c:229,242
1990/0227    
	lock(&procalloc); 
	if(p = procalloc.free){		/* assign = */ 
		procalloc.free = p->qnext; 
		p->state = Zombie; 
1991/0926    
		p->state = Scheding; 
		p->psstate = "New"; 
1990/0227    
		unlock(&procalloc); 
		p->mach = 0; 
		p->qnext = 0; 
		p->nchild = 0; 
		p->child = 0; 
		p->exiting = 0; 
1991/0926    
		p->nwait = 0; 
		p->waitq = 0; 
1991/0317    
		p->pgrp = 0; 
1991/0705    
		p->egrp = 0; 
		p->fgrp = 0; 
1991/0919/sys/src/9/port/proc.c:492,4971991/0926/sys/src/9/port/proc.c:495,501
1990/1101    
	broken.p[broken.n++] = c; 
	unlock(&broken); 
	c->state = Broken; 
1991/0926    
	c->psstate = 0; 
1990/1101    
	sched();		/* until someone lets us go */ 
	lock(&broken); 
	for(b=0; b<NBROKEN; b++) 
1991/0919/sys/src/9/port/proc.c:520,6191991/0926/sys/src/9/port/proc.c:524,596
1990/1101    
void 
1991/0717    
pexit(char *exitstr, int freemem) 
1990/0227    
{ 
	ulong mypid; 
1990/03081    
	Proc *p, *c, *k, *l; 
1991/0705    
	int n, i; 
1990/03081    
	Chan *ch; 
1991/0110    
	char msg[ERRLEN]; 
1990/0227    
	ulong *up, *ucp, *wp; 
1991/0926    
	Proc *p, *c; 
1991/0717    
	Segment **s, **es, *os; 
1991/0926    
	Waitq *wq, *f, *next; 
1990/0227    
 
1991/0717    
	if(exitstr) 			/* squirrel away before we lose our address space */ 
		strcpy(msg, exitstr); 
1991/0110    
	else 
		msg[0] = 0; 
1991/0705    
	                 
1990/03081    
	c = u->p; 
1991/0513    
	c->alarm = 0; 
1990/03081    
	mypid = c->pid; 
1991/0517    
 
1991/0712    
	if(c->fgrp) 
		closefgrp(c->fgrp); 
1991/0517    
 
1990/0227    
	if(freemem){ 
1991/0705    
		flushvirt(); 
1991/0717    
		es = &c->seg[NSEG]; 
		for(s = c->seg; s < es; s++) 
			if(os = *s) { 
				*s = 0; 
				putseg(os); 
			} 
1990/03081    
		closepgrp(c->pgrp); 
1991/0712    
		if(c->egrp) 
			closeegrp(c->egrp); 
1990/0227    
		close(u->dot); 
	} 
	/* 
	 * Any of my children exiting? 
	 */ 
1990/03081    
	while(c->nchild){ 
1990/0324    
		lock(&c->wait.queue); 
		if(canlock(&c->wait.use)){	/* no child is exiting */ 
1990/03081    
			c->exiting = 1; 
1990/0324    
			unlock(&c->wait.use); 
			unlock(&c->wait.queue); 
1990/0227    
			break; 
		}else{				/* must wait for child */ 
1990/0324    
			unlock(&c->wait.queue); 
1990/0227    
			pwait(0); 
		} 
	} 
1991/0926    
	wq = newwaitq(); 
	wq->w.pid = c->pid; 
	wq->w.time[TUser] = TK2MS(c->time[TUser]); 
	wq->w.time[TCUser] = TK2MS(c->time[TCUser]); 
	wq->w.time[TSys] = TK2MS(c->time[TSys]); 
	wq->w.time[TCSys] = TK2MS(c->time[TCSys]); 
	wq->w.time[TReal] = TK2MS(MACHP(0)->ticks - c->time[TReal]); 
	if(exitstr) 
		strncpy(wq->w.msg, exitstr, ERRLEN); 
	else 
		wq->w.msg[0] = '\0'; 
1990/0227    
 
1990/03081    
	c->time[TReal] = MACHP(0)->ticks - c->time[TReal]; 
1990/0227    
	/* 
	 * Tell my parent 
	 */ 
1991/0926    
	/* Find my parent */ 
1990/03081    
	p = c->parent; 
1990/0227    
	if(p == 0) 
		goto out; 
	qlock(&p->wait); 
1990/0324    
	lock(&p->wait.queue); 
1990/03081    
	if(p->pid==c->parentpid && !p->exiting){ 
1991/0318    
		memmove(p->waitmsg.msg, msg, ERRLEN); 
1991/0109    
		p->waitmsg.pid = mypid; 
		wp = &p->waitmsg.time[TUser]; 
1990/03081    
		up = &c->time[TUser]; 
		ucp = &c->time[TCUser]; 
1990/0614    
		*wp++ = TK2MS(*up++ + *ucp++); 
		*wp++ = TK2MS(*up++ + *ucp  ); 
		*wp   = TK2MS(*up           ); 
1990/03081    
		p->child = c; 
		c->state = Exiting; 
1990/0227    
		if(p->state == Inwait) 
			ready(p); 
1990/0324    
		unlock(&p->wait.queue); 
1990/0227    
		sched(); 
	}else{ 
1990/0324    
		unlock(&p->wait.queue); 
1990/0227    
		qunlock(&p->wait); 
1991/0926    
 
	lock(&p->exl); 
	/* My parent still alive */ 
	if(p->pid == c->parentpid && p->state != Broken && p->nwait < 128) {	 
		p->nchild--; 
		p->time[TCUser] += c->time[TUser] + c->time[TCUser]; 
		p->time[TCSys] += c->time[TSys] + c->time[TCSys]; 
 
		wq->next = p->waitq; 
		p->waitq = wq; 
		p->nwait++; 
		unlock(&p->exl); 
 
		wakeup(&p->waitr); 
1990/0227    
	} 
   out: 
	if(!freemem){ 
1990/1101    
		addbroken(c); 
1991/0705    
		flushvirt(); 
1991/0717    
		es = &c->seg[NSEG]; 
		for(s = c->seg; s < es; s++) 
			if(os = *s) { 
				*s = 0; 
				putseg(os); 
			} 
1990/03081    
		closepgrp(c->pgrp); 
1991/0705    
		closeegrp(c->egrp); 
1990/0227    
		close(u->dot); 
1991/0926    
	else { 
		unlock(&p->exl); 
		freewaitq(wq); 
1990/0227    
	} 
1990/03081    
 
    done: 
1991/0926    
	if(!freemem) 
		addbroken(c); 
1990/03081    
 
1991/0926    
	flushvirt(); 
	es = &c->seg[NSEG]; 
	for(s = c->seg; s < es; s++) 
		if(os = *s) { 
			*s = 0; 
			putseg(os); 
		} 
	closepgrp(c->pgrp); 
	closeegrp(c->egrp); 
	close(u->dot); 
 
	lock(&c->exl);		/* Prevent my children from leaving waits */ 
	c->pid = 0; 
	unlock(&c->exl); 
 
	for(f = c->waitq; f; f = next) { 
		next = f->next; 
		freewaitq(f); 
	} 
 
1991/0705    
	/* 
	 * sched() cannot wait on these locks 
	 */ 
1991/0919/sys/src/9/port/proc.c:626,6711991/0926/sys/src/9/port/proc.c:603,648
1991/0705    
	panic("pexit"); 
1990/0227    
} 
 
1991/0926    
int 
haswaitq(void *x) 
{ 
	Proc *p; 
 
	p = (Proc *)x; 
	return p->waitq != 0; 
} 
 
1990/0227    
ulong 
pwait(Waitmsg *w) 
{ 
	Proc *c, *p; 
1991/0926    
	Proc *p; 
1990/0227    
	ulong cpid; 
1991/0926    
	Waitq *wq; 
1990/0227    
 
	p = u->p; 
again: 
1990/0324    
	while(canlock(&p->wait.use)){ 
1990/0227    
		if(p->nchild == 0){ 
			qunlock(&p->wait); 
1990/11211    
			error(Enochild); 
1990/0227    
		} 
		p->state = Inwait; 
		qunlock(&p->wait); 
		sched(); 
1991/0926    
 
	lock(&p->exl); 
	if(p->nchild == 0 && p->waitq == 0) { 
		unlock(&p->exl); 
		error(Enochild); 
1990/0227    
	} 
1990/0324    
	lock(&p->wait.queue);	/* wait until child is finished */ 
1990/0227    
	c = p->child; 
	if(c == 0){ 
		p->state = Inwait; 
1990/0324    
		unlock(&p->wait.queue); 
1990/0227    
		sched(); 
		goto again; 
	} 
	p->child = 0; 
1991/0926    
	unlock(&p->exl); 
 
	sleep(&p->waitr, haswaitq, u->p); 
 
	lock(&p->exl); 
	wq = p->waitq; 
	p->waitq = wq->next; 
	p->nwait--; 
	unlock(&p->exl); 
 
1990/0227    
	if(w) 
1991/0109    
		*w = p->waitmsg; 
	cpid = p->waitmsg.pid; 
1990/0227    
	p->time[TCUser] += c->time[TUser] + c->time[TCUser]; 
	p->time[TCSys] += c->time[TSys] + c->time[TCSys]; 
	p->time[TCReal] += c->time[TReal]; 
	p->nchild--; 
1990/0324    
	unlock(&p->wait.queue); 
1990/0227    
	qunlock(&p->wait); 
	ready(c); 
1991/0926    
		memmove(w, &wq->w, sizeof(Waitmsg)); 
	cpid = wq->w.pid; 
	freewaitq(wq); 
1990/0227    
	return cpid; 
} 
 
                 
Proc* 
proctab(int i) 
{ 
1991/0919/sys/src/9/port/proc.c:706,7111991/0926/sys/src/9/port/proc.c:683,689
1990/0227    
	 * Kernel stack 
	 */ 
	p = newproc(); 
1991/0926    
	p->psstate = 0; 
1990/1212    
	p->kp = 1; 
1990/0227    
	p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF)); 
1990/0617    
	k = kmap(p->upage); 
1991/0919/sys/src/9/port/proc.c:732,7461991/0926/sys/src/9/port/proc.c:710,715
1990/0227    
	 * Sched 
	 */ 
	if(setlabel(&p->sched)){ 
1991/0919    
		/* 
		 *  use u->p instead of p, because we 
		 *  don't trust the compiler, after a 
		 *  gotolabel, to find the correct contents 
		 *  of a local variable.  Passed parameters 
		 *  (func & arg) are a bit safer since we 
		 *  don't play with them anywhere else. 
		 */ 
		p = u->p; 
1990/0227    
		p->state = Running; 
		p->mach = m; 
		m->proc = p; 
1991/0919/sys/src/9/port/proc.c:765,7701991/0926/sys/src/9/port/proc.c:734,740
1990/0227    
	p->parent = 0; 
	memset(p->time, 0, sizeof(p->time)); 
	p->time[TReal] = MACHP(0)->ticks; 
1991/0926    
	ready(p); 
1991/0529    
	/* 
	 *  since the bss/data segments are now shareable, 
	 *  any mmu info about this process is now stale 
1991/0919/sys/src/9/port/proc.c:771,7781991/0926/sys/src/9/port/proc.c:741,746
1991/0529    
	 *  and has to be discarded. 
	 */ 
1990/0227    
	flushmmu(); 
1991/0919    
	clearmmucache(); 
	ready(p); 
1991/0705    
} 
 
void 
1991/0919/sys/src/9/port/proc.c:811,8131991/0926/sys/src/9/port/proc.c:779,815
1991/0710    
	gotolabel(&u->errlab[--u->nerrlab]); 
} 
 
1991/0926    
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); 
	} 
} 
 
void 
freewaitq(Waitq *wq) 
{ 
	lock(&waitqalloc); 
	wq->next = waitqalloc.free; 
	waitqalloc.free = wq; 
	unlock(&waitqalloc); 
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)