Annotation of MiNT/src/timeout.c, revision 1.1.1.2

1.1       root        1: /*
                      2: 
                      3: Copyright 1990,1991 Eric R. Smith. All rights reserved.
                      4: 
                      5: */
                      6: 
                      7: 
                      8: 
                      9: #include "mint.h"
                     10: 
                     11: 
                     12: 
                     13: /*
                     14: 
                     15:  * We initialize proc_clock to a very large value so that we don't have
                     16: 
                     17:  * to worry about unexpected process switches while starting up
                     18: 
                     19:  */
                     20: 
                     21: 
                     22: 
                     23: short proc_clock = 0x7fff;
                     24: 
                     25: 
                     26: 
                     27: /* used by filesystems for time/date stamps; updated once per second */
                     28: 
                     29: short timestamp, datestamp;
                     30: 
                     31: 
                     32: 
                     33: extern short in_kernel;        /* in main.c */
                     34: 
                     35: 
                     36: 
                     37: static void unnapme P_((PROC *));
                     38: 
                     39: 
                     40: 
                     41: /*
                     42: 
                     43:  * addtimeout(long delta, void (*func)()): schedule a timeout for the current
                     44: 
                     45:  * process, to take place in "delta" milliseconds. "func" specifies a
                     46: 
                     47:  * function to be called at that time; the function is passed as a parameter
                     48: 
                     49:  * the process for which the timeout was specified (i.e. the value of
                     50: 
                     51:  * curproc at the time addtimeout() was called; note that this is probably
                     52: 
                     53:  * *not* the current process when the timeout occurs).
                     54: 
                     55:  */
                     56: 
                     57: 
                     58: 
                     59: TIMEOUT *tlist;
                     60: 
                     61: 
                     62: 
                     63: #define newtimeout() (TIMEOUT *)kmalloc(SIZEOF(TIMEOUT))
                     64: 
                     65: #define disposetimeout(t) kfree(t)
                     66: 
                     67: 
                     68: 
                     69: TIMEOUT *
                     70: 
                     71: addtimeout(delta, func)
                     72: 
                     73:        long delta;
                     74: 
                     75:        void (*func) P_((PROC *));
                     76: 
                     77: {
                     78: 
                     79:        TIMEOUT *t, **prev, *cur;
                     80: 
                     81: 
                     82: 
                     83:        t = newtimeout();
                     84: 
                     85: 
                     86: 
                     87: /* BUG: we should have some fallback mechanism for timeouts when the
                     88: 
                     89:    kernel memory is exhausted
                     90: 
                     91:  */
                     92: 
                     93:        assert(t);
                     94: 
                     95: 
                     96: 
                     97:        t->proc = curproc;
                     98: 
                     99:        t->func = func;
                    100: 
                    101: 
                    102: 
                    103:        cur = tlist;
                    104: 
                    105:        prev = &tlist;
                    106: 
                    107:        while (cur) {
                    108: 
                    109:                if (cur->when >= delta) {
                    110: 
                    111:                        cur->when -= delta;
                    112: 
                    113:                        t->next = cur;
                    114: 
                    115:                        t->when = delta;
                    116: 
                    117:                        *prev = t;
                    118: 
                    119:                        return t;
                    120: 
                    121:                }
                    122: 
                    123:                delta -= cur->when;
                    124: 
                    125:                prev = &cur->next;
                    126: 
                    127:                cur = cur->next;
                    128: 
                    129:        }
                    130: 
                    131:        assert(delta >= 0);
                    132: 
                    133:        t->when = delta;
                    134: 
                    135:        t->next = cur;
                    136: 
                    137:        *prev = t;
                    138: 
                    139:        return t;
                    140: 
                    141: }
                    142: 
                    143: 
                    144: 
                    145: /*
                    146: 
                    147:  * cancelalltimeouts(): cancels all pending timeouts for the current
                    148: 
                    149:  * process
                    150: 
                    151:  */
                    152: 
                    153: 
                    154: 
                    155: void
                    156: 
                    157: cancelalltimeouts()
                    158: 
                    159: {
                    160: 
                    161:        TIMEOUT *cur, **prev, *old;
                    162: 
                    163:        long delta;
                    164: 
                    165: 
                    166: 
                    167:        cur = tlist;
                    168: 
                    169:        prev = &tlist;
                    170: 
                    171:        while (cur) {
                    172: 
                    173:                if (cur->proc == curproc) {
                    174: 
                    175:                        delta = cur->when;
                    176: 
                    177:                        old = cur;
                    178: 
                    179:                        *prev = cur = cur->next;
                    180: 
                    181:                        if (cur) cur->when += delta;
                    182: 
                    183:                        disposetimeout(old);
                    184: 
                    185:                }
                    186: 
                    187:                else {
                    188: 
                    189:                        prev = &cur->next;
                    190: 
                    191:                        cur = cur->next;
                    192: 
                    193:                }
                    194: 
                    195:        }
                    196: 
                    197: }
                    198: 
                    199: 
                    200: 
                    201: /*
                    202: 
                    203:  * Cancel a specific timeout. If the timeout isn't on the list, or isn't
                    204: 
                    205:  * for this process, we do nothing; otherwise, we cancel the time out
                    206: 
                    207:  * and then free the memory it used. *NOTE*: it's very possible (indeed
                    208: 
                    209:  * likely) that "this" was already removed from the list and disposed of
                    210: 
                    211:  * by the timeout processing routines, so it's important that we check
                    212: 
                    213:  * for it's presence in the list and do absolutely nothing if we don't
                    214: 
                    215:  * find it there!
                    216: 
                    217:  */
                    218: 
                    219: 
                    220: 
                    221: void
                    222: 
                    223: canceltimeout(this)
                    224: 
                    225:        TIMEOUT *this;
                    226: 
                    227: {
                    228: 
                    229:        TIMEOUT *cur, **prev;
                    230: 
                    231: 
                    232: 
                    233:        prev = &tlist;
                    234: 
                    235:        for (cur = tlist; cur; cur = cur->next) {
                    236: 
                    237:                if (cur == this && cur->proc == curproc) {
                    238: 
                    239:                        *prev = cur->next;
                    240: 
                    241:                        if (cur->next) {
                    242: 
                    243:                                cur->next->when += this->when;
                    244: 
                    245:                        }
                    246: 
                    247:                        disposetimeout(this);
                    248: 
                    249:                        break;
                    250: 
                    251:                }
                    252: 
                    253:                prev = &cur->next;
                    254: 
                    255:        }
                    256: 
                    257: }
                    258: 
                    259: 
                    260: 
                    261: /*
                    262: 
                    263:  * timeout: called every 20 ms or so by GEMDOS, this routine
                    264: 
                    265:  * is responsible for maintaining process times and such.
                    266: 
                    267:  * it should also decrement the "proc_clock" variable, but
                    268: 
                    269:  * should *not* take any action when it reaches 0 (the state of the
                    270: 
                    271:  * stack is too uncertain, and time is too critical). Instead,
                    272: 
                    273:  * a vbl routine checks periodically and if "proc_clock" is 0
                    274: 
                    275:  * suspends the current process
                    276: 
                    277:  */
                    278: 
                    279: 
                    280: 
                    281: volatile int our_clock = 1000;
                    282: 
                    283: 
                    284: 
1.1.1.2 ! root      285: void ARGS_ON_STACK
1.1       root      286: 
                    287: timeout()
                    288: 
                    289: {
                    290: 
                    291:        int ms;         /* time between ticks */
                    292: 
                    293: 
                    294: 
                    295:        ms = *((short *)0x442L);
                    296: 
                    297:        if (proc_clock > 0)
                    298: 
                    299:                proc_clock--;
                    300: 
                    301: 
                    302: 
                    303:        our_clock -= ms;
                    304: 
                    305:        if (tlist) {
                    306: 
                    307:                tlist->when -= ms;
                    308: 
                    309:        }
                    310: 
                    311: }
                    312: 
                    313: 
                    314: 
                    315: /*
                    316: 
                    317:  * sleep() calls this routine to check on alarms and other sorts
                    318: 
                    319:  * of time-outs on every context switch.
                    320: 
                    321:  */
                    322: 
                    323: 
                    324: 
                    325: void
                    326: 
                    327: checkalarms()
                    328: 
                    329: {
                    330: 
                    331:        extern long searchtime;         /* in dosdir.c */
                    332: 
                    333:        PROC *p;
                    334: 
                    335:        long delta;
                    336: 
                    337:        void (*evnt) P_((PROC *));
                    338: 
                    339:        TIMEOUT *old;
                    340: 
                    341: 
                    342: 
                    343: /* do the once per second things */
                    344: 
                    345:        while (our_clock < 0) {
                    346: 
                    347:                our_clock += 1000;
                    348: 
                    349:                timestamp = Tgettime();
                    350: 
                    351:                datestamp = Tgetdate();
                    352: 
                    353:                searchtime++;
                    354: 
                    355:                reset_priorities();
                    356: 
                    357:        }
                    358: 
                    359: 
                    360: 
                    361: /* see if there are outstanding timeout requests to do */
                    362: 
                    363:        while (tlist && ((delta = tlist->when) <= 0)) {
                    364: 
                    365:                p = tlist->proc;
                    366: 
1.1.1.2 ! root      367:                TRACE(("doing timeout code for pid %d", p->pid));
1.1       root      368: 
                    369:                evnt = tlist->func;
                    370: 
                    371:                old = tlist;
                    372: 
                    373:                tlist = tlist->next;
                    374: 
                    375:                disposetimeout(old);
                    376: 
                    377:        /* call the timeout function */
                    378: 
                    379:                (*evnt)(p);
                    380: 
                    381: 
                    382: 
                    383: /* if delta < 0, it's possible that the time has come for the next timeout
                    384: 
                    385:    to occur */
                    386: 
                    387:                if (tlist)
                    388: 
                    389:                        tlist->when += delta;
                    390: 
                    391:        }
                    392: 
                    393: }
                    394: 
                    395: 
                    396: 
                    397: /*
                    398: 
                    399:  * nap(n): nap for n milliseconds. Used in loops where we're waiting for
                    400: 
                    401:  * an event. If we expect the event *very* soon, we should use yield
                    402: 
                    403:  * instead.
                    404: 
                    405:  * NOTE: we may not sleep for exactly n milliseconds; signals can wake
                    406: 
                    407:  * us earlier, and the vagaries of process scheduling may cause us to
                    408: 
                    409:  * oversleep...
                    410: 
                    411:  */
                    412: 
                    413: 
                    414: 
                    415: static void
                    416: 
                    417: unnapme(p)
                    418: 
                    419:        PROC *p;
                    420: 
                    421: {
                    422: 
1.1.1.2 ! root      423:        if (p->wait_q == SELECT_Q && p->wait_cond == (long)nap) {
1.1       root      424: 
                    425:                rm_q(SELECT_Q, p);
                    426: 
                    427:                add_q(READY_Q, p);
                    428: 
                    429:                p->wait_cond = 0;
                    430: 
                    431:        }
                    432: 
                    433: }
                    434: 
                    435: 
                    436: 
1.1.1.2 ! root      437: void ARGS_ON_STACK 
1.1       root      438: 
                    439: nap(n)
                    440: 
                    441:        unsigned n;
                    442: 
                    443: {
                    444: 
                    445:        TIMEOUT *t;
                    446: 
                    447: 
                    448: 
                    449:        t = addtimeout((long)n, unnapme);
                    450: 
1.1.1.2 ! root      451:        sleep(SELECT_Q, (long)nap);
1.1       root      452: 
                    453:        canceltimeout(t);
                    454: 
                    455: }
                    456: 

unix.superglobalmegacorp.com

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