## 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
|