Annotation of lucent/sys/src/9/port/proc.c, revision 1.1

1.1     ! root        1: #include       "u.h"
        !             2: #include       "../port/lib.h"
        !             3: #include       "mem.h"
        !             4: #include       "dat.h"
        !             5: #include       "fns.h"
        !             6: #include       "../port/error.h"
        !             7: 
        !             8: Ref    pidalloc;
        !             9: Ref    noteidalloc;
        !            10: 
        !            11: struct
        !            12: {
        !            13:        Lock;
        !            14:        Proc    *arena;
        !            15:        Proc    *free;
        !            16: }procalloc;
        !            17: 
        !            18: struct
        !            19: {
        !            20:        Lock;
        !            21:        Waitq   *free;
        !            22: }waitqalloc;
        !            23: 
        !            24: typedef struct
        !            25: {
        !            26:        Lock;
        !            27:        Proc    *head;
        !            28:        Proc    *tail;
        !            29:        int     n;
        !            30: } Schedq;
        !            31: 
        !            32: int    nrdy;
        !            33: int    lastreadied;
        !            34: Schedq runq[Nrq];
        !            35: 
        !            36: char *statename[] =
        !            37: {                      /* BUG: generate automatically */
        !            38:        "Dead",
        !            39:        "Moribund",
        !            40:        "Ready",
        !            41:        "Scheding",
        !            42:        "Running",
        !            43:        "Queueing",
        !            44:        "Wakeme",
        !            45:        "Broken",
        !            46:        "Stopped",
        !            47:        "Rendez",
        !            48: };
        !            49: 
        !            50: /*
        !            51:  * Always splhi()'ed.
        !            52:  */
        !            53: void
        !            54: schedinit(void)                /* never returns */
        !            55: {
        !            56:        Proc *p;
        !            57: 
        !            58:        setlabel(&m->sched);
        !            59:        if(u){
        !            60:                m->proc = 0;
        !            61:                p = u->p;
        !            62:                invalidateu();  /* safety first */
        !            63:                u = 0;
        !            64:                if(p->state == Running)
        !            65:                        ready(p);
        !            66:                else
        !            67:                if(p->state == Moribund) {
        !            68:                        p->pid = 0;
        !            69:                        p->state = Dead;
        !            70:                        /* 
        !            71:                         * Holding locks from pexit:
        !            72:                         *      procalloc, palloc
        !            73:                         */
        !            74:                        mmurelease(p);
        !            75:                        simpleputpage(p->upage);
        !            76:                        p->upage = 0;
        !            77: 
        !            78:                        p->qnext = procalloc.free;
        !            79:                        procalloc.free = p;
        !            80:                
        !            81:                        unlock(&palloc);
        !            82:                        unlock(&procalloc);
        !            83:                }
        !            84:                p->mach = 0;
        !            85:        }
        !            86:        sched();
        !            87: }
        !            88: 
        !            89: void
        !            90: sched(void)
        !            91: {
        !            92:        Proc *p;
        !            93: 
        !            94:        if(u){
        !            95:                splhi();
        !            96:                m->cs++;
        !            97:                procsave(u->p);
        !            98:                if(setlabel(&u->p->sched)){     /* woke up */
        !            99:                        p = u->p;
        !           100:                        p->state = Running;
        !           101:                        p->mach = m;
        !           102:                        m->proc = p;
        !           103:                        procrestore(p);
        !           104:                        spllo();
        !           105:                        return;
        !           106:                }
        !           107:                gotolabel(&m->sched);
        !           108:        }
        !           109:        p = runproc();
        !           110:        mapstack(p);
        !           111:        gotolabel(&p->sched);
        !           112: }
        !           113: 
        !           114: /*
        !           115:  *  this should be called in clock() to implement round robin
        !           116:  */
        !           117: int
        !           118: anyready(void)
        !           119: {
        !           120:        return nrdy;
        !           121: }
        !           122: 
        !           123: /*
        !           124:  *  this should be called in non-clock traps to implement preemptive scheduling
        !           125:  */
        !           126: int
        !           127: anyhigher(void)
        !           128: {
        !           129:        int x;
        !           130: 
        !           131:        x = lastreadied;
        !           132:        lastreadied = 0;
        !           133:        return nrdy && x >= u->p->priority;
        !           134: }
        !           135: 
        !           136: enum
        !           137: {
        !           138:        Squantum = (HZ+Nrq-1)/Nrq,
        !           139: };
        !           140: 
        !           141: void
        !           142: ready(Proc *p)
        !           143: {
        !           144:        int s, pri;
        !           145:        Schedq *rq;
        !           146: 
        !           147:        s = splhi();
        !           148: 
        !           149:        /* history counts */
        !           150:        if(p->state == Running){
        !           151:                p->rt++;
        !           152:                pri = ((p->art + (p->rt<<1))>>2)/Squantum;
        !           153:        } else {
        !           154:                p->art = (p->art + (p->rt<<1))>>2;
        !           155:                p->rt = 0;
        !           156:                pri = p->art/Squantum;
        !           157:        }
        !           158:        pri = p->basepri - pri;
        !           159:        if(pri < 0)
        !           160:                pri = 0;
        !           161: 
        !           162:        /* the only intersection between the classes is at PriNormal */
        !           163:        if(pri < PriNormal && p->basepri > PriNormal)
        !           164:                pri = PriNormal;
        !           165:        p->priority = pri;
        !           166:        rq = &runq[p->priority];
        !           167: 
        !           168:        lock(runq);
        !           169:        p->rnext = 0;
        !           170:        if(rq->tail)
        !           171:                rq->tail->rnext = p;
        !           172:        else
        !           173:                rq->head = p;
        !           174:        rq->tail = p;
        !           175:        rq->n++;
        !           176:        nrdy++;
        !           177:        p->readytime = m->ticks;
        !           178:        p->state = Ready;
        !           179:        if(p->priority > lastreadied)
        !           180:                lastreadied = p->priority;
        !           181:        unlock(runq);
        !           182:        splx(s);
        !           183: }
        !           184: 
        !           185: /*
        !           186:  * Always called splhi
        !           187:  */
        !           188: #include "io.h"
        !           189: Proc*
        !           190: runproc(void)
        !           191: {
        !           192:        int i;
        !           193:        Schedq *rq;
        !           194:        Proc *p, *l;
        !           195:        static ulong lastfair;
        !           196: 
        !           197: loop:
        !           198: 
        !           199:        /*
        !           200:         *  find a process that last ran on this processor (affinity),
        !           201:         *  or one that hasn't moved in a while (load balancing).
        !           202:         */
        !           203:        spllo();
        !           204:        for(;;){
        !           205:                /*
        !           206:                 *  Once a second we look for a long waiting process
        !           207:                 *  in the lowest priority queue to make sure nothing
        !           208:                 *  gets starved out by a malfunctioning high priority
        !           209:                 *  process.
        !           210:                 */
        !           211:                if(m->machno == 0 && m->ticks - lastfair > HZ){
        !           212:                        lastfair = m->ticks;
        !           213:                        for(rq = runq; rq < &runq[Nrq]; rq++){
        !           214:                                p = rq->head;
        !           215:                                if(p){
        !           216:                                        i = m->ticks - p->readytime;
        !           217:                                        if(i > HZ){
        !           218:                                                p->art = 0;
        !           219:                                                p->movetime = 0;
        !           220:                                                goto found;
        !           221:                                        }
        !           222:                                        break;
        !           223:                                }
        !           224:                        }
        !           225:                }
        !           226: 
        !           227:                /*
        !           228:                 *  get highest priority process that this
        !           229:                 *  processor can run given affinity constraints
        !           230:                 */
        !           231:                for(rq = &runq[Nrq-1]; rq >= runq; rq--){
        !           232:                        if(rq->head == 0)
        !           233:                                continue;
        !           234:                        for(p = rq->head; p; p = p->rnext){
        !           235:                                if(p->mp == m || m->ticks - p->movetime > HZ/2)
        !           236:                                        goto found;
        !           237:                        }
        !           238:                }
        !           239:        }
        !           240: 
        !           241: 
        !           242: found:
        !           243:        splhi();
        !           244:        lock(runq);
        !           245: 
        !           246:        l = 0;
        !           247:        for(p = rq->head; p; p = p->rnext){
        !           248:                if(p->mp == m || m->ticks - p->movetime > HZ/2)
        !           249:                        break;
        !           250:                l = p;
        !           251:        }
        !           252: 
        !           253:        /*
        !           254:         *  p->mach==0 only when process state is saved
        !           255:         */
        !           256:        if(p == 0 || p->mach){  
        !           257:                unlock(runq);
        !           258:                goto loop;
        !           259:        }
        !           260:        if(p->rnext == 0)
        !           261:                rq->tail = l;
        !           262:        if(l)
        !           263:                l->rnext = p->rnext;
        !           264:        else
        !           265:                rq->head = p->rnext;
        !           266:        rq->n--;
        !           267:        nrdy--;
        !           268:        if(p->state != Ready)
        !           269:                print("runproc %s %d %s\n", p->text, p->pid, statename[p->state]);
        !           270:        unlock(runq);
        !           271: 
        !           272:        p->state = Scheding;
        !           273:        if(p->mp != m)
        !           274:                p->movetime = m->ticks;
        !           275:        p->mp = m;
        !           276:        return p;
        !           277: }
        !           278: 
        !           279: int
        !           280: canpage(Proc *p)
        !           281: {
        !           282:        int ok = 0;
        !           283: 
        !           284:        splhi();
        !           285:        lock(&runq[0]);
        !           286:        /* Only reliable way to see if we are Running */
        !           287:        if(p->mach == 0) {
        !           288:                p->newtlb = 1;
        !           289:                ok = 1;
        !           290:        }
        !           291:        unlock(&runq[0]);
        !           292:        spllo();
        !           293: 
        !           294:        return ok;
        !           295: }
        !           296: 
        !           297: Proc*
        !           298: newproc(void)
        !           299: {
        !           300:        Proc *p;
        !           301: 
        !           302:        for(;;) {
        !           303:                lock(&procalloc);
        !           304:                if(p = procalloc.free){         /* assign = */
        !           305:                        procalloc.free = p->qnext;
        !           306:                        p->state = Scheding;
        !           307:                        p->psstate = "New";
        !           308:                        unlock(&procalloc);
        !           309:                        p->mach = 0;
        !           310:                        p->qnext = 0;
        !           311:                        p->nchild = 0;
        !           312:                        p->nwait = 0;
        !           313:                        p->waitq = 0;
        !           314:                        p->pgrp = 0;
        !           315:                        p->egrp = 0;
        !           316:                        p->fgrp = 0;
        !           317:                        p->pdbg = 0;
        !           318:                        p->fpstate = FPinit;
        !           319:                        p->kp = 0;
        !           320:                        p->procctl = 0;
        !           321:                        p->notepending = 0;
        !           322:                        p->mp = 0;
        !           323:                        p->movetime = 0;
        !           324:                        memset(p->seg, 0, sizeof p->seg);
        !           325:                        p->pid = incref(&pidalloc);
        !           326:                        p->noteid = incref(&noteidalloc);
        !           327:                        if(p->pid==0 || p->noteid==0)
        !           328:                                panic("pidalloc");
        !           329:                        return p;
        !           330:                }
        !           331:                unlock(&procalloc);
        !           332:                resrcwait("no procs");
        !           333:        }
        !           334:        return 0;               /* not reached */
        !           335: }
        !           336: 
        !           337: void
        !           338: procinit0(void)                /* bad planning - clashes with devproc.c */
        !           339: {
        !           340:        Proc *p;
        !           341:        int i;
        !           342: 
        !           343:        procalloc.free = xalloc(conf.nproc*sizeof(Proc));
        !           344:        procalloc.arena = procalloc.free;
        !           345: 
        !           346:        p = procalloc.free;
        !           347:        for(i=0; i<conf.nproc-1; i++,p++)
        !           348:                p->qnext = p+1;
        !           349:        p->qnext = 0;
        !           350: }
        !           351: 
        !           352: void
        !           353: sleep1(Rendez *r, int (*f)(void*), void *arg)
        !           354: {
        !           355:        Proc *p;
        !           356:        int s;
        !           357: 
        !           358:        /*
        !           359:         * spl is to allow lock to be called
        !           360:         * at interrupt time. lock is mutual exclusion
        !           361:         */
        !           362:        s = splhi();
        !           363:        p = u->p;
        !           364:        p->r = r;       /* early so postnote knows */
        !           365:        lock(r);
        !           366: 
        !           367:        /*
        !           368:         * if condition happened, never mind
        !           369:         */
        !           370:        if((*f)(arg)){
        !           371:                p->r = 0;
        !           372:                unlock(r);
        !           373:                splx(s);
        !           374:                return;
        !           375:        }
        !           376: 
        !           377:        /*
        !           378:         * now we are committed to
        !           379:         * change state and call scheduler
        !           380:         */
        !           381:        if(r->p){
        !           382:                print("double sleep %d %d\n", r->p->pid, p->pid);
        !           383:                dumpstack();
        !           384:        }
        !           385:        p->state = Wakeme;
        !           386:        r->p = p;
        !           387:        unlock(r);
        !           388: }
        !           389: 
        !           390: void
        !           391: sleep(Rendez *r, int (*f)(void*), void *arg)
        !           392: {
        !           393:        Proc *p;
        !           394:        int s;
        !           395: 
        !           396:        p = u->p;
        !           397:        sleep1(r, f, arg);
        !           398:        if(p->notepending == 0)
        !           399:                sched();        /* notepending may go true while asleep */
        !           400:        if(p->notepending){
        !           401:                p->notepending = 0;
        !           402:                s = splhi();
        !           403:                lock(r);
        !           404:                if(r->p == p)
        !           405:                        r->p = 0;
        !           406:                unlock(r);
        !           407:                splx(s);
        !           408:                error(Eintr);
        !           409:        }
        !           410: }
        !           411: 
        !           412: int
        !           413: tfn(void *arg)
        !           414: {
        !           415:        Proc *p;
        !           416: 
        !           417:        p = u->p;
        !           418:        return MACHP(0)->ticks >= p->twhen || (*p->tfn)(arg);
        !           419: }
        !           420: 
        !           421: void
        !           422: tsleep(Rendez *r, int (*fn)(void*), void *arg, int ms)
        !           423: {
        !           424:        ulong when;
        !           425:        Proc *p, *f, **l;
        !           426: 
        !           427:        p = u->p;
        !           428:        when = MS2TK(ms)+MACHP(0)->ticks;
        !           429: 
        !           430:        lock(&talarm);
        !           431:        /* take out of list if checkalarm didn't */
        !           432:        if(p->trend) {
        !           433:                l = &talarm.list;
        !           434:                for(f = *l; f; f = f->tlink) {
        !           435:                        if(f == p) {
        !           436:                                *l = p->tlink;
        !           437:                                break;
        !           438:                        }
        !           439:                        l = &f->tlink;
        !           440:                }
        !           441:        }
        !           442:        /* insert in increasing time order */
        !           443:        l = &talarm.list;
        !           444:        for(f = *l; f; f = f->tlink) {
        !           445:                if(f->twhen >= when)
        !           446:                        break;
        !           447:                l = &f->tlink;
        !           448:        }
        !           449:        p->trend = r;
        !           450:        p->twhen = when;
        !           451:        p->tfn = fn;
        !           452:        p->tlink = *l;
        !           453:        *l = p;
        !           454:        unlock(&talarm);
        !           455: 
        !           456:        sleep(r, tfn, arg);
        !           457:        p->twhen = 0;
        !           458: }
        !           459: 
        !           460: /*
        !           461:  * Expects that only one process can call wakeup for any given Rendez
        !           462:  */
        !           463: void
        !           464: wakeup(Rendez *r)
        !           465: {
        !           466:        Proc *p;
        !           467:        int s;
        !           468: 
        !           469:        s = splhi();
        !           470:        lock(r);
        !           471:        p = r->p;
        !           472:        if(p){
        !           473:                r->p = 0;
        !           474:                if(p->state != Wakeme) 
        !           475:                        panic("wakeup: state");
        !           476:                p->r = 0;
        !           477:                ready(p);
        !           478:        }
        !           479:        unlock(r);
        !           480:        splx(s);
        !           481: }
        !           482: 
        !           483: int
        !           484: postnote(Proc *p, int dolock, char *n, int flag)
        !           485: {
        !           486:        User *up;
        !           487:        KMap *k;
        !           488:        int s, ret;
        !           489:        Rendez *r;
        !           490:        Proc *d, **l;
        !           491: 
        !           492:        if(dolock)
        !           493:                qlock(&p->debug);
        !           494: 
        !           495:        if(p->kp)
        !           496:                print("sending %s to kproc %d %s\n", n, p->pid, p->text);
        !           497: 
        !           498:        if(p->upage == 0){
        !           499:                if(dolock)
        !           500:                        qunlock(&p->debug);
        !           501:                return 0;
        !           502:        }
        !           503: 
        !           504:        SET(k);
        !           505:        if(u == 0 || p != u->p){
        !           506:                k = kmap(p->upage);
        !           507:                up = (User*)VA(k);
        !           508:        }else
        !           509:                up = u;
        !           510:        USED(k);
        !           511: 
        !           512:        if(flag!=NUser && (up->notify==0 || up->notified))
        !           513:                up->nnote = 0;  /* force user's hand */
        !           514: 
        !           515:        ret = 0;
        !           516:        if(up->nnote < NNOTE){
        !           517:                strcpy(up->note[up->nnote].msg, n);
        !           518:                up->note[up->nnote++].flag = flag;
        !           519:                ret = 1;
        !           520:        }
        !           521:        p->notepending = 1;
        !           522:        if(up != u)
        !           523:                kunmap(k);
        !           524:        if(dolock)
        !           525:                qunlock(&p->debug);
        !           526: 
        !           527:        if(r = p->r){           /* assign = */
        !           528:                /* wake up; can't call wakeup itself because we're racing with it */
        !           529:                for(;;) {
        !           530:                        s = splhi();
        !           531:                        if(canlock(r))
        !           532:                                break;
        !           533:                        splx(s);
        !           534:                }
        !           535:                if(p->r==r && r->p==p && p->state==Wakeme){     /* check we won the race */
        !           536:                        r->p = 0;
        !           537:                        p->r = 0;
        !           538:                        ready(p);
        !           539:                }
        !           540:                unlock(r);
        !           541:                splx(s);
        !           542:        }
        !           543: 
        !           544:        if(p->state != Rendezvous)
        !           545:                return ret;
        !           546: 
        !           547:        /* Try and pull out of a rendezvous */
        !           548:        lock(p->pgrp);
        !           549:        if(p->state == Rendezvous) {
        !           550:                p->rendval = ~0;
        !           551:                l = &REND(p->pgrp, p->rendtag);
        !           552:                for(d = *l; d; d = d->rendhash) {
        !           553:                        if(d == p) {
        !           554:                                *l = p->rendhash;
        !           555:                                ready(p);
        !           556:                                break;
        !           557:                        }
        !           558:                        l = &d->rendhash;
        !           559:                }
        !           560:        }
        !           561:        unlock(p->pgrp);
        !           562:        return ret;
        !           563: }
        !           564: 
        !           565: /*
        !           566:  * weird thing: keep at most NBROKEN around
        !           567:  */
        !           568: #define        NBROKEN 4
        !           569: struct
        !           570: {
        !           571:        QLock;
        !           572:        int     n;
        !           573:        Proc    *p[NBROKEN];
        !           574: }broken;
        !           575: 
        !           576: void
        !           577: addbroken(Proc *p)
        !           578: {
        !           579:        qlock(&broken);
        !           580:        if(broken.n == NBROKEN) {
        !           581:                ready(broken.p[0]);
        !           582:                memmove(&broken.p[0], &broken.p[1], sizeof(Proc*)*(NBROKEN-1));
        !           583:                --broken.n;
        !           584:        }
        !           585:        broken.p[broken.n++] = p;
        !           586:        qunlock(&broken);
        !           587: 
        !           588:        p->state = Broken;
        !           589:        p->psstate = 0;
        !           590:        sched();
        !           591: }
        !           592: 
        !           593: void
        !           594: unbreak(Proc *p)
        !           595: {
        !           596:        int b;
        !           597: 
        !           598:        qlock(&broken);
        !           599:        for(b=0; b < broken.n; b++)
        !           600:                if(broken.p[b] == p) {
        !           601:                        broken.n--;
        !           602:                        memmove(&broken.p[b], &broken.p[b+1],
        !           603:                                        sizeof(Proc*)*(NBROKEN-(b+1)));
        !           604:                        ready(p);
        !           605:                        break;
        !           606:                }
        !           607:        qunlock(&broken);
        !           608: }
        !           609: 
        !           610: int
        !           611: freebroken(void)
        !           612: {
        !           613:        int i, n;
        !           614: 
        !           615:        qlock(&broken);
        !           616:        n = broken.n;
        !           617:        for(i=0; i<n; i++) {
        !           618:                ready(broken.p[i]);
        !           619:                broken.p[i] = 0;
        !           620:        }
        !           621:        broken.n = 0;
        !           622:        qunlock(&broken);
        !           623:        return n;
        !           624: }
        !           625: 
        !           626: void
        !           627: pexit(char *exitstr, int freemem)
        !           628: {
        !           629:        int n;
        !           630:        long utime, stime;
        !           631:        Proc *p, *c;
        !           632:        Segment **s, **es;
        !           633:        Waitq *wq, *f, *next;
        !           634: 
        !           635:        c = u->p;
        !           636:        c->alarm = 0;
        !           637: 
        !           638:        if(c->fgrp)
        !           639:                closefgrp(c->fgrp);
        !           640:        closepgrp(c->pgrp);
        !           641:        close(u->dot);
        !           642:        if(c->egrp)
        !           643:                closeegrp(c->egrp);
        !           644: 
        !           645:        /*
        !           646:         * if not a kernel process and have a parent,
        !           647:         * do some housekeeping.
        !           648:         */
        !           649:        if(c->kp == 0) {
        !           650:                p = c->parent;
        !           651:                if(p == 0) {
        !           652:                        if(exitstr == 0)
        !           653:                                exitstr = "unknown";
        !           654:                        panic("boot process died: %s", exitstr);
        !           655:                }
        !           656: 
        !           657:                while(waserror())
        !           658:                        ;       
        !           659:                wq = smalloc(sizeof(Waitq));
        !           660:                poperror();
        !           661: 
        !           662:                readnum(0, wq->w.pid, NUMSIZE, c->pid, NUMSIZE);
        !           663:                utime = c->time[TUser] + c->time[TCUser];
        !           664:                stime = c->time[TSys] + c->time[TCSys];
        !           665:                readnum(0, &wq->w.time[TUser*12], NUMSIZE,
        !           666:                        TK2MS(utime), NUMSIZE);
        !           667:                readnum(0, &wq->w.time[TSys*12], NUMSIZE,
        !           668:                        TK2MS(stime), NUMSIZE);
        !           669:                readnum(0, &wq->w.time[TReal*12], NUMSIZE,
        !           670:                        TK2MS(MACHP(0)->ticks - c->time[TReal]), NUMSIZE);
        !           671:                if(exitstr && exitstr[0]){
        !           672:                        n = sprint(wq->w.msg, "%s %d:", c->text, c->pid);
        !           673:                        strncpy(wq->w.msg+n, exitstr, ERRLEN-n);
        !           674:                        wq->w.msg[ERRLEN-1] = 0;
        !           675:                }
        !           676:                else
        !           677:                        wq->w.msg[0] = '\0';
        !           678: 
        !           679:                lock(&p->exl);
        !           680:                /* My parent still alive, processes are limited to 128 Zombies to
        !           681:                 * prevent a badly written daemon lots of wait records
        !           682:                 */
        !           683:                if(p->pid == c->parentpid && p->state != Broken && p->nwait < 128) {    
        !           684:                        p->nchild--;
        !           685:                        p->time[TCUser] += utime;
        !           686:                        p->time[TCSys] += stime;
        !           687:        
        !           688:                        wq->next = p->waitq;
        !           689:                        p->waitq = wq;
        !           690:                        p->nwait++;
        !           691:                        unlock(&p->exl);
        !           692: 
        !           693:                        wakeup(&p->waitr);
        !           694:                }
        !           695:                else {
        !           696:                        unlock(&p->exl);
        !           697:                        free(wq);
        !           698:                }
        !           699:        }
        !           700: 
        !           701:        if(!freemem)
        !           702:                addbroken(c);
        !           703: 
        !           704:        es = &c->seg[NSEG];
        !           705:        for(s = c->seg; s < es; s++)
        !           706:                if(*s)
        !           707:                        putseg(*s);
        !           708: 
        !           709:        lock(&c->exl);          /* Prevent my children from leaving waits */
        !           710:        c->pid = 0;
        !           711:        unlock(&c->exl);
        !           712: 
        !           713:        for(f = c->waitq; f; f = next) {
        !           714:                next = f->next;
        !           715:                free(f);
        !           716:        }
        !           717: 
        !           718:        /*
        !           719:         * sched() cannot wait on these locks
        !           720:         */
        !           721:        qlock(&c->debug);
        !           722:        /* release debuggers */
        !           723:        if(c->pdbg) {
        !           724:                wakeup(&c->pdbg->sleep);
        !           725:                c->pdbg = 0;
        !           726:        }
        !           727: 
        !           728:        qunlock(&u->p->debug);
        !           729:        lock(&procalloc);
        !           730:        lock(&palloc);
        !           731: 
        !           732:        c->state = Moribund;
        !           733:        sched();
        !           734:        panic("pexit");
        !           735: }
        !           736: 
        !           737: int
        !           738: haswaitq(void *x)
        !           739: {
        !           740:        Proc *p;
        !           741: 
        !           742:        p = (Proc *)x;
        !           743:        return p->waitq != 0;
        !           744: }
        !           745: 
        !           746: ulong
        !           747: pwait(Waitmsg *w)
        !           748: {
        !           749:        Proc *p;
        !           750:        ulong cpid;
        !           751:        Waitq *wq;
        !           752: 
        !           753:        p = u->p;
        !           754: 
        !           755:        if(!canqlock(&p->qwaitr))
        !           756:                error(Einuse);
        !           757: 
        !           758:        if(waserror()) {
        !           759:                qunlock(&p->qwaitr);
        !           760:                nexterror();
        !           761:        }
        !           762: 
        !           763:        lock(&p->exl);
        !           764:        if(p->nchild == 0 && p->waitq == 0) {
        !           765:                unlock(&p->exl);
        !           766:                error(Enochild);
        !           767:        }
        !           768:        unlock(&p->exl);
        !           769: 
        !           770:        sleep(&p->waitr, haswaitq, u->p);
        !           771: 
        !           772:        lock(&p->exl);
        !           773:        wq = p->waitq;
        !           774:        p->waitq = wq->next;
        !           775:        p->nwait--;
        !           776:        unlock(&p->exl);
        !           777: 
        !           778:        qunlock(&p->qwaitr);
        !           779:        poperror();
        !           780: 
        !           781:        if(w)
        !           782:                memmove(w, &wq->w, sizeof(Waitmsg));
        !           783:        cpid = atoi(wq->w.pid);
        !           784:        free(wq);
        !           785:        return cpid;
        !           786: }
        !           787: 
        !           788: Proc*
        !           789: proctab(int i)
        !           790: {
        !           791:        return &procalloc.arena[i];
        !           792: }
        !           793: 
        !           794: void
        !           795: procdump(void)
        !           796: {
        !           797:        int i;
        !           798:        char *s;
        !           799:        Proc *p;
        !           800:        ulong bss;
        !           801:        Schedq *rq;
        !           802: 
        !           803:        for(i=0; i<conf.nproc; i++){
        !           804:                p = procalloc.arena+i;
        !           805:                if(p->state != Dead){
        !           806:                        bss = 0;
        !           807:                        if(p->seg[BSEG])
        !           808:                                bss = p->seg[BSEG]->top;
        !           809: 
        !           810:                        s = p->psstate;
        !           811:                        if(s == 0)
        !           812:                                s = "kproc";
        !           813:                        print("%3d:%10s %10s pc %8lux %8s (%s) ut %ld st %ld r %lux qpc %lux bss %lux\n",
        !           814:                                p->pid, p->text, p->user, p->pc, 
        !           815:                                s, statename[p->state], p->time[0],
        !           816:                                p->time[1], p->r, p->qlockpc, bss);
        !           817:                }
        !           818:        }
        !           819:        for(rq = runq; rq < &runq[Nrq]; rq++){
        !           820:                if(rq->head == 0)
        !           821:                        continue;
        !           822:                print("rq%d:", rq-runq);
        !           823:                for(p = rq->head; p; p = p->rnext)
        !           824:                        print(" %d(%d)", p->pid, m->ticks - p->readytime);
        !           825:                print("\n");
        !           826:        }
        !           827:        print("nrdy %d\n", nrdy);
        !           828: }
        !           829: 
        !           830: void
        !           831: kproc(char *name, void (*func)(void *), void *arg)
        !           832: {
        !           833:        Proc *p;
        !           834:        int n;
        !           835:        ulong upa;
        !           836:        User *up;
        !           837:        KMap *k;
        !           838:        static Pgrp *kpgrp;
        !           839:        char *user;
        !           840:        int lastvar;    /* used to compute stack address */
        !           841: 
        !           842:        /*
        !           843:         * Kernel stack
        !           844:         */
        !           845:        p = newproc();
        !           846:        p->psstate = 0;
        !           847:        p->procmode = 0644;
        !           848:        p->kp = 1;
        !           849:        p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF));
        !           850:        k = kmap(p->upage);
        !           851:        upa = VA(k);
        !           852:        up = (User*)upa;
        !           853: 
        !           854:        /*
        !           855:         * Save time: only copy u-> data and useful stack
        !           856:         */
        !           857:        memmove(up, u, sizeof(User));
        !           858:        n = USERADDR+BY2PG - (ulong)&lastvar;
        !           859:        n = (n+32) & ~(BY2WD-1);        /* be safe & word align */
        !           860:        memmove((void*)(upa+BY2PG-n), (void*)(USERADDR+BY2PG-n), n);
        !           861:        up->p = p;
        !           862: 
        !           863:        p->basepri = PriKproc;
        !           864:        p->priority = p->basepri;
        !           865: 
        !           866:        /*
        !           867:         * Refs
        !           868:         */
        !           869:        incref(up->dot);
        !           870:        kunmap(k);
        !           871: 
        !           872:        /*
        !           873:         * Sched
        !           874:         */
        !           875:        if(setlabel(&p->sched)){
        !           876:                p->state = Running; 
        !           877:                p->mach = m;
        !           878:                m->proc = p;
        !           879:                spllo();
        !           880:                (*func)(arg);
        !           881:                pexit(0, 1);
        !           882:        }
        !           883: 
        !           884:        user = eve;
        !           885:        strcpy(p->user, user);
        !           886:        if(kpgrp == 0){
        !           887:                kpgrp = newpgrp();
        !           888:        }
        !           889:        p->pgrp = kpgrp;
        !           890:        incref(kpgrp);
        !           891: 
        !           892:        strcpy(p->text, name);
        !           893: 
        !           894:        p->nchild = 0;
        !           895:        p->parent = 0;
        !           896:        memset(p->time, 0, sizeof(p->time));
        !           897:        p->time[TReal] = MACHP(0)->ticks;
        !           898:        ready(p);
        !           899:        /*
        !           900:         *  since the bss/data segments are now shareable,
        !           901:         *  any mmu info about this process is now stale
        !           902:         *  and has to be discarded.
        !           903:         */
        !           904:        flushmmu();
        !           905: }
        !           906: 
        !           907: /*
        !           908:  *  called splhi() by notify().  See comment in notify for the
        !           909:  *  reasoning.
        !           910:  */
        !           911: void
        !           912: procctl(Proc *p)
        !           913: {
        !           914:        char *state;
        !           915:        ulong s;
        !           916: 
        !           917:        switch(p->procctl) {
        !           918:        case Proc_exitme:
        !           919:                spllo();        /* pexit has locks in it */
        !           920:                pexit("Killed", 1);
        !           921: 
        !           922:        case Proc_traceme:
        !           923:                if(u->nnote == 0)
        !           924:                        return;
        !           925:                /* No break */
        !           926: 
        !           927:        case Proc_stopme:
        !           928:                p->procctl = 0;
        !           929:                state = p->psstate;
        !           930:                p->psstate = "Stopped";
        !           931:                /* free a waiting debugger */
        !           932:                s = spllo();
        !           933:                qlock(&p->debug);
        !           934:                if(p->pdbg) {
        !           935:                        wakeup(&p->pdbg->sleep);
        !           936:                        p->pdbg = 0;
        !           937:                }
        !           938:                qunlock(&p->debug);
        !           939:                splhi();
        !           940:                p->state = Stopped;
        !           941:                sched();
        !           942:                p->psstate = state;
        !           943:                splx(s);
        !           944:                return;
        !           945:        }
        !           946: }
        !           947: 
        !           948: #include "errstr.h"
        !           949: 
        !           950: void
        !           951: error(char *err)
        !           952: {
        !           953:        spllo();
        !           954:        strncpy(u->error, err, ERRLEN);
        !           955:        nexterror();
        !           956: }
        !           957: 
        !           958: void
        !           959: nexterror(void)
        !           960: {
        !           961:        gotolabel(&u->errlab[--u->nerrlab]);
        !           962: }
        !           963: 
        !           964: void
        !           965: exhausted(char *resource)
        !           966: {
        !           967:        char buf[ERRLEN];
        !           968: 
        !           969:        sprint(buf, "no free %s", resource);
        !           970:        error(buf);
        !           971: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.