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