view TaskManager.cbc @ 2:803d6bf22e6d default tip

second commit. it's far to complete..
author kent <kent@cr.ie.u-ryukyu.ac.jp>
date Tue, 22 Dec 2009 16:19:56 +0900
parents aef83aed7a07
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*);

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)
 *   		}
 *   	}
 *   }
 *
 *   CPUがfullでないかをTaskManager側でケアするならこっちに変更かな
 *   while (1) {
 *   	while switch checkAction() {
 *   	newTask:
 *   		add task to waiting or ready.
 *   	finishTask:
 *   		remove task from running.
 *   	}
 *   	if (cpu ready) {
 *   		foreach task in readylist {
 *   			executeTask(task)
 *  			move task to running from ready.
 *   		}
 *   	}
 *   	foreach task in waitinglist {
 *   		if (!task_has_waitee) {
 *   			if (CPU ready) {
 *   				executeTask(task)
 *   				move task to running from waiting.
 *   			} else {
 *   				move task to running from ready.
 *   			}
 *   		}
 *   	}
 *   }
 */

/* statics  */
__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)
{
	/* receive a Task which has already been created in AbstractLayer.  */
	/* but It must be freed in TaskManager.  */
	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 may be moved to AbstractLayer.  */

Task *newTask(int typeid)
{
	Task *task;
	static int id=0;
	task = malloc(sizeof(Task));

	//task->tasktype = tasktypes[typeid];
	task->id = id;
	task->waiter = NULL;
	task->waitee = NULL;

	return task;
}

void setData(Task *task, void *rbuff, size_t rs, void *wbuff, size_t ws)
{
	task->rbuff = rbuff;
	task->wbuff = wbuff;
	task->rsize = rs;
	task->wsize = ws;
}