int schedgain = 30; /* units in seconds */
int nrdy;
-Ref noteidalloc;
void updatecpu(Proc*);
int reprioritize(Proc*);
long preempts;
ulong load;
-static Ref pidalloc;
-
static struct Procalloc
{
Lock;
"Waitrelease",
};
-static void pidhash(Proc*);
-static void pidunhash(Proc*);
+static void pidfree(Proc*);
static void rebalance(void);
/*
Edf *e;
setlabel(&m->sched);
- if(up) {
- if((e = up->edf) && (e->flags & Admitted))
+ if(up != nil) {
+ if((e = up->edf) != nil && (e->flags & Admitted))
edfrecord(up);
- m->proc = 0;
+ m->proc = nil;
switch(up->state) {
case Running:
ready(up);
case Moribund:
up->state = Dead;
edfstop(up);
- if (up->edf)
+ if(up->edf != nil)
free(up->edf);
up->edf = nil;
* palloc
*/
mmurelease(up);
+ unlock(&palloc);
+
+ up->mach = nil;
+ updatecpu(up);
up->qnext = procalloc.free;
procalloc.free = up;
- unlock(&palloc);
+ /* proc is free now, make sure unlock() wont touch it */
+ up = procalloc.Lock.p = nil;
unlock(&procalloc);
- break;
+ sched();
}
up->mach = nil;
updatecpu(up);
panic("cpu%d: ilockdepth %d, last lock %#p at %#p, sched called from %#p",
m->machno,
m->ilockdepth,
- up? up->lastilock: nil,
- (up && up->lastilock)? up->lastilock->pc: 0,
+ up != nil ? up->lastilock: nil,
+ (up != nil && up->lastilock != nil) ? up->lastilock->pc: 0,
getcallerpc(&p+2));
- if(up){
+ if(up != nil) {
/*
* Delay the sched until the process gives up the locks
* it is holding. This avoids dumb lock loops.
* in the middle of taslock when a process holds a lock
* but Lock.p has not yet been initialized.
*/
- if(up->nlocks.ref)
+ if(up->nlocks)
if(up->state != Moribund)
if(up->delaysched < 20
|| palloc.Lock.p == up
gotolabel(&m->sched);
}
p = runproc();
- if(!p->edf){
+ if(p->edf == nil){
updatecpu(p);
p->priority = reprioritize(p);
}
if(p != m->readied)
m->schedticks = m->ticks + HZ/10;
- m->readied = 0;
+ m->readied = nil;
up = p;
up->state = Running;
up->mach = MACHP(m->machno);
m->proc = up;
+ //print("poolcheck sched %s\n", p->text);
+ //#include <pool.h>
+ //poolcheck(mainmem);
mmuswitch(up);
gotolabel(&up->sched);
}
int
preempted(void)
{
- if(up && up->state == Running)
+ if(up != nil && up->state == Running)
if(up->preempted == 0)
if(anyhigher())
if(!active.exiting){
int n, t, ocpu;
int D = schedgain*HZ*Scaling;
- if(p->edf)
+ if(p->edf != nil)
return;
t = MACHP(0)->ticks*Scaling + Scaling/2;
return p->basepri;
/*
- * fairshare = 1.000 * conf.nproc * 1.000/load,
+ * fairshare = 1.000 * conf.nmach * 1.000/load,
* except the decimal point is moved three places
* on both load and fairshare.
*/
pri = rq - runq;
lock(runq);
p->priority = pri;
- p->rnext = 0;
- if(rq->tail)
+ p->rnext = nil;
+ if(rq->tail != nil)
rq->tail->rnext = p;
else
rq->head = p;
* the queue may have changed before we locked runq,
* refind the target process.
*/
- l = 0;
- for(p = rq->head; p; p = p->rnext){
+ l = nil;
+ for(p = rq->head; p != nil; p = p->rnext){
if(p == tp)
break;
l = p;
/*
* p->mach==0 only when process state is saved
*/
- if(p == 0 || p->mach){
+ if(p == nil || p->mach != nil){
unlock(runq);
return nil;
}
- if(p->rnext == 0)
+ if(p->rnext == nil)
rq->tail = l;
- if(l)
+ if(l != nil)
l->rnext = p->rnext;
else
rq->head = p->rnext;
Schedq *rq;
void (*pt)(Proc*, int, vlong);
+ if(p->state == Ready){
+ print("double ready %s %lud pc %p\n", p->text, p->pid, getcallerpc(&p));
+ return;
+ }
+
s = splhi();
if(edfready(p)){
splx(s);
return;
}
- if(up != p)
+ if(up != p && (p->wired == nil || p->wired == MACHP(m->machno)))
m->readied = p; /* group scheduling */
updatecpu(p);
p->state = Ready;
queueproc(rq, p);
pt = proctrace;
- if(pt)
+ if(pt != nil)
pt(p, SReady, 0);
splx(s);
}
if(npri != pri){
x = splhi();
p = dequeueproc(rq, p);
- if(p)
+ if(p != nil)
queueproc(&runq[npri], p);
splx(x);
goto another;
start = perfticks();
/* cooperative scheduling until the clock ticks */
- if((p=m->readied) && p->mach==0 && p->state==Ready
+ if((p = m->readied) != nil && p->mach == nil && p->state == Ready
+ && (p->wired == nil || p->wired == MACHP(m->machno))
&& runq[Nrq-1].head == nil && runq[Nrq-2].head == nil){
skipscheds++;
rq = &runq[p->priority];
*
*/
for(rq = &runq[Nrq-1]; rq >= runq; rq--){
- for(p = rq->head; p; p = p->rnext){
+ for(p = rq->head; p != nil; p = p->rnext){
if(p->mp == nil || p->mp == MACHP(m->machno)
- || (!p->wired && i > 0))
+ || (p->wired == nil && i > 0))
goto found;
}
}
edfunlock();
}
pt = proctrace;
- if(pt)
+ if(pt != nil)
pt(p, SRun, 0);
return p;
}
splhi();
lock(runq);
/* Only reliable way to see if we are Running */
- if(p->mach == 0) {
+ if(p->mach == nil) {
p->newtlb = 1;
ok = 1;
}
lock(&procalloc);
for(;;) {
- if(p = procalloc.free)
+ if((p = procalloc.free) != nil)
break;
snprint(msg, sizeof msg, "no procs; %s forking",
- up? up->text: "kernel");
+ up != nil ? up->text: "kernel");
unlock(&procalloc);
resrcwait(msg);
lock(&procalloc);
p->state = Scheding;
p->psstate = "New";
- p->mach = 0;
- p->qnext = 0;
+ p->mach = nil;
+ p->eql = nil;
+ p->qnext = nil;
p->nchild = 0;
p->nwait = 0;
- p->waitq = 0;
- p->parent = 0;
- p->pgrp = 0;
- p->egrp = 0;
- p->fgrp = 0;
- p->rgrp = 0;
- p->pdbg = 0;
+ p->waitq = nil;
+ p->parent = nil;
+ p->pgrp = nil;
+ p->egrp = nil;
+ p->fgrp = nil;
+ p->rgrp = nil;
+ p->pdbg = nil;
p->fpstate = FPinit;
p->kp = 0;
- if(up && up->procctl == Proc_tracesyscall)
- p->procctl = Proc_tracesyscall;
- else
- p->procctl = 0;
- p->syscalltrace = 0;
+ p->procctl = 0;
+ p->syscalltrace = nil;
p->notepending = 0;
- p->ureg = 0;
+ p->ureg = nil;
p->privatemem = 0;
p->noswap = 0;
p->errstr = p->errbuf0;
p->syserrstr = p->errbuf1;
p->errbuf0[0] = '\0';
p->errbuf1[0] = '\0';
- p->nlocks.ref = 0;
+ p->nlocks = 0;
p->delaysched = 0;
p->trace = 0;
kstrdup(&p->user, "*nouser");
p->nargs = 0;
p->setargs = 0;
memset(p->seg, 0, sizeof p->seg);
- p->pid = incref(&pidalloc);
- pidhash(p);
- p->noteid = incref(¬eidalloc);
- if(p->pid==0 || p->noteid==0)
- panic("pidalloc");
- if(p->kstack == 0)
+ p->parentpid = 0;
+ p->noteid = pidalloc(p);
+ if(p->kstack == nil)
p->kstack = smalloc(KSTACK);
/* sched params */
- p->mp = 0;
- p->wired = 0;
+ p->mp = nil;
+ p->wired = nil;
procpriority(p, PriNormal, 0);
p->cpu = 0;
p->lastupdate = MACHP(0)->ticks*Scaling;
if(bm < 0){
/* pick a machine to wire to */
memset(nwired, 0, sizeof(nwired));
- p->wired = 0;
+ p->wired = nil;
pp = proctab(0);
for(i=0; i<conf.nproc; i++, pp++){
wm = pp->wired;
- if(wm && pp->pid)
+ if(wm != nil && pp->pid)
nwired[wm->machno]++;
}
bm = 0;
Proc *p;
int i;
- procalloc.free = xalloc(conf.nproc*sizeof(Proc));
- if(procalloc.free == nil){
+ p = xalloc(conf.nproc*sizeof(Proc));
+ if(p == nil){
xsummary();
- panic("cannot allocate %lud procs (%ludMB)\n", conf.nproc, conf.nproc*sizeof(Proc)/(1024*1024));
+ panic("cannot allocate %lud procs (%ludMB)", conf.nproc, conf.nproc*sizeof(Proc)/(1024*1024));
}
- procalloc.arena = procalloc.free;
-
- p = procalloc.free;
- for(i=0; i<conf.nproc-1; i++,p++)
+ procalloc.arena = p;
+ procalloc.free = p;
+ for(i=0; i<conf.nproc-1; i++, p++)
p->qnext = p+1;
- p->qnext = 0;
+ p->qnext = nil;
}
/*
s = splhi();
- if(up->nlocks.ref)
- print("process %lud sleeps with %lud locks held, last lock %#p locked at pc %#lux, sleep called from %#p\n",
- up->pid, up->nlocks.ref, up->lastlock, up->lastlock->pc, getcallerpc(&r));
+ if(up->nlocks)
+ print("process %lud sleeps with %d locks held, last lock %#p locked at pc %#p, sleep called from %#p\n",
+ up->pid, up->nlocks, up->lastlock, up->lastlock->pc, getcallerpc(&r));
lock(r);
lock(&up->rlock);
- if(r->p){
+ if(r->p != nil){
print("double sleep called from %#p, %lud %lud\n", getcallerpc(&r), r->p->pid, up->pid);
dumpstack();
}
* change state and call scheduler
*/
pt = proctrace;
- if(pt)
+ if(pt != nil)
pt(up, SSleep, 0);
up->state = Wakeme;
up->r = r;
if(up->notepending) {
up->notepending = 0;
splx(s);
- if(up->procctl == Proc_exitme && up->closingfgrp)
- forceclosefgrp();
- error(Eintr);
+ interrupted();
}
splx(s);
}
+void
+interrupted(void)
+{
+ if(up->procctl == Proc_exitme && up->closingfgrp != nil)
+ forceclosefgrp();
+ error(Eintr);
+}
+
static int
tfn(void *arg)
{
p = t->ta;
trend = p->trend;
- p->trend = 0;
- if(trend)
+ p->trend = nil;
+ if(trend != nil)
wakeup(trend);
}
void
tsleep(Rendez *r, int (*fn)(void*), void *arg, ulong ms)
{
- if (up->tt){
+ if(up->tt != nil){
print("tsleep: timer active: mode %d, tf %#p\n", up->tmode, up->tf);
timerdel(up);
}
nexterror();
}
sleep(r, tfn, arg);
- if (up->tt)
+ if(up->tt != nil)
timerdel(up);
up->twhen = 0;
poperror();
postnote(Proc *p, int dolock, char *n, int flag)
{
int s, ret;
- Rendez *r;
- Proc *d, **l;
+ QLock *q;
+
+ if(p == nil)
+ return 0;
if(dolock)
qlock(&p->debug);
- if(flag != NUser && (p->notify == 0 || p->notified))
+ if(p->pid == 0){
+ if(dolock)
+ qunlock(&p->debug);
+ return 0;
+ }
+
+ if(n != nil && flag != NUser && (p->notify == 0 || p->notified))
p->nnote = 0;
ret = 0;
- if(p->nnote < NNOTE) {
- strcpy(p->note[p->nnote].msg, n);
+ if(p->nnote < NNOTE && n != nil) {
+ kstrcpy(p->note[p->nnote].msg, n, ERRMAX);
p->note[p->nnote++].flag = flag;
ret = 1;
}
/* this loop is to avoid lock ordering problems. */
for(;;){
+ Rendez *r;
+
s = splhi();
lock(&p->rlock);
r = p->r;
unlock(&p->rlock);
splx(s);
- if(p->state != Rendezvous)
- return ret;
-
- /* Try and pull out of a rendezvous */
- lock(p->rgrp);
- if(p->state == Rendezvous) {
- p->rendval = ~0;
- l = &REND(p->rgrp, p->rendtag);
- for(d = *l; d; d = d->rendhash) {
- if(d == p) {
- *l = p->rendhash;
- break;
+ switch(p->state){
+ case Queueing:
+ /* Try and pull out of a eqlock */
+ if((q = p->eql) != nil){
+ lock(&q->use);
+ if(p->state == Queueing && p->eql == q){
+ Proc *d, *l;
+
+ for(l = nil, d = q->head; d != nil; l = d, d = d->qnext){
+ if(d == p){
+ if(l != nil)
+ l->qnext = p->qnext;
+ else
+ q->head = p->qnext;
+ if(p->qnext == nil)
+ q->tail = l;
+ p->qnext = nil;
+ p->eql = nil; /* not taken */
+ ready(p);
+ break;
+ }
+ }
}
- l = &d->rendhash;
+ unlock(&q->use);
}
- ready(p);
+ break;
+ case Rendezvous:
+ /* Try and pull out of a rendezvous */
+ lock(p->rgrp);
+ if(p->state == Rendezvous) {
+ Proc *d, **l;
+
+ l = &REND(p->rgrp, p->rendtag);
+ for(d = *l; d != nil; d = d->rendhash) {
+ if(d == p) {
+ *l = p->rendhash;
+ p->rendval = ~0;
+ ready(p);
+ break;
+ }
+ l = &d->rendhash;
+ }
+ }
+ unlock(p->rgrp);
+ break;
}
- unlock(p->rgrp);
return ret;
}
edfstop(up);
p->state = Broken;
- p->psstate = 0;
+ p->psstate = nil;
sched();
}
n = broken.n;
for(i=0; i<n; i++) {
ready(broken.p[i]);
- broken.p[i] = 0;
+ broken.p[i] = nil;
}
broken.n = 0;
qunlock(&broken);
Proc *p;
Segment **s, **es;
long utime, stime;
- Waitq *wq, *f, *next;
+ Waitq *wq;
Fgrp *fgrp;
Egrp *egrp;
Rgrp *rgrp;
Chan *dot;
void (*pt)(Proc*, int, vlong);
- if(up->syscalltrace)
- free(up->syscalltrace);
up->alarm = 0;
- if (up->tt)
+ if(up->tt != nil)
timerdel(up);
pt = proctrace;
- if(pt)
+ if(pt != nil)
pt(up, SDead, 0);
/* nil out all the resources under lock (free later) */
up->dot = nil;
qunlock(&up->debug);
- if(fgrp)
+ if(fgrp != nil)
closefgrp(fgrp);
- if(egrp)
+ if(egrp != nil)
closeegrp(egrp);
- if(rgrp)
+ if(rgrp != nil)
closergrp(rgrp);
- if(dot)
+ if(dot != nil)
cclose(dot);
- if(pgrp)
+ if(pgrp != nil)
closepgrp(pgrp);
/*
* if not a kernel process and have a parent,
* do some housekeeping.
*/
- if(up->kp == 0) {
- p = up->parent;
- if(p == 0) {
- if(exitstr == 0)
- exitstr = "unknown";
- panic("boot process died: %s", exitstr);
- }
-
- while(waserror())
- ;
-
+ if(up->kp == 0 && up->parentpid != 0) {
wq = smalloc(sizeof(Waitq));
- poperror();
-
wq->w.pid = up->pid;
utime = up->time[TUser] + up->time[TCUser];
stime = up->time[TSys] + up->time[TCSys];
wq->w.time[TUser] = tk2ms(utime);
wq->w.time[TSys] = tk2ms(stime);
wq->w.time[TReal] = tk2ms(MACHP(0)->ticks - up->time[TReal]);
- if(exitstr && exitstr[0])
+ if(exitstr != nil && exitstr[0])
snprint(wq->w.msg, sizeof(wq->w.msg), "%s %lud: %s", up->text, up->pid, exitstr);
else
wq->w.msg[0] = '\0';
+ p = up->parent;
lock(&p->exl);
/*
* Check that parent is still alive.
}
}
unlock(&p->exl);
- if(wq)
+ if(wq != nil)
free(wq);
}
+ else if(up->kp == 0 && up->parent == nil){
+ if(exitstr == nil)
+ exitstr = "unknown";
+ panic("boot process died: %s", exitstr);
+ }
if(!freemem)
addbroken(up);
qlock(&up->seglock);
es = &up->seg[NSEG];
for(s = up->seg; s < es; s++) {
- if(*s) {
+ if(*s != nil) {
putseg(*s);
- *s = 0;
+ *s = nil;
}
}
qunlock(&up->seglock);
lock(&up->exl); /* Prevent my children from leaving waits */
- pidunhash(up);
+ pidfree(up);
up->pid = 0;
wakeup(&up->waitr);
unlock(&up->exl);
- for(f = up->waitq; f; f = next) {
- next = f->next;
- free(f);
+ while((wq = up->waitq) != nil){
+ up->waitq = wq->next;
+ free(wq);
}
/* release debuggers */
qlock(&up->debug);
- if(up->pdbg) {
+ if(up->pdbg != nil) {
wakeup(&up->pdbg->sleep);
- up->pdbg = 0;
+ up->pdbg = nil;
+ }
+ if(up->syscalltrace != nil) {
+ free(up->syscalltrace);
+ up->syscalltrace = nil;
}
qunlock(&up->debug);
panic("pexit");
}
-int
+static int
haswaitq(void *x)
{
- Proc *p;
-
- p = (Proc *)x;
- return p->waitq != 0;
+ return ((Proc*)x)->waitq != nil;
}
ulong
}
lock(&up->exl);
- if(up->nchild == 0 && up->waitq == 0) {
+ while(up->waitq == nil) {
+ if(up->nchild == 0) {
+ unlock(&up->exl);
+ error(Enochild);
+ }
unlock(&up->exl);
- error(Enochild);
+ sleep(&up->waitr, haswaitq, up);
+ lock(&up->exl);
}
- unlock(&up->exl);
-
- sleep(&up->waitr, haswaitq, up);
-
- lock(&up->exl);
wq = up->waitq;
up->waitq = wq->next;
up->nwait--;
qunlock(&up->qwaitr);
poperror();
- if(w)
+ if(w != nil)
memmove(w, &wq->w, sizeof(Waitmsg));
cpid = wq->w.pid;
free(wq);
ulong bss;
char *s;
- if(p == 0)
+ if(p == nil)
return;
bss = 0;
- if(p->seg[BSEG])
+ if(p->seg[BSEG] != nil)
bss = p->seg[BSEG]->top;
s = p->psstate;
- if(s == 0)
+ if(s == nil)
s = statename[p->state];
- print("%3lud:%10s pc %8lux dbgpc %8lux %8s (%s) ut %ld st %ld bss %lux qpc %lux nl %lud nd %lud lpc %lux pri %lud\n",
+ print("%3lud:%10s pc %#p dbgpc %#p %8s (%s) ut %ld st %ld bss %lux qpc %#p nl %d nd %lud lpc %#p pri %lud\n",
p->pid, p->text, p->pc, dbgpc(p), s, statename[p->state],
- p->time[0], p->time[1], bss, p->qpc, p->nlocks.ref, p->delaysched, p->lastlock ? p->lastlock->pc : 0, p->priority);
+ p->time[0], p->time[1], bss, p->qpc, p->nlocks, p->delaysched,
+ p->lastlock ? p->lastlock->pc : 0, p->priority);
}
void
int i;
Proc *p;
- if(up)
+ if(up != nil)
print("up %lud\n", up->pid);
else
print("no current process\n");
for(i=0; i<conf.nproc; i++) {
p = &procalloc.arena[i];
- if(p->state == Dead)
- continue;
-
- dumpaproc(p);
+ if(p->state != Dead)
+ dumpaproc(p);
}
}
return;
/*
- * wait for all processors to take a clock interrupt
+ * wait for all other processors to take a clock interrupt
* and flush their mmu's
*/
for(nm = 0; nm < conf.nmach; nm++)
- if(MACHP(nm) != m)
- while(MACHP(nm)->flushmmu)
- sched();
+ while(m->machno != nm && MACHP(nm)->flushmmu)
+ sched();
}
void
Schedq *rq;
for(rq = &runq[Nrq-1]; rq >= runq; rq--){
- if(rq->head == 0)
+ if(rq->head == nil)
continue;
print("rq%ld:", rq-runq);
- for(p = rq->head; p; p = p->rnext)
+ for(p = rq->head; p != nil; p = p->rnext)
print(" %lud(%lud)", p->pid, m->ticks - p->readytime);
print("\n");
delay(150);
static Pgrp *kpgrp;
p = newproc();
- p->psstate = 0;
+ p->psstate = nil;
p->procmode = 0640;
p->kp = 1;
p->noswap = 1;
- p->fpsave = up->fpsave;
p->scallnr = up->scallnr;
p->s = up->s;
p->nerrlab = 0;
p->slash = up->slash;
- p->dot = up->dot;
- if(p->dot)
+ p->dot = up->slash; /* unlike fork, do not inherit the dot for kprocs */
+ if(p->dot != nil)
incref(p->dot);
memmove(p->note, up->note, sizeof(p->note));
p->notified = 0;
p->lastnote = up->lastnote;
p->notify = up->notify;
- p->ureg = 0;
- p->dbgreg = 0;
+ p->ureg = nil;
+ p->dbgreg = nil;
procpriority(p, PriKproc, 0);
kstrdup(&p->user, eve);
kstrdup(&p->text, name);
- if(kpgrp == 0)
+ if(kpgrp == nil)
kpgrp = newpgrp();
p->pgrp = kpgrp;
incref(kpgrp);
memset(p->time, 0, sizeof(p->time));
p->time[TReal] = MACHP(0)->ticks;
ready(p);
- /*
- * since the bss/data segments are now shareable,
- * any mmu info about this process is now stale
- * and has to be discarded.
- */
- p->newtlb = 1;
- flushmmu();
}
/*
* reasoning.
*/
void
-procctl(Proc *p)
+procctl(void)
{
char *state;
ulong s;
- switch(p->procctl) {
+ switch(up->procctl) {
case Proc_exitbig:
spllo();
+ pprint("Killed: Insufficient physical memory\n");
pexit("Killed: Insufficient physical memory", 1);
case Proc_exitme:
pexit("Killed", 1);
case Proc_traceme:
- if(p->nnote == 0)
+ if(up->nnote == 0)
return;
/* No break */
case Proc_stopme:
- p->procctl = 0;
- state = p->psstate;
- p->psstate = "Stopped";
+ up->procctl = 0;
+ state = up->psstate;
+ up->psstate = "Stopped";
/* free a waiting debugger */
s = spllo();
- qlock(&p->debug);
- if(p->pdbg) {
- wakeup(&p->pdbg->sleep);
- p->pdbg = 0;
+ qlock(&up->debug);
+ if(up->pdbg != nil) {
+ wakeup(&up->pdbg->sleep);
+ up->pdbg = nil;
}
- qunlock(&p->debug);
+ qunlock(&up->debug);
splhi();
- p->state = Stopped;
+ up->state = Stopped;
sched();
- p->psstate = state;
+ up->psstate = state;
splx(s);
return;
}
void
nexterror(void)
{
+ assert(up->nerrlab > 0);
gotolabel(&up->errlab[--up->nerrlab]);
}
error(buf);
}
+ulong
+procpagecount(Proc *p)
+{
+ Segment *s;
+ ulong pages;
+ int i;
+
+ eqlock(&p->seglock);
+ if(waserror()){
+ qunlock(&p->seglock);
+ nexterror();
+ }
+ pages = 0;
+ for(i=0; i<NSEG; i++){
+ if((s = p->seg[i]) != nil){
+ eqlock(s);
+ pages += mcountseg(s);
+ qunlock(s);
+ }
+ }
+ qunlock(&p->seglock);
+ poperror();
+
+ return pages;
+}
+
void
killbig(char *why)
{
Proc *p, *ep, *kp;
max = 0;
- kp = 0;
+ kp = nil;
ep = procalloc.arena+conf.nproc;
for(p = procalloc.arena; p < ep; p++) {
if(p->state == Dead || p->kp)
continue;
- l = 0;
- for(i=1; i<NSEG; i++) {
- s = p->seg[i];
- if(s != 0)
- l += s->top - s->base;
- }
- if(l > max && ((p->procmode&0222) || strcmp(eve, p->user)!=0)) {
+ if((p->noswap || (p->procmode & 0222) == 0) && strcmp(eve, p->user) == 0)
+ continue;
+ l = procpagecount(p);
+ if(l > max){
kp = p;
max = l;
}
}
-
+ if(kp == nil)
+ return;
print("%lud: %s killed: %s\n", kp->pid, kp->text, why);
+ qlock(&kp->seglock);
for(p = procalloc.arena; p < ep; p++) {
if(p->state == Dead || p->kp)
continue;
- if(p != kp && p->seg[BSEG] && p->seg[BSEG] == kp->seg[BSEG])
+ if(p != kp && p->seg[BSEG] != nil && p->seg[BSEG] == kp->seg[BSEG])
p->procctl = Proc_exitbig;
}
kp->procctl = Proc_exitbig;
for(i = 0; i < NSEG; i++) {
s = kp->seg[i];
- if(s != 0 && canqlock(&s->lk)) {
- mfreeseg(s, s->base, (s->top - s->base)/BY2PG);
- qunlock(&s->lk);
+ if(s == nil)
+ continue;
+ switch(s->type & SG_TYPE){
+ case SG_SHARED:
+ case SG_PHYSICAL:
+ case SG_FIXED:
+ continue;
}
+ qlock(s);
+ mfreeseg(s, s->base, (s->top - s->base)/BY2PG);
+ qunlock(s);
}
+ qunlock(&kp->seglock);
}
/*
ep = procalloc.arena+conf.nproc;
for(p = procalloc.arena; p < ep; p++)
- if(p->user!=nil && strcmp(old, p->user)==0)
+ if(p->user != nil && strcmp(old, p->user) == 0)
kstrdup(&p->user, new);
}
static ulong nrun;
p = m->proc;
- if(p) {
+ if(p != nil) {
nrun++;
p->time[p->insyscall]++;
}
n = perfticks();
per = n - m->perf.last;
m->perf.last = n;
- per = (m->perf.period*(HZ-1) + per)/HZ;
+ per = ((uvlong)m->perf.period*(HZ-1) + per)/HZ;
if(per != 0)
m->perf.period = per;
- m->perf.avg_inidle = (m->perf.avg_inidle*(HZ-1)+m->perf.inidle)/HZ;
+ m->perf.avg_inidle = ((uvlong)m->perf.avg_inidle*(HZ-1)+m->perf.inidle)/HZ;
m->perf.inidle = 0;
- m->perf.avg_inintr = (m->perf.avg_inintr*(HZ-1)+m->perf.inintr)/HZ;
+ m->perf.avg_inintr = ((uvlong)m->perf.avg_inintr*(HZ-1)+m->perf.inintr)/HZ;
m->perf.inintr = 0;
/* only one processor gets to compute system load averages */
*/
n = nrun;
nrun = 0;
- n = (nrdy+n)*1000;
- m->load = (m->load*(HZ-1)+n)/HZ;
+ n = (nrdy+n)*1000*100;
+ load = ((uvlong)load*(HZ-1)+n)/HZ;
+ m->load = load/100;
}
-static void
-pidhash(Proc *p)
+int
+pidalloc(Proc *p)
{
- int h;
+ static int gen, wrapped;
+ int pid, h;
+ Proc *x;
- h = p->pid % nelem(procalloc.ht);
lock(&procalloc);
- p->pidhash = procalloc.ht[h];
- procalloc.ht[h] = p;
+Retry:
+ pid = ++gen & 0x7FFFFFFF;
+ if(pid == 0){
+ wrapped = 1;
+ goto Retry;
+ }
+ h = pid % nelem(procalloc.ht);
+ if(wrapped)
+ for(x = procalloc.ht[h]; x != nil; x = x->pidhash)
+ if(x->pid == pid)
+ goto Retry;
+ if(p != nil){
+ p->pid = pid;
+ p->pidhash = procalloc.ht[h];
+ procalloc.ht[h] = p;
+ }
unlock(&procalloc);
+ return pid;
}
static void
-pidunhash(Proc *p)
+pidfree(Proc *p)
{
int h;
Proc **l;