Annotation of researchv10no/cmd/cfront/libC/task/sched.c, revision 1.1

1.1     ! root        1: /*ident        "%W%" */
        !             2: /**************************************************************************
        !             3:                        Copyright (c) 1984 AT&T
        !             4:                          All Rights Reserved   
        !             5: 
        !             6:        THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T
        !             7:        
        !             8:        The copyright notice above does not evidence any        
        !             9:        actual or intended publication of such source code.
        !            10: 
        !            11: *****************************************************************************/
        !            12: #include <osfcn.h>
        !            13: #include <task.h>
        !            14: 
        !            15: void
        !            16: sched::setclock(long t)
        !            17: {
        !            18:        if (clxck) object::task_error(E_SETCLOCK, (object*)0);
        !            19:        clxck = t;
        !            20: }
        !            21: 
        !            22: void
        !            23: sched::cancel(int res)
        !            24: {
        !            25:        if (s_state==RUNNING) remove();
        !            26:        s_state = TERMINATED;
        !            27:        s_time = res;
        !            28:        alert();
        !            29: }
        !            30: 
        !            31: int
        !            32: sched::result()
        !            33: /* wait for termination and retrieve result */
        !            34: {
        !            35:        if (this == (sched*)this_task()) task_error(E_RESULT, this);
        !            36:        while (s_state != TERMINATED) {
        !            37:                this_task()->sleep(this);
        !            38:        }
        !            39: 
        !            40:        return (int) s_time;
        !            41: }
        !            42: 
        !            43: void
        !            44: sched::schedule()
        !            45: /* schedule either clock_task or front of runchain */
        !            46: {
        !            47:        register sched* p;
        !            48:        register long tt;
        !            49: 
        !            50: keep_waiting:
        !            51:        if (p = priority_sched) {
        !            52:                priority_sched = 0;  // no chain here
        !            53:                p->remove();  // in case it's also on the runchain
        !            54:                p->s_state = RUNNING;  // since remove sets it IDLE
        !            55:        }
        !            56:        else if (p = runchain) {
        !            57:                runchain = (sched*) p->o_next;
        !            58:                p->o_next = 0;
        !            59:        }
        !            60:        else {
        !            61:                if (keep_waiting_count) {
        !            62:                        ::wait(0);
        !            63:                        goto keep_waiting;
        !            64:                }
        !            65:                if (exit_fct) (*exit_fct)();
        !            66:                for (p = task::txsk_chxin; p; p = ((task*)p)->t_next) {
        !            67:                        if (p->s_state == RUNNING) p->remove();
        !            68:                        p->s_state = TERMINATED;
        !            69:                        p->s_time = 0;
        !            70:                }
        !            71:                exit(exit_status);
        !            72:        }
        !            73: 
        !            74:        tt = p->s_time;
        !            75:        if (tt != clxck) {
        !            76:                if (tt < clxck) task_error(E_SCHTIME, this);
        !            77:                clxck = tt;
        !            78:                if (clock_task) {
        !            79:                        if (clock_task->s_state != IDLE)
        !            80:                                task_error(E_CLOCKIDLE, this);
        !            81:                        /* clock_task preferred -- put p back onto runchain */
        !            82:                        p->o_next = (object*) runchain;
        !            83:                        runchain = p;
        !            84:                        p = (sched*) clock_task;
        !            85:                }
        !            86:        }
        !            87:        if (p != this)
        !            88:                p->resume();
        !            89: } /* schedule */
        !            90: 
        !            91: void
        !            92: sched::insert(int d, object* who)
        !            93: /*
        !            94:        schedule THIS to run in ``d'' time units
        !            95:        inserted by who
        !            96: */
        !            97: {
        !            98:        register sched * p;
        !            99:        register sched * pp;
        !           100:        register long tt = s_time = clxck + d;
        !           101: 
        !           102:        switch (s_state) {
        !           103:        case TERMINATED:
        !           104:                task_error(E_RESTERM, this);
        !           105:                break;
        !           106:        case IDLE:
        !           107:                break;
        !           108:        case RUNNING:
        !           109:                if (this != (class sched *)this_task()) task_error(E_RESRUN, this);
        !           110:        }
        !           111: 
        !           112:        if (d<0) task_error(E_NEGTIME, this);   
        !           113: 
        !           114:        if (o_next) task_error(E_RESOBJ, this);
        !           115: 
        !           116:        s_state = RUNNING;
        !           117:        setwho(who);
        !           118: 
        !           119:        /* runchain ordered by s_time */
        !           120:        if (p = runchain) {
        !           121:                if (tt < p->s_time) {
        !           122:                        o_next = (object*) runchain;
        !           123:                        runchain = this;
        !           124:                }
        !           125:                else {
        !           126:                        while (pp = (sched *) p->o_next) {
        !           127:                                if (tt < pp->s_time) {
        !           128:                                        o_next = pp;
        !           129:                                        p->o_next = this;
        !           130:                                        return;
        !           131:                                }
        !           132:                                else p = pp;
        !           133:                        }
        !           134:                        p->o_next = this;
        !           135:                }
        !           136:        }
        !           137:        else 
        !           138:                runchain = this;
        !           139: }
        !           140: 
        !           141: void
        !           142: sched::remove()
        !           143: /* remove from runchain and make IDLE */
        !           144: {
        !           145:        register class sched * p;
        !           146:        register class sched * pp;
        !           147: 
        !           148:        if (p = runchain)
        !           149:                if (p == this)
        !           150:                        runchain = (sched*) o_next;
        !           151:                else
        !           152:                        for (; pp = (sched*) p->o_next; p=pp)
        !           153:                                if (pp == this) {
        !           154:                                        p->o_next = pp->o_next;
        !           155:                                        break;
        !           156:                                }
        !           157:        s_state = IDLE;
        !           158:        o_next = 0;
        !           159: }
        !           160: 
        !           161: void
        !           162: sched::print(int n, int baseClass)
        !           163: {
        !           164:        if (!baseClass)
        !           165:                printf("naked sched (object not part of class derived from sched)");
        !           166:        if (n&VERBOSE) {
        !           167:                printf("\tsched:  this=%x\n", this);
        !           168:        }
        !           169:        if (n&CHAIN) {
        !           170:                object::print(n, 1);    // call object::print here to keep
        !           171:                                        // output for same object together
        !           172:                // If this is a task, all task objects are already being
        !           173:                // printed under CHAIN.  Therefore, don't call print
        !           174:                // recursively for tasks.  If current task is thistask,
        !           175:                // print entire run_chain with 0 arg, to keep it short.
        !           176:                if (o_type() == TASK) {
        !           177:                        if (this == thxstxsk) {
        !           178:                                sched *sp = get_run_chain();
        !           179:                                if (sp == 0) {
        !           180:                                        printf("run chain is empty\n");
        !           181:                                } else {
        !           182:                                        printf("run chain is:\n");
        !           183:                                        for (; sp; sp = (sched*)sp->o_next) {
        !           184:                                                sp->print(0);
        !           185:                                        }
        !           186:                                        printf("end of run chain.\n");
        !           187:                                }
        !           188:                        }
        !           189:                } else if (o_next)  {
        !           190:                        printf("Next sched object on run chain is:\n");
        !           191:                        ((sched*) o_next)->print(n);
        !           192:                } 
        !           193:        } else {
        !           194:                object::print(n, 1);
        !           195:        }
        !           196: 
        !           197:        if (!baseClass)
        !           198:                task_error(E_SCHOBJ, this);  // only derived class instances allowed
        !           199: 
        !           200: }
        !           201: 
        !           202: /* sched::resume() is a virtual function.  Because sched is not intended
        !           203:  * to be used directly, but only as a base class, this should never be called.
        !           204:  * Must define resume for each class derived from sched.
        !           205:  */
        !           206: void
        !           207: sched::resume()
        !           208: {
        !           209:        task_error(E_SCHOBJ, this);
        !           210: }
        !           211: 
        !           212: /* sched::setwho() is a virtual function.  Because sched is not intended
        !           213:  * to be used directly, but only as a base class, this should never be called.
        !           214:  * Must define setwho for each class derived from sched.
        !           215:  */
        !           216: void
        !           217: sched::setwho(object*)
        !           218: {
        !           219:        task_error(E_SCHOBJ, this);
        !           220: }

unix.superglobalmegacorp.com

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