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

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: 
        !           285: void
        !           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: #if 0
        !           314: 
        !           315:        /* AKP: I moved this to traps.s */
        !           316: 
        !           317:        if (in_kernel)
        !           318: 
        !           319:                curproc->systime += ms;
        !           320: 
        !           321:        else
        !           322: 
        !           323:                curproc->usrtime += ms;
        !           324: 
        !           325: #endif
        !           326: 
        !           327: }
        !           328: 
        !           329: 
        !           330: 
        !           331: /*
        !           332: 
        !           333:  * sleep() calls this routine to check on alarms and other sorts
        !           334: 
        !           335:  * of time-outs on every context switch.
        !           336: 
        !           337:  */
        !           338: 
        !           339: 
        !           340: 
        !           341: void
        !           342: 
        !           343: checkalarms()
        !           344: 
        !           345: {
        !           346: 
        !           347:        extern long searchtime;         /* in dosdir.c */
        !           348: 
        !           349:        PROC *p;
        !           350: 
        !           351:        long delta;
        !           352: 
        !           353:        void (*evnt) P_((PROC *));
        !           354: 
        !           355:        TIMEOUT *old;
        !           356: 
        !           357: 
        !           358: 
        !           359: /* do the once per second things */
        !           360: 
        !           361:        while (our_clock < 0) {
        !           362: 
        !           363:                our_clock += 1000;
        !           364: 
        !           365:                timestamp = Tgettime();
        !           366: 
        !           367:                datestamp = Tgetdate();
        !           368: 
        !           369:                searchtime++;
        !           370: 
        !           371:                reset_priorities();
        !           372: 
        !           373:        }
        !           374: 
        !           375: 
        !           376: 
        !           377: /* see if there are outstanding timeout requests to do */
        !           378: 
        !           379:        while (tlist && ((delta = tlist->when) <= 0)) {
        !           380: 
        !           381:                p = tlist->proc;
        !           382: 
        !           383:                TRACE("doing timeout code for pid %d", p->pid);
        !           384: 
        !           385:                evnt = tlist->func;
        !           386: 
        !           387:                old = tlist;
        !           388: 
        !           389:                tlist = tlist->next;
        !           390: 
        !           391:                disposetimeout(old);
        !           392: 
        !           393:        /* call the timeout function */
        !           394: 
        !           395:                (*evnt)(p);
        !           396: 
        !           397: 
        !           398: 
        !           399: /* if delta < 0, it's possible that the time has come for the next timeout
        !           400: 
        !           401:    to occur */
        !           402: 
        !           403:                if (tlist)
        !           404: 
        !           405:                        tlist->when += delta;
        !           406: 
        !           407:        }
        !           408: 
        !           409: }
        !           410: 
        !           411: 
        !           412: 
        !           413: /*
        !           414: 
        !           415:  * nap(n): nap for n milliseconds. Used in loops where we're waiting for
        !           416: 
        !           417:  * an event. If we expect the event *very* soon, we should use yield
        !           418: 
        !           419:  * instead.
        !           420: 
        !           421:  * NOTE: we may not sleep for exactly n milliseconds; signals can wake
        !           422: 
        !           423:  * us earlier, and the vagaries of process scheduling may cause us to
        !           424: 
        !           425:  * oversleep...
        !           426: 
        !           427:  */
        !           428: 
        !           429: 
        !           430: 
        !           431: static void
        !           432: 
        !           433: unnapme(p)
        !           434: 
        !           435:        PROC *p;
        !           436: 
        !           437: {
        !           438: 
        !           439:        if (p->wait_q == SELECT_Q && p->wait_cond == (long)&nap) {
        !           440: 
        !           441:                rm_q(SELECT_Q, p);
        !           442: 
        !           443:                add_q(READY_Q, p);
        !           444: 
        !           445:                p->wait_cond = 0;
        !           446: 
        !           447:        }
        !           448: 
        !           449: }
        !           450: 
        !           451: 
        !           452: 
        !           453: void
        !           454: 
        !           455: nap(n)
        !           456: 
        !           457:        unsigned n;
        !           458: 
        !           459: {
        !           460: 
        !           461:        TIMEOUT *t;
        !           462: 
        !           463: 
        !           464: 
        !           465:        t = addtimeout((long)n, unnapme);
        !           466: 
        !           467:        sleep(SELECT_Q, (long)&nap);
        !           468: 
        !           469:        canceltimeout(t);
        !           470: 
        !           471: }
        !           472: 

unix.superglobalmegacorp.com

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