Annotation of coherent/d/kernel/USRSRC/coh/proc.c, revision 1.1.1.1

1.1       root        1: /* $Header: /newbits/kernel/USRSRC/coh/RCS/proc.c,v 1.4 91/07/24 07:51:40 bin Exp Locker: bin $ */
                      2: /* (lgl-
                      3:  *     The information contained herein is a trade secret of Mark Williams
                      4:  *     Company, and  is confidential information.  It is provided  under a
                      5:  *     license agreement,  and may be  copied or disclosed  only under the
                      6:  *     terms of  that agreement.  Any  reproduction or disclosure  of this
                      7:  *     material without the express written authorization of Mark Williams
                      8:  *     Company or persuant to the license agreement is unlawful.
                      9:  *
                     10:  *     COHERENT Version 2.3.37
                     11:  *     Copyright (c) 1982, 1983, 1984.
                     12:  *     An unpublished work by Mark Williams Company, Chicago.
                     13:  *     All rights reserved.
                     14:  -lgl) */
                     15: /*
                     16:  * Coherent.
                     17:  * Process handling and scheduling.
                     18:  *
                     19:  * $Log:       proc.c,v $
                     20:  * Revision 1.4  91/07/24  07:51:40  bin
                     21:  * update prov by hal
                     22:  * 
                     23:  * 
                     24:  * Revision 1.2        88/08/05  15:30:01      src
                     25:  * pfork() made more rigorous, supports loadable driver forks, etc.
                     26:  * lock/unlock more efficient, since know wakeup is synchronous.
                     27:  * 
                     28:  * Revision 1.1        88/03/24  16:14:16      src
                     29:  * Initial revision
                     30:  * 
                     31:  * 88/03/10    Allan Cornish           /usr/src/sys/coh/proc.c
                     32:  * Numerous temporary fixes due to AMD 286 chip being buggy in protected mode.
                     33:  * These partial fixes will be removed once all CPU's are replaced.
                     34:  *
                     35:  * 88/01/21    Allan Cornish           /usr/src/sys/coh/proc.c
                     36:  * Race condition caused by pexit() calling sfree() on the user-area
                     37:  * when the segmentation gate is locked is now prevented.
                     38:  * Release of the user area now deferred until relproc() invoked by uwait().
                     39:  *
                     40:  * 87/11/13    Allan Cornish           /usr/src/sys/coh/proc.c
                     41:  * pexit() now sets uasa to 0 before dispatching processor.
                     42:  *
                     43:  * 87/11/05    Allan Cornish           /usr/src/sys/coh/proc.c
                     44:  * New seg struct now used to allow extended addressing.
                     45:  *
                     46:  * 87/07/08    Allan Cornish           /usr/src/sys/coh/proc.c
                     47:  * pexit() now cancels poll/alarm timed functions before terminating.
                     48:  *
                     49:  * 87/01/05    Allan Cornish           /usr/src/sys/coh/proc.c
                     50:  * pexit() now wakes the swapper before terminating.
                     51:  */
                     52: #include <sys/coherent.h>
                     53: #include <acct.h>
                     54: #include <errno.h>
                     55: #include <sys/inode.h>
                     56: #include <sys/proc.h>
                     57: #include <sys/ptrace.h>
                     58: #include <sys/sched.h>
                     59: #include <sys/seg.h>
                     60: #include <signal.h>
                     61: #include <sys/stat.h>
                     62: #include <sys/uproc.h>
                     63: 
                     64: /*
                     65:  * Initialisation.
                     66:  * Set up the hash table queues.
                     67:  */
                     68: pcsinit()
                     69: {
                     70:        register PROC *pp;
                     71:        register PLINK *lp;
                     72: 
                     73:        pp = &procq;
                     74:        SELF = pp;
                     75:        procq.p_nforw = pp;
                     76:        procq.p_nback = pp;
                     77:        procq.p_lforw = pp;
                     78:        procq.p_lback = pp;
                     79:        for (lp=&linkq[0]; lp<&linkq[NHPLINK]; lp++) {
                     80:                lp->p_lforw = lp;
                     81:                lp->p_lback = lp;
                     82:        }
                     83: }
                     84: 
                     85: /*
                     86:  * Initiate a process.  `f' is a kernel function that is associated with
                     87:  * the process.
                     88:  */
                     89: PROC *
                     90: process(f)
                     91: int (*f)();
                     92: {
                     93:        register PROC *pp1;
                     94:        register PROC *pp;
                     95:        register SEG *sp;
                     96:        MCON mcon;
                     97: 
                     98:        if ((pp=kalloc(sizeof(PROC))) == NULL)
                     99:                return (NULL);
                    100: 
                    101:        pp->p_flags = PFCORE;
                    102:        pp->p_state = PSRUN;
                    103:        pp->p_ttdev = NODEV;
                    104: 
                    105:        if (f != NULL) {
                    106:                pp->p_flags |= PFKERN;
                    107:                sp = salloc((fsize_t)UPASIZE, SFSYST|SFHIGH|SFNSWP);
                    108:                if (sp == NULL) {
                    109:                        kfree(pp);
                    110:                        return (NULL);
                    111:                }
                    112:                pp->p_segp[SIUSERP] = sp;
                    113:                msetsys( &mcon, f, FP_SEL(sp->s_faddr) );
                    114:                kfcopy( (char *)&mcon,
                    115:                        sp->s_faddr + offset(uproc, u_syscon),
                    116:                        sizeof(mcon) );
                    117:        }
                    118:        lock(pnxgate);
                    119: next:
                    120:        pp->p_pid = cpid++;
                    121:        if (cpid >= NPID)
                    122:                cpid = 2;
                    123:        pp1 = &procq;
                    124:        while ((pp1=pp1->p_nforw) != &procq) {
                    125:                if (pp1->p_pid < pp->p_pid)
                    126:                        break;
                    127:                if (pp1->p_pid == pp->p_pid)
                    128:                        goto next;
                    129:        }
                    130:        pp->p_nback = pp1->p_nback;
                    131:        pp1->p_nback->p_nforw = pp;
                    132:        pp->p_nforw = pp1;
                    133:        pp1->p_nback = pp;
                    134:        unlock(pnxgate);
                    135:        return (pp);
                    136: }
                    137: 
                    138: /*
                    139:  * Remove a process from the next queue and release and space.
                    140:  */
                    141: relproc(pp)
                    142: register PROC *pp;
                    143: {
                    144:        register SEG * sp;
                    145: 
                    146:        /*
                    147:         * Child process still has a user-area.
                    148:         */
                    149:        if ( (sp = pp->p_segp[SIUSERP]) != NULL ) {
                    150: 
                    151:                /*
                    152:                 * Detach user-area from child process.
                    153:                 */
                    154:                pp->p_segp[SIUSERP] = NULL;
                    155: 
                    156:                /*
                    157:                 * Child process is swapped out.
                    158:                 */
                    159:                if ( pp->p_flags & PFSWAP )
                    160:                        sp->s_lrefc++;
                    161: 
                    162:                /*
                    163:                 * Release child's user-area.
                    164:                 */
                    165:                sfree( sp );
                    166:        }
                    167: 
                    168:        /*
                    169:         * Remove process from doubly-linked list of all processes.
                    170:         * Release space allocated for proc structure.
                    171:         */
                    172:        lock(pnxgate);
                    173:        pp->p_nback->p_nforw = pp->p_nforw;
                    174:        pp->p_nforw->p_nback = pp->p_nback;
                    175:        unlock(pnxgate);
                    176:        kfree(pp);
                    177: }
                    178: 
                    179: /*
                    180:  * Create a clone of ourselves.
                    181:  *     N.B. - consave(&mcon) returns twice; anything not initialized
                    182:  *     in automatic storage before the call to segadup() will not be
                    183:  *     initialized when the second return from consave() commences.
                    184:  */
                    185: pfork()
                    186: {
                    187:        register PROC *cpp;
                    188:        register PROC *pp;
                    189:        register int s;
                    190:        MCON mcon;
                    191: 
                    192:        if ((cpp=process(NULL)) == NULL) {
                    193:                u.u_error = EAGAIN;
                    194:                return;
                    195:        }
                    196: 
                    197:        s = sphi();     /* Make usave a null macro if unnecessary */
                    198:        usave();        /* Put the current copy of uarea into its segment */
                    199:        spl(s);
                    200: 
                    201:        if (segadup(cpp) == 0) {
                    202:                u.u_error = EAGAIN;
                    203:                relproc(cpp);
                    204:                return;
                    205:        }
                    206:        if ( u.u_rdir != NULL )
                    207:                u.u_rdir->i_refc++;
                    208:        if ( u.u_cdir != NULL )
                    209:                u.u_cdir->i_refc++;
                    210:        fdadupl();
                    211:        pp = SELF;
                    212:        cpp->p_uid   = pp->p_uid;
                    213:        cpp->p_ruid  = pp->p_ruid;
                    214:        cpp->p_rgid  = pp->p_rgid;
                    215:        cpp->p_ppid  = pp->p_pid;
                    216:        cpp->p_ttdev = pp->p_ttdev;
                    217:        cpp->p_group = pp->p_group;
                    218:        cpp->p_ssig  = pp->p_ssig;
                    219:        cpp->p_isig  = pp->p_isig;
                    220:        cpp->p_cval  = CVCHILD;
                    221:        cpp->p_ival  = IVCHILD;
                    222:        cpp->p_sval  = SVCHILD;
                    223:        cpp->p_rval  = RVCHILD;
                    224: 
                    225:        s = sphi();
                    226:        consave(&mcon);
                    227:        spl( s );
                    228: 
                    229:        /*
                    230:         * Parent process.
                    231:         */
                    232:        if ( (pp = SELF) != cpp ) {
                    233:                segfinm(cpp->p_segp[SIUSERP]);
                    234:                kfcopy( (char *)&mcon,
                    235:                        cpp->p_segp[SIUSERP]->s_faddr + offset(uproc,u_syscon),
                    236:                        sizeof(mcon) );
                    237:                mfixcon(cpp);
                    238:                s = sphi();
                    239:                setrun(cpp);
                    240:                spl(s);
                    241:                return( cpp->p_pid );
                    242:        }
                    243: 
                    244:        /*
                    245:         * Child process.
                    246:         */
                    247:        else {
                    248:                u.u_btime = timer.t_time;
                    249:                u.u_flag = AFORK;
                    250:                /* for (i=0; i<NUSEG; i++) done in sproto */
                    251:                        /* u.u_segl[i].sr_segp = pp->p_segp[i]; ditto */
                    252:                sproto();
                    253:                segload();
                    254:                return( 0 );
                    255:        }
                    256: }
                    257: 
                    258: /*
                    259:  * Die.
                    260:  */
                    261: pexit(s)
                    262: {
                    263:        register PROC *pp1;
                    264:        register PROC *pp;
                    265:        register SEG  *sp;
                    266:        register int n;
                    267: 
                    268:        pp = SELF;
                    269: 
                    270:        /*
                    271:         * Cancel alarm and poll timers [if any].
                    272:         */
                    273:        timeout( &pp->p_alrmtim, 0, NULL, 0 );
                    274:        timeout( &pp->p_polltim, 0, NULL, 0 );
                    275: 
                    276:        /*
                    277:         * Write out accounting directory and close all files associated with
                    278:         * this process.
                    279:         */
                    280:        setacct();
                    281:        if ( u.u_rdir )
                    282:                ldetach(u.u_rdir);
                    283:        if ( u.u_cdir )
                    284:                ldetach(u.u_cdir);
                    285:        fdaclose();
                    286: 
                    287:        /*
                    288:         * Free all segments in reverse order, except for user-area.
                    289:         */
                    290:        for ( n = NUSEG; --n > 0; ) {
                    291:                if ( (sp = pp->p_segp[n]) != NULL ) {
                    292:                        pp->p_segp[n] = NULL;
                    293:                        sfree( sp );
                    294:                }
                    295:        }
                    296: 
                    297:        /*
                    298:         * Wakeup our parent.  If we have any children, init will become the
                    299:         * new parent.  If there are any children we are tracing who are
                    300:         * waiting for us, we wake them up.
                    301:         */
                    302:        pp1 = &procq;
                    303:        while ((pp1=pp1->p_nforw) != &procq) {
                    304:                if (pp1->p_pid == pp->p_ppid) {
                    305:                        if (pp1->p_state==PSSLEEP && pp1->p_event==(char *)pp1)
                    306:                                wakeup((char *)pp1);
                    307:                }
                    308:                if (pp1->p_ppid == pp->p_pid) {
                    309:                        pp1->p_ppid = 1;
                    310:                        if (pp1->p_state == PSDEAD)
                    311:                                wakeup((char *)eprocp);
                    312:                        if ((pp1->p_flags&PFTRAC) != 0)
                    313:                                wakeup((char *)&pts.pt_req);
                    314:                }
                    315:        }
                    316: 
                    317:        /*
                    318:         * Wake up swapper if swap timer is active.
                    319:         */
                    320:        if ( stimer.t_last != 0 )
                    321:                wakeup( (char *) &stimer );
                    322: 
                    323:        /*
                    324:         * And finally mark us as dead and give up the processor forever.
                    325:         */
                    326:        pp->p_exit = s;
                    327:        pp->p_state = PSDEAD;
                    328:        uasa = 0;
                    329:        dispatch();
                    330: }
                    331: 
                    332: /*
                    333:  * Sleep on the event `e'.  This gives up the processor until someone
                    334:  * wakes us up.  Since it is possible for many people to sleep on the
                    335:  * same event, the caller when awakened should make sure that what he
                    336:  * was waiting for has completed and if not, go to sleep again.  `cl'
                    337:  * is the cpu value we get to get the cpu as soon as we are woken up.
                    338:  * `sl' is the swap value we get to keep us in memory for the duration
                    339:  * of the sleep.  `sr' is the swap value that allows us to get swapped
                    340:  * in if we have been swapped out.
                    341:  */
                    342: sleep(e, cl, sl, sr)
                    343: char *e;
                    344: {
                    345:        register PROC *bp;
                    346:        register PROC *fp;
                    347:        register PROC *pp;
                    348:        register int s;
                    349: 
                    350:        pp = SELF;
                    351: 
                    352:        /*
                    353:         * See if we have a signal awaiting.
                    354:         */
                    355:        if (cl<CVNOSIG && pp->p_ssig && nondsig()) {
                    356:                sphi();
                    357:                envrest(&u.u_sigenv);
                    358:        }
                    359: 
                    360:        /*
                    361:         * Get ready to go to sleep and do so.
                    362:         */
                    363:        s = sphi();
                    364:        pp->p_state = PSSLEEP;
                    365:        pp->p_event = e;
                    366:        pp->p_lctim = utimer;
                    367:        addu(pp->p_cval, cl);
                    368:        pp->p_ival = sl;
                    369:        pp->p_rval = sr;
                    370:        fp = &linkq[hash(e)];
                    371:        bp = fp->p_lback;
                    372:        pp->p_lforw = fp;
                    373:        fp->p_lback = pp;
                    374:        pp->p_lback = bp;
                    375:        bp->p_lforw = pp;
                    376:        spl(s);
                    377:        dispatch();
                    378: 
                    379:        /*
                    380:         * We have just woken up.  Get ready to return.
                    381:         */
                    382:        subu(pp->p_cval, cl);
                    383:        pp->p_ival = 0;
                    384:        pp->p_rval = 0;
                    385: 
                    386:        /*
                    387:         * Check for an interrupted system call.
                    388:         */
                    389:        if (cl<CVNOSIG && pp->p_ssig && nondsig()) {
                    390:                sphi();
                    391:                envrest(&u.u_sigenv);
                    392:        }
                    393: }
                    394: 
                    395: /*
                    396:  * Defer function to wake up all processes sleeping on the event `e'.
                    397:  */
                    398: wakeup(e)
                    399: char *e;
                    400: {
                    401:        extern void dwakeup();
                    402: 
                    403:        defer( dwakeup, e );
                    404: }
                    405: 
                    406: /*
                    407:  * Wake up all processes sleeping on the event `e'.
                    408:  */
                    409: static void
                    410: dwakeup( e )
                    411: char *e;
                    412: {
                    413:        register PROC *pp;
                    414:        register PROC *pp1;
                    415:        register int s;
                    416: 
                    417:        /*
                    418:         * Identify event queue to check.
                    419:         * Disable interrupts.
                    420:         */
                    421:        pp1 = &linkq[hash(e)];
                    422:        pp = pp1;
                    423:        s = sphi();
                    424: 
                    425:        /*
                    426:         * Traverse doubly-linked circular event-queue.
                    427:         */
                    428:        while ( (pp = pp->p_lforw) != pp1 ) {
                    429: 
                    430:                /*
                    431:                 * Process is waiting on event 'e'.
                    432:                 */
                    433:                if ( pp->p_event == e ) {
                    434:                        /*
                    435:                         * Remove process from event queue.
                    436:                         * Update process priority.
                    437:                         * Insert process into run queue.
                    438:                         */
                    439:                        pp->p_lback->p_lforw = pp->p_lforw;
                    440:                        pp->p_lforw->p_lback = pp->p_lback;
                    441:                        addu( pp->p_cval, (utimer-pp->p_lctim)*CVCLOCK );
                    442:                        setrun( pp );
                    443: 
                    444:                        /*
                    445:                         * Enable interrupts.
                    446:                         * Restart search at start of event queue.
                    447:                         * Disable interrupts.
                    448:                         */
                    449:                        spl( s );
                    450:                        pp = pp1;
                    451:                        s = sphi();
                    452:                }
                    453:        }
                    454:        spl(s);
                    455: }
                    456: 
                    457: /*
                    458:  * Reschedule the processor.
                    459:  */
                    460: dispatch()
                    461: {
                    462:        register PROC *pp1;
                    463:        register PROC *pp2;
                    464:        register unsigned v;
                    465:        register int s;
                    466: 
                    467:        s = sphi();
                    468:        pp1 = iprocp;
                    469:        pp2 = &procq;
                    470:        v = 0;
                    471:        while ((pp2=pp2->p_lforw) != &procq) {
                    472:                v -= pp2->p_cval;
                    473:                if ((pp2->p_flags&PFCORE) == 0)
                    474:                        continue;
                    475:                pp1 = pp2->p_lforw;
                    476:                pp1->p_cval += pp2->p_cval;
                    477:                pp2->p_cval = v;
                    478:                pp1->p_lback = pp2->p_lback;
                    479:                pp1->p_lback->p_lforw = pp1;
                    480:                pp1 = pp2;
                    481:                break;
                    482:        }
                    483:        spl(s);
                    484: 
                    485:        quantum = NCRTICK;
                    486:        disflag = 0;
                    487:        if ( pp1 != SELF ) {
                    488:                /*
                    489:                 * Consave() returns twice.
                    490:                 * 1st time is after our context is saved in u.u_syscon,
                    491:                 *      whereupon we should restore other proc's context.
                    492:                 * 2nd time is after our context is restored by another proc.
                    493:                 * Conrest() forces a context switch to a new process.
                    494:                 */
                    495:                s = sphi();
                    496:                SELF = pp1;
                    497:                if (consave(&u.u_syscon) == 0)
                    498:                        conrest( FP_SEL(pp1->p_u->s_faddr),
                    499:                                 offset(uproc,u_syscon) );
                    500:                if ( SELF->p_pid != 0 )
                    501:                        segload();
                    502:                spl(s);
                    503:        }
                    504: }
                    505: 
                    506: /*
                    507:  * Add a process to the run queue.
                    508:  * This routine must be called at high priority.
                    509:  */
                    510: setrun(pp1)
                    511: register PROC *pp1;
                    512: {
                    513:        register PROC *pp2;
                    514:        register unsigned v;
                    515: 
                    516:        v = 0;
                    517:        pp2 = &procq;
                    518:        for (;;) {
                    519:                pp2 = pp2->p_lback;
                    520:                if ((v+=pp2->p_lforw->p_cval) >= pp1->p_cval)
                    521:                        break;
                    522:                if (pp2 == &procq)
                    523:                        break;
                    524:        }
                    525:        pp2->p_lforw->p_lback = pp1;
                    526:        pp1->p_lforw = pp2->p_lforw;
                    527:        pp2->p_lforw = pp1;
                    528:        pp1->p_lback = pp2;
                    529:        v -= pp1->p_cval;
                    530:        pp1->p_cval = v;
                    531:        pp1->p_lforw->p_cval -= v;
                    532:        pp1->p_state = PSRUN;
                    533: }
                    534: 
                    535: /*
                    536:  * Wait for the gate `g' to unlock, and then lock it.
                    537:  */
                    538: lock(g)
                    539: register GATE g;
                    540: {
                    541:        register int s;
                    542: 
                    543:        s = sphi();
                    544:        while (g[0]) {
                    545:                g[1] = 1;
                    546:                sleep((char *)g, CVGATE, IVGATE, SVGATE);
                    547:        }
                    548:        g[0] = 1;
                    549:        spl(s);
                    550: }
                    551: 
                    552: /*
                    553:  * Unlock the gate `g'.
                    554:  */
                    555: unlock(g)
                    556: register GATE g;
                    557: {
                    558:        g[0] = 0;
                    559:        if (g[1]) {
                    560:                g[1] = 0;
                    561:                disflag = 1;
                    562:                wakeup((char *)g);
                    563:        }
                    564: }

unix.superglobalmegacorp.com

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