/* * Always splhi()'ed. */ void schedinit(void) /* never returns */ { Edf *e; machp()->inidle = 1; machp()->proc = nil; ainc(&run.nmach); setlabel(&machp()->sched); Proc *up = externup(); if(infected_with_std()){ print("mach %d got an std from %s (pid %d)!\n", machp()->machno, up ? up->text : "*notext", up ? up->pid : -1 ); disinfect_std(); } if(up) { if((e = up->edf) && (e->flags & Admitted)) edfrecord(up); machp()->qstart = 0; machp()->qexpired = 0; coherence(); machp()->proc = 0; switch(up->state) { case Running: ready(up); break; case Moribund: up->state = Dead; stopac(); edfstop(up); if (up->edf) free(up->edf); up->edf = nil; /* * Holding locks from pexit: * procalloc * pga */ mmurelease(up); unlock(&pga.l); psrelease(up); unlock(&procalloc.l); break; } up->mach = nil; updatecpu(up); machp()->externup = nil; } sched(); }
/* * Always splhi()'ed. */ void schedinit(void) /* never returns */ { Mach *m = machp(); Edf *e; m->inidle = 1; m->proc = nil; ainc(&run.nmach); setlabel(&m->sched); if(m->externup) { if((e = m->externup->edf) && (e->flags & Admitted)) edfrecord(m->externup); m->qstart = 0; m->qexpired = 0; coherence(); m->proc = 0; switch(m->externup->state) { case Running: ready(m->externup); break; case Moribund: m->externup->state = Dead; stopac(); edfstop(m->externup); if (m->externup->edf) free(m->externup->edf); m->externup->edf = nil; /* * Holding locks from pexit: * procalloc * pga */ mmurelease(m->externup); unlock(&pga); psrelease(m->externup); unlock(&procalloc); break; } m->externup->mach = nil; updatecpu(m->externup); m->externup = nil; } sched(); }
/* * Always splhi()'ed. */ void schedinit(void) /* never returns */ { Edf *e; setlabel(&m->sched); if(up != nil) { if((e = up->edf) != nil && (e->flags & Admitted)) edfrecord(up); m->proc = nil; switch(up->state) { case Running: ready(up); break; case Moribund: up->state = Dead; edfstop(up); if(up->edf != nil) free(up->edf); up->edf = nil; /* * Holding locks from pexit: * procalloc * palloc */ mmurelease(up); unlock(&palloc); up->mach = nil; updatecpu(up); up->qnext = procalloc.free; procalloc.free = up; /* proc is free now, make sure unlock() wont touch it */ up = procalloc.Lock.p = nil; unlock(&procalloc); sched(); } up->mach = nil; updatecpu(up); up = nil; } sched(); }
void addbroken(Proc *p) { qlock(&broken); if(broken.n == NBROKEN) { ready(broken.p[0]); memmove(&broken.p[0], &broken.p[1], sizeof(Proc*)*(NBROKEN-1)); --broken.n; } broken.p[broken.n++] = p; qunlock(&broken); edfstop(up); p->state = Broken; p->psstate = nil; sched(); }
void addbroken(Proc *p) { Mach *m = machp(); qlock(&broken); if(broken.n == NBROKEN) { ready(broken.p[0]); memmove(&broken.p[0], &broken.p[1], sizeof(Proc*)*(NBROKEN-1)); --broken.n; } broken.p[broken.n++] = p; qunlock(&broken); stopac(); edfstop(m->externup); p->state = Broken; p->psstate = 0; sched(); }
void pexit(char *exitstr, int freemem) { Proc *p; Segment **s, **es; long utime, stime; Waitq *wq; Fgrp *fgrp; Egrp *egrp; Rgrp *rgrp; Pgrp *pgrp; Chan *dot; void (*pt)(Proc*, int, vlong); up->alarm = 0; if(up->tt != nil) timerdel(up); pt = proctrace; if(pt != nil) pt(up, SDead, 0); /* nil out all the resources under lock (free later) */ qlock(&up->debug); fgrp = up->fgrp; up->fgrp = nil; egrp = up->egrp; up->egrp = nil; rgrp = up->rgrp; up->rgrp = nil; pgrp = up->pgrp; up->pgrp = nil; dot = up->dot; up->dot = nil; qunlock(&up->debug); if(fgrp != nil) closefgrp(fgrp); if(egrp != nil) closeegrp(egrp); if(rgrp != nil) closergrp(rgrp); if(dot != nil) cclose(dot); if(pgrp != nil) closepgrp(pgrp); /* * if not a kernel process and have a parent, * do some housekeeping. */ if(up->kp == 0 && up->parentpid != 0) { wq = smalloc(sizeof(Waitq)); 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 != 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. */ if(p->pid == up->parentpid && p->state != Broken) { p->nchild--; p->time[TCUser] += utime; p->time[TCSys] += stime; /* * If there would be more than 128 wait records * processes for my parent, then don't leave a wait * record behind. This helps prevent badly written * daemon processes from accumulating lots of wait * records. */ if(p->nwait < 128) { wq->next = p->waitq; p->waitq = wq; p->nwait++; wq = nil; wakeup(&p->waitr); } } unlock(&p->exl); 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 != nil) { putseg(*s); *s = nil; } } qunlock(&up->seglock); lock(&up->exl); /* Prevent my children from leaving waits */ pidfree(up); up->pid = 0; wakeup(&up->waitr); unlock(&up->exl); while((wq = up->waitq) != nil){ up->waitq = wq->next; free(wq); } /* release debuggers */ qlock(&up->debug); if(up->pdbg != nil) { wakeup(&up->pdbg->sleep); up->pdbg = nil; } if(up->syscalltrace != nil) { free(up->syscalltrace); up->syscalltrace = nil; } qunlock(&up->debug); /* Sched must not loop for these locks */ lock(&procalloc); lock(&palloc); edfstop(up); up->state = Moribund; sched(); panic("pexit"); }
void pexit(char *exitstr, int freemem) { Mach *m = machp(); Proc *p; Segment **s, **es; int32_t utime, stime; Waitq *wq, *f, *next; Fgrp *fgrp; Egrp *egrp; Rgrp *rgrp; Pgrp *pgrp; Chan *dot; if(0 && m->externup->nfullq > 0) iprint(" %s=%d", m->externup->text, m->externup->nfullq); if(0 && m->externup->nicc > 0) iprint(" [%s nicc %ud tctime %ulld actime %ulld]\n", m->externup->text, m->externup->nicc, m->externup->tctime, m->externup->actime); if(m->externup->syscalltrace != nil) free(m->externup->syscalltrace); m->externup->syscalltrace = nil; m->externup->alarm = 0; if (m->externup->tt) timerdel(m->externup); if(m->externup->trace) proctrace(m->externup, SDead, 0); /* nil out all the resources under lock (free later) */ qlock(&m->externup->debug); fgrp = m->externup->fgrp; m->externup->fgrp = nil; egrp = m->externup->egrp; m->externup->egrp = nil; rgrp = m->externup->rgrp; m->externup->rgrp = nil; pgrp = m->externup->pgrp; m->externup->pgrp = nil; dot = m->externup->dot; m->externup->dot = nil; qunlock(&m->externup->debug); if(fgrp) closefgrp(fgrp); if(egrp) closeegrp(egrp); if(rgrp) closergrp(rgrp); if(dot) cclose(dot); if(pgrp) closepgrp(pgrp); /* * if not a kernel process and have a parent, * do some housekeeping. */ if(m->externup->kp == 0) { p = m->externup->parent; if(p == 0) { if(exitstr == 0) exitstr = "unknown"; //die("bootprocessdeath"); panic("boot process died: %s", exitstr); } while(waserror()) ; wq = smalloc(sizeof(Waitq)); poperror(); wq->w.pid = m->externup->pid; utime = m->externup->time[TUser] + m->externup->time[TCUser]; stime = m->externup->time[TSys] + m->externup->time[TCSys]; wq->w.time[TUser] = tk2ms(utime); wq->w.time[TSys] = tk2ms(stime); wq->w.time[TReal] = tk2ms(sys->machptr[0]->ticks - m->externup->time[TReal]); if(exitstr && exitstr[0]) snprint(wq->w.msg, sizeof(wq->w.msg), "%s %d: %s", m->externup->text, m->externup->pid, exitstr); else wq->w.msg[0] = '\0'; lock(&p->exl); /* * Check that parent is still alive. */ if(p->pid == m->externup->parentpid && p->state != Broken) { p->nchild--; p->time[TCUser] += utime; p->time[TCSys] += stime; /* * If there would be more than 128 wait records * processes for my parent, then don't leave a wait * record behind. This helps prevent badly written * daemon processes from accumulating lots of wait * records. */ if(p->nwait < 128) { wq->next = p->waitq; p->waitq = wq; p->nwait++; wq = nil; wakeup(&p->waitr); } } unlock(&p->exl); if(wq) free(wq); } if(!freemem) addbroken(m->externup); qlock(&m->externup->seglock); es = &m->externup->seg[NSEG]; for(s = m->externup->seg; s < es; s++) { if(*s) { putseg(*s); *s = 0; } } qunlock(&m->externup->seglock); lock(&m->externup->exl); /* Prevent my children from leaving waits */ psunhash(m->externup); m->externup->pid = 0; wakeup(&m->externup->waitr); unlock(&m->externup->exl); for(f = m->externup->waitq; f; f = next) { next = f->next; free(f); } /* release debuggers */ qlock(&m->externup->debug); if(m->externup->pdbg) { wakeup(&m->externup->pdbg->sleep); m->externup->pdbg = 0; } qunlock(&m->externup->debug); /* Sched must not loop for these locks */ lock(&procalloc); lock(&pga); stopac(); edfstop(m->externup); m->externup->state = Moribund; sched(); panic("pexit"); }