|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.