Plan 9 from Bell Labs’s /usr/web/sources/extra/9hist/gnot/proc.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


## diffname gnot/proc.c 1990/03091
## diff -e /dev/null /n/bootesdump/1990/03091/sys/src/9/68020/proc.c
0a
#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#include	"errno.h"

struct
{
	Lock;
	ulong	pid;
}pidalloc;

struct
{
	Lock;
	Proc	*arena;
	Proc	*free;
}procalloc;

struct
{
	Lock;
	Proc	*head;
	Proc	*tail;
}runq;

char *statename[]={	/* BUG: generate automatically */
	"Dead",
	"Moribund",
	"Zombie",
	"Ready",
	"Scheding",
	"Running",
	"Queueing",
	"MMUing",
	"Exiting",
	"Inwait",
	"Wakeme",
	"Broken",
};

/*
 * Always splhi()'ed.
 */
void
schedinit(void)		/* never returns */
{
	Proc *p;

	setlabel(&m->sched);
	if(u){
		m->proc = 0;
		p = u->p;
		putkmmu(USERADDR, INVALIDPTE);	/* safety first */
		u = 0;
		if(p->state == Running)
			ready(p);
		else if(p->state == Moribund){
			p->pid = 0;
			unlock(&p->debug);
			p->upage->ref--;
			/* procalloc already locked */
			p->qnext = procalloc.free;
			procalloc.free = p;
			p->upage = 0;
			unlock(&procalloc);
			p->state = Dead;
		}
		p->mach = 0;
	}
	sched();
}

void
sched(void)
{
	Proc *p;
	ulong tlbvirt, tlbphys;
	void (*f)(ulong);

	if(u){
		splhi();
		if(setlabel(&u->p->sched)){	/* woke up */
if(u->p->mach)panic("mach non zero");
			p = u->p;
			p->state = Running;
			p->mach = m;
			m->proc = p;
			spllo();
			return;
		}
		gotolabel(&m->sched);
	}
	spllo();
	p = runproc();
	splhi();
	mapstack(p);
	gotolabel(&p->sched);
}

void
ready(Proc *p)
{
	int s;

	s = splhi();
	lock(&runq);
	p->rnext = 0;
	if(runq.tail)
		runq.tail->rnext = p;
	else
		runq.head = p;
	runq.tail = p;
	p->state = Ready;
	unlock(&runq);
	splx(s);
}

/*
 * Always called spllo
 */
Proc*
runproc(void)
{
	Proc *p;

loop:
	do; while(runq.head == 0);
	splhi();
	lock(&runq);
	p = runq.head;
	if(p==0 || p->mach){	/* p->mach==0 only when process state is saved */
		unlock(&runq);
		spllo();
		goto loop;
	}
	if(p->rnext == 0)
		runq.tail = 0;
	runq.head = p->rnext;
	if(p->state != Ready)
		print("runproc %s %d %s\n", p->text, p->pid, statename[p->state]);
	unlock(&runq);
	p->state = Scheding;
	spllo();
	return p;
}

Proc*
newproc(void)
{
	Proc *p;

loop:
	lock(&procalloc);
	if(p = procalloc.free){		/* assign = */
		procalloc.free = p->qnext;
		p->state = Zombie;
		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;
		memset(p->pidonmach, 0, sizeof p->pidonmach);
		memset(p->seg, 0, sizeof p->seg);
		lock(&pidalloc);
		p->pid = ++pidalloc.pid;
		unlock(&pidalloc);
		if(p->pid == 0)
			panic("pidalloc");
		return p;
	}
	unlock(&procalloc);
	print("no procs\n");
	if(u == 0)
		panic("newproc");
	alarm(1000, wakeme, u->p);
	sched();
	goto loop;
}

void
procinit0(void)		/* bad planning - clashes with devproc.c */
{
	Proc *p;
	int i;

	procalloc.free = ialloc(conf.nproc*sizeof(Proc), 0);
	procalloc.arena = procalloc.free;

	p = procalloc.free;
	for(i=0; i<conf.nproc-1; i++,p++){
		lock(p);	/* allocate now, not during wakeup */
		unlock(p);
		p->qnext = p+1;
	}
	p->qnext = 0;
}

void
sleep1(Rendez *r, int (*f)(void*), void *arg)
{
	Proc *p;
	int s;

	/*
	 * spl is to allow lock to be called
	 * at interrupt time. lock is mutual exclusion
	 */
	s = splhi();
	lock(r);

	/*
	 * if condition happened, never mind
	 */
	if((*f)(arg)){	
		unlock(r);
		splx(s);
		return;
	}

	/*
	 * now we are committed to
	 * change state and call scheduler
	 */
	p = u->p;
	if(r->p)
		print("double sleep %d %d\n", r->p->pid, p->pid);
	p->r = r;
	p->wokeup = 0;
	p->state = Wakeme;
	r->p = p;
	unlock(r);
}

void
sleep(Rendez *r, int (*f)(void*), void *arg)
{
	sleep1(r, f, arg);
	sched();
	if(u->p->wokeup){
		u->p->wokeup = 0;
		error(0, Eintr);
	}
}

void
tsleep(Rendez *r, int (*f)(void*), void *arg, int ms)
{
	Alarm *a;

	sleep1(r, f, arg);
	a = alarm(ms, twakeme, r);
	sched();
	cancel(a);
	if(u->p->wokeup){
		u->p->wokeup = 0;
		error(0, Eintr);
	}
}

void
wakeup(Rendez *r)
{
	Proc *p;
	int s;

	s = splhi();
	lock(r);
	p = r->p;
	if(p){
		r->p = 0;
		if(p->state != Wakeme)
			panic("wakeup: not Wakeme");
		p->r = 0;
		ready(p);
	}
	unlock(r);
	splx(s);
}

void
wakeme(Alarm *a)
{
	ready((Proc*)(a->arg));
	cancel(a);
}

void
twakeme(Alarm *a)
{
	wakeup((Rendez*)(a->arg));
}

int
postnote(Proc *p, int dolock, char *n, int flag)
{
	User *up;
	int s;
	Rendez *r;

	if(dolock)
		lock(&p->debug);
	up = (User*)(p->upage->pa|KZERO);
	if(flag!=NUser && (up->notify==0 || up->notified))
		up->nnote = 0;	/* force user's hand */
	else if(up->nnote == NNOTE-1)
		return 0;
	strcpy(up->note[up->nnote].msg, n);
	up->note[up->nnote++].flag = flag;
	if(dolock)
		unlock(&p->debug);
	if(r = p->r){	/* assign = */
		/* wake up */
		s = splhi();
		lock(r);
		if(p->r==r && r->p==p){
			r->p = 0;
			if(p->state != Wakeme)
				panic("postnote wakeup: not Wakeme");
			p->wokeup = 1;
			p->r = 0;
			ready(p);
		}
		unlock(r);
		splx(s);
	}
	return 1;
}

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

	c = u->p;
	mypid = c->pid;
	if(s)
		strcpy(status, s);
	else
		status[0] = 0;
	if(freemem){
		freesegs(-1);
		closepgrp(c->pgrp);
		close(u->dot);
	}
	for(n=0; n<=u->maxfd; n++)
		if(ch = u->fd[n])	/* assign = */
			close(ch);
	/*
	 * Any of my children exiting?
	 */
	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(&c->wait.queue);
			pwait(0);
		}
	}

	c->time[TReal] = MACHP(0)->ticks - c->time[TReal];
	/*
	 * Tell my parent
	 */
	p = c->parent;
	if(p == 0)
		goto out;
	qlock(&p->wait);
	lock(&p->wait.queue);
	if(p->pid==c->parentpid && !p->exiting){
		w.pid = mypid;
		strcpy(w.msg, status);
		wp = &w.time[TUser];
		up = &c->time[TUser];
		ucp = &c->time[TCUser];
		*wp++ = (*up++ + *ucp++)*MS2HZ;
		*wp++ = (*up++ + *ucp  )*MS2HZ;
		*wp   = (*up           )*MS2HZ;
		p->child = c;
		/*
		 * Pass info through back door, to avoid huge Proc's
		 */
		p->waitmsg = (Waitmsg*)(c->upage->pa|(((ulong)&w)&(BY2PG-1))|KZERO);
		c->state = Exiting;
		if(p->state == Inwait)
			ready(p);
		unlock(&p->wait.queue);
		sched();
	}else{
		unlock(&p->wait.queue);
		qunlock(&p->wait);
	}
   out:
	if(!freemem){
		c->state = Broken;
		sched();		/* until someone lets us go */
		freesegs(-1);
		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(&c->debug);	/* sched() can't do this */
	c->state = Moribund;
	sched();	/* never returns */
}

ulong
pwait(Waitmsg *w)
{
	Proc *c, *p;
	ulong cpid;

	p = u->p;
again:
	while(canlock(&p->wait.use)){
		if(p->nchild == 0){
			qunlock(&p->wait);
			error(0, Enochild);
		}
		p->state = Inwait;
		qunlock(&p->wait);
		sched();
	}
	lock(&p->wait.queue);	/* wait until child is finished */
	c = p->child;
	if(c == 0){
		print("pwait %d\n", p->pid);
		p->state = Inwait;
		unlock(&p->wait.queue);
		sched();
		goto again;
	}
	p->child = 0;
	if(w)
		*w = *p->waitmsg;
	cpid = p->waitmsg->pid;
	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--;
	unlock(&p->wait.queue);
	qunlock(&p->wait);
	ready(c);
	return cpid;
}

Proc*
proctab(int i)
{
	return &procalloc.arena[i];
}

#include <ureg.h>
DEBUG()
{
	int i;
	Proc *p;

	print("DEBUG\n");
	for(i=0; i<conf.nproc; i++){
		p = procalloc.arena+i;
		if(p->state != Dead)
			print("%d:%s upc %lux %s ut %ld st %ld\n",
				p->pid, p->text, p->pc, statename[p->state],
				p->time[0], p->time[1]);
	}
}
.
## diffname gnot/proc.c 1990/0310
## diff -e /n/bootesdump/1990/03091/sys/src/9/68020/proc.c /n/bootesdump/1990/0310/sys/src/9/68020/proc.c
200d
196,198c
	for(i=0; i<conf.nproc-1; i++,p++)
.
## diffname gnot/proc.c 1990/0312
## diff -e /n/bootesdump/1990/0310/sys/src/9/68020/proc.c /n/bootesdump/1990/0312/sys/src/9/68020/proc.c
524a
}

void
kproc(char *name, void (*func)(void *), void *arg)
{
	Proc *p;
	int n;
	ulong upa;
	int lastvar;	/* used to compute stack address */
	User *up;

	/*
	 * Kernel stack
	 */
	p = newproc();
	p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF));
	upa = p->upage->pa|KZERO;
	up = (User *)upa;

	/*
	 * Save time: only copy u-> data and useful stack
	 */
	memcpy((void*)upa, u, sizeof(User));
	n = USERADDR+BY2PG - (ulong)&lastvar;
	n = (n+32) & ~(BY2WD-1);	/* be safe & word align */
	memcpy((void*)(upa+BY2PG-n), (void*)((u->p->upage->pa|KZERO)+BY2PG-n), n);
	((User *)upa)->p = p;

	/*
	 * Refs
	 */
	incref(up->dot);
	for(n=0; n<=up->maxfd; n++)
		up->fd[n] = 0;
	up->maxfd = 0;

	/*
	 * Sched
	 */
	if(setlabel(&p->sched)){
		u->p = p;
		p->state = Running;
		p->mach = m;
		m->proc = p;
		spllo();
		strncpy(p->text, name, sizeof p->text);
		(*func)(arg);
		pexit(0, 1);
	}
	p->pgrp = u->p->pgrp;
	incref(p->pgrp);
	p->nchild = 0;
	p->parent = 0;
	memset(p->time, 0, sizeof(p->time));
	p->time[TReal] = MACHP(0)->ticks;
	ready(p);
	flushmmu();
.
174a
print("allocate process %d\n", p->pid);
DEBUG();
.
## diffname gnot/proc.c 1990/0315
## diff -e /n/bootesdump/1990/0312/sys/src/9/68020/proc.c /n/bootesdump/1990/0315/sys/src/9/68020/proc.c
175,176d
## diffname gnot/proc.c 1990/0321
## diff -e /n/bootesdump/1990/0315/sys/src/9/68020/proc.c /n/bootesdump/1990/0321/sys/src/9/68020/proc.c
119a
void
checksched(void)		/* just for efficiency; don't sched if no need */
{
	if(runq.head)
		sched();
}

.
## diffname gnot/proc.c 1990/0509
## diff -e /n/bootesdump/1990/0321/sys/src/9/68020/proc.c /n/bootesdump/1990/0509/sys/src/9/68020/proc.c
415a
		lock(&broken);
		for(b=0; b<NBROKEN; b++)
			if(broken.p[b] == c){
				broken.n--;
				memcpy(&broken.p[b], &broken.p[b+1], sizeof(Proc*)*(NBROKEN-(b+1)));
				break;
			}
		unlock(&broken);
.
413a
		/*
		 * weird thing: keep at most NBROKEN around
		 */
		#define	NBROKEN 4
		static struct{
			Lock;
			int	n;
			Proc	*p[NBROKEN];
		}broken;
		int b;

		lock(&broken);
		if(broken.n == NBROKEN){
			ready(broken.p[0]);
			memcpy(&broken.p[0], &broken.p[1], sizeof(Proc*)*(NBROKEN-1));
			--broken.n;
		}
		broken.p[broken.n++] = c;
		unlock(&broken);
.
## diffname gnot/proc.c 1990/05313
## diff -e /n/bootesdump/1990/0509/sys/src/9/68020/proc.c /n/bootesdump/1990/05313/sys/src/9/68020/proc.c
557c
				p->time[0], p->time[1], p->qlock);
.
555c
			print("%d:%s upc %lux %s ut %ld st %ld %lux\n",
.
519d
175d
## diffname gnot/proc.c 1990/06021
## diff -e /n/bootesdump/1990/05313/sys/src/9/68020/proc.c /n/bootesdump/1990/06021/sys/src/9/68020/proc.c
591a
	kunmap(k);
.
582,583c
	memcpy((void*)(upa+BY2PG-n), (void*)(USERADDR+BY2PG-n), n);
.
579c
	memcpy(up, u, sizeof(User));
.
573,574c
	k = kmap(p->upage);
	upa = k->va;
	up = (User*)upa;
	up->p = p;
.
566a
	KMap *k;
.
525,526c
		*w = *(Waitmsg*)(p->waitmsg|k->va);
	cpid = ((Waitmsg*)(p->waitmsg|k->va))->pid;
	kunmap(k);
.
523a
	k = kmap(c->upage);
.
501a
	KMap *k;
.
401c
		p->waitmsg = (((ulong)&w)&(BY2PG-1));
.
317a
	kunmap(k);
.
315a
	}
.
314c
	else if(up->nnote == NNOTE-1){
		kunmap(k);
.
311c
	k = kmap(p->upage);
	up = (User*)k->va;
.
305a
	KMap *k;
.
## diffname gnot/proc.c 1990/06111
## diff -e /n/bootesdump/1990/06021/sys/src/9/68020/proc.c /n/bootesdump/1990/06111/sys/src/9/68020/proc.c
399,401c
		*wp++ = TK2MS(*up++ + *ucp++);
		*wp++ = TK2MS(*up++ + *ucp  );
		*wp   = TK2MS(*up           );
.
## diffname gnot/proc.c 1990/0614
## diff -e /n/bootesdump/1990/06111/sys/src/9/68020/proc.c /n/bootesdump/1990/0614/sys/src/9/68020/proc.c
583c
	upa = VA(k);
.
532,533c
		*w = *(Waitmsg*)(p->waitmsg|VA(k));
	cpid = ((Waitmsg*)(p->waitmsg|VA(k)))->pid;
.
313c
	up = (User*)VA(k);
.
## diffname gnot/proc.c 1990/0619
## diff -e /n/bootesdump/1990/0614/sys/src/9/68020/proc.c /n/bootesdump/1990/0619/sys/src/9/68020/proc.c
186a
	u->p->state = Wakeme;
.
## diffname gnot/proc.c 1990/0629
## diff -e /n/bootesdump/1990/0619/sys/src/9/68020/proc.c /n/bootesdump/1990/0629/sys/src/9/68020/proc.c
564c
				p->time[0], p->time[1], p->qlock, p->r);
.
562c
			print("%d:%s upc %lux %s ut %ld st %ld q %lux r %lux\n",
.
## diffname gnot/proc.c 1990/0705
## diff -e /n/bootesdump/1990/0629/sys/src/9/68020/proc.c /n/bootesdump/1990/0705/sys/src/9/68020/proc.c
513c
	while(canqlock(&p->wait)){
.
## diffname gnot/proc.c 1990/0722
## diff -e /n/bootesdump/1990/0705/sys/src/9/68020/proc.c /n/bootesdump/1990/0722/sys/src/9/68020/proc.c
174a
		p->fpstate = FPinit;
.
## diffname gnot/proc.c 1990/0725
## diff -e /n/bootesdump/1990/0722/sys/src/9/68020/proc.c /n/bootesdump/1990/0725/sys/src/9/68020/proc.c
619,620c
	if(kpgrp == 0){
		kpgrp = newpgrp();
		strcpy(kpgrp->user, "bootes");
	}
	p->pgrp = kpgrp;
	incref(kpgrp);
	sprint(p->text, "%s.%.6s", name, u->p->pgrp->user);
.
615d
577a
	static Pgrp *kpgrp;
.
## diffname gnot/proc.c 1990/0726
## diff -e /n/bootesdump/1990/0725/sys/src/9/68020/proc.c /n/bootesdump/1990/0726/sys/src/9/68020/proc.c
619,625c
	p->pgrp = u->p->pgrp;
	incref(p->pgrp);
.
615a
		strncpy(p->text, name, sizeof p->text);
.
578d
## diffname gnot/proc.c 1990/0728
## diff -e /n/bootesdump/1990/0726/sys/src/9/68020/proc.c /n/bootesdump/1990/0728/sys/src/9/68020/proc.c
619,620c
	if(kpgrp == 0){
		kpgrp = newpgrp();
		strcpy(kpgrp->user, "bootes");
	}
	p->pgrp = kpgrp;
	incref(kpgrp);
	sprint(p->text, "%s.%.6s", name, u->p->pgrp->user);
.
615d
577a
	static Pgrp *kpgrp;
.
## diffname gnot/proc.c 1990/08163
## diff -e /n/bootesdump/1990/0728/sys/src/9/68020/proc.c /n/bootesdump/1990/08163/sys/src/9/68020/proc.c
89a
			if(p->fpstate != m->fpstate){
				if(p->fpstate == FPinit){
					u->p->fpstate = FPinit;
					fprestore((FPsave*)&fpnull);
					m->fpstate = FPinit;
				}else{
					fpregrestore(u->fpsave.reg);
					fprestore(&u->fpsave);
					m->fpstate = FPdirty;
				}
			}
.
83a
		fpsave(&u->fpsave);
		if(u->fpsave.type){
			fpregsave(u->fpsave.reg);
			u->p->fpstate = FPactive;
			m->fpstate = FPdirty;
		}
.
80a
	long fpnull = 0;
.
## diffname gnot/proc.c 1990/0902
## diff -e /n/bootesdump/1990/08163/sys/src/9/68020/proc.c /n/bootesdump/1990/0902/sys/src/9/68020/proc.c
107a
			if(balu.cr0 != 0xFFFFFFFF)	/* balu busy */
				memcpy(BALU, &balu, sizeof balu);
.
90a
		if(BALU->cr0 != 0xFFFFFFFF)	/* balu busy */
			memcpy(&balu, BALU, sizeof balu);
		else{
			balu.cr0 = 0xFFFFFFFF;
			BALU->cr0 = 0xFFFFFFFF;
		}
.
84a

.
81a
	Balu balu;
.
7a
#include	<balu.h>

.
## diffname gnot/proc.c 1990/0905
## diff -e /n/bootesdump/1990/0902/sys/src/9/68020/proc.c /n/bootesdump/1990/0905/sys/src/9/68020/proc.c
110c
					fprestore(&initfp);
.
90a
			if(u->fpsave.size > sizeof u->fpsave.junk)
				panic("fpsize %d max %d\n", u->fpsave.size, sizeof u->fpsave.junk);
.
82,83d
8c
#include	<gnot.h>
.
## diffname gnot/proc.c 1990/0914
## diff -e /n/bootesdump/1990/0905/sys/src/9/68020/proc.c /n/bootesdump/1990/0914/sys/src/9/68020/proc.c
7a
#include	<libg.h>
.
## diffname gnot/proc.c 1990/0921
## diff -e /n/bootesdump/1990/0914/sys/src/9/68020/proc.c /n/bootesdump/1990/0921/sys/src/9/68020/proc.c
623a
	clearmmucache();
.
## diffname gnot/proc.c 1990/0928
## diff -e /n/bootesdump/1990/0921/sys/src/9/68020/proc.c /n/bootesdump/1990/0928/sys/src/9/68020/proc.c
624d
## diffname gnot/proc.c 1990/1004
## diff -e /n/bootesdump/1990/0928/sys/src/9/68020/proc.c /n/bootesdump/1990/1004/sys/src/9/68020/proc.c
642,646c
		restore();
.
635a
	up->p = p;
.
623a
	clearmmucache();
.
619d
614a
	p->kp = 1;
.
585c
void
DEBUG(void)
.
532a

	/*
	 * Call the scheduler.  This process gets cleaned up in restore() by the next
	 * process that runs.  That means that if there is no other process, we'll
	 * hang around for a little while.
	 */
.
206a
		p->kp = 0;
.
162,187d
151,160d
137a
	if (p->spin) {
		p->state = Running;
		return;
	}
.
127,130c

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

	/*
	 * Complete restoring the process.
	 */
	restore();
.
125a
	p->spin = 0;

	/*
	 * The first process on the run queue is the process we are going to run.  First
	 * save our state before we jump to schedinit.  If this process was running, put
	 * it on the run queue.
	 */
	if (p->state == Running) {
		p->state = Ready;
		p->rnext = 0;
		runq.tail->rnext = p;
		runq.tail = p;
	}

	/*
	 * Save some process state (if we haven't done that already) and save/restore
	 * pc and sp.  We have to jump to schedinit() because we are going to remap the
	 * stack.
	 */
	if (!saved)
		save(&balu);
	if (setlabel(&p->sched) == 0)
		gotolabel(&m->sched);

	/*
	 * Interrupts are ok now.  Note that the process state is still not Running,
	 * so no rescheduling.
	 */
.
119,124c
	
		/*
		 * Disable clock interrupts so that there will be no rescheduling in this
		 * section (on this machine).  If there is still a process on the run
		 * queue, break out of this loop.
		 */
		splhi();
		lock(&runq);
		if (runq.head != 0)
			break;
		unlock(&runq);
.
88,117c
	/*
	 * Look for a new process to be run.
	 */
	for (;;) {
		spllo();

		/*
		 * Idle loop.  Return when this process becomes runnable.  If nothing else
		 * to do, start saving some of the process state.
		 */
		while (runq.head == 0)
			if (p->state == Running)
				return;
			else if (!saved) {
				save(&balu);
				saved = 1;
.
85,86c
	/*
	 * Record that the process is spinning instead of blocked.  Ready() uses this
	 * information to decide what to do with the process.
	 */
	p->spin = 1;
.
83a
	int saved = 0;
.
81,82c
	Proc *p = u->p;
	long initfp;
.
78a
save(Balu *balu)
{
	fpsave(&u->fpsave);
	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 */
		memcpy(balu, BALU, sizeof *balu);
	else {
		balu->cr0 = 0xFFFFFFFF;
		BALU->cr0 = 0xFFFFFFFF;
	}
}

/*
 * Reschedule the process.  We do not know whether the interrupt level is low or high
 * here, but we set it to low in any case.  If there is no other process to run, and
 * this process is Running, return immediately.  If this process is blocked, and there
 * is no other process to run, keep spinning until either this process or another
 * process becomes runnable.  If it was this process, we can return immediately.
 */
void
.
77a
/*
 * Save part of the process state.  Note: this is not the counterpart of restore().
 */
.
75d
55,73c

	/*
	 * Take a process from the run queue.  The run queue is locked here, and guaranteed
	 * to have a process on it.
	 */
	p = runq.head;
	if ((runq.head = p->rnext) == 0)
		runq.tail = 0;
	unlock(&runq);

	/*
	 * Ok, here we go.  We have a process and we can start running.
	 */
	mapstack(p);
	gotolabel(&p->sched);
}

/*
 * Complete the restoring of a process after mapstack().  The interrupt level here is low.
 * However, since the process is not Running, it cannot be rescheduled at this point.  We
 * set the process state to Running.  If the previous process was dead, clean it up.
 */
void
restore(void)
{
	Proc *p = m->proc;	/* previous process */

	u->p->mach = m;
	m->proc = u->p;
	u->p->state = Running;
	if (p->state == Moribund) {
		p->pid = 0;
		unlock(&p->debug);		/* set in pexit */
		p->upage->ref--;
		p->upage = 0;
		p->qnext = procalloc.free;
		procalloc.free = p;
		unlock(&procalloc);		/* set in pexit */
		p->state = Dead;
.
53a
	/*
	 * At init time:  wait for a process on the run queue.
	 */
	for (;;) {
		spllo();
		while (runq.head == 0)
			/* idle loop */;
		splhi();
		lock(&runq);
		if (runq.head != 0)
			break;
		unlock(&runq);
	}

	/*
	 * Set the u pointer and leave it there.  In fact, it might as well be a define.
	 */
	u = (User *) USERADDR;

	/*
	 * For later rescheduling.  Jumped to by sched() on stack switch.
	 */
.
47c
 * Called as the last routine in main().  Wait for a process on the run queue, grab it,
 * and run it.  Note that in this routine the interrupts are enabled for the first time.
.
45a
int page_alloc(int);	/* !ORIG */
void page_free(int, int);

.
## diffname gnot/proc.c 1990/1104
## diff -e /n/bootesdump/1990/1004/sys/src/9/68020/proc.c /n/bootesdump/1990/1104/sys/src/9/68020/proc.c
751a
	return p;
.
739,744c
	if(func){
		if(kpgrp == 0){
			kpgrp = newpgrp();
			strcpy(kpgrp->user, "bootes");
		}
		p->pgrp = kpgrp;
	} else
		p->pgrp = u->p->pgrp;
	incref(p->pgrp);
.
736,737c
		if(func){
			(*func)(arg);
			pexit(0, 1);
		} else
			return 0;
.
691c
/*
 *  create a kernel process.  if func is nonzero put the process in the kernel
 *  process group, have it call func, and exit.
 *
 *  otherwise, the new process stays in the same process group and returns.
 */
Proc *
.
## diffname gnot/proc.c 1990/1106
## diff -e /n/bootesdump/1990/1104/sys/src/9/68020/proc.c /n/bootesdump/1990/1106/sys/src/9/68020/proc.c
257d
254a
		splx(s);
.
253c
	s = splhi();
	if(p->spin){
.
239c
	if(balu.cr0 != 0xFFFFFFFF)	/* balu busy */
.
234c
		else{
.
228,229c
	if(p->fpstate != m->fpstate)
		if(p->fpstate == FPinit){
.
216c
	if(setlabel(&p->sched) == 0)
.
214c
	if(!saved)
.
202c
	if(p->state == Running){
.
191c
		if(runq.head != 0)
.
179c
			else if(!saved){
.
177c
			if(p->state == Running)
.
169c
	for (;;){
.
139c
	else{
.
137c
	if(BALU->cr0 != 0xFFFFFFFF)	/* balu busy */
.
130c
	if(u->fpsave.type){
.
111c
	if(p->state == Moribund){
.
87c
	if((runq.head = p->rnext) == 0)
.
67c
		if(runq.head != 0)
.
61c
	for(;;){
.
## diffname gnot/proc.c 1990/11062
## diff -e /n/bootesdump/1990/1106/sys/src/9/68020/proc.c /n/bootesdump/1990/11062/sys/src/9/68020/proc.c
138c
		memcpy(balu, BALU, sizeof(Balu));
.
## diffname gnot/proc.c 1990/1110
## diff -e /n/bootesdump/1990/11062/sys/src/9/68020/proc.c /n/bootesdump/1990/1110/sys/src/9/68020/proc.c
733,734c
		if(func)
			up->fd[n] = 0;
		else if(c = u->fd[n])		/* assign = */
			incref(c);
	if(!func)
		up->maxfd = 0;
.
701a
	Chan *c;
.
## diffname gnot/proc.c 1990/11211
## diff -e /n/bootesdump/1990/1110/sys/src/9/68020/proc.c /n/bootesdump/1990/11211/sys/src/9/68020/proc.c
639c
			error(Enochild);
.
383c
		error(Eintr);
.
368c
		error(Eintr);
.
## diffname gnot/proc.c 1990/1124
## diff -e /n/bootesdump/1990/11211/sys/src/9/68020/proc.c /n/bootesdump/1990/1124/sys/src/9/68020/proc.c
613d
570,611d
353c
		print("double sleep %lux %d %d\n", r, r->p->pid, p->pid);
.
284,286d
## diffname gnot/proc.c 1990/1211 # deleted
## diff -e /n/bootesdump/1990/1124/sys/src/9/68020/proc.c /n/bootesdump/1990/1211/sys/src/9/68020/proc.c
1,725d

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.