Annotation of researchv9/cmd/cfront/libC/task/sched.c, revision 1.1.1.1

1.1       root        1: #include "task.h"
                      2: 
                      3: void setclock(long t)
                      4: {
                      5:        if (clock) task_error(E_SETCLOCK,0);
                      6:        clock = t;
                      7: }
                      8: 
                      9: int in_error = 0;
                     10: 
                     11: int task_error(int n, object* oo)
                     12: {
                     13:        if (in_error)
                     14:                exit(in_error);
                     15:        else
                     16:                in_error = n;
                     17: 
                     18:        if (error_fct) {
                     19:                n = (*error_fct)(n,oo);
                     20:                if (n) exit(n);
                     21:        }
                     22:        else {
                     23:                print_error(n);
                     24:                exit(n);
                     25:        }
                     26:        in_error = 0;
                     27:        return 0;
                     28: }
                     29: 
                     30: char* error_name[] = {
                     31:        "",
                     32:        "object.delete(): has chain",
                     33:        "object.delete(): on chain",
                     34:        "qhead.get(): empty",
                     35:        "qhead.putback(): object on other queue",
                     36:        "qhead.putback(): full",
                     37:        "qtail.put(): object on other queue",
                     38:        "qtail.put(): full",
                     39:        "set_clock(): clock!=0",
                     40:        "schedule(): clock_task not idle",
                     41:        "schedule: terminated", 
                     42:        "schedule: running",
                     43:        "schedule: clock<0",
                     44:        "schedule: task or timer on other queue",
                     45:        "histogram.new(): bad arguments",
                     46:        "task.save(): stack overflow",
                     47:        "new: free store exhausted",
                     48:        "task.new(): bad mode",
                     49:        "task.delete(): not terminated",
                     50:        "task.preempt(): not running",
                     51:        "timer.delete(): not terminated",
                     52:        "schedule: bad time",
                     53:        "schedule: bad object",
                     54:        "queue.delete(): not empty",
                     55:        "thistask->result()",
                     56:        "task.wait(thistask)",
                     57: };
                     58: 
                     59: void print_error(int n)
                     60: {
                     61: 
                     62:        register i = (n<1 || MAXERR<n) ? 0 : n;
                     63: 
                     64:        printf("\n\n***** task_error(%d) %s\n",n,error_name[i]);
                     65: 
                     66:        if (thistask) { 
                     67:                printf("thistask: ");
                     68:                thistask->print(VERBOSE|STACK);
                     69:        }
                     70:        if (run_chain) {
                     71:                printf("run_chain:\n");
                     72:                run_chain->print(CHAIN);
                     73:        }
                     74: } /* task_error */
                     75: 
                     76: sched* run_chain = 0;
                     77: task* task_chain = 0;
                     78: long clock = 0;
                     79: task* thistask = 0;
                     80: task* clock_task = 0;
                     81: PFIO error_fct = 0;
                     82: /*PFIO sched_fct = 0;*/
                     83: PFV exit_fct = 0;
                     84: 
                     85: void sched.cancel(int res)
                     86: {
                     87:        if (s_state==RUNNING) remove();
                     88:        s_state = TERMINATED;
                     89:        s_time = res;
                     90:        alert();
                     91: }
                     92: 
                     93: int sched.result()
                     94: /* wait for termination and retrieve result */
                     95: {
                     96:        if (this == (sched*)thistask) task_error(E_RESULT,0);
                     97:        while (s_state != TERMINATED) {
                     98:                remember(thistask);
                     99:                thistask->sleep();
                    100:                forget(thistask);
                    101:        }
                    102: 
                    103:        return (int) s_time;
                    104: }
                    105: 
                    106: void sched.schedule()
                    107: /* schedule either clock_task or front of run_chain */
                    108: {
                    109:        register sched* p;
                    110:        register long tt;
                    111: 
                    112: lll:
                    113:        if (p = run_chain) {
                    114:                run_chain = (sched*) p->o_next;
                    115:                p->o_next = 0;
                    116:        }
                    117:        else {
                    118:                if (exit_fct) (*exit_fct)();
                    119:                exit(0);
                    120:        }
                    121: 
                    122:        tt = p->s_time;
                    123:        if (tt != clock) {
                    124:                if (tt < clock) task_error(E_SCHTIME,this);
                    125:                clock = tt;
                    126:                if (clock_task) {
                    127:                        if (clock_task->s_state != IDLE)
                    128:                                task_error(E_CLOCKIDLE,this);
                    129:                        /* clock_task preferred */
                    130:                        p->o_next = (object*) run_chain;
                    131:                        run_chain = p;
                    132:                        p = (sched*) clock_task;
                    133:                }
                    134:        }
                    135: 
                    136:        switch (p->o_type) {
                    137:        case TIMER: /* time is up; "delete" timer & schedule next task */
                    138:                p->s_state = TERMINATED;
                    139:                p->alert();
                    140:                goto lll;
                    141:        case TASK:
                    142:                if (p != this) {
                    143:                        if (thistask && thistask->s_state != TERMINATED)
                    144:                                thistask->save();
                    145:                        thistask = (task*) p;
                    146:                        thistask->restore();
                    147:                }
                    148:                break;
                    149:        default:
                    150:                task_error(E_SCHOBJ,this);
                    151:        }
                    152: } /* schedule */
                    153: 
                    154: void sched.insert(int d, object* who)
                    155: /*
                    156:        schedule THIS to run in ``d'' time units
                    157:        inserted by who
                    158: */
                    159: {
                    160:        register sched * p;
                    161:        register sched * pp;
                    162:        register long tt = s_time = clock + d;
                    163: 
                    164:        switch (s_state) {
                    165:        case TERMINATED:
                    166:                task_error(E_RESTERM,this);
                    167:                break;
                    168:        case IDLE:
                    169:                break;
                    170:        case RUNNING:
                    171:                if (this != (class sched *)thistask) task_error(E_RESRUN,this);
                    172:        }
                    173: 
                    174:        if (d<0) task_error(E_NEGTIME,this);    
                    175: 
                    176:        if (o_next) task_error(E_RESOBJ,this);
                    177: 
                    178:        s_state = RUNNING;
                    179:        if (o_type == TASK) ((task *) this)->t_alert = who;
                    180: 
                    181:        /* run_chain ordered by s_time */
                    182:        if (p = run_chain) {
                    183:                if (tt < p->s_time) {
                    184:                        o_next = (object*) run_chain;
                    185:                        run_chain = this;
                    186:                }
                    187:                else {
                    188:                        while (pp = (sched *) p->o_next) {
                    189:                                if (tt < pp->s_time) {
                    190:                                        o_next = pp;
                    191:                                        p->o_next = this;
                    192:                                        return;
                    193:                                }
                    194:                                else p = pp;
                    195:                        }
                    196:                        p->o_next = this;
                    197:                }
                    198:        }
                    199:        else 
                    200:                run_chain = this;
                    201: }
                    202: 
                    203: void sched.remove()
                    204: /* remove from run_chain and make IDLE */
                    205: {
                    206:        register class sched * p;
                    207:        register class sched * pp;
                    208: 
                    209:        if (p = run_chain)
                    210:                if (p == this)
                    211:                        run_chain = (sched*) o_next;
                    212:                else
                    213:                        for (; pp = (sched*) p->o_next; p=pp)
                    214:                                if (pp == this) {
                    215:                                        p->o_next = pp->o_next;
                    216:                                        goto ll;
                    217:                                }
                    218: ll:
                    219:        s_state = IDLE;
                    220:        o_next = 0;
                    221: }
                    222: 
                    223: void sched.print(int n)
                    224: {
                    225:        int m = n & ~CHAIN;
                    226: 
                    227:        switch (o_type) {
                    228:        case TIMER:
                    229:                ((timer*)this)->print(m);
                    230:                break;
                    231:        case TASK:
                    232:                ((task*)this)->print(m);
                    233:                break;
                    234:        }
                    235: 
                    236:        if (n&CHAIN) {
                    237:                if (o_next) ((sched*) o_next)->print(n);
                    238:        }
                    239: }

unix.superglobalmegacorp.com

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