Annotation of coherent/d/PS2_KERNEL/coh.386/proc.c, revision 1.1

1.1     ! root        1: /* (lgl-
        !             2:  *     The information contained herein is a trade secret of Mark Williams
        !             3:  *     Company, and  is confidential information.  It is provided  under a
        !             4:  *     license agreement,  and may be  copied or disclosed  only under the
        !             5:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
        !             6:  *     material without the express written authorization of Mark Williams
        !             7:  *     Company or persuant to the license agreement is unlawful.
        !             8:  *
        !             9:  *     COHERENT Version 2.3.37
        !            10:  *     Copyright (c) 1982, 1983, 1984.
        !            11:  *     An unpublished work by Mark Williams Company, Chicago.
        !            12:  *     All rights reserved.
        !            13:  -lgl) */
        !            14: /*
        !            15:  * Coherent.
        !            16:  * Process handling and scheduling.
        !            17:  *
        !            18:  * $Log:       proc.c,v $
        !            19:  * Revision 1.2  92/08/04  12:34:18  bin
        !            20:  * changed for ker 59
        !            21:  * 
        !            22:  * Revision 1.5  92/04/03  14:35:36  hal
        !            23:  * Kernel #49: piggy trace variable.
        !            24:  * 
        !            25:  * Revision 1.4  92/02/03  17:00:09  piggy
        !            26:  * Send SIGHUP to all group members on death of group leader.
        !            27:  */
        !            28: #include <sys/coherent.h>
        !            29: #include <acct.h>
        !            30: #include <errno.h>
        !            31: #include <sys/inode.h>
        !            32: #include <sys/proc.h>
        !            33: #include <sys/ptrace.h>
        !            34: #include <sys/sched.h>
        !            35: #include <sys/seg.h>
        !            36: #include <signal.h>
        !            37: #include <sys/stat.h>
        !            38: 
        !            39: /*
        !            40:  * Initialization.
        !            41:  * Set up the hash table queues.
        !            42:  */
        !            43: pcsinit()
        !            44: {
        !            45:        register PROC *pp;
        !            46:        register PLINK *lp;
        !            47: 
        !            48:        /*
        !            49:         * Explicitly initialize everything in the first process.
        !            50:         */
        !            51:        pp = &procq;
        !            52:        SELF = pp;
        !            53:        procq.p_nforw = pp;
        !            54:        procq.p_nback = pp;
        !            55:        procq.p_lforw = pp;
        !            56:        procq.p_lback = pp;
        !            57: 
        !            58: #ifdef _I386
        !            59:        /* Segments are initialized in mchinit() and eveinit().  */
        !            60: 
        !            61:        procq.p_uid = 0;                /* Effective uid */
        !            62:        procq.p_ruid = 0;               /* Real uid */
        !            63:        procq.p_rgid = 0;               /* Real gid */
        !            64:        procq.p_state = 0;              /* Scheduling state */
        !            65:        procq.p_flags = 0;              /* Flags */
        !            66:        procq.p_ssig = (sig_t) 0;       /* Signals which have been set */
        !            67: #ifdef _I386
        !            68:        procq.p_dfsig = (sig_t) 0xffffffff;  /* All signals are defaulted.  */
        !            69:        procq.p_hsig = (sig_t) 0;       /* Signals which are being held */
        !            70:        procq.p_dsig = (sig_t) 0;       /* Signals which are being deferred */
        !            71: #endif
        !            72:        procq.p_isig = (sig_t) 0;       /* Signals which are being ignored */
        !            73:        procq.p_event = NULL;           /* Wakeup event channel */
        !            74:        procq.p_alarm = 0;              /* Timer for alarms */
        !            75:        procq.p_group = 0;              /* Process group */
        !            76: /*
        !            77:  * Set ttdev to null so that we do not accidentally set a tty for init.
        !            78:  */
        !            79:        procq.p_ttdev = makedev(0,0);   /* Controlling terminal */
        !            80:        procq.p_nice = 0;               /* Nice value */
        !            81:        procq.p_cval = 0;               /* Cpu schedule value */
        !            82:        procq.p_sval = 0;               /* Swap schedule value */
        !            83:        procq.p_ival = 0;               /* Importance value */
        !            84:        procq.p_rval = 0;               /* Response value */
        !            85:        procq.p_lctim = 0;              /* Last time cval was updated */
        !            86:        procq.p_utime = 0L;             /* User time (HZ) */
        !            87:        procq.p_stime = 0L;             /* System time */
        !            88:        procq.p_cutime = 0L;            /* Sum of childs user time */
        !            89:        procq.p_cstime = 0L;            /* Sum of childs system time */
        !            90:        procq.p_exit = 0;               /* Exit status */
        !            91:        procq.p_polls = NULL;           /* Enabled polls */
        !            92:        /* Poll  timer */
        !            93:        procq.p_polltim.t_next = NULL;
        !            94:        procq.p_polltim.t_last = NULL;
        !            95:        procq.p_polltim.t_lbolt = 0L;
        !            96:        procq.p_polltim.t_func = NULL;
        !            97:        procq.p_polltim.t_farg = NULL;
        !            98: #ifndef _I386
        !            99:        procq.p_polltim.t_ldrv = 0;
        !           100: #endif /* _I386 */
        !           101: 
        !           102:        /* Alarm timer */
        !           103:        procq.p_alrmtim.t_next = NULL;
        !           104:        procq.p_alrmtim.t_last = NULL;
        !           105:        procq.p_alrmtim.t_lbolt = 0L;
        !           106:        procq.p_alrmtim.t_func = NULL;
        !           107:        procq.p_alrmtim.t_farg = NULL;
        !           108: #ifndef _I386
        !           109:        procq.p_alrmtim.t_ldrv = 0;
        !           110: #endif /* _I386 */
        !           111: 
        !           112:        procq.p_prl = NULL;             /* Pending record lock */
        !           113: #endif /* _I386 */
        !           114: 
        !           115:        for (lp=&linkq[0]; lp<&linkq[NHPLINK]; lp++) {
        !           116:                lp->p_lforw = lp;
        !           117:                lp->p_lback = lp;
        !           118:        }
        !           119: }
        !           120: 
        !           121: /*
        !           122:  * Initiate a process.
        !           123:  */
        !           124: PROC *
        !           125: #ifdef _I386
        !           126: process()
        !           127: #else
        !           128: process(f)
        !           129: int (*f)();
        !           130: #endif
        !           131: {
        !           132:        register PROC *pp1;
        !           133:        register PROC *pp;
        !           134:        register SEG *sp;
        !           135:        MCON mcon;
        !           136: 
        !           137:        if ((pp=kalloc(sizeof(PROC))) == NULL)
        !           138:                return (NULL);
        !           139: 
        !           140:        pp->p_flags = PFCORE;
        !           141:        pp->p_state = PSRUN;
        !           142:        pp->p_ttdev = NODEV;
        !           143: #ifndef _I386
        !           144:        /*
        !           145:         * What is this, and why is it 286 only?
        !           146:         */
        !           147:        if (f != NULL) {
        !           148:                pp->p_flags |= PFKERN;
        !           149:                sp = salloc((fsize_t)UPASIZE, SFSYST|SFHIGH|SFNSWP);
        !           150:                if (sp == NULL) {
        !           151:                        kfree(pp);
        !           152:                        return (NULL);
        !           153:                }
        !           154:                pp->p_segp[SIUSERP] = sp;
        !           155:                msetsys(&mcon, f, FP_SEL(sp->s_faddr));
        !           156:                kfcopy( (char *)&mcon,
        !           157:                        sp->s_faddr + offset(uproc, u_syscon),
        !           158:                        sizeof(mcon));
        !           159:        }
        !           160: #endif
        !           161:        lock(pnxgate);
        !           162: next:
        !           163: 
        !           164:        /*
        !           165:         * Pick the next process id.
        !           166:         */
        !           167:        /* DO NOT MESS WITH THE FOLLOWING CONDITIONAL UNLESS YOU
        !           168:           TEST THE RESULTS ON BOTH 286 AND 386 */
        !           169: #ifdef _I386
        !           170:        if (++cpid >= NPID)
        !           171:                cpid = 2;
        !           172:        pp->p_pid = cpid;
        !           173: #else
        !           174:        pp->p_pid = cpid++;
        !           175:        if (cpid >= NPID)
        !           176:                cpid = 2;
        !           177: #endif
        !           178: 
        !           179:        /*
        !           180:         * Make sure that process id is not in use.
        !           181:         */
        !           182:        pp1 = &procq;
        !           183:        while ((pp1=pp1->p_nforw) != &procq) {
        !           184:                if (pp1->p_pid < pp->p_pid)
        !           185:                        break;
        !           186:                if (pp1->p_pid == pp->p_pid)
        !           187:                        goto next;
        !           188:        }
        !           189: 
        !           190:        /*
        !           191:         * We've got a valid pid, so let's put this process into
        !           192:         * the process table.
        !           193:         */
        !           194:        pp->p_nback = pp1->p_nback;
        !           195:        pp1->p_nback->p_nforw = pp;
        !           196:        pp->p_nforw = pp1;
        !           197:        pp1->p_nback = pp;
        !           198:        unlock(pnxgate);
        !           199:        return (pp);
        !           200: }
        !           201: 
        !           202: /*
        !           203:  * Remove a process from the next queue and release and space.
        !           204:  */
        !           205: relproc(pp)
        !           206: register PROC *pp;
        !           207: {
        !           208:        register SEG * sp;
        !           209: 
        !           210:        /*
        !           211:         * Child process still has a user-area.
        !           212:         */
        !           213:        if ((sp = pp->p_segp[SIUSERP]) != NULL) {
        !           214: 
        !           215:                /*
        !           216:                 * Detach user-area from child process.
        !           217:                 */
        !           218:                pp->p_segp[SIUSERP] = NULL;
        !           219: 
        !           220:                /*
        !           221:                 * Child process is swapped out.
        !           222:                 */
        !           223:                if (pp->p_flags & PFSWAP)
        !           224:                        sp->s_lrefc++;
        !           225: 
        !           226:                /*
        !           227:                 * Release child's user-area.
        !           228:                 */
        !           229:                sfree(sp);
        !           230:        }
        !           231: 
        !           232:        /*
        !           233:         * Remove process from doubly-linked list of all processes.
        !           234:         * Release space allocated for proc structure.
        !           235:         */
        !           236:        lock(pnxgate);
        !           237:        pp->p_nback->p_nforw = pp->p_nforw;
        !           238:        pp->p_nforw->p_nback = pp->p_nback;
        !           239:        unlock(pnxgate);
        !           240:        kfree(pp);
        !           241: }
        !           242: 
        !           243: /*
        !           244:  * Create a clone of ourselves.
        !           245:  *     N.B. - consave(&mcon) returns twice; anything not initialized
        !           246:  *     in automatic storage before the call to segadup() will not be
        !           247:  *     initialized when the second return from consave() commences.
        !           248:  */
        !           249: pfork()
        !           250: {
        !           251:        register PROC *cpp;
        !           252:        register PROC *pp;
        !           253:        register int s;
        !           254:        MCON mcon;
        !           255: 
        !           256: #ifdef _I386
        !           257:        if ((cpp=process()) == NULL) {
        !           258: #else
        !           259:        if ((cpp=process(NULL)) == NULL) {
        !           260: #endif
        !           261:                SET_U_ERROR( EAGAIN, "no more process table entries" );
        !           262:                return -1;
        !           263:        }
        !           264: 
        !           265: #ifndef _I386
        !           266:        s = sphi();
        !           267:        usave();        /* Put the current copy of uarea into its segment */
        !           268:        spl(s);
        !           269: #endif
        !           270: 
        !           271:        pp = SELF;
        !           272:        s = sphi();     /* put current interrupt level into s before segadup */
        !           273:        spl(s);
        !           274:        /*
        !           275:         * As stated above, no auto variable may be changed between calls
        !           276:         * to segadup() and consave().
        !           277:         */
        !           278:        if (segadup(cpp) == 0) {
        !           279:                SET_U_ERROR( EAGAIN, "can not duplicate segments" );
        !           280:                relproc(cpp);
        !           281:                return -1;
        !           282:        }
        !           283:        if (u.u_rdir != NULL)
        !           284:                u.u_rdir->i_refc++;
        !           285:        if (u.u_cdir != NULL)
        !           286:                u.u_cdir->i_refc++;
        !           287:        fdadupl();
        !           288:        cpp->p_uid   = pp->p_uid;
        !           289:        cpp->p_ruid  = pp->p_ruid;
        !           290:        cpp->p_rgid  = pp->p_rgid;
        !           291:        cpp->p_ppid  = pp->p_pid;
        !           292:        cpp->p_ttdev = pp->p_ttdev;
        !           293:        cpp->p_group = pp->p_group;
        !           294:        cpp->p_ssig  = pp->p_ssig;
        !           295: #ifdef _I386
        !           296:        cpp->p_dfsig  = pp->p_dfsig;
        !           297:        cpp->p_dsig  = pp->p_dsig;
        !           298:        cpp->p_hsig  = pp->p_hsig;
        !           299: #endif /* _I386 */
        !           300:        cpp->p_isig  = pp->p_isig;
        !           301:        cpp->p_cval  = CVCHILD;
        !           302:        cpp->p_ival  = IVCHILD;
        !           303:        cpp->p_sval  = SVCHILD;
        !           304:        cpp->p_rval  = RVCHILD;
        !           305: #ifdef _I386
        !           306:        cpp->p_prl = NULL;
        !           307: #endif
        !           308: 
        !           309:        sphi();         /* s = sphi() was done before segadup() */
        !           310:        consave(&mcon);
        !           311:        spl(s);
        !           312: 
        !           313:        /*
        !           314:         * Parent process.
        !           315:         */
        !           316:        if ((pp = SELF) != cpp) {
        !           317:                segfinm(cpp->p_segp[SIUSERP]);
        !           318: #ifdef _I386
        !           319:                dmaout(sizeof(mcon), 
        !           320:                   MAPIO(cpp->p_segp[SIUSERP]->s_vmem,offset(uproc,u_syscon)),
        !           321:                        (char *)&mcon);
        !           322: #else
        !           323:                kfcopy((char *)&mcon,
        !           324:                        cpp->p_segp[SIUSERP]->s_faddr + offset(uproc,u_syscon),
        !           325:                        sizeof(mcon));
        !           326: #endif
        !           327:                mfixcon(cpp);
        !           328:                s = sphi();
        !           329:                setrun(cpp);
        !           330:                spl(s);
        !           331: #ifdef _I386
        !           332:                u.u_rval2 = 0;
        !           333: #endif
        !           334:                return(cpp->p_pid);
        !           335:        }
        !           336: 
        !           337:        /*
        !           338:         * Child process.
        !           339:         */
        !           340:        else {
        !           341:                u.u_btime = timer.t_time;
        !           342:                u.u_flag = AFORK;
        !           343: #ifdef _I386
        !           344: #ifdef UPROC_VERSION
        !           345:                u.u_version = UPROC_VERSION;
        !           346: #endif /* UPROC_VERSION */
        !           347:                u.u_sleep[0] = '\0'; /* We are not sleeping to start with.  */
        !           348:                sproto(0);
        !           349: #else
        !           350:                sproto();
        !           351: #endif
        !           352:                segload();
        !           353: #ifdef _I386
        !           354:                u.u_rval2 = SELF->p_ppid;
        !           355: #endif
        !           356:                return 0;
        !           357:        }
        !           358: }
        !           359: 
        !           360: /*
        !           361:  * Die.
        !           362:  */
        !           363: pexit(s)
        !           364: {
        !           365:        register PROC *pp1;
        !           366:        register PROC *pp;
        !           367:        register SEG  *sp;
        !           368:        register int n;
        !           369:        PROC *parent;
        !           370: 
        !           371:        pp = SELF;
        !           372: 
        !           373:        T_PIGGY( 0x1, printf("%s:pexit(%x)", u.u_comm, s); );
        !           374:        /*
        !           375:         * Cancel alarm and poll timers [if any].
        !           376:         */
        !           377:        timeout(&pp->p_alrmtim, 0, NULL, 0);
        !           378:        timeout(&pp->p_polltim, 0, NULL, 0);
        !           379: 
        !           380:        /*
        !           381:         * Write out accounting directory and close all files associated with
        !           382:         * this process.
        !           383:         */
        !           384:        setacct();
        !           385:        if (u.u_rdir)
        !           386:                ldetach(u.u_rdir);
        !           387:        if (u.u_cdir)
        !           388:                ldetach(u.u_cdir);
        !           389:        fdaclose();
        !           390: 
        !           391:        /*
        !           392:         * Free all segments in reverse order, except for user-area.
        !           393:         */
        !           394:        for (n = NUSEG; --n > 0;) {
        !           395:                if ((sp = pp->p_segp[n]) != NULL) {
        !           396:                        pp->p_segp[n] = NULL;
        !           397:                        sfree(sp);
        !           398:                }
        !           399:        }
        !           400: 
        !           401:        /*
        !           402:         * Wakeup our parent.  If we have any children, init will become the
        !           403:         * new parent.  If there are any children we are tracing who are
        !           404:         * waiting for us, we wake them up.
        !           405:         */
        !           406:        pp1 = &procq;
        !           407:        while ((pp1=pp1->p_nforw) != &procq) {
        !           408:                if (pp1->p_pid == pp->p_ppid) {
        !           409:                        parent = pp1;   /* Remember our parent.  */
        !           410:                        if (pp1->p_state==PSSLEEP && pp1->p_event==(char *)pp1)
        !           411:                                wakeup((char *)pp1);
        !           412:                }
        !           413:                if (pp1->p_ppid == pp->p_pid) {
        !           414:                        pp1->p_ppid = 1;
        !           415:                        if (pp1->p_state == PSDEAD)
        !           416:                                wakeup((char *)eprocp);
        !           417:                        if ((pp1->p_flags&PFTRAC) != 0)
        !           418:                                wakeup((char *)&pts.pt_req);
        !           419:                }
        !           420:        }
        !           421: 
        !           422:        /*
        !           423:         * Wake up swapper if swap timer is active.
        !           424:         */
        !           425:        if (stimer.t_last != 0)
        !           426:                wakeup((char *) &stimer);
        !           427: 
        !           428:        /*
        !           429:         * Mark us as dead and give up the processor forever.
        !           430:         */
        !           431:        pp->p_exit = s;
        !           432:        pp->p_state = PSDEAD;
        !           433: 
        !           434: #ifdef _I386
        !           435:        /*
        !           436:         * If this is a process group leader, inform all members of the group
        !           437:         * of the recent death with a HUP signal.
        !           438:         */
        !           439:        if (pp->p_group == pp->p_pid) {
        !           440:                ukill(-pp->p_pid, SIGHUP);
        !           441:        }
        !           442: #else
        !           443:        uasa = 0;
        !           444: #endif
        !           445: 
        !           446: #ifdef _I386
        !           447:        T_PIGGY( 0x100, printf("<CHLD pid: %d ppid: %d>",
        !           448:                                pp->p_pid, parent->p_pid); );
        !           449: 
        !           450:        /*
        !           451:         * If the parent is ignoring SIGCHLD, 
        !           452:         * remove the zombie right away.
        !           453:         */
        !           454: #      define CHLDBIT (((sig_t) 1) << (SIGCHLD - 1))
        !           455:        if (CHLDBIT & parent->p_isig) {
        !           456:                parent->p_cutime += pp->p_utime + pp->p_cutime;
        !           457:                parent->p_cstime += pp->p_stime + pp->p_cstime;
        !           458:                relproc(pp);
        !           459:        } else {
        !           460:                /*
        !           461:                 * If SIGCHLD is not defaulted, notify our parent
        !           462:                 * of our demise.
        !           463:                 */
        !           464:                if (!(CHLDBIT & parent->p_dfsig)) {
        !           465:                        sendsig(SIGCHLD, parent );
        !           466:                }
        !           467:        }
        !           468: #endif /* _I386 */
        !           469: 
        !           470:        dispatch();
        !           471: }
        !           472: 
        !           473: #ifdef _I386
        !           474: /*
        !           475:  * Sleep verbosely.  Put a short string describing our reason for sleeping
        !           476:  * into our U area, and then go to sleep.
        !           477:  */
        !           478: v_sleep(e, cl, sl, sr, msg)
        !           479:        char *e;
        !           480:        int cl, sl, sr;
        !           481:        char *msg;
        !           482: {
        !           483:        int i;
        !           484: 
        !           485:        /*
        !           486:         * The descriptive string may be at most 10 characters long.
        !           487:         * It will only be NUL terminated if it has 9 or fewer characters.
        !           488:         */
        !           489:        for (i = 0; i < 10; ++i) {
        !           490:                if ('\0' == (u.u_sleep[i] = msg[i])) {
        !           491:                        break;
        !           492:                }
        !           493:        }
        !           494: 
        !           495:        sleep(e, cl, sl, sr);
        !           496: } /* v_sleep() */
        !           497: #endif
        !           498: 
        !           499: /*
        !           500:  * Sleep on the event `e'.  This gives up the processor until someone
        !           501:  * wakes us up.  Since it is possible for many people to sleep on the
        !           502:  * same event, the caller when awakened should make sure that what he
        !           503:  * was waiting for has completed and if not, go to sleep again.  `cl'
        !           504:  * is the cpu value we get to get the cpu as soon as we are woken up.
        !           505:  * `sl' is the swap value we get to keep us in memory for the duration
        !           506:  * of the sleep.  `sr' is the swap value that allows us to get swapped
        !           507:  * in if we have been swapped out.
        !           508:  */
        !           509: sleep(e, cl, sl, sr)
        !           510: char *e;
        !           511: {
        !           512:        register PROC *bp;
        !           513:        register PROC *fp;
        !           514:        register PROC *pp;
        !           515:        register int s;
        !           516: 
        !           517:        pp = SELF;
        !           518: 
        !           519:        /*
        !           520:         * See if we have a signal awaiting.
        !           521:         */
        !           522:        if (cl<CVNOSIG && pp->p_ssig && nondsig()) {
        !           523:                sphi();
        !           524:                envrest(&u.u_sigenv);
        !           525:        }
        !           526: 
        !           527:        /*
        !           528:         * Get ready to go to sleep and do so.
        !           529:         */
        !           530:        s = sphi();
        !           531:        pp->p_state = PSSLEEP;
        !           532:        pp->p_event = e;
        !           533:        pp->p_lctim = utimer;
        !           534:        addu(pp->p_cval, cl);
        !           535:        pp->p_ival = sl;
        !           536:        pp->p_rval = sr;
        !           537:        fp = &linkq[hash(e)];
        !           538:        bp = fp->p_lback;
        !           539:        pp->p_lforw = fp;
        !           540:        fp->p_lback = pp;
        !           541:        pp->p_lback = bp;
        !           542:        bp->p_lforw = pp;
        !           543:        spl(s);
        !           544:        dispatch();
        !           545: 
        !           546:        /*
        !           547:         * We have just woken up.  Get ready to return.
        !           548:         */
        !           549:        subu(pp->p_cval, cl);
        !           550:        pp->p_ival = 0;
        !           551:        pp->p_rval = 0;
        !           552: 
        !           553:        /*
        !           554:         * Since we are no longer asleep, we no longer need 
        !           555:         * to publish a reason for sleeping.
        !           556:         */
        !           557: #ifdef _I386
        !           558:        u.u_sleep[0] = '\0';
        !           559: #endif
        !           560: 
        !           561:        /*
        !           562:         * Check for an interrupted system call.
        !           563:         */
        !           564:        if (cl<CVNOSIG && pp->p_ssig && nondsig()) {
        !           565:                sphi();
        !           566:                envrest(&u.u_sigenv);
        !           567:        }
        !           568: }
        !           569: 
        !           570: /*
        !           571:  * Defer function to wake up all processes sleeping on the event `e'.
        !           572:  */
        !           573: wakeup(e)
        !           574: char *e;
        !           575: {
        !           576:        void dwakeup();
        !           577: 
        !           578: #ifdef TRACER
        !           579:        /*
        !           580:         * In diagnostic kernel, keep return addr on queue as well.
        !           581:         */
        !           582:        int *r=(int*)(&e);
        !           583:        defer0(dwakeup, e, *(r-1));
        !           584: #else
        !           585:        defer(dwakeup, e);
        !           586: #endif
        !           587: }
        !           588: 
        !           589: /*
        !           590:  * Wake up all processes sleeping on the event `e'.
        !           591:  */
        !           592: void
        !           593: dwakeup(e)
        !           594: char *e;
        !           595: {
        !           596:        register PROC *pp;
        !           597:        register PROC *pp1;
        !           598:        register int s;
        !           599: 
        !           600:        /*
        !           601:         * Identify event queue to check.
        !           602:         * Disable interrupts.
        !           603:         */
        !           604:        pp1 = &linkq[hash(e)];
        !           605:        pp = pp1;
        !           606:        s = sphi();
        !           607: 
        !           608:        /*
        !           609:         * Traverse doubly-linked circular event-queue.
        !           610:         */
        !           611:        while ((pp = pp->p_lforw) != pp1) {
        !           612: 
        !           613:                /*
        !           614:                 * Process is waiting on event 'e'.
        !           615:                 */
        !           616:                if (pp->p_event == e) {
        !           617:                        /*
        !           618:                         * Remove process from event queue.
        !           619:                         * Update process priority.
        !           620:                         * Insert process into run queue.
        !           621:                         */
        !           622:                        pp->p_lback->p_lforw = pp->p_lforw;
        !           623:                        pp->p_lforw->p_lback = pp->p_lback;
        !           624:                        addu(pp->p_cval, (utimer-pp->p_lctim)*CVCLOCK);
        !           625:                        setrun(pp);
        !           626: 
        !           627:                        /*
        !           628:                         * Enable interrupts.
        !           629:                         * Restart search at start of event queue.
        !           630:                         * Disable interrupts.
        !           631:                         */
        !           632:                        spl(s);
        !           633:                        pp = pp1;
        !           634:                        s = sphi();
        !           635:                }
        !           636:        }
        !           637:        spl(s);
        !           638: }
        !           639: 
        !           640: /*
        !           641:  * Reschedule the processor.
        !           642:  */
        !           643: dispatch()
        !           644: {
        !           645:        register PROC *pp1;
        !           646:        register PROC *pp2;
        !           647:        register unsigned v;
        !           648:        register int s;
        !           649: 
        !           650:        s = sphi();
        !           651:        pp1 = iprocp;
        !           652:        pp2 = &procq;
        !           653:        v = 0;
        !           654:        while ((pp2=pp2->p_lforw) != &procq) {
        !           655:                v -= pp2->p_cval;
        !           656:                if ((pp2->p_flags&PFCORE) == 0)
        !           657:                        continue;
        !           658:                pp1 = pp2->p_lforw;
        !           659:                pp1->p_cval += pp2->p_cval;
        !           660:                pp2->p_cval = v;
        !           661:                pp1->p_lback = pp2->p_lback;
        !           662:                pp1->p_lback->p_lforw = pp1;
        !           663:                pp1 = pp2;
        !           664:                break;
        !           665:        }
        !           666:        spl(s);
        !           667: 
        !           668:        quantum = NCRTICK;
        !           669:        disflag = 0;
        !           670:        if (pp1 != SELF) {
        !           671:                /*
        !           672:                 * Consave() returns twice.
        !           673:                 * 1st time is after our context is saved in u.u_syscon,
        !           674:                 *      whereupon we should restore other proc's context.
        !           675:                 * 2nd time is after our context is restored by another proc.
        !           676:                 * Conrest() forces a context switch to a new process.
        !           677:                 */
        !           678:                s = sphi();
        !           679:                SELF = pp1;
        !           680:                if (consave(&u.u_syscon) == 0) {
        !           681: #ifdef _I386
        !           682:                        conrest(*pp1->p_segp[SIUSERP]->s_vmem, &u.u_syscon);
        !           683: #else
        !           684:                        conrest(
        !           685:                          FP_SEL(pp1->p_u->s_faddr), offset(uproc,u_syscon));
        !           686: #endif
        !           687:                }
        !           688:                if (SELF->p_pid != 0)
        !           689:                        segload();
        !           690:                spl(s);
        !           691:        }
        !           692: }
        !           693: 
        !           694: /*
        !           695:  * Add a process to the run queue.
        !           696:  * This routine must be called at high priority.
        !           697:  */
        !           698: setrun(pp1)
        !           699: register PROC *pp1;
        !           700: {
        !           701:        register PROC *pp2;
        !           702:        register unsigned v;
        !           703: 
        !           704:        v = 0;
        !           705:        pp2 = &procq;
        !           706:        for (;;) {
        !           707:                pp2 = pp2->p_lback;
        !           708:                if ((v+=pp2->p_lforw->p_cval) >= pp1->p_cval)
        !           709:                        break;
        !           710:                if (pp2 == &procq)
        !           711:                        break;
        !           712:        }
        !           713:        pp2->p_lforw->p_lback = pp1;
        !           714:        pp1->p_lforw = pp2->p_lforw;
        !           715:        pp2->p_lforw = pp1;
        !           716:        pp1->p_lback = pp2;
        !           717:        v -= pp1->p_cval;
        !           718:        pp1->p_cval = v;
        !           719:        pp1->p_lforw->p_cval -= v;
        !           720:        pp1->p_state = PSRUN;
        !           721: }
        !           722: 
        !           723: /*
        !           724:  * Wait for the gate `g' to unlock, and then lock it.
        !           725:  */
        !           726: lock(g)
        !           727: register GATE g;
        !           728: {
        !           729:        register int s;
        !           730: 
        !           731:        s = sphi();
        !           732:        while (g[0]) {
        !           733:                g[1] = 1;
        !           734:                v_sleep((char *)g, CVGATE, IVGATE, SVGATE, "lock");
        !           735:                /* Waiting for a gate to unlock.  */
        !           736:        }
        !           737:        g[0] = 1;
        !           738:        spl(s);
        !           739: }
        !           740: 
        !           741: /*
        !           742:  * Unlock the gate `g'.
        !           743:  */
        !           744: unlock(g)
        !           745: register GATE g;
        !           746: {
        !           747:        g[0] = 0;
        !           748:        if (g[1]) {
        !           749:                g[1] = 0;
        !           750:                disflag = 1;
        !           751:                wakeup((char *)g);
        !           752:        }
        !           753: }

unix.superglobalmegacorp.com

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