|
|
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.