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

1.1       root        1: /*
                      2: 
1.1.1.3   root        3: Copyright 1990,1991,1992 Eric R. Smith.
                      4: 
1.1.1.6 ! root        5: Copyright 1992,1993,1994 Atari Corporation.
1.1.1.3   root        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: 
1.1.1.6 ! root       23: static void do_wakeup_things P_((int sr, int newslice));
1.1       root       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: 
1.1.1.5   root      219:        p->nsigs = 0;
                    220: 
1.1       root      221:        p->sysstack = (long)(p->stack + STKSIZE - 12);
                    222: 
                    223:        p->ctxt[CURRENT].ssp = p->sysstack;
                    224: 
                    225:        p->ctxt[SYSCALL].ssp = (long)(p->stack + ISTKSIZE);
                    226: 
                    227:        p->alarmtim = 0;
                    228: 
                    229:        p->curpri = p->pri;
                    230: 
                    231:        p->slices = SLICES(p->pri);
                    232: 
                    233:        p->starttime = timestamp;
                    234: 
                    235:        p->startdate = datestamp;
                    236: 
1.1.1.6 ! root      237:        p->itimer[0].interval = 0;
        !           238: 
        !           239:        p->itimer[0].reqtime = 0;
        !           240: 
        !           241:        p->itimer[0].timeout = 0;
        !           242: 
        !           243:        p->itimer[1].interval = 0;
        !           244: 
        !           245:        p->itimer[1].reqtime = 0;
        !           246: 
        !           247:        p->itimer[1].timeout = 0;
        !           248: 
        !           249:        p->itimer[2].interval = 0;
        !           250: 
        !           251:        p->itimer[2].reqtime = 0;
        !           252: 
        !           253:        p->itimer[2].timeout = 0;
        !           254: 
1.1       root      255: 
                    256: 
                    257:        ((long *)p->sysstack)[1] = FRAME_MAGIC;
                    258: 
                    259:        ((long *)p->sysstack)[2] = 0;
                    260: 
                    261:        ((long *)p->sysstack)[3] = 0;
                    262: 
                    263: 
                    264: 
                    265:        p->usrtime = p->systime = p->chldstime = p->chldutime = 0;
                    266: 
                    267: 
                    268: 
1.1.1.5   root      269: /* allocate space for memory regions: do it here so that we can fail
                    270: 
                    271:  * before we duplicate anything else. The memory regions are
                    272: 
                    273:  * actually copied later
                    274: 
                    275:  */
                    276: 
                    277:        p->mem = (MEMREGION **) kmalloc(p->num_reg * SIZEOF(MEMREGION *));
                    278: 
                    279:        if (!p->mem) {
                    280: 
                    281:                dispose_proc(p);
                    282: 
                    283:                goto nomem;
                    284: 
                    285:        }
                    286: 
                    287:        p->addr = (virtaddr *)kmalloc(p->num_reg * SIZEOF(virtaddr));
                    288: 
                    289:        if (!p->addr) {
                    290: 
                    291:                kfree(p->mem);
                    292: 
                    293:                dispose_proc(p);
                    294: 
                    295:                goto nomem;
                    296: 
                    297:        }
                    298: 
                    299: 
                    300: 
1.1       root      301: /* copy open handles */
                    302: 
                    303:        for (i = MIN_HANDLE; i < MAX_OPEN; i++) {
                    304: 
                    305:                if ((f = p->handle[i]) != 0) {
                    306: 
1.1.1.6 ! root      307:                        if (f == (FILEPTR *)1 || f->flags & O_NOINHERIT)
1.1       root      308: 
                    309:                /* oops, we didn't really want to copy this handle */
                    310: 
                    311:                                p->handle[i] = 0;
                    312: 
                    313:                        else
                    314: 
                    315:                                f->links++;
                    316: 
                    317:                }
                    318: 
                    319:        }
                    320: 
                    321: 
                    322: 
1.1.1.3   root      323: /* copy root and current directories */
                    324: 
                    325:        for (i = 0; i < NUM_DRIVES; i++) {
                    326: 
                    327:                dup_cookie(&p->root[i], &curproc->root[i]);
                    328: 
                    329:                dup_cookie(&p->curdir[i], &curproc->curdir[i]);
                    330: 
                    331:        }
                    332: 
                    333: 
                    334: 
1.1.1.4   root      335: /* jr: copy ploadinfo */
                    336: 
1.1.1.6 ! root      337:        strncpy(p->cmdlin, curproc->cmdlin, 128);
1.1.1.4   root      338: 
1.1.1.6 ! root      339:        strcpy(p->fname, curproc->fname);
1.1.1.4   root      340: 
                    341: 
                    342: 
1.1       root      343: /* clear directory search info */
                    344: 
                    345:        zero((char *)p->srchdta, NUM_SEARCH * SIZEOF(DTABUF *));
                    346: 
1.1.1.4   root      347:        zero((char *)p->srchdir, SIZEOF(p->srchdir));
                    348: 
1.1.1.3   root      349:        p->searches = 0;
                    350: 
1.1       root      351: 
                    352: 
                    353: /* copy memory */
                    354: 
                    355:        for (i = 0; i < curproc->num_reg; i++) {
                    356: 
1.1.1.2   root      357:                p->mem[i] = curproc->mem[i];
                    358: 
                    359:                if (p->mem[i] != 0)
1.1       root      360: 
                    361:                        p->mem[i]->links++;
                    362: 
                    363:                p->addr[i] = curproc->addr[i];
                    364: 
                    365:        }
                    366: 
                    367: 
                    368: 
1.1.1.3   root      369: /* now that memory ownership is copied, fill in page table */
                    370: 
                    371:        init_page_table(p);
                    372: 
                    373: 
                    374: 
1.1.1.2   root      375: /* child isn't traced */
                    376: 
                    377:        p->ptracer = 0;
                    378: 
                    379:        p->ptraceflags = 0;
                    380: 
                    381: 
                    382: 
1.1       root      383:        p->starttime = Tgettime();
                    384: 
                    385:        p->startdate = Tgetdate();
                    386: 
                    387: 
                    388: 
                    389:        p->q_next = 0;
                    390: 
                    391:        p->wait_q = 0;
                    392: 
                    393:        p->gl_next = proclist;
                    394: 
                    395:        proclist = p;                   /* hook into the process list */
                    396: 
                    397:        return p;
                    398: 
                    399: }
                    400: 
                    401: 
                    402: 
                    403: /*
                    404: 
                    405:  * initialize the process table
                    406: 
                    407:  */
                    408: 
                    409: 
                    410: 
                    411: void
                    412: 
                    413: init_proc()
                    414: 
                    415: {
                    416: 
                    417:        int i;
                    418: 
                    419:        FILESYS *fs;
                    420: 
                    421:        fcookie dir;
                    422: 
1.1.1.3   root      423:        long_desc *pthold;
                    424: 
                    425:        void *ptmemhold;
                    426: 
1.1       root      427: 
                    428: 
                    429:        rootproc = curproc = new_proc();
                    430: 
                    431:        assert(curproc);
                    432: 
                    433: 
                    434: 
1.1.1.3   root      435:        pthold = curproc->page_table;
                    436: 
                    437:        ptmemhold = curproc->pt_mem;
                    438: 
1.1       root      439:        zero((char *)curproc, (long)sizeof(PROC));
                    440: 
1.1.1.3   root      441:        curproc->page_table = pthold;
                    442: 
                    443:        curproc->pt_mem = ptmemhold;
                    444: 
1.1       root      445: 
                    446: 
                    447:        curproc->ppid = -1;             /* no parent */
                    448: 
                    449:        curproc->domain = DOM_TOS;      /* TOS domain */
                    450: 
                    451:        curproc->sysstack = (long) (curproc->stack+STKSIZE-12);
                    452: 
                    453:        curproc->magic = CTXT_MAGIC;
                    454: 
1.1.1.3   root      455:        curproc->memflags = F_PROT_S;   /* default prot mode: super-only */
                    456: 
1.1       root      457:        ((long *)curproc->sysstack)[1] = FRAME_MAGIC;
                    458: 
                    459:        ((long *)curproc->sysstack)[2] = 0;
                    460: 
                    461:        ((long *)curproc->sysstack)[3] = 0;
                    462: 
                    463: 
                    464: 
1.1.1.2   root      465: /* NOTE: in main.c this could be changed, later */
                    466: 
                    467:        curproc->base = _base;
1.1       root      468: 
                    469: 
                    470: 
                    471:        strcpy(curproc->name, "MiNT");
                    472: 
                    473: 
                    474: 
                    475: /* get some memory */
                    476: 
                    477:        curproc->mem = (MEMREGION **)kmalloc(NUM_REGIONS*SIZEOF(MEMREGION *));
                    478: 
                    479:        curproc->addr = (virtaddr *)kmalloc(NUM_REGIONS*SIZEOF(virtaddr));
                    480: 
                    481:        assert(curproc->mem && curproc->addr);
                    482: 
                    483: 
                    484: 
                    485: /* make sure it's filled with zeros */
                    486: 
                    487:        zero((char *)curproc->addr, NUM_REGIONS * SIZEOF(virtaddr));
                    488: 
                    489:        zero((char *)curproc->mem, NUM_REGIONS * SIZEOF(MEMREGION *));
                    490: 
                    491:        curproc->num_reg = NUM_REGIONS;
                    492: 
                    493: 
                    494: 
                    495: /* get root and current directories for all drives */
                    496: 
                    497:        for (i = 0; i < NUM_DRIVES; i++) {
                    498: 
                    499:                if ((fs = drives[i]) != 0 && (*fs->root)(i, &dir) == E_OK) {
                    500: 
1.1.1.3   root      501:                                dup_cookie(&curproc->curdir[i], &dir);
                    502: 
                    503:                                curproc->root[i] = dir;
1.1       root      504: 
                    505:                } else {
                    506: 
                    507:                        curproc->root[i].fs = curproc->curdir[i].fs = 0;
                    508: 
                    509:                        curproc->root[i].dev = curproc->curdir[i].dev = i;
                    510: 
                    511:                }
                    512: 
                    513:        }
                    514: 
                    515: 
                    516: 
1.1.1.3   root      517:        init_page_table(curproc);
                    518: 
                    519: 
                    520: 
1.1       root      521: /* Set the correct drive. The current directory we
                    522: 
                    523:  * set later, after all file systems have been loaded.
                    524: 
                    525:  */
                    526: 
                    527: 
                    528: 
                    529:        curproc->curdrv = Dgetdrv();
                    530: 
                    531:        proclist = curproc;
                    532: 
                    533: 
                    534: 
                    535:        curproc->umask = 0;
                    536: 
                    537: 
                    538: 
                    539: /*
                    540: 
                    541:  * some more protection against job control; unless these signals are
                    542: 
                    543:  * re-activated by a shell that knows about job control, they'll have
                    544: 
                    545:  * no effect
                    546: 
                    547:  */
                    548: 
                    549:        curproc->sighandle[SIGTTIN] = curproc->sighandle[SIGTTOU] =
                    550: 
                    551:                curproc->sighandle[SIGTSTP] = SIG_IGN;
                    552: 
                    553: 
                    554: 
                    555: /* set up some more per-process variables */
                    556: 
                    557:        curproc->starttime = Tgettime();
                    558: 
                    559:        curproc->startdate = Tgetdate();
                    560: 
                    561:        if (has_bconmap)
                    562: 
1.1.1.6 ! root      563: /* init_xbios not happened yet */
        !           564: 
        !           565:                curproc->bconmap = (int) Bconmap(-1);
1.1       root      566: 
                    567:        else
                    568: 
                    569:                curproc->bconmap = 1;
                    570: 
                    571: 
                    572: 
                    573:        curproc->logbase = (void *)Logbase();
                    574: 
1.1.1.2   root      575:        curproc->criticerr = *((long ARGS_ON_STACK (**) P_((long)))0x404L);
1.1       root      576: 
                    577: }
                    578: 
                    579: 
                    580: 
                    581: /*
                    582: 
                    583:  * reset all process priorities to their base level
                    584: 
                    585:  * called once per second, so that cpu hogs can get _some_ time
                    586: 
                    587:  * slices :-).
                    588: 
                    589:  */
                    590: 
                    591: 
                    592: 
                    593: void
                    594: 
                    595: reset_priorities()
                    596: 
                    597: {
                    598: 
                    599:        PROC *p;
                    600: 
                    601: 
                    602: 
                    603:        for (p = proclist; p; p = p->gl_next) {
                    604: 
1.1.1.6 ! root      605:                if (p->slices >= 0) {
1.1       root      606: 
1.1.1.6 ! root      607:                        p->curpri = p->pri;
        !           608: 
        !           609:                        p->slices = SLICES(p->curpri);
        !           610: 
        !           611:                }
1.1       root      612: 
                    613:        }
                    614: 
                    615: }
                    616: 
                    617: 
                    618: 
                    619: /*
                    620: 
                    621:  * more priority code stuff:
                    622: 
                    623:  * run_next(p, slices): schedule process "p" to run next, with "slices"
                    624: 
                    625:  *       initial time slices; "p" does not actually start running until
                    626: 
                    627:  *       the next context switch
                    628: 
                    629:  * fresh_slices(slices): give the current process "slices" more slices in
                    630: 
                    631:  *       which to run
                    632: 
                    633:  */
                    634: 
                    635: 
                    636: 
                    637: void
                    638: 
                    639: run_next(p, slices)
                    640: 
                    641:        PROC *p;
                    642: 
1.1.1.6 ! root      643:        int slices;
1.1       root      644: 
                    645: {
                    646: 
1.1.1.6 ! root      647:        short sr = spl7();
1.1.1.2   root      648: 
1.1.1.6 ! root      649:        p->slices = -slices;
1.1       root      650: 
                    651:        p->curpri = MAX_NICE;
                    652: 
                    653:        p->wait_q = READY_Q;
                    654: 
                    655:        p->q_next = sys_q[READY_Q];
                    656: 
                    657:        sys_q[READY_Q] = p;
                    658: 
1.1.1.6 ! root      659:        spl(sr);
        !           660: 
1.1       root      661: }
                    662: 
                    663: 
                    664: 
                    665: void
                    666: 
                    667: fresh_slices(slices)
                    668: 
                    669:        int slices;
                    670: 
                    671: {
                    672: 
1.1.1.6 ! root      673:        reset_priorities();
        !           674: 
1.1       root      675:        curproc->slices = 0;
                    676: 
                    677:        curproc->curpri = MAX_NICE+1;
                    678: 
1.1.1.6 ! root      679:        proc_clock = TIME_SLICE+slices;
1.1       root      680: 
                    681: }
                    682: 
                    683: 
                    684: 
                    685: /*
                    686: 
                    687:  * add a process to a wait (or ready) queue.
                    688: 
                    689:  *
                    690: 
                    691:  * processes go onto a queue in first in-first out order
                    692: 
                    693:  */
                    694: 
                    695: 
                    696: 
                    697: void
                    698: 
                    699: add_q(que, proc)
                    700: 
                    701:        int que;
                    702: 
                    703:        PROC *proc;
                    704: 
                    705: {
                    706: 
                    707:        PROC *q, **lastq;
                    708: 
                    709: 
                    710: 
                    711: /* "proc" should not already be on a list */
                    712: 
                    713:        assert(proc->wait_q == 0);
                    714: 
                    715:        assert(proc->q_next == 0);
                    716: 
                    717: 
                    718: 
                    719:        lastq = &sys_q[que];
                    720: 
                    721:        q = *lastq;
                    722: 
                    723:        while(q) {
                    724: 
                    725:                lastq = &q->q_next;
                    726: 
                    727:                q = *lastq;
                    728: 
                    729:        }
                    730: 
                    731:        *lastq = proc;
                    732: 
                    733:        proc->wait_q = que;
                    734: 
1.1.1.6 ! root      735:        if (que != READY_Q && proc->slices >= 0) {
1.1       root      736: 
                    737:                proc->curpri = proc->pri;       /* reward the process */
                    738: 
                    739:                proc->slices = SLICES(proc->curpri);
                    740: 
                    741:        }
                    742: 
                    743: }
                    744: 
                    745: 
                    746: 
                    747: /*
                    748: 
                    749:  * remove a process from a queue
                    750: 
                    751:  */
                    752: 
                    753: 
                    754: 
                    755: void
                    756: 
                    757: rm_q(que, proc)
                    758: 
                    759:        int que;
                    760: 
                    761:        PROC *proc;
                    762: 
                    763: {
                    764: 
                    765:        PROC *q;
                    766: 
                    767:        PROC *old = 0;
                    768: 
                    769: 
                    770: 
                    771:        assert(proc->wait_q == que);
                    772: 
                    773: 
                    774: 
                    775:        q = sys_q[que];
                    776: 
                    777:        while (q && q != proc) {
                    778: 
                    779:                old = q;
                    780: 
                    781:                q = q->q_next;
                    782: 
                    783:        }
                    784: 
                    785:        if (q == 0)
                    786: 
                    787:                FATAL("rm_q: unable to remove process from queue");
                    788: 
                    789: 
                    790: 
                    791:        if (old)
                    792: 
                    793:                old->q_next = proc->q_next;
                    794: 
                    795:        else
                    796: 
                    797:                sys_q[que] = proc->q_next;
                    798: 
                    799: 
                    800: 
                    801:        proc->wait_q = 0;
                    802: 
                    803:        proc->q_next = 0;
                    804: 
                    805: }
                    806: 
                    807: 
                    808: 
                    809: /*
                    810: 
                    811:  * preempt(): called by the vbl routine and/or the trap handlers when
                    812: 
                    813:  * they detect that a process has exceeded its time slice and hasn't
                    814: 
                    815:  * yielded gracefully. For now, it just does sleep(READY_Q); later,
                    816: 
                    817:  * we might want to keep track of statistics or something.
                    818: 
                    819:  */
                    820: 
                    821: 
                    822: 
1.1.1.2   root      823: void ARGS_ON_STACK
1.1       root      824: 
                    825: preempt()
                    826: 
                    827: {
                    828: 
                    829:        extern short bconbsiz;  /* in bios.c */
                    830: 
                    831: 
                    832: 
                    833:        if (bconbsiz)
                    834: 
                    835:                (void)bflush();
                    836: 
                    837:        else {
                    838: 
                    839:                /* punish the pre-empted process */
                    840: 
                    841:                if (curproc->curpri >= MIN_NICE)
                    842: 
                    843:                        curproc->curpri -= 1;
                    844: 
                    845:        }
                    846: 
                    847:        sleep(READY_Q, curproc->wait_cond);
                    848: 
                    849: }
                    850: 
                    851: 
                    852: 
                    853: /*
                    854: 
                    855:  * sleep(que, cond): put the current process on the given queue, then switch
                    856: 
                    857:  * contexts. Before a new process runs, give it a fresh time slice. "cond"
                    858: 
                    859:  * is the condition for which the process is waiting, and is placed in
                    860: 
                    861:  * curproc->wait_cond
                    862: 
                    863:  */
                    864: 
                    865: 
                    866: 
1.1.1.6 ! root      867: INLINE static void
1.1       root      868: 
1.1.1.6 ! root      869: do_wakeup_things(sr, newslice)
        !           870: 
        !           871: int sr;
        !           872: 
        !           873: int newslice;
1.1       root      874: 
                    875: {
                    876: 
                    877: /*
                    878: 
                    879:  * check for stack underflow, just in case
                    880: 
                    881:  */
                    882: 
                    883:        auto int foo;
                    884: 
1.1.1.2   root      885:        PROC *p;
1.1       root      886: 
                    887: 
                    888: 
1.1.1.2   root      889:        p = curproc;
1.1       root      890: 
1.1.1.2   root      891: 
                    892: 
1.1.1.6 ! root      893:        if ((sr & 0x700) < 0x500) {
1.1.1.2   root      894: 
1.1.1.6 ! root      895: /* skip all this if int level is too high */
1.1.1.2   root      896: 
1.1.1.6 ! root      897:                if ( p->pid != 0 &&
1.1       root      898: 
1.1.1.6 ! root      899:                     ((long)&foo) < (long)p->stack + ISTKSIZE + 512 ) {
1.1       root      900: 
1.1.1.6 ! root      901:                        ALERT("stack underflow");
        !           902: 
        !           903:                        handle_sig(SIGBUS);
        !           904: 
        !           905:                }
1.1       root      906: 
1.1.1.2   root      907: 
                    908: 
                    909: /* see if process' time limit has been exceeded */
                    910: 
                    911: 
                    912: 
1.1.1.6 ! root      913:                if (p->maxcpu) {
1.1.1.2   root      914: 
1.1.1.6 ! root      915:                        if (p->maxcpu <= p->systime + p->usrtime) {
1.1.1.2   root      916: 
1.1.1.6 ! root      917:                                DEBUG(("cpu limit exceeded"));
1.1.1.2   root      918: 
1.1.1.6 ! root      919:                                raise(SIGXCPU);
1.1.1.2   root      920: 
1.1.1.6 ! root      921:                        }
1.1.1.2   root      922: 
1.1.1.6 ! root      923:                }
1.1.1.2   root      924: 
                    925: 
                    926: 
1.1       root      927: /*
                    928: 
1.1.1.2   root      929:  * check for alarms and similar time out stuff (see timeout.c)
1.1       root      930: 
                    931:  */
                    932: 
                    933: 
                    934: 
1.1.1.6 ! root      935:                checkalarms();
        !           936: 
        !           937:                if (p->sigpending)
        !           938: 
        !           939:                        check_sigs();           /* check for signals */
        !           940: 
        !           941:        }
        !           942: 
        !           943: 
        !           944: 
        !           945:        if (newslice) {
        !           946: 
        !           947:                if (p->slices >= 0) {
        !           948: 
        !           949:                        proc_clock = TIME_SLICE;        /* get a fresh time slice */
        !           950: 
        !           951:                } else {
1.1       root      952: 
1.1.1.6 ! root      953:                        proc_clock = TIME_SLICE-p->slices; /* slices set by run_next */
1.1       root      954: 
1.1.1.6 ! root      955:                        p->curpri = p->pri;
1.1       root      956: 
1.1.1.6 ! root      957:                }
1.1       root      958: 
1.1.1.6 ! root      959:                p->slices = SLICES(p->curpri);
1.1       root      960: 
1.1.1.6 ! root      961:        }
1.1       root      962: 
1.1.1.2   root      963:        p->slices = SLICES(p->curpri);
1.1       root      964: 
                    965: }
                    966: 
                    967: 
                    968: 
1.1.1.6 ! root      969: static long sleepcond, iwakecond;
        !           970: 
        !           971: 
        !           972: 
1.1.1.5   root      973: /*
                    974: 
                    975:  * sleep: returns 1 if no signals have happened since our last sleep, 0
                    976: 
                    977:  * if some have
                    978: 
                    979:  */
                    980: 
                    981: 
                    982: 
                    983: int ARGS_ON_STACK 
1.1       root      984: 
1.1.1.6 ! root      985: sleep(_que, cond)
1.1       root      986: 
1.1.1.6 ! root      987:        int _que;
1.1       root      988: 
                    989:        long cond;
                    990: 
                    991: {
                    992: 
                    993:        PROC *p;
                    994: 
1.1.1.6 ! root      995:        short sr, que = _que & 0xff;
1.1       root      996: 
1.1.1.5   root      997:        ulong onsigs = curproc->nsigs;
                    998: 
1.1       root      999:        extern short kintr;     /* in bios.c */
                   1000: 
1.1.1.6 ! root     1001:        int newslice = 1;
        !          1002: 
1.1.1.4   root     1003: #ifndef MULTITOS
                   1004: 
1.1       root     1005: #ifdef FASTTEXT
                   1006: 
                   1007:        extern int hardscroll;  /* in fasttext.c */
                   1008: 
                   1009: #endif
                   1010: 
1.1.1.4   root     1011: #endif
                   1012: 
1.1       root     1013: 
                   1014: 
1.1.1.6 ! root     1015: /* save condition, checkbttys may just wake() it right away...
        !          1016: 
        !          1017:  * note this assumes the condition will never be waked from interrupts
        !          1018: 
        !          1019:  * or other than thru wake() before we really went to sleep, otherwise
        !          1020: 
        !          1021:  * use the 0x100 bit like select
        !          1022: 
        !          1023:  */
        !          1024: 
        !          1025:        sleepcond = cond;
        !          1026: 
        !          1027: 
        !          1028: 
1.1       root     1029: /*
                   1030: 
                   1031:  * if there have been keyboard interrupts since our last sleep, check for
                   1032: 
                   1033:  * special keys like CTRL-ALT-Fx
                   1034: 
                   1035:  */
                   1036: 
                   1037: 
                   1038: 
1.1.1.6 ! root     1039:        sr = spl7();
        !          1040: 
        !          1041:        if ((sr & 0x700) < 0x500) {
        !          1042: 
        !          1043: /* can't call checkkeys if sleep was called with interrupts off  -nox */
        !          1044: 
        !          1045:                spl(sr);
        !          1046: 
        !          1047:                (void)checkbttys();
        !          1048: 
        !          1049:                if (kintr) {
        !          1050: 
        !          1051:                        (void)checkkeys();
        !          1052: 
        !          1053:                        kintr = 0;
        !          1054: 
        !          1055:                }
        !          1056: 
        !          1057:                sr = spl7();
        !          1058: 
        !          1059:                if ((curproc->sigpending & ~(curproc->sigmask)) &&
        !          1060: 
        !          1061:                    curproc->pid && que != ZOMBIE_Q && que != TSR_Q) {
1.1       root     1062: 
1.1.1.6 ! root     1063:                        spl(sr);
1.1       root     1064: 
1.1.1.6 ! root     1065:                        check_sigs();
        !          1066: 
        !          1067:                        sr = spl7();
        !          1068: 
        !          1069:                        sleepcond = 0;  /* possibly handled a signal, return */
        !          1070: 
        !          1071:                }
1.1       root     1072: 
                   1073:        }
                   1074: 
                   1075: 
                   1076: 
1.1.1.6 ! root     1077: /*
        !          1078: 
        !          1079:  * kay: If _que & 0x100 != 0 then take curproc->wait_cond != cond as an
        !          1080: 
        !          1081:  * indicatation that the wakeup has already happend before we actually
        !          1082: 
        !          1083:  * go to sleep and return immediatly.
        !          1084: 
        !          1085:  */
        !          1086: 
        !          1087: 
        !          1088: 
        !          1089:        if ((que == READY_Q && !sys_q[READY_Q]) ||
        !          1090: 
        !          1091:            ((sleepcond != cond ||
        !          1092: 
        !          1093:              (iwakecond == cond && cond) ||
        !          1094: 
        !          1095:              (_que & 0x100 && curproc->wait_cond != cond)) &&
        !          1096: 
        !          1097:             (!sys_q[READY_Q] || (newslice = 0, proc_clock)))) {
1.1       root     1098: 
                   1099: /* we're just going to wake up again right away! */
                   1100: 
1.1.1.6 ! root     1101:                iwakecond = 0;
        !          1102: 
        !          1103:                spl(sr);
        !          1104: 
        !          1105:                do_wakeup_things(sr, newslice);
1.1       root     1106: 
1.1.1.5   root     1107:                return (onsigs != curproc->nsigs);
1.1       root     1108: 
                   1109:        }
                   1110: 
                   1111: 
                   1112: 
1.1.1.6 ! root     1113: /*
        !          1114: 
        !          1115:  * unless our time slice has expired (proc_clock == 0) and other
        !          1116: 
        !          1117:  * processes are ready...
        !          1118: 
        !          1119:  */
1.1       root     1120: 
1.1.1.6 ! root     1121:        iwakecond = 0;
1.1       root     1122: 
1.1.1.6 ! root     1123:        if (!newslice)
        !          1124: 
        !          1125:                que = READY_Q;
        !          1126: 
        !          1127:        else
        !          1128: 
        !          1129:                curproc->wait_cond = cond;
1.1       root     1130: 
                   1131:        add_q(que, curproc);
                   1132: 
                   1133: 
                   1134: 
1.1.1.6 ! root     1135: /* alright curproc is on que now...  maybe there's an interrupt pending
        !          1136: 
        !          1137:  * that will wakeselect or signal someone
        !          1138: 
        !          1139:  */
        !          1140: 
        !          1141:        spl(sr);
1.1       root     1142: 
                   1143:        if (!sys_q[READY_Q]) {
                   1144: 
                   1145: /* hmm, no-one is ready to run. might be a deadlock, might not.
                   1146: 
                   1147:  * first, try waking up any napping processes; if that doesn't work,
                   1148: 
                   1149:  * run the root process, just so we have someone to charge time
                   1150: 
                   1151:  * to.
                   1152: 
                   1153:  */
                   1154: 
1.1.1.2   root     1155:                wake(SELECT_Q, (long)nap);
1.1       root     1156: 
1.1.1.6 ! root     1157:                sr = spl7();
        !          1158: 
1.1       root     1159:                if (!sys_q[READY_Q]) {
                   1160: 
                   1161:                        p = rootproc;           /* pid 0 */
                   1162: 
                   1163:                        rm_q(p->wait_q, p);
                   1164: 
                   1165:                        add_q(READY_Q, p);
                   1166: 
                   1167:                }
                   1168: 
1.1.1.6 ! root     1169:                spl(sr);
        !          1170: 
1.1       root     1171:        }
                   1172: 
                   1173: 
                   1174: 
                   1175: /*
                   1176: 
                   1177:  * Walk through the ready list, to find what process should run next.
                   1178: 
                   1179:  * Lower priority processes don't get to run every time through this
                   1180: 
                   1181:  * loop; if "p->slices" is positive, it's the number of times that they
                   1182: 
                   1183:  * will have to miss a turn before getting to run again
                   1184: 
                   1185:  */
                   1186: 
1.1.1.3   root     1187: 
                   1188: 
                   1189: /*
                   1190: 
                   1191:  * Loop structure:
                   1192: 
                   1193:  *     while (we haven't picked anybody) {
                   1194: 
                   1195:  *             for (each process) {
                   1196: 
                   1197:  *                     if (sleeping off a penalty) {
                   1198: 
                   1199:  *                             decrement penalty counter
                   1200: 
                   1201:  *                     }
                   1202: 
                   1203:  *                     else {
                   1204: 
                   1205:  *                             pick this one and break out of both loops
                   1206: 
                   1207:  *                     }
                   1208: 
                   1209:  *             }
                   1210: 
                   1211:  *     }
                   1212: 
                   1213:  */
                   1214: 
1.1       root     1215:        p = 0;
                   1216: 
                   1217: 
                   1218: 
                   1219:        while (!p) {
                   1220: 
                   1221:                for (p = sys_q[READY_Q]; p; p = p->q_next) {
                   1222: 
                   1223:                        if (p->slices > 0)
                   1224: 
                   1225:                                p->slices--;
                   1226: 
                   1227:                        else
                   1228: 
                   1229:                                break;
                   1230: 
                   1231:                }
                   1232: 
                   1233:        }
                   1234: 
1.1.1.3   root     1235: 
                   1236: 
                   1237:        /* p is our victim */
                   1238: 
                   1239: 
                   1240: 
1.1       root     1241:        rm_q(READY_Q, p);
                   1242: 
                   1243: 
                   1244: 
                   1245:        spl(sr);
                   1246: 
                   1247: 
                   1248: 
                   1249:        if (save_context(&(curproc->ctxt[CURRENT]))) {
                   1250: 
                   1251: /*
                   1252: 
                   1253:  * restore per-process variables here
                   1254: 
                   1255:  */
                   1256: 
1.1.1.4   root     1257: #ifndef MULTITOS
                   1258: 
1.1       root     1259: #ifdef FASTTEXT
                   1260: 
                   1261:                if (!hardscroll)
                   1262: 
                   1263:                        *((void **)0x44eL) = curproc->logbase;
                   1264: 
1.1.1.4   root     1265: #endif
                   1266: 
1.1.1.6 ! root     1267: #endif
        !          1268: 
        !          1269:                do_wakeup_things(sr, 1);
1.1       root     1270: 
1.1.1.5   root     1271:                return (onsigs != curproc->nsigs);
1.1       root     1272: 
                   1273:        }
                   1274: 
                   1275: /*
                   1276: 
                   1277:  * save per-process variables here
                   1278: 
                   1279:  */
                   1280: 
1.1.1.4   root     1281: #ifndef MULTITOS
                   1282: 
1.1       root     1283: #ifdef FASTTEXT
                   1284: 
                   1285:        if (!hardscroll)
                   1286: 
                   1287:                curproc->logbase = *((void **)0x44eL);
                   1288: 
1.1.1.4   root     1289: #endif
                   1290: 
1.1.1.6 ! root     1291: #endif
        !          1292: 
        !          1293: 
        !          1294: 
1.1       root     1295:        curproc->ctxt[CURRENT].regs[0] = 1;
                   1296: 
                   1297:        curproc = p;
                   1298: 
                   1299:        proc_clock = TIME_SLICE;        /* fresh time */
                   1300: 
                   1301:        if ((p->ctxt[CURRENT].sr & 0x2000) == 0) {      /* user mode? */
                   1302: 
                   1303:                leave_kernel();
                   1304: 
                   1305:        }
                   1306: 
                   1307:        assert(p->magic == CTXT_MAGIC);
                   1308: 
1.1.1.3   root     1309:        change_context(&(p->ctxt[CURRENT]));
1.1       root     1310: 
1.1.1.5   root     1311:        /* not reached */
                   1312: 
                   1313:        return 0;
                   1314: 
1.1       root     1315: }
                   1316: 
                   1317: 
                   1318: 
                   1319: /*
                   1320: 
                   1321:  * wake(que, cond): wake up all processes on the given queue that are waiting
                   1322: 
                   1323:  * for the indicated condition
                   1324: 
                   1325:  */
                   1326: 
                   1327: 
                   1328: 
1.1.1.6 ! root     1329: INLINE static void
1.1       root     1330: 
1.1.1.6 ! root     1331: do_wake(que, cond)
1.1       root     1332: 
                   1333:        int que;
                   1334: 
                   1335:        long cond;
                   1336: 
                   1337: {
                   1338: 
                   1339:        PROC *p;
                   1340: 
1.1.1.6 ! root     1341: top:
        !          1342: 
        !          1343:        for(p = sys_q[que]; p;) {
1.1       root     1344: 
1.1.1.6 ! root     1345:                short s = spl7();
        !          1346: 
        !          1347:                PROC *q;
        !          1348: 
        !          1349: 
        !          1350: 
        !          1351: /* check p is still on the right queue, maybe an interrupt just woke it... */
        !          1352: 
        !          1353:                if (p->wait_q != que) {
        !          1354: 
        !          1355:                        spl(s);
        !          1356: 
        !          1357:                        goto top;
        !          1358: 
        !          1359:                }
        !          1360: 
        !          1361:                q = p;
        !          1362: 
        !          1363:                p = p->q_next;
        !          1364: 
        !          1365:                if (q->wait_cond == cond) {
        !          1366: 
        !          1367:                        rm_q(que, q);
        !          1368: 
        !          1369:                        add_q(READY_Q, q);
        !          1370: 
        !          1371:                }
        !          1372: 
        !          1373:                spl(s);
        !          1374: 
        !          1375:        }
        !          1376: 
        !          1377: }
        !          1378: 
        !          1379: 
        !          1380: 
        !          1381: void ARGS_ON_STACK 
        !          1382: 
        !          1383: wake(que, cond)
        !          1384: 
        !          1385:        int que;
        !          1386: 
        !          1387:        long cond;
        !          1388: 
        !          1389: {
1.1       root     1390: 
                   1391:        if (que == READY_Q) {
                   1392: 
                   1393:                ALERT("wake: why wake up ready processes??");
                   1394: 
                   1395:                return;
                   1396: 
                   1397:        }
                   1398: 
1.1.1.6 ! root     1399:        if (sleepcond == cond)
1.1       root     1400: 
1.1.1.6 ! root     1401:                sleepcond = 0;
1.1       root     1402: 
1.1.1.6 ! root     1403:        do_wake(que, cond);
1.1       root     1404: 
1.1.1.6 ! root     1405: }
1.1.1.3   root     1406: 
1.1       root     1407: 
1.1.1.6 ! root     1408: 
        !          1409: /*
        !          1410: 
        !          1411:  * iwake(que, cond, pid): special version of wake() for IO interrupt
        !          1412: 
        !          1413:  * handlers and such.  the normal wake() would lose when its
        !          1414: 
        !          1415:  * interrupt goes off just before a process is calling sleep() on the
        !          1416: 
        !          1417:  * same condition (similar problem like with wakeselect...)
        !          1418: 
        !          1419:  *
        !          1420: 
        !          1421:  * use like this:
        !          1422: 
        !          1423:  *     static ipid = -1;
        !          1424: 
        !          1425:  *     static volatile sleepers = 0;   (optional, to save useless calls)
        !          1426: 
        !          1427:  *     ...
        !          1428: 
        !          1429:  *     device_read(...)
        !          1430: 
        !          1431:  *     {
        !          1432: 
        !          1433:  *             ipid = curproc->pid;    (p_getpid() for device drivers...)
        !          1434: 
        !          1435:  *             while (++sleepers, (not ready for IO...)) {
        !          1436: 
        !          1437:  *                     sleep(IO_Q, cond);
        !          1438: 
        !          1439:  *                     if (--sleepers < 0)
        !          1440: 
        !          1441:  *                             sleepers = 0;
        !          1442: 
        !          1443:  *             }
        !          1444: 
        !          1445:  *             if (--sleepers < 0)
        !          1446: 
        !          1447:  *                     sleepers = 0;
        !          1448: 
        !          1449:  *             ipid = -1;
        !          1450: 
        !          1451:  *             ...
        !          1452: 
        !          1453:  *     }
        !          1454: 
        !          1455:  *
        !          1456: 
        !          1457:  * and in the interrupt handler:
        !          1458: 
        !          1459:  *     if (sleepers > 0) {
        !          1460: 
        !          1461:  *             sleepers = 0;
        !          1462: 
        !          1463:  *             iwake(IO_Q, cond, ipid);
        !          1464: 
        !          1465:  *     }
        !          1466: 
        !          1467:  *
        !          1468: 
        !          1469:  * caller is responsible for not trying to wake READY_Q or other nonsense :)
        !          1470: 
        !          1471:  * and making sure the passed pid is always -1 when curproc is calling
        !          1472: 
        !          1473:  * sleep() for another than the waked que/condition.
        !          1474: 
        !          1475:  */
        !          1476: 
        !          1477: 
        !          1478: 
        !          1479: void ARGS_ON_STACK 
        !          1480: 
        !          1481: iwake(que, cond, pid)
        !          1482: 
        !          1483:        int que;
        !          1484: 
        !          1485:        long cond;
        !          1486: 
        !          1487:        short pid;
        !          1488: 
        !          1489: {
        !          1490: 
        !          1491:        if (pid >= 0) {
        !          1492: 
        !          1493:                short s = spl7();
        !          1494: 
        !          1495:                if (iwakecond == cond) {
1.1       root     1496: 
1.1.1.3   root     1497:                        spl(s);
                   1498: 
1.1.1.6 ! root     1499:                        return;
1.1       root     1500: 
                   1501:                }
                   1502: 
1.1.1.6 ! root     1503:                if (curproc->pid == pid && !curproc->wait_q)
        !          1504: 
        !          1505:                        iwakecond = cond;
        !          1506: 
        !          1507:                spl(s);
        !          1508: 
1.1       root     1509:        }
                   1510: 
1.1.1.6 ! root     1511:        do_wake(que, cond);
        !          1512: 
1.1       root     1513: }
                   1514: 
                   1515: 
                   1516: 
                   1517: /*
                   1518: 
                   1519:  * wakeselect(p): wake process p from a select() system call
                   1520: 
                   1521:  * may be called by an interrupt handler or whatever
                   1522: 
                   1523:  */
                   1524: 
                   1525: 
                   1526: 
1.1.1.2   root     1527: void ARGS_ON_STACK 
1.1       root     1528: 
                   1529: wakeselect(param)
                   1530: 
                   1531:        long param;
                   1532: 
                   1533: {
                   1534: 
                   1535:        PROC *p = (PROC *)param;
                   1536: 
                   1537:        short s;
                   1538: 
1.1.1.6 ! root     1539:        extern short select_coll;       /* in dosfile.c */
        !          1540: 
1.1       root     1541: 
                   1542: 
                   1543:        s = spl7();     /* block interrupts */
                   1544: 
1.1.1.6 ! root     1545:        if(p->wait_cond == (long)wakeselect ||
        !          1546: 
        !          1547:           p->wait_cond == (long)&select_coll) {
1.1       root     1548: 
                   1549:                p->wait_cond = 0;
                   1550: 
                   1551:        }
                   1552: 
                   1553:        if (p->wait_q == SELECT_Q) {
                   1554: 
                   1555:                rm_q(SELECT_Q, p);
                   1556: 
                   1557:                add_q(READY_Q, p);
                   1558: 
                   1559:        }
                   1560: 
                   1561:        spl(s);
                   1562: 
                   1563: }
                   1564: 
                   1565: 
                   1566: 
                   1567: /*
                   1568: 
                   1569:  * dump out information about processes
                   1570: 
                   1571:  */
                   1572: 
                   1573: 
                   1574: 
                   1575: /*
                   1576: 
1.1.1.3   root     1577:  * kludge alert! In order to get the right pid printed by FORCE, we use
1.1       root     1578: 
                   1579:  * curproc as the loop variable.
                   1580: 
1.1.1.3   root     1581:  *
                   1582: 
                   1583:  * I have changed this function so it is more useful to a user, less to
                   1584: 
                   1585:  * somebody debugging MiNT.  I haven't had any stack problems in MiNT
                   1586: 
                   1587:  * at all, so I consider all that stack info wasted space.  -- AKP
                   1588: 
1.1       root     1589:  */
                   1590: 
                   1591: 
                   1592: 
1.1.1.4   root     1593: #ifdef DEBUG_INFO
1.1.1.3   root     1594: 
                   1595: static const char *qstring[] = {
                   1596: 
                   1597:        "run", "ready", "wait", "iowait", "zombie", "tsr", "stop", "select"
                   1598: 
                   1599: };
                   1600: 
                   1601: 
                   1602: 
                   1603: /* UNSAFE macro for qname, evaluates x 1, 2, or 3 times */
                   1604: 
                   1605: #define qname(x) ((x >= 0 && x < NUM_QUEUES) ? qstring[x] : "unkn")
                   1606: 
                   1607: #endif
                   1608: 
                   1609: 
                   1610: 
1.1.1.6 ! root     1611: #include "loadave.h"
        !          1612: 
        !          1613: 
        !          1614: 
        !          1615: unsigned long uptime = 0;
        !          1616: 
        !          1617: unsigned long avenrun[3] = {0,0,0};
        !          1618: 
        !          1619: short uptimetick = 200;
        !          1620: 
        !          1621: static int number_running;
        !          1622: 
        !          1623: static int one_min_ptr = 0, five_min_ptr = 0, fifteen_min_ptr = 0;
        !          1624: 
        !          1625: static unsigned long sum1 = 0, sum5 = 0, sum15 = 0;
        !          1626: 
        !          1627: static unsigned char one_min[SAMPS_PER_MIN];
        !          1628: 
        !          1629: static unsigned char five_min[SAMPS_PER_5MIN];
        !          1630: 
        !          1631: static unsigned char fifteen_min[SAMPS_PER_15MIN];
        !          1632: 
        !          1633: 
        !          1634: 
1.1       root     1635: void
                   1636: 
                   1637: DUMPPROC()
                   1638: 
                   1639: {
                   1640: 
1.1.1.4   root     1641: #ifdef DEBUG_INFO
1.1.1.2   root     1642: 
1.1       root     1643:        PROC *p = curproc;
                   1644: 
                   1645: 
                   1646: 
1.1.1.6 ! root     1647:        FORCE("Uptime: %ld seconds Loads: %ld %ld %ld Processes running: %d",
        !          1648: 
        !          1649:                uptime,
        !          1650: 
        !          1651:                (avenrun[0]*100)/2048 , (avenrun[1]*100)/2048, (avenrun[2]*100/2048),
        !          1652: 
        !          1653:                number_running);
        !          1654: 
        !          1655: 
        !          1656: 
1.1       root     1657:        for (curproc = proclist; curproc; curproc = curproc->gl_next) {
                   1658: 
1.1.1.3   root     1659:            FORCE("state %s PC: %lx BP: %lx",
1.1       root     1660: 
1.1.1.3   root     1661:                qname(curproc->wait_q),
1.1       root     1662: 
                   1663:                curproc->ctxt[SYSCALL].pc,
                   1664: 
1.1.1.3   root     1665:                curproc->base);
1.1       root     1666: 
                   1667:        }
                   1668: 
                   1669:        curproc = p;            /* restore the real curproc */
                   1670: 
1.1.1.2   root     1671: #endif
                   1672: 
1.1       root     1673: }
                   1674: 
1.1.1.6 ! root     1675: 
        !          1676: 
        !          1677: unsigned long
        !          1678: 
        !          1679: gen_average(sum, load_ptr, max_size)
        !          1680: 
        !          1681:        unsigned long *sum;
        !          1682: 
        !          1683:        unsigned char *load_ptr;
        !          1684: 
        !          1685:        int max_size;
        !          1686: 
        !          1687: {
        !          1688: 
        !          1689:        int old_load, new_load;
        !          1690: 
        !          1691: 
        !          1692: 
        !          1693:        old_load = (int)*load_ptr;
        !          1694: 
        !          1695:        new_load = number_running;
        !          1696: 
        !          1697:        *load_ptr = (char)new_load;
        !          1698: 
        !          1699: 
        !          1700: 
        !          1701:        *sum += ((long) (new_load - old_load) * LOAD_SCALE);
        !          1702: 
        !          1703: 
        !          1704: 
        !          1705:        return (*sum / max_size);
        !          1706: 
        !          1707: }
        !          1708: 
        !          1709: 
        !          1710: 
        !          1711: void
        !          1712: 
        !          1713: calc_load_average()
        !          1714: 
        !          1715: {
        !          1716: 
        !          1717:        PROC *p;
        !          1718: 
        !          1719: 
        !          1720: 
        !          1721:        uptime++;
        !          1722: 
        !          1723:        uptimetick += 200;
        !          1724: 
        !          1725: 
        !          1726: 
        !          1727:        if (uptime % 5) return;
        !          1728: 
        !          1729: 
        !          1730: 
        !          1731:        number_running = 0;
        !          1732: 
        !          1733:        
        !          1734: 
        !          1735:        for (p = proclist; p; p = p->gl_next)
        !          1736: 
        !          1737:                if (p != rootproc)
        !          1738: 
        !          1739:                        if ((p->wait_q == 0) || (p->wait_q == 1))
        !          1740: 
        !          1741:                                number_running++;
        !          1742: 
        !          1743: 
        !          1744: 
        !          1745:        avenrun[0] = gen_average(&sum1, &one_min[one_min_ptr++],
        !          1746: 
        !          1747:                                 SAMPS_PER_MIN);
        !          1748: 
        !          1749: 
        !          1750: 
        !          1751:        if (one_min_ptr == SAMPS_PER_MIN)
        !          1752: 
        !          1753:                one_min_ptr = 0;
        !          1754: 
        !          1755: 
        !          1756: 
        !          1757:        avenrun[1] = gen_average(&sum5, &five_min[five_min_ptr++],
        !          1758: 
        !          1759:                                 SAMPS_PER_5MIN);
        !          1760: 
        !          1761: 
        !          1762: 
        !          1763:        if (five_min_ptr == SAMPS_PER_5MIN)
        !          1764: 
        !          1765:                five_min_ptr = 0;
        !          1766: 
        !          1767: 
        !          1768: 
        !          1769:        avenrun[2] = gen_average(&sum15, &fifteen_min[fifteen_min_ptr++],
        !          1770: 
        !          1771:                                 SAMPS_PER_15MIN);
        !          1772: 
        !          1773: 
        !          1774: 
        !          1775:        if (fifteen_min_ptr == SAMPS_PER_15MIN)
        !          1776: 
        !          1777:                fifteen_min_ptr = 0;
        !          1778: 
        !          1779: 
        !          1780: 
        !          1781: }
        !          1782: 
        !          1783: 
        !          1784: 

unix.superglobalmegacorp.com

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