File:  [Research Unix] / researchv10no / cmd / cfront / libC / otask / sched.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:21:35 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv10, HEAD
researchv10 Norman

#include <osfcn.h>
#include "task.h"

void
sched::setclock(long t)
{
	if (clxck) task_error(E_SETCLOCK);
	clxck = t;
}

void
sched::cancel(int res)
{
	if (s_state==RUNNING) remove();
	s_state = TERMINATED;
	s_time = res;
	alert();
}

int
sched::result()
/* wait for termination and retrieve result */
{
	if (this == (sched*)this_task()) ((object*)0)->task_error(E_RESULT);
	while (s_state != TERMINATED) {
		this_task()->sleep(this);
	}

	return (int) s_time;
}

void
sched::schedule()
/* schedule either clock_task or front of runchain.
	This routine causes a coroutine switch by calling resume.
	When control eventually returns to this coroutine, it does so
	through task::restore and swap().
	For the 68000 implementation, the exit sequence of this function must
	match that of task::task() and swap(), so check and be sure they
	do.  Copy the exit sequence into swap if necesssary.
*/
{
	int a_dummy;
	register sched* p;
	register long tt;
	register int* p1_dummy;
	register int* p2_dummy;
	// we must trick the compiler into thinking we really use all these registers
	register int	y, z, u, v, w;
	w = 0; v = w; u = v; z = u; y = z; a_dummy = y;
	p1_dummy = p2_dummy = 0;

keep_waiting:
	if (p = priority_sched) {
		priority_sched = 0;  // no chain here
		p->remove();  // in case it's also on the runchain
		p->s_state = RUNNING;  // since remove sets it IDLE
	}
	else if (p = runchain) {
		runchain = (sched*) p->o_next;
		p->o_next = 0;
	}
	else {
		if (keep_waiting_count) {
			::wait(0);
			goto keep_waiting;
		}
		if (exit_fct) (*exit_fct)();
		for (p = task::txsk_chxin; p; p = ((task*)p)->t_next) {
			if (p->s_state == RUNNING) p->remove();
			p->s_state = TERMINATED;
			p->s_time = 0;
		}
		exit(0);
	}

	tt = p->s_time;
	if (tt != clxck) {
		if (tt < clxck) task_error(E_SCHTIME);
		clxck = tt;
		if (clock_task) {
			if (clock_task->s_state != IDLE)
				task_error(E_CLOCKIDLE);
			/* clock_task preferred -- put p back onto runchain */
			p->o_next = (object*) runchain;
			runchain = p;
			p = (sched*) clock_task;
		}
	}

	if (p != this)
		p->resume();
} /* schedule */

void
sched::insert(int d, object* who)
/*
	schedule THIS to run in ``d'' time units
	inserted by who
*/
{
	register sched * p;
	register sched * pp;
	register long tt = s_time = clxck + d;

	switch (s_state) {
	case TERMINATED:
		task_error(E_RESTERM);
		break;
	case IDLE:
		break;
	case RUNNING:
		if (this != (class sched *)this_task()) task_error(E_RESRUN);
	}

	if (d<0) task_error(E_NEGTIME);	

	if (o_next) task_error(E_RESOBJ);

	s_state = RUNNING;
	setwho(who);

	/* runchain ordered by s_time */
	if (p = runchain) {
		if (tt < p->s_time) {
			o_next = (object*) runchain;
			runchain = this;
		}
		else {
			while (pp = (sched *) p->o_next) {
				if (tt < pp->s_time) {
					o_next = pp;
					p->o_next = this;
					return;
				}
				else p = pp;
			}
			p->o_next = this;
		}
	}
	else 
		runchain = this;
}

void
sched::remove()
/* remove from runchain and make IDLE */
{
	register class sched * p;
	register class sched * pp;

	if (p = runchain)
		if (p == this)
			runchain = (sched*) o_next;
		else
			for (; pp = (sched*) p->o_next; p=pp)
				if (pp == this) {
					p->o_next = pp->o_next;
					break;
				}
	s_state = IDLE;
	o_next = 0;
}


void
sched::print(int n, int baseClass)
{
	if (!baseClass)
		printf("naked sched ");
	if (n&CHAIN) {
		if (o_next) ((sched*) o_next)->print(n);
	}

	object::print(n, 1);
	if (!baseClass)
		task_error(E_SCHOBJ);  // only derived class instances allowed
}

int
sched::pending()
{
	return s_state != TERMINATED;
}

void
sched::resume()  // this should never be called
{
	task_error(E_SCHOBJ);
}

void
sched::setwho(object*)  // this should never be called
{
	task_error(E_SCHOBJ);
}


unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.