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

unix.superglobalmegacorp.com

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