view TaskScheduler.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 "Task.h"
#include <stdint.h>
#include <stdlib.h>
#include "TaskScheduler.h"
#include "List.h"

enum wait{
	NOWAIT=0,
	WAIT=1,
};
extern __code checkNewCode(TaskScheduler *, enum wait);

__code (*scheduler)(void*,Taskrun,void*,void*);

typedef List SchedTaskList;
#define addSchedTask(a,b) (SchedTaskList*)_listAddFirst((List*)(a),(void*)(b))
#define removeTask(a,b) (SchedTaskList*)_listRemove((List*)(a),(void*)(b))
// inline functionのがいいか

__code schedEntry(TaskScheduler *tsched, Taskrun nextcode, void *rbuff, void *wbuff);

//static TaskScheduler *tsched;

extern void *allocate(size_t);
__code
initScheduler(__code (*ret)(TaskScheduler*,void*), void *arg)
{
	TaskScheduler *tsched;
	tsched = allocate(sizeof(TaskScheduler));
	tsched->runnable = NULL;
	tsched->running = NULL;
	//tsched->schedule = SchedEntry;
	scheduler = schedEntry;
	goto ret(tsched, arg);
}

__code
addCode(TaskScheduler *tsched, ID id, Taskrun code0, void *rbuff, void *wbuff)
{
	SchedTask *newst;
	newst = allocate(sizeof(SchedTask)); //これはAbstractLayerで生成してもいいのだが…
	newst->nextcode = code0;
	newst->rbuff = rbuff; //taskの遷移で引数が変化しないならいならい
	newst->wbuff = wbuff;

	/* regist new task to runnable list.  */
	tsched->runnable = addSchedTask(tsched->runnable, newst);

	goto selectCode(tsched);
}

__code
selectCode(TaskScheduler *tsched)
{
	SchedTask *task;
	if (tsched->runnable) {
		task = (SchedTask*)_listGetLastData(tsched->runnable);
		tsched->running = task;

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

__code
schedEntry(TaskScheduler *tsched, Taskrun nextcode, void *rbuff, void *wbuff)
{
	/* schedulerd  */
	if ( nextcode==NULL ) {
		/* the task finished.  */
		ID id = tsched->running->id;
		tsched->runnable =
			removeTask(tsched->runnable, tsched->running);
		free(tsched->running);
		tsched->running = NULL;
		goto exitCode(tsched, id);
	} 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->runnable = _listMoveLasttoFirst(tsched->runnable);
		goto checkNewCode(tsched, NOWAIT);
	}
}