view Fifo/TaskManager.cbc @ 5:91a07e20e06d

commit.
author kent <kent@cr.ie.u-ryukyu.ac.jp>
date Fri, 25 Dec 2009 17:53:11 +0900
parents
children 299cc57f332b
line wrap: on
line source

#include "TaskManager.h"
#include "Task.h"
#include "Debug.h"

/* defined in TaskManagerAbst.  */
extern Task *createTask(int, char *);
extern void taskSetData(Task*, void*, int, void*, int);
extern void taskSpawn(TaskManager*, Task*);

/* declarations of code segment.  */
int main (int argc, char **argv);
__code startTaskManager ();
__code searchStartTask (TaskManager *manager);
__code searchStartTask_1 (TaskManager *manager, int i);
__code startTask (TaskManager *manager, int i);
__code executeTask (TaskManager *manager, ListIter *iter, Task *task);
__code checkEvent (TaskManager *manager);
__code checkEvent_real (TaskManager *manager);
__code selectCode (TaskManager *tsched);
__code schedEntry (TaskManager *tsched, Taskrun nextcode, void *rbuff, void *wbuff);

/* external code segments.  */
extern __code executed (TaskManager *manager, ListIter *iter, Task *task);
extern __code finishTask (TaskManager *manager, Task *task);
extern __code noEvent (TaskManager *manager);


/* for Debug.  */
void printTasks(TaskManager *manager);


/* Global variable for user task.  */
__code (*scheduler)(TaskManager*, Taskrun, void*, void*);




int
main(int argc, char **argv)
{
	goto startTaskManager();
}

/*
 *   Initialization
 */
__code
startTaskManager()
{
	TaskManager *manager;
	manager = malloc(sizeof(TaskManager));
	manager->waitingList = NULL;
	manager->schedTasks = NULL;
	manager->exitTasks = NULL;
	manager->running = NULL;
	scheduler = schedEntry;
	goto searchStartTask(manager);
}
/*
 *  Start first task
 */
__code
searchStartTask(TaskManager *manager)
{
	int i=0;
	goto searchStartTask_1(manager, i);
}
__code
searchStartTask_1(TaskManager *manager, int i)
{
	if (tasktypes[i].flag & F_STARTER ) {
		goto startTask(manager, i);
	} else {
		goto searchStartTask_1(manager, i+1);
	}
}
__code
startTask(TaskManager *manager, int i)
{
	Task *task;
	task = createTask(i, "start task");
	taskSetData(task, NULL, 0, NULL, 0);
	taskSpawn(manager, task);

	goto checkEvent_real(manager);
}


__code
executeTask(TaskManager *manager, ListIter *iter, Task *task)
{
	SchedTask *stask;
	stask = malloc(sizeof(SchedTask));
	stask->task = task;
	stask->nextcode = tasktypes[task->typeid].code;
	stask->rbuff = task->rbuff;
	stask->wbuff = task->wbuff;

	manager->schedTasks = _listAddFirst(manager->schedTasks, stask);
	goto executed(manager, iter, task);
}

__code
checkEvent(TaskManager *manager)
{
	goto selectCode(manager);
	// to selectCode, run tasks, and return to checkEvent_real.
}
__code
checkEvent_real(TaskManager *manager)
{
	SchedTask *stask;
	Task *task;
	printTasks(manager);
	if (manager->exitTasks) {
		stask = _listGetnthData(manager->exitTasks, 0);
		manager->exitTasks = _listRemove(manager->exitTasks, stask);
		task = stask->task;
		free(stask);
		__DEBUG("task[%p] finished.\n", task->rbuff);
		goto finishTask(manager, task);
	/*} else if (manager->newtasks) { */
	} else {
		goto noEvent(manager);
	}
}



/*
 *  Scheduler
 */
__code
selectCode(TaskManager *tsched)
{
	SchedTask *task;
	if (tsched->schedTasks) {
		task = (SchedTask*)_listGetLastData(tsched->schedTasks);
		tsched->running = task;

		/* goto user-defined task.  */
		goto task->nextcode(tsched, task->task->rbuff, task->task->wbuff);
	} else {
		/* no task we have.  */
		//goto checkNewCode();
		goto checkEvent_real(tsched);
	}
}

__code
schedEntry(TaskManager *tsched, Taskrun nextcode, void *rbuff, void *wbuff)
{
	/* schedulerd  */
	if ( nextcode==NULL ) {
		/* the task finished.  */
		tsched->schedTasks =
			_listRemove(tsched->schedTasks, tsched->running);
		tsched->exitTasks =
			_listAddFirst(tsched->exitTasks, tsched->running);
		goto selectCode(tsched);
	} else {
		/* save the next code segment for the task.  */
		tsched->running->nextcode = nextcode;
		tsched->running->rbuff = rbuff;
		tsched->running->wbuff = wbuff;
		/* move last task to first to be fair.  */
		tsched->schedTasks = _listMoveLasttoFirst(tsched->schedTasks);
		goto selectCode(tsched);
	}
}



/*
 *  for Debug.
 */
void
printTasks(TaskManager *manager)
{
	Task *task;
	SchedTask *stask;
	ListIter *iter;
	__DEBUG("waiting:\n\t");
	iter = _listIterator(manager->waitingList);
	while ( (task=_listIterNext(iter))!=NULL ) {
		__DEBUGnoF("%d, ", task->id);
	}
	__DEBUGnoF("\n");
	_listIterEnd(iter);

	__DEBUG("scheduled:\n\t");
	iter = _listIterator(manager->schedTasks);
	while ( (stask=_listIterNext(iter))!=NULL ) {
		__DEBUGnoF("%d, ", stask->task->id);
	}
	__DEBUGnoF("\n");
	_listIterEnd(iter);

	__DEBUG("exit:\n\t");
	iter = _listIterator(manager->exitTasks);
	while ( (stask=_listIterNext(iter))!=NULL ) {
		__DEBUGnoF("%d, ", stask->task->id);
	}
	__DEBUGnoF("\n");
	_listIterEnd(iter);
}