Annotation of coherent/d/PS2_KERNEL/coh.386/proc.c, revision 1.1.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.