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

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

unix.superglobalmegacorp.com

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