view TaskManagerAbst.cbc @ 6:51c3a631a7bc

add taskinit.
author kent <kent@cr.ie.u-ryukyu.ac.jp>
date Fri, 25 Dec 2009 17:55:24 +0900
parents 91a07e20e06d
children 299cc57f332b
line wrap: on
line source

#include <assert.h>
#include "TaskManager.h"
#include "Task.h"
#include "List.h"
// TODO: malloc

extern __code checkEvent(TaskManager *);
extern __code executeTask(TaskManager*, ListIter*, Task*);

typedef List TaskList;

/*
 * TaskManager's main loop.
 *
 *   while (1) {
 *   	while switch checkEvent() {
 *   	newTask:
 *   		add task to waiting.
 *   	finishTask:
 *   		remove task from active.
 *   	}
 *   	foreach task in waitinglist {
 *   		if (!task_has_waitee) {
 *   			move task to active from waiting.
 *   			executeTask(task)
 *   		}
 *   	}
 *   }
 */

/* declarations  */
__code initTaskManager (__code(*ret)(TaskManager*,void*), void *arg);
__code start (TaskManager *manager);
__code addNewTask (TaskManager *manager, Task *task);
__code finishTask (TaskManager *manager, Task *task);
__code noEvent (TaskManager *manager);
__code getTask (TaskManager *manager, ListIter *iter);
__code executed (TaskManager *manager, ListIter *iter, Task *task);
__code cannotExecute (TaskManager *manager, Task *task);
__code finishTask_1 (TaskManager *manager, Task *task);
__code finishTask_iter (TaskManager *manager, Task *task, ListIter *iter);
__code finishTask_end (TaskManager *manager, Task *task);
void setData (Task *task, void *rbuff, size_t rs, void *wbuff, size_t ws);

__code
initTaskManager(__code(*ret)(TaskManager*,void*), void *arg)
{
	TaskManager *manager;
	manager = malloc(sizeof(TaskManager));
	goto ret(manager, arg);
}

__code
start(TaskManager *manager)
{
	goto checkEvent(manager);
}
__code
addNewTask(TaskManager *manager, Task *task)
{
	manager->waitingList = _listAddFirst(manager->waitingList, task);
	goto start(manager);
}

__code
finishTask(TaskManager *manager, Task *task)
{
	goto finishTask_1(manager, task);
}

__code
noEvent(TaskManager *manager)
{
	ListIter *iter;
	iter = _listIterator(manager->waitingList);
	goto getTask(manager, iter);
}

__code
getTask(TaskManager *manager, ListIter *iter)
{
	Task *task;
	task = (Task*)_listIterNext(iter);
	if (!task)
		/* iteration finished.  */
		goto start(manager);
	if (task->waitee)
		/* the task has been waiting yet.  */
		goto getTask(manager, iter);
	else
		/* the task is ready!  */
		goto executeTask(manager, iter, task);
}

__code
executed(TaskManager *manager, ListIter *iter, Task *task)
{
	manager->waitingList = _listIterRemoveCurrent(iter);
	//manager->activeList = _listAddFirst(manager->activeList, task);
	goto getTask(manager, iter);
}
/*
__code cannotExecute(TaskManager *manager, Task *task) { }
*/


__code
finishTask_1(TaskManager *manager, Task *task)
{
	ListIter *iter;

	//manager->activeList = _listRemove(manager->activeList, task);
	iter = _listIterator(task->waiter);
	goto finishTask_iter(manager, task, iter);
}

__code
finishTask_iter(TaskManager *manager, Task *task, ListIter *iter)
{
	Task *waiter;
	waiter = _listIterNext(iter);
	if (waiter) {
		waiter->waitee = _listRemove(waiter->waitee, task);
		task->waiter = _listIterRemoveCurrent(iter);
		goto finishTask_iter(manager, task, iter);
	} else {
		_listIterEnd(iter);
		goto finishTask_end(manager, task);
	}
}

__code
finishTask_end(TaskManager *manager, Task *task)
{
	/* TODO: free(task)  */
	assert (!task->waiter);
	assert (!task->waitee);
	free(task);
	goto start(manager);
}



/*
 * belows is Interfaces for Users.
 * it may be  to code segment.  but how?
 * And it may be moved to AbstractLayer.
 * Now, a task cannot create other tasks on remote host.
 */

Task *
createTask(int typeid, char *name)
{
	static int id=0;
	Task *task;
	if (!name) name = "(no name)";

	task = malloc(sizeof(Task));
	task->typeid = typeid;
	task->id = id++;
	task->rbuff = NULL;
	task->wbuff = NULL;
	task->waiter = NULL;
	task->waitee = NULL;
	task->name = name;
	task->cpu = ANY;
	task->rsize = 0;
	task->wsize = 0;

	return task;
}

void
taskSetData(Task *task, void *rbuff, int rsize, void *wbuff, int wsize)
{
	task->rbuff = rbuff;
	task->wbuff = wbuff;
	task->rsize = rsize;
	task->wsize = wsize;
}

void
taskSetWait(Task *task_a, Task *task_b)
{
	/* set a waiting for b.  */
	task_a->waitee = _listAddFirst(task_a->waitee, task_b);
	task_b->waiter = _listAddFirst(task_b->waiter, task_a);
}

void
taskSpawn(TaskManager *manager, Task *task)
{
	manager->waitingList = _listAddFirst(manager->waitingList, task);
	//ablayer->spawnedTasks = _listAddFirst(ablayer->spawnedTasks, task);
	return ;
}