Annotation of MiNT/src/proc.c, revision 1.1

1.1     ! root        1: /*
        !             2: 
        !             3: Copyright 1990,1991,1992 Eric R. Smith. All rights reserved.
        !             4: 
        !             5: */
        !             6: 
        !             7: 
        !             8: 
        !             9: /* routines for handling processes */
        !            10: 
        !            11: 
        !            12: 
        !            13: #include "mint.h"
        !            14: 
        !            15: #include "xbra.h"
        !            16: 
        !            17: 
        !            18: 
        !            19: static void do_wakeup_things P_((void));
        !            20: 
        !            21: 
        !            22: 
        !            23: extern short proc_clock;
        !            24: 
        !            25: 
        !            26: 
        !            27: /* global process variables */
        !            28: 
        !            29: PROC *proclist;                        /* list of all active processes */
        !            30: 
        !            31: PROC *curproc;                 /* current process              */
        !            32: 
        !            33: PROC *rootproc;                        /* pid 0 -- MiNT itself         */
        !            34: 
        !            35: PROC *sys_q[NUM_QUEUES];
        !            36: 
        !            37: 
        !            38: 
        !            39: #define TIME_SLICE     1       /* number of 20ms ticks before process is
        !            40: 
        !            41:                                   pre-empted */
        !            42: 
        !            43: 
        !            44: 
        !            45: 
        !            46: 
        !            47: /* macro for calculating number of missed time slices, based on a
        !            48: 
        !            49:  * process' priority
        !            50: 
        !            51:  */
        !            52: 
        !            53: #define SLICES(pri)    (((pri) >= 0) ? 0 : -(pri))
        !            54: 
        !            55: 
        !            56: 
        !            57: extern FILESYS bios_filesys;
        !            58: 
        !            59: 
        !            60: 
        !            61: /*
        !            62: 
        !            63:  * get a new process struct
        !            64: 
        !            65:  */
        !            66: 
        !            67: #define NPROC  5       /* get this many PROC structures at a time */
        !            68: 
        !            69: 
        !            70: 
        !            71: PROC *pfreelist = 0;
        !            72: 
        !            73: 
        !            74: 
        !            75: PROC *
        !            76: 
        !            77: new_proc()
        !            78: 
        !            79: {
        !            80: 
        !            81:        PROC *p;
        !            82: 
        !            83: #if 0
        !            84: 
        !            85:        int i;
        !            86: 
        !            87: 
        !            88: 
        !            89:        if (pfreelist == 0) {
        !            90: 
        !            91:                p = (PROC *)kmalloc(NPROC * SIZEOF(PROC));
        !            92: 
        !            93:                if (!p) {
        !            94: 
        !            95:                        ALERT("new_proc: couldn't get a PROC structure");
        !            96: 
        !            97:                        return 0;
        !            98: 
        !            99:                }
        !           100: 
        !           101:                else {
        !           102: 
        !           103:                        for (i = 0; i < NPROC; i++) {
        !           104: 
        !           105:                                p->gl_next = pfreelist;
        !           106: 
        !           107:                                pfreelist = p;
        !           108: 
        !           109:                                p++;
        !           110: 
        !           111:                        }
        !           112: 
        !           113:                }
        !           114: 
        !           115:        }
        !           116: 
        !           117:        p = pfreelist;
        !           118: 
        !           119:        pfreelist = p->gl_next;
        !           120: 
        !           121:        p->gl_next = 0;
        !           122: 
        !           123: #else
        !           124: 
        !           125:        p = (PROC *)kmalloc(SIZEOF(PROC));
        !           126: 
        !           127: #endif
        !           128: 
        !           129:        return p;
        !           130: 
        !           131: }
        !           132: 
        !           133: 
        !           134: 
        !           135: /*
        !           136: 
        !           137:  * dispose of an old proc
        !           138: 
        !           139:  */
        !           140: 
        !           141: 
        !           142: 
        !           143: void
        !           144: 
        !           145: dispose_proc(p)
        !           146: 
        !           147:        PROC *p;
        !           148: 
        !           149: {
        !           150: 
        !           151: #if 0
        !           152: 
        !           153:        p->gl_next = pfreelist;
        !           154: 
        !           155:        pfreelist = p;
        !           156: 
        !           157: #else
        !           158: 
        !           159:        kfree(p);
        !           160: 
        !           161: #endif
        !           162: 
        !           163: }
        !           164: 
        !           165: 
        !           166: 
        !           167: /*
        !           168: 
        !           169:  * create a new process that is (practically) a duplicate of the
        !           170: 
        !           171:  * current one
        !           172: 
        !           173:  */
        !           174: 
        !           175: 
        !           176: 
        !           177: PROC *
        !           178: 
        !           179: fork_proc()
        !           180: 
        !           181: {
        !           182: 
        !           183:        PROC *p;
        !           184: 
        !           185:        int i;
        !           186: 
        !           187:        FILEPTR *f;
        !           188: 
        !           189: 
        !           190: 
        !           191:        if (!(p = new_proc())) {
        !           192: 
        !           193: nomem:
        !           194: 
        !           195:                DEBUG("fork_proc: insufficient memory");
        !           196: 
        !           197:                mint_errno = ENSMEM; return 0;
        !           198: 
        !           199:        }
        !           200: 
        !           201: 
        !           202: 
        !           203:        *p = *curproc;  /* child shares most things with parent... */
        !           204: 
        !           205: 
        !           206: 
        !           207: /* ... except for these: */
        !           208: 
        !           209:        p->ppid = curproc->pid;
        !           210: 
        !           211:        p->pid = newpid();
        !           212: 
        !           213:        p->sigpending = 0;
        !           214: 
        !           215:        p->sysstack = (long)(p->stack + STKSIZE - 12);
        !           216: 
        !           217:        p->ctxt[CURRENT].ssp = p->sysstack;
        !           218: 
        !           219:        p->ctxt[SYSCALL].ssp = (long)(p->stack + ISTKSIZE);
        !           220: 
        !           221:        p->alarmtim = 0;
        !           222: 
        !           223:        p->curpri = p->pri;
        !           224: 
        !           225:        p->slices = SLICES(p->pri);
        !           226: 
        !           227:        p->starttime = timestamp;
        !           228: 
        !           229:        p->startdate = datestamp;
        !           230: 
        !           231: 
        !           232: 
        !           233:        ((long *)p->sysstack)[1] = FRAME_MAGIC;
        !           234: 
        !           235:        ((long *)p->sysstack)[2] = 0;
        !           236: 
        !           237:        ((long *)p->sysstack)[3] = 0;
        !           238: 
        !           239: 
        !           240: 
        !           241:        p->usrtime = p->systime = p->chldstime = p->chldutime = 0;
        !           242: 
        !           243: 
        !           244: 
        !           245: /* copy open handles */
        !           246: 
        !           247:        for (i = MIN_HANDLE; i < MAX_OPEN; i++) {
        !           248: 
        !           249:                if ((f = p->handle[i]) != 0) {
        !           250: 
        !           251:                        if (f->flags & O_NOINHERIT)
        !           252: 
        !           253:                /* oops, we didn't really want to copy this handle */
        !           254: 
        !           255:                                p->handle[i] = 0;
        !           256: 
        !           257:                        else
        !           258: 
        !           259:                                f->links++;
        !           260: 
        !           261:                }
        !           262: 
        !           263:        }
        !           264: 
        !           265: 
        !           266: 
        !           267: /* clear directory search info */
        !           268: 
        !           269:        zero((char *)p->srchdta, NUM_SEARCH * SIZEOF(DTABUF *));
        !           270: 
        !           271: 
        !           272: 
        !           273: /* copy memory */
        !           274: 
        !           275:        p->mem = (MEMREGION **) kmalloc(p->num_reg * SIZEOF(MEMREGION *));
        !           276: 
        !           277:        if (!p->mem) {
        !           278: 
        !           279:                dispose_proc(p);
        !           280: 
        !           281:                goto nomem;
        !           282: 
        !           283:        }
        !           284: 
        !           285:        p->addr = (virtaddr *)kmalloc(p->num_reg * SIZEOF(virtaddr));
        !           286: 
        !           287:        if (!p->addr) {
        !           288: 
        !           289:                kfree(p->mem);
        !           290: 
        !           291:                dispose_proc(p);
        !           292: 
        !           293:                goto nomem;
        !           294: 
        !           295:        }
        !           296: 
        !           297: 
        !           298: 
        !           299:        for (i = 0; i < curproc->num_reg; i++) {
        !           300: 
        !           301:                if (p->mem[i] = curproc->mem[i])        /* yes, "=" is right */
        !           302: 
        !           303:                        p->mem[i]->links++;
        !           304: 
        !           305:                p->addr[i] = curproc->addr[i];
        !           306: 
        !           307:        }
        !           308: 
        !           309: 
        !           310: 
        !           311:        p->starttime = Tgettime();
        !           312: 
        !           313:        p->startdate = Tgetdate();
        !           314: 
        !           315: 
        !           316: 
        !           317:        p->q_next = 0;
        !           318: 
        !           319:        p->wait_q = 0;
        !           320: 
        !           321:        p->gl_next = proclist;
        !           322: 
        !           323:        proclist = p;                   /* hook into the process list */
        !           324: 
        !           325:        return p;
        !           326: 
        !           327: }
        !           328: 
        !           329: 
        !           330: 
        !           331: /*
        !           332: 
        !           333:  * initialize the process table
        !           334: 
        !           335:  */
        !           336: 
        !           337: 
        !           338: 
        !           339: void
        !           340: 
        !           341: init_proc()
        !           342: 
        !           343: {
        !           344: 
        !           345:        int i;
        !           346: 
        !           347:        FILESYS *fs;
        !           348: 
        !           349:        fcookie dir;
        !           350: 
        !           351:        extern BASEPAGE **tosbp;        /* in main.c */
        !           352: 
        !           353: 
        !           354: 
        !           355:        rootproc = curproc = new_proc();
        !           356: 
        !           357:        assert(curproc);
        !           358: 
        !           359: 
        !           360: 
        !           361:        zero((char *)curproc, (long)sizeof(PROC));
        !           362: 
        !           363: 
        !           364: 
        !           365:        curproc->ppid = -1;             /* no parent */
        !           366: 
        !           367:        curproc->domain = DOM_TOS;      /* TOS domain */
        !           368: 
        !           369:        curproc->sysstack = (long) (curproc->stack+STKSIZE-12);
        !           370: 
        !           371:        curproc->magic = CTXT_MAGIC;
        !           372: 
        !           373:        ((long *)curproc->sysstack)[1] = FRAME_MAGIC;
        !           374: 
        !           375:        ((long *)curproc->sysstack)[2] = 0;
        !           376: 
        !           377:        ((long *)curproc->sysstack)[3] = 0;
        !           378: 
        !           379: 
        !           380: 
        !           381:        curproc->base = (BASEPAGE *) *tosbp;
        !           382: 
        !           383: 
        !           384: 
        !           385:        strcpy(curproc->name, "MiNT");
        !           386: 
        !           387: 
        !           388: 
        !           389: /* get some memory */
        !           390: 
        !           391:        curproc->mem = (MEMREGION **)kmalloc(NUM_REGIONS*SIZEOF(MEMREGION *));
        !           392: 
        !           393:        curproc->addr = (virtaddr *)kmalloc(NUM_REGIONS*SIZEOF(virtaddr));
        !           394: 
        !           395:        assert(curproc->mem && curproc->addr);
        !           396: 
        !           397: 
        !           398: 
        !           399: /* make sure it's filled with zeros */
        !           400: 
        !           401:        zero((char *)curproc->addr, NUM_REGIONS * SIZEOF(virtaddr));
        !           402: 
        !           403:        zero((char *)curproc->mem, NUM_REGIONS * SIZEOF(MEMREGION *));
        !           404: 
        !           405:        curproc->num_reg = NUM_REGIONS;
        !           406: 
        !           407: 
        !           408: 
        !           409: /* get root and current directories for all drives */
        !           410: 
        !           411:        for (i = 0; i < NUM_DRIVES; i++) {
        !           412: 
        !           413:                if ((fs = drives[i]) != 0 && (*fs->root)(i, &dir) == E_OK) {
        !           414: 
        !           415:                                curproc->root[i] = curproc->curdir[i] = dir;
        !           416: 
        !           417:                } else {
        !           418: 
        !           419:                        curproc->root[i].fs = curproc->curdir[i].fs = 0;
        !           420: 
        !           421:                        curproc->root[i].dev = curproc->curdir[i].dev = i;
        !           422: 
        !           423:                }
        !           424: 
        !           425:        }
        !           426: 
        !           427: 
        !           428: 
        !           429: /* Set the correct drive. The current directory we
        !           430: 
        !           431:  * set later, after all file systems have been loaded.
        !           432: 
        !           433:  */
        !           434: 
        !           435: 
        !           436: 
        !           437:        curproc->curdrv = Dgetdrv();
        !           438: 
        !           439:        proclist = curproc;
        !           440: 
        !           441: 
        !           442: 
        !           443:        curproc->umask = 0;
        !           444: 
        !           445: 
        !           446: 
        !           447: /*
        !           448: 
        !           449:  * some more protection against job control; unless these signals are
        !           450: 
        !           451:  * re-activated by a shell that knows about job control, they'll have
        !           452: 
        !           453:  * no effect
        !           454: 
        !           455:  */
        !           456: 
        !           457:        curproc->sighandle[SIGTTIN] = curproc->sighandle[SIGTTOU] =
        !           458: 
        !           459:                curproc->sighandle[SIGTSTP] = SIG_IGN;
        !           460: 
        !           461: 
        !           462: 
        !           463: /* set up some more per-process variables */
        !           464: 
        !           465:        curproc->starttime = Tgettime();
        !           466: 
        !           467:        curproc->startdate = Tgetdate();
        !           468: 
        !           469:        if (has_bconmap)
        !           470: 
        !           471:                curproc->bconmap = curbconmap;
        !           472: 
        !           473:        else
        !           474: 
        !           475:                curproc->bconmap = 1;
        !           476: 
        !           477: 
        !           478: 
        !           479:        curproc->logbase = (void *)Logbase();
        !           480: 
        !           481:        curproc->criticerr = *((long (**) P_((long)))0x404L);
        !           482: 
        !           483: }
        !           484: 
        !           485: 
        !           486: 
        !           487: /*
        !           488: 
        !           489:  * reset all process priorities to their base level
        !           490: 
        !           491:  * called once per second, so that cpu hogs can get _some_ time
        !           492: 
        !           493:  * slices :-).
        !           494: 
        !           495:  */
        !           496: 
        !           497: 
        !           498: 
        !           499: void
        !           500: 
        !           501: reset_priorities()
        !           502: 
        !           503: {
        !           504: 
        !           505:        PROC *p;
        !           506: 
        !           507: 
        !           508: 
        !           509:        for (p = proclist; p; p = p->gl_next) {
        !           510: 
        !           511:                p->curpri = p->pri;
        !           512: 
        !           513:                p->slices = SLICES(p->curpri);
        !           514: 
        !           515:        }
        !           516: 
        !           517: }
        !           518: 
        !           519: 
        !           520: 
        !           521: /*
        !           522: 
        !           523:  * more priority code stuff:
        !           524: 
        !           525:  * run_next(p, slices): schedule process "p" to run next, with "slices"
        !           526: 
        !           527:  *       initial time slices; "p" does not actually start running until
        !           528: 
        !           529:  *       the next context switch
        !           530: 
        !           531:  * fresh_slices(slices): give the current process "slices" more slices in
        !           532: 
        !           533:  *       which to run
        !           534: 
        !           535:  */
        !           536: 
        !           537: 
        !           538: 
        !           539: void
        !           540: 
        !           541: run_next(p, slices)
        !           542: 
        !           543:        PROC *p;
        !           544: 
        !           545:        int slices;     /* BUG: currently ignored */
        !           546: 
        !           547: {
        !           548: 
        !           549:        p->slices = 0;
        !           550: 
        !           551:        p->curpri = MAX_NICE;
        !           552: 
        !           553:        p->wait_q = READY_Q;
        !           554: 
        !           555:        p->q_next = sys_q[READY_Q];
        !           556: 
        !           557:        sys_q[READY_Q] = p;
        !           558: 
        !           559: }
        !           560: 
        !           561: 
        !           562: 
        !           563: void
        !           564: 
        !           565: fresh_slices(slices)
        !           566: 
        !           567:        int slices;
        !           568: 
        !           569: {
        !           570: 
        !           571:        curproc->slices = 0;
        !           572: 
        !           573:        curproc->curpri = MAX_NICE+1;
        !           574: 
        !           575:        proc_clock = slices;
        !           576: 
        !           577: }
        !           578: 
        !           579: 
        !           580: 
        !           581: /*
        !           582: 
        !           583:  * add a process to a wait (or ready) queue.
        !           584: 
        !           585:  *
        !           586: 
        !           587:  * processes go onto a queue in first in-first out order
        !           588: 
        !           589:  */
        !           590: 
        !           591: 
        !           592: 
        !           593: void
        !           594: 
        !           595: add_q(que, proc)
        !           596: 
        !           597:        int que;
        !           598: 
        !           599:        PROC *proc;
        !           600: 
        !           601: {
        !           602: 
        !           603:        PROC *q, **lastq;
        !           604: 
        !           605: 
        !           606: 
        !           607: /* "proc" should not already be on a list */
        !           608: 
        !           609:        assert(proc->wait_q == 0);
        !           610: 
        !           611:        assert(proc->q_next == 0);
        !           612: 
        !           613: 
        !           614: 
        !           615:        lastq = &sys_q[que];
        !           616: 
        !           617:        q = *lastq;
        !           618: 
        !           619:        while(q) {
        !           620: 
        !           621:                lastq = &q->q_next;
        !           622: 
        !           623:                q = *lastq;
        !           624: 
        !           625:        }
        !           626: 
        !           627:        *lastq = proc;
        !           628: 
        !           629:        proc->wait_q = que;
        !           630: 
        !           631:        if (que != READY_Q) {
        !           632: 
        !           633:                proc->curpri = proc->pri;       /* reward the process */
        !           634: 
        !           635:                proc->slices = SLICES(proc->curpri);
        !           636: 
        !           637:        }
        !           638: 
        !           639: }
        !           640: 
        !           641: 
        !           642: 
        !           643: /*
        !           644: 
        !           645:  * remove a process from a queue
        !           646: 
        !           647:  */
        !           648: 
        !           649: 
        !           650: 
        !           651: void
        !           652: 
        !           653: rm_q(que, proc)
        !           654: 
        !           655:        int que;
        !           656: 
        !           657:        PROC *proc;
        !           658: 
        !           659: {
        !           660: 
        !           661:        PROC *q;
        !           662: 
        !           663:        PROC *old = 0;
        !           664: 
        !           665: 
        !           666: 
        !           667:        assert(proc->wait_q == que);
        !           668: 
        !           669: 
        !           670: 
        !           671:        q = sys_q[que];
        !           672: 
        !           673:        while (q && q != proc) {
        !           674: 
        !           675:                old = q;
        !           676: 
        !           677:                q = q->q_next;
        !           678: 
        !           679:        }
        !           680: 
        !           681:        if (q == 0)
        !           682: 
        !           683:                FATAL("rm_q: unable to remove process from queue");
        !           684: 
        !           685: 
        !           686: 
        !           687:        if (old)
        !           688: 
        !           689:                old->q_next = proc->q_next;
        !           690: 
        !           691:        else
        !           692: 
        !           693:                sys_q[que] = proc->q_next;
        !           694: 
        !           695: 
        !           696: 
        !           697:        proc->wait_q = 0;
        !           698: 
        !           699:        proc->q_next = 0;
        !           700: 
        !           701: }
        !           702: 
        !           703: 
        !           704: 
        !           705: /*
        !           706: 
        !           707:  * preempt(): called by the vbl routine and/or the trap handlers when
        !           708: 
        !           709:  * they detect that a process has exceeded its time slice and hasn't
        !           710: 
        !           711:  * yielded gracefully. For now, it just does sleep(READY_Q); later,
        !           712: 
        !           713:  * we might want to keep track of statistics or something.
        !           714: 
        !           715:  */
        !           716: 
        !           717: 
        !           718: 
        !           719: void
        !           720: 
        !           721: preempt()
        !           722: 
        !           723: {
        !           724: 
        !           725:        extern short bconbsiz;  /* in bios.c */
        !           726: 
        !           727: 
        !           728: 
        !           729:        if (bconbsiz)
        !           730: 
        !           731:                (void)bflush();
        !           732: 
        !           733:        else {
        !           734: 
        !           735:                /* punish the pre-empted process */
        !           736: 
        !           737:                if (curproc->curpri >= MIN_NICE)
        !           738: 
        !           739:                        curproc->curpri -= 1;
        !           740: 
        !           741:        }
        !           742: 
        !           743:        sleep(READY_Q, curproc->wait_cond);
        !           744: 
        !           745: }
        !           746: 
        !           747: 
        !           748: 
        !           749: /*
        !           750: 
        !           751:  * sleep(que, cond): put the current process on the given queue, then switch
        !           752: 
        !           753:  * contexts. Before a new process runs, give it a fresh time slice. "cond"
        !           754: 
        !           755:  * is the condition for which the process is waiting, and is placed in
        !           756: 
        !           757:  * curproc->wait_cond
        !           758: 
        !           759:  */
        !           760: 
        !           761: 
        !           762: 
        !           763: static void
        !           764: 
        !           765: do_wakeup_things()
        !           766: 
        !           767: {
        !           768: 
        !           769: /*
        !           770: 
        !           771:  * check for stack underflow, just in case
        !           772: 
        !           773:  */
        !           774: 
        !           775:        auto int foo;
        !           776: 
        !           777: 
        !           778: 
        !           779:        if ( curproc->pid != 0 &&
        !           780: 
        !           781:             ((long)&foo) < (long)curproc->stack + ISTKSIZE + 512 ) {
        !           782: 
        !           783:                ALERT("sleep: stack overflow");
        !           784: 
        !           785:                handle_sig(SIGBUS);
        !           786: 
        !           787:        }
        !           788: 
        !           789: /*
        !           790: 
        !           791:  * check processes for alarms
        !           792: 
        !           793:  */
        !           794: 
        !           795: 
        !           796: 
        !           797:        checkalarms();
        !           798: 
        !           799: 
        !           800: 
        !           801:        check_time();           /* check for CPU limit exceeded */
        !           802: 
        !           803:        check_sigs();           /* check for signals */
        !           804: 
        !           805: 
        !           806: 
        !           807:        proc_clock = TIME_SLICE;        /* get a fresh time slice */
        !           808: 
        !           809:        curproc->slices = SLICES(curproc->curpri);
        !           810: 
        !           811: }
        !           812: 
        !           813: 
        !           814: 
        !           815: void
        !           816: 
        !           817: sleep(que, cond)
        !           818: 
        !           819:        int que;
        !           820: 
        !           821:        long cond;
        !           822: 
        !           823: {
        !           824: 
        !           825:        PROC *p;
        !           826: 
        !           827:        short sr;
        !           828: 
        !           829:        extern short kintr;     /* in bios.c */
        !           830: 
        !           831:        extern short bconbsiz;
        !           832: 
        !           833: #ifdef FASTTEXT
        !           834: 
        !           835:        extern int hardscroll;  /* in fasttext.c */
        !           836: 
        !           837: #endif
        !           838: 
        !           839:        assert(bconbsiz == 0);
        !           840: 
        !           841: 
        !           842: 
        !           843: /*
        !           844: 
        !           845:  * if there have been keyboard interrupts since our last sleep, check for
        !           846: 
        !           847:  * special keys like CTRL-ALT-Fx
        !           848: 
        !           849:  */
        !           850: 
        !           851: 
        !           852: 
        !           853:        if (kintr) {
        !           854: 
        !           855:                (void)checkkeys();
        !           856: 
        !           857:                kintr = 0;
        !           858: 
        !           859:        }
        !           860: 
        !           861: 
        !           862: 
        !           863:        if (que == READY_Q && !sys_q[READY_Q]) {
        !           864: 
        !           865: /* we're just going to wake up again right away! */
        !           866: 
        !           867:                do_wakeup_things();
        !           868: 
        !           869:                return;
        !           870: 
        !           871:        }
        !           872: 
        !           873: 
        !           874: 
        !           875:        sr = spl7();
        !           876: 
        !           877: 
        !           878: 
        !           879:        add_q(que, curproc);
        !           880: 
        !           881:        curproc->wait_cond = cond;
        !           882: 
        !           883: 
        !           884: 
        !           885:        if (!sys_q[READY_Q]) {
        !           886: 
        !           887: /* hmm, no-one is ready to run. might be a deadlock, might not.
        !           888: 
        !           889:  * first, try waking up any napping processes; if that doesn't work,
        !           890: 
        !           891:  * run the root process, just so we have someone to charge time
        !           892: 
        !           893:  * to.
        !           894: 
        !           895:  */
        !           896: 
        !           897:                wake(SELECT_Q, (long)&nap);
        !           898: 
        !           899:                if (!sys_q[READY_Q]) {
        !           900: 
        !           901:                        p = rootproc;           /* pid 0 */
        !           902: 
        !           903:                        rm_q(p->wait_q, p);
        !           904: 
        !           905:                        add_q(READY_Q, p);
        !           906: 
        !           907:                }
        !           908: 
        !           909:        }
        !           910: 
        !           911: 
        !           912: 
        !           913: /*
        !           914: 
        !           915:  * Walk through the ready list, to find what process should run next.
        !           916: 
        !           917:  * Lower priority processes don't get to run every time through this
        !           918: 
        !           919:  * loop; if "p->slices" is positive, it's the number of times that they
        !           920: 
        !           921:  * will have to miss a turn before getting to run again
        !           922: 
        !           923:  */
        !           924: 
        !           925:        p = 0;
        !           926: 
        !           927: 
        !           928: 
        !           929:        while (!p) {
        !           930: 
        !           931:                for (p = sys_q[READY_Q]; p; p = p->q_next) {
        !           932: 
        !           933:                        if (p->slices > 0)
        !           934: 
        !           935:                                p->slices--;
        !           936: 
        !           937:                        else
        !           938: 
        !           939:                                break;
        !           940: 
        !           941:                }
        !           942: 
        !           943:        }
        !           944: 
        !           945:        rm_q(READY_Q, p);
        !           946: 
        !           947: 
        !           948: 
        !           949:        spl(sr);
        !           950: 
        !           951: 
        !           952: 
        !           953:        if (save_context(&(curproc->ctxt[CURRENT]))) {
        !           954: 
        !           955:                if (curproc->q_next) {
        !           956: 
        !           957:                        DEBUG("sleep: why is curproc on a queue???");
        !           958: 
        !           959:                }
        !           960: 
        !           961: /*
        !           962: 
        !           963:  * restore per-process variables here
        !           964: 
        !           965:  */
        !           966: 
        !           967: #ifdef FASTTEXT
        !           968: 
        !           969:                if (!hardscroll)
        !           970: 
        !           971: #endif
        !           972: 
        !           973:                        *((void **)0x44eL) = curproc->logbase;
        !           974: 
        !           975:                do_wakeup_things();
        !           976: 
        !           977:                return;
        !           978: 
        !           979:        }
        !           980: 
        !           981: /*
        !           982: 
        !           983:  * save per-process variables here
        !           984: 
        !           985:  */
        !           986: 
        !           987: #ifdef FASTTEXT
        !           988: 
        !           989:        if (!hardscroll)
        !           990: 
        !           991: #endif
        !           992: 
        !           993:                curproc->logbase = *((void **)0x44eL);
        !           994: 
        !           995:        curproc->ctxt[CURRENT].regs[0] = 1;
        !           996: 
        !           997:        curproc = p;
        !           998: 
        !           999:        proc_clock = TIME_SLICE;        /* fresh time */
        !          1000: 
        !          1001:        if ((p->ctxt[CURRENT].sr & 0x2000) == 0) {      /* user mode? */
        !          1002: 
        !          1003:                leave_kernel();
        !          1004: 
        !          1005:        }
        !          1006: 
        !          1007:        assert(p->magic == CTXT_MAGIC);
        !          1008: 
        !          1009:        restore_context(&(p->ctxt[CURRENT]));
        !          1010: 
        !          1011: }
        !          1012: 
        !          1013: 
        !          1014: 
        !          1015: /*
        !          1016: 
        !          1017:  * wake(que, cond): wake up all processes on the given queue that are waiting
        !          1018: 
        !          1019:  * for the indicated condition
        !          1020: 
        !          1021:  */
        !          1022: 
        !          1023: 
        !          1024: 
        !          1025: void
        !          1026: 
        !          1027: wake(que, cond)
        !          1028: 
        !          1029:        int que;
        !          1030: 
        !          1031:        long cond;
        !          1032: 
        !          1033: {
        !          1034: 
        !          1035:        PROC *p;
        !          1036: 
        !          1037: 
        !          1038: 
        !          1039:        if (que == READY_Q) {
        !          1040: 
        !          1041:                ALERT("wake: why wake up ready processes??");
        !          1042: 
        !          1043:                return;
        !          1044: 
        !          1045:        }
        !          1046: 
        !          1047: top:
        !          1048: 
        !          1049:        for(p = sys_q[que]; p; p = p->q_next) {
        !          1050: 
        !          1051:                if (p->wait_cond == cond) {
        !          1052: 
        !          1053:                        rm_q(que, p);
        !          1054: 
        !          1055:                        add_q(READY_Q, p);
        !          1056: 
        !          1057:                        goto top;
        !          1058: 
        !          1059:                }
        !          1060: 
        !          1061:        }
        !          1062: 
        !          1063: }
        !          1064: 
        !          1065: 
        !          1066: 
        !          1067: /*
        !          1068: 
        !          1069:  * wakeselect(p): wake process p from a select() system call
        !          1070: 
        !          1071:  * may be called by an interrupt handler or whatever
        !          1072: 
        !          1073:  */
        !          1074: 
        !          1075: 
        !          1076: 
        !          1077: void
        !          1078: 
        !          1079: wakeselect(param)
        !          1080: 
        !          1081:        long param;
        !          1082: 
        !          1083: {
        !          1084: 
        !          1085:        PROC *p = (PROC *)param;
        !          1086: 
        !          1087:        short s;
        !          1088: 
        !          1089: 
        !          1090: 
        !          1091:        s = spl7();     /* block interrupts */
        !          1092: 
        !          1093:        if(p->wait_cond == (long)&wakeselect) {
        !          1094: 
        !          1095:                p->wait_cond = 0;
        !          1096: 
        !          1097:        }
        !          1098: 
        !          1099:        if (p->wait_q == SELECT_Q) {
        !          1100: 
        !          1101:                rm_q(SELECT_Q, p);
        !          1102: 
        !          1103:                add_q(READY_Q, p);
        !          1104: 
        !          1105:        }
        !          1106: 
        !          1107:        spl(s);
        !          1108: 
        !          1109: }
        !          1110: 
        !          1111: 
        !          1112: 
        !          1113: /*
        !          1114: 
        !          1115:  * check_time(): check to see if process' time limit has been exceeded
        !          1116: 
        !          1117:  */
        !          1118: 
        !          1119: 
        !          1120: 
        !          1121: void
        !          1122: 
        !          1123: check_time()
        !          1124: 
        !          1125: {
        !          1126: 
        !          1127:        if (curproc->maxcpu) {
        !          1128: 
        !          1129:                if (curproc->maxcpu <= curproc->systime + curproc->usrtime) {
        !          1130: 
        !          1131:                        DEBUG("cpu limit exceeded");
        !          1132: 
        !          1133:                        raise(SIGXCPU);
        !          1134: 
        !          1135:                }
        !          1136: 
        !          1137:        }
        !          1138: 
        !          1139: }
        !          1140: 
        !          1141: 
        !          1142: 
        !          1143: /*
        !          1144: 
        !          1145:  * dump out information about processes
        !          1146: 
        !          1147:  */
        !          1148: 
        !          1149: 
        !          1150: 
        !          1151: /*
        !          1152: 
        !          1153:  * kludge alert! In order to get the right pid printed by ALERT, we use
        !          1154: 
        !          1155:  * curproc as the loop variable.
        !          1156: 
        !          1157:  */
        !          1158: 
        !          1159: 
        !          1160: 
        !          1161: void
        !          1162: 
        !          1163: DUMPPROC()
        !          1164: 
        !          1165: {
        !          1166: 
        !          1167:        PROC *p = curproc;
        !          1168: 
        !          1169: 
        !          1170: 
        !          1171:        for (curproc = proclist; curproc; curproc = curproc->gl_next) {
        !          1172: 
        !          1173:            ALERT("queue %d cond %lx PC: %lx USP: %lx SSP: %lx SYSSP: %lx FRAME: %lx",
        !          1174: 
        !          1175:                curproc->wait_q, curproc->wait_cond,
        !          1176: 
        !          1177:                curproc->ctxt[SYSCALL].pc,
        !          1178: 
        !          1179:                curproc->ctxt[SYSCALL].usp,
        !          1180: 
        !          1181:                curproc->ctxt[SYSCALL].ssp,
        !          1182: 
        !          1183:                curproc->sysstack,
        !          1184: 
        !          1185:                ((long *)curproc->sysstack)[2]
        !          1186: 
        !          1187:            );
        !          1188: 
        !          1189:        }
        !          1190: 
        !          1191:        curproc = p;            /* restore the real curproc */
        !          1192: 
        !          1193: }
        !          1194: 

unix.superglobalmegacorp.com

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