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