view src/TaskManagerAbst.cbc @ 18:d31f9a0f9024

change interfaces of List.c.
author kent <kent@cr.ie.u-ryukyu.ac.jp>
date Wed, 13 Jan 2010 17:26:58 +0900
parents 5f65da34f4f3
children
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*);
extern __code exitTaskManager(TaskManager*);

typedef List TaskList;

/* 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 searchStartTask(TaskManager *manager);
__code searchStartTask_1(TaskManager *manager, int i);
__code startTask(TaskManager *manager, int i);

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

/*
 *  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);
	task->cpu = MAIN;
	listAddFirst(manager->waitingList, task);

	goto checkEvent(manager);
}


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

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

__code
noEvent(TaskManager *manager)
{
	ListIter *iter;
	if (listEmpty(manager->waitingList) && listEmpty(manager->activeList))
		goto exitTaskManager(manager);
	iter = createIterator(manager->waitingList);
	goto getTask(manager, iter);
}

__code
getTask(TaskManager *manager, ListIter *iter)
{
	Task *task;
	if (!listIterhasNext(iter)) {
		/* iteration finished.  */
		goto start(manager);
	}

	task = (Task*)listIterNext(iter);
	if (listEmpty(task->waitee)) {
		/* the task is ready!  */
		goto executeTask(manager, iter, task);
	} else {
		/* the task has been waiting yet.  */
		goto getTask(manager, iter);
	}
}

__code
executed(TaskManager *manager, ListIter *iter, Task *task)
{
	listIterRemove(iter);
	listAddFirst(manager->activeList, task);
	goto getTask(manager, iter);
}
/*
__code cannotExecute(TaskManager *manager, Task *task) { }
*/


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

	listRemove(manager->activeList, task);
	iter = createIterator(task->waiter);
	goto finishTask_iter(manager, task, iter);
}

__code
finishTask_iter(TaskManager *manager, Task *task, ListIter *iter)
{
	Task *waiter;
	if (listIterhasNext(iter)) {
		waiter = listIterNext(iter);
		listRemove(waiter->waitee, task);
		listIterRemove(iter);
		goto finishTask_iter(manager, task, iter);
	} else {
		destroyIterator(iter);
		goto finishTask_end(manager, task);
	}
}

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



/*
 * belows is Interfaces for Users.
 * it should be code segment.  but how?
 * Now, these interfaces can be used only PPE local.
 */

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 = createList();
	task->waitee = createList();
	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.  */
	listAddFirst(task_a->waitee, task_b);
	listAddFirst(task_b->waiter, task_a);
}