|
|
1.1 ! root 1: #include <osfcn.h> ! 2: #include "task.h" ! 3: ! 4: void ! 5: sched::setclock(long t) ! 6: { ! 7: if (clxck) task_error(E_SETCLOCK); ! 8: clxck = t; ! 9: } ! 10: ! 11: void ! 12: sched::cancel(int res) ! 13: { ! 14: if (s_state==RUNNING) remove(); ! 15: s_state = TERMINATED; ! 16: s_time = res; ! 17: alert(); ! 18: } ! 19: ! 20: int ! 21: sched::result() ! 22: /* wait for termination and retrieve result */ ! 23: { ! 24: if (this == (sched*)this_task()) ((object*)0)->task_error(E_RESULT); ! 25: while (s_state != TERMINATED) { ! 26: this_task()->sleep(this); ! 27: } ! 28: ! 29: return (int) s_time; ! 30: } ! 31: ! 32: void ! 33: sched::schedule() ! 34: /* schedule either clock_task or front of runchain. ! 35: This routine causes a coroutine switch by calling resume. ! 36: When control eventually returns to this coroutine, it does so ! 37: through task::restore and swap(). ! 38: For the 68000 implementation, the exit sequence of this function must ! 39: match that of task::task() and swap(), so check and be sure they ! 40: do. Copy the exit sequence into swap if necesssary. ! 41: */ ! 42: { ! 43: int a_dummy; ! 44: register sched* p; ! 45: register long tt; ! 46: register int* p1_dummy; ! 47: register int* p2_dummy; ! 48: // we must trick the compiler into thinking we really use all these registers ! 49: register int y, z, u, v, w; ! 50: w = 0; v = w; u = v; z = u; y = z; a_dummy = y; ! 51: p1_dummy = p2_dummy = 0; ! 52: ! 53: keep_waiting: ! 54: if (p = priority_sched) { ! 55: priority_sched = 0; // no chain here ! 56: p->remove(); // in case it's also on the runchain ! 57: p->s_state = RUNNING; // since remove sets it IDLE ! 58: } ! 59: else if (p = runchain) { ! 60: runchain = (sched*) p->o_next; ! 61: p->o_next = 0; ! 62: } ! 63: else { ! 64: if (keep_waiting_count) { ! 65: ::wait(0); ! 66: goto keep_waiting; ! 67: } ! 68: if (exit_fct) (*exit_fct)(); ! 69: for (p = task::txsk_chxin; p; p = ((task*)p)->t_next) { ! 70: if (p->s_state == RUNNING) p->remove(); ! 71: p->s_state = TERMINATED; ! 72: p->s_time = 0; ! 73: } ! 74: exit(0); ! 75: } ! 76: ! 77: tt = p->s_time; ! 78: if (tt != clxck) { ! 79: if (tt < clxck) task_error(E_SCHTIME); ! 80: clxck = tt; ! 81: if (clock_task) { ! 82: if (clock_task->s_state != IDLE) ! 83: task_error(E_CLOCKIDLE); ! 84: /* clock_task preferred -- put p back onto runchain */ ! 85: p->o_next = (object*) runchain; ! 86: runchain = p; ! 87: p = (sched*) clock_task; ! 88: } ! 89: } ! 90: ! 91: if (p != this) ! 92: p->resume(); ! 93: } /* schedule */ ! 94: ! 95: void ! 96: sched::insert(int d, object* who) ! 97: /* ! 98: schedule THIS to run in ``d'' time units ! 99: inserted by who ! 100: */ ! 101: { ! 102: register sched * p; ! 103: register sched * pp; ! 104: register long tt = s_time = clxck + d; ! 105: ! 106: switch (s_state) { ! 107: case TERMINATED: ! 108: task_error(E_RESTERM); ! 109: break; ! 110: case IDLE: ! 111: break; ! 112: case RUNNING: ! 113: if (this != (class sched *)this_task()) task_error(E_RESRUN); ! 114: } ! 115: ! 116: if (d<0) task_error(E_NEGTIME); ! 117: ! 118: if (o_next) task_error(E_RESOBJ); ! 119: ! 120: s_state = RUNNING; ! 121: setwho(who); ! 122: ! 123: /* runchain ordered by s_time */ ! 124: if (p = runchain) { ! 125: if (tt < p->s_time) { ! 126: o_next = (object*) runchain; ! 127: runchain = this; ! 128: } ! 129: else { ! 130: while (pp = (sched *) p->o_next) { ! 131: if (tt < pp->s_time) { ! 132: o_next = pp; ! 133: p->o_next = this; ! 134: return; ! 135: } ! 136: else p = pp; ! 137: } ! 138: p->o_next = this; ! 139: } ! 140: } ! 141: else ! 142: runchain = this; ! 143: } ! 144: ! 145: void ! 146: sched::remove() ! 147: /* remove from runchain and make IDLE */ ! 148: { ! 149: register class sched * p; ! 150: register class sched * pp; ! 151: ! 152: if (p = runchain) ! 153: if (p == this) ! 154: runchain = (sched*) o_next; ! 155: else ! 156: for (; pp = (sched*) p->o_next; p=pp) ! 157: if (pp == this) { ! 158: p->o_next = pp->o_next; ! 159: break; ! 160: } ! 161: s_state = IDLE; ! 162: o_next = 0; ! 163: } ! 164: ! 165: ! 166: void ! 167: sched::print(int n, int baseClass) ! 168: { ! 169: if (!baseClass) ! 170: printf("naked sched "); ! 171: if (n&CHAIN) { ! 172: if (o_next) ((sched*) o_next)->print(n); ! 173: } ! 174: ! 175: object::print(n, 1); ! 176: if (!baseClass) ! 177: task_error(E_SCHOBJ); // only derived class instances allowed ! 178: } ! 179: ! 180: int ! 181: sched::pending() ! 182: { ! 183: return s_state != TERMINATED; ! 184: } ! 185: ! 186: void ! 187: sched::resume() // this should never be called ! 188: { ! 189: task_error(E_SCHOBJ); ! 190: } ! 191: ! 192: void ! 193: sched::setwho(object*) // this should never be called ! 194: { ! 195: task_error(E_SCHOBJ); ! 196: } ! 197:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.