Annotation of researchv10no/cmd/cfront/libC/task/sched.c, revision 1.1.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.