X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=sys%2Fsrc%2F9%2Fport%2Fproc.c;h=eadca93ec267f133c7804114f99c2e5527c33d45;hb=c4fdc6bfdb2211e13643d5fba75edf437c122eef;hp=25e84cd2ce465afd3865737d7310bafbe9242462;hpb=c2212865791d11a38c9e65654fd2f3feff840d3b;p=plan9front.git diff --git a/sys/src/9/port/proc.c b/sys/src/9/port/proc.c index 25e84cd2c..eadca93ec 100644 --- a/sys/src/9/port/proc.c +++ b/sys/src/9/port/proc.c @@ -9,7 +9,6 @@ int schedgain = 30; /* units in seconds */ int nrdy; -Ref noteidalloc; void updatecpu(Proc*); int reprioritize(Proc*); @@ -19,8 +18,6 @@ long skipscheds; long preempts; ulong load; -static Ref pidalloc; - static struct Procalloc { Lock; @@ -56,8 +53,7 @@ char *statename[] = "Waitrelease", }; -static void pidhash(Proc*); -static void pidunhash(Proc*); +static void pidfree(Proc*); static void rebalance(void); /* @@ -69,10 +65,10 @@ schedinit(void) /* never returns */ 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); @@ -80,7 +76,7 @@ schedinit(void) /* never returns */ case Moribund: up->state = Dead; edfstop(up); - if (up->edf) + if(up->edf != nil) free(up->edf); up->edf = nil; @@ -90,13 +86,18 @@ schedinit(void) /* never returns */ * 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); @@ -118,10 +119,10 @@ sched(void) 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. @@ -136,7 +137,7 @@ sched(void) * 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 @@ -161,13 +162,13 @@ sched(void) 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); @@ -213,7 +214,7 @@ hzsched(void) int preempted(void) { - if(up && up->state == Running) + if(up != nil && up->state == Running) if(up->preempted == 0) if(anyhigher()) if(!active.exiting){ @@ -273,7 +274,7 @@ updatecpu(Proc *p) int n, t, ocpu; int D = schedgain*HZ*Scaling; - if(p->edf) + if(p->edf != nil) return; t = MACHP(0)->ticks*Scaling + Scaling/2; @@ -316,7 +317,7 @@ reprioritize(Proc *p) 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. */ @@ -344,8 +345,8 @@ queueproc(Schedq *rq, Proc *p) 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; @@ -371,8 +372,8 @@ dequeueproc(Schedq *rq, Proc *tp) * 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; @@ -381,13 +382,13 @@ dequeueproc(Schedq *rq, Proc *tp) /* * 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; @@ -413,13 +414,18 @@ ready(Proc *p) 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); @@ -429,7 +435,7 @@ ready(Proc *p) p->state = Ready; queueproc(rq, p); pt = proctrace; - if(pt) + if(pt != nil) pt(p, SReady, 0); splx(s); } @@ -480,7 +486,7 @@ another: if(npri != pri){ x = splhi(); p = dequeueproc(rq, p); - if(p) + if(p != nil) queueproc(&runq[npri], p); splx(x); goto another; @@ -504,7 +510,8 @@ runproc(void) 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]; @@ -527,9 +534,9 @@ loop: * */ 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; } } @@ -557,7 +564,7 @@ found: edfunlock(); } pt = proctrace; - if(pt) + if(pt != nil) pt(p, SRun, 0); return p; } @@ -570,7 +577,7 @@ canpage(Proc *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; } @@ -588,11 +595,11 @@ newproc(void) 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); @@ -602,33 +609,31 @@ newproc(void) 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"); @@ -637,17 +642,14 @@ newproc(void) 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; @@ -670,11 +672,11 @@ procwired(Proc *p, int bm) 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; iwired; - if(wm && pp->pid) + if(wm != nil && pp->pid) nwired[wm->machno]++; } bm = 0; @@ -712,17 +714,16 @@ procinit0(void) /* bad planning - clashes with devproc.c */ 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; iqnext = p+1; - p->qnext = 0; + p->qnext = nil; } /* @@ -741,12 +742,12 @@ sleep(Rendez *r, int (*f)(void*), void *arg) 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(); } @@ -773,7 +774,7 @@ sleep(Rendez *r, int (*f)(void*), void *arg) * change state and call scheduler */ pt = proctrace; - if(pt) + if(pt != nil) pt(up, SSleep, 0); up->state = Wakeme; up->r = r; @@ -801,14 +802,20 @@ sleep(Rendez *r, int (*f)(void*), void *arg) 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) { @@ -823,15 +830,15 @@ twakeup(Ureg*, Timer *t) 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); } @@ -848,7 +855,7 @@ tsleep(Rendez *r, int (*fn)(void*), void *arg, ulong ms) nexterror(); } sleep(r, tfn, arg); - if (up->tt) + if(up->tt != nil) timerdel(up); up->twhen = 0; poperror(); @@ -900,16 +907,26 @@ int postnote(Proc *p, int dolock, char *n, int flag) { int s, ret; + 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; } @@ -948,38 +965,31 @@ postnote(Proc *p, int dolock, char *n, int flag) unlock(&p->rlock); splx(s); -Pullout: switch(p->state){ case Queueing: /* Try and pull out of a eqlock */ - lock(&p->eqlock); - if(p->state == Queueing && p->eql && p->notepending){ - Proc *d, *l; - QLock *q; - - q = p->eql; - if(!canlock(&q->use)){ - unlock(&p->eqlock); - sched(); - goto Pullout; - } - - for(l = nil, d = q->head; d; l = d, d = d->qnext) - if(d == p){ - if(l) - l->qnext = p->qnext; - else - q->head = p->qnext; - if(p->qnext == 0) - q->tail = l; - p->qnext = 0; - p->eql = 0; - ready(p); - break; + 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; + } } + } unlock(&q->use); } - unlock(&p->eqlock); break; case Rendezvous: /* Try and pull out of a rendezvous */ @@ -987,16 +997,16 @@ Pullout: if(p->state == Rendezvous) { Proc *d, **l; - p->rendval = ~0; l = &REND(p->rgrp, p->rendtag); - for(d = *l; d; d = d->rendhash) { + for(d = *l; d != nil; d = d->rendhash) { if(d == p) { *l = p->rendhash; + p->rendval = ~0; + ready(p); break; } l = &d->rendhash; } - ready(p); } unlock(p->rgrp); break; @@ -1029,7 +1039,7 @@ addbroken(Proc *p) edfstop(up); p->state = Broken; - p->psstate = 0; + p->psstate = nil; sched(); } @@ -1059,7 +1069,7 @@ freebroken(void) n = broken.n; for(i=0; isyscalltrace) - 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) */ @@ -1103,46 +1111,35 @@ pexit(char *exitstr, int freemem) 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. @@ -1167,9 +1164,14 @@ pexit(char *exitstr, int freemem) } } 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); @@ -1177,29 +1179,33 @@ pexit(char *exitstr, int freemem) 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); @@ -1213,13 +1219,10 @@ pexit(char *exitstr, int freemem) panic("pexit"); } -int +static int haswaitq(void *x) { - Proc *p; - - p = (Proc *)x; - return p->waitq != 0; + return ((Proc*)x)->waitq != nil; } ulong @@ -1237,15 +1240,15 @@ pwait(Waitmsg *w) } 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--; @@ -1254,7 +1257,7 @@ pwait(Waitmsg *w) qunlock(&up->qwaitr); poperror(); - if(w) + if(w != nil) memmove(w, &wq->w, sizeof(Waitmsg)); cpid = wq->w.pid; free(wq); @@ -1273,19 +1276,20 @@ dumpaproc(Proc *p) 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 @@ -1294,16 +1298,14 @@ procdump(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; istate == Dead) - continue; - - dumpaproc(p); + if(p->state != Dead) + dumpaproc(p); } } @@ -1343,13 +1345,12 @@ procflushseg(Segment *s) 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 @@ -1359,10 +1360,10 @@ scheddump(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); @@ -1377,18 +1378,17 @@ kproc(char *name, void (*func)(void *), void *arg) 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)); @@ -1396,8 +1396,8 @@ kproc(char *name, void (*func)(void *), void *arg) 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); @@ -1405,7 +1405,7 @@ kproc(char *name, void (*func)(void *), void *arg) kstrdup(&p->user, eve); kstrdup(&p->text, name); - if(kpgrp == 0) + if(kpgrp == nil) kpgrp = newpgrp(); p->pgrp = kpgrp; incref(kpgrp); @@ -1420,12 +1420,12 @@ kproc(char *name, void (*func)(void *), void *arg) * 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"); @@ -1436,26 +1436,26 @@ procctl(Proc *p) 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; } @@ -1477,6 +1477,7 @@ error(char *err) void nexterror(void) { + assert(up->nerrlab > 0); gotolabel(&up->errlab[--up->nerrlab]); } @@ -1490,6 +1491,32 @@ exhausted(char *resource) 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; iseg[i]) != nil){ + eqlock(s); + pages += mcountseg(s); + qunlock(s); + } + } + qunlock(&p->seglock); + poperror(); + + return pages; +} + void killbig(char *why) { @@ -1499,38 +1526,45 @@ 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; iseg[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); } /* @@ -1544,7 +1578,7 @@ renameuser(char *old, char *new) 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); } @@ -1559,7 +1593,7 @@ accounttime(void) static ulong nrun; p = m->proc; - if(p) { + if(p != nil) { nrun++; p->time[p->insyscall]++; } @@ -1568,14 +1602,14 @@ accounttime(void) 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 */ @@ -1593,24 +1627,41 @@ accounttime(void) */ 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;