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

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

unix.superglobalmegacorp.com

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