# HG changeset patch # User kent # Date 1261731191 -32400 # Node ID 91a07e20e06d6dcfa8d89bacbb28640313fdc092 # Parent 5a3e2b0622fd330234a9cbfea00b6fcb48a5fc4f commit. diff -r 5a3e2b0622fd -r 91a07e20e06d Debug.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Debug.h Fri Dec 25 17:53:11 2009 +0900 @@ -0,0 +1,20 @@ +#ifndef _DEBUG_H +#define _DEBUG_H + +#ifdef DEBUG + +#include + +#define __DEBUG(f, args...) \ + fprintf(stderr, "in %s: "f, __FUNCTION__, ## args) + +#define __DEBUGnoF(f, args...) \ + fprintf(stderr, f, ## args) + +#else + +#define __DEBUG(f, args...) + +#endif + +#endif /* !_DEBUG_H */ diff -r 5a3e2b0622fd -r 91a07e20e06d Fifo/SchedTask.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fifo/SchedTask.h Fri Dec 25 17:53:11 2009 +0900 @@ -0,0 +1,14 @@ +#ifndef _SCHEDTASK_H +#define _SCHEDTASK_H + +#include "user.h" +#include "Task.h" + +typedef struct _SchedTask { + Task *task; + Taskrun nextcode; + void *rbuff; + void *wbuff; +} SchedTask; + +#endif /* !_SCHEDTASK_H */ diff -r 5a3e2b0622fd -r 91a07e20e06d Fifo/Scheduler.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fifo/Scheduler.cbc Fri Dec 25 17:53:11 2009 +0900 @@ -0,0 +1,88 @@ +//#include "Task.h" +#include +#include +#include "TaskManager.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); + +extern void *allocate(size_t); + +#if 0 +__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 schedtasks list. */ + tsched->schedtasks = addSchedTask(tsched->schedtasks, newst); + + goto selectCode(tsched); +} +#endif + +__code +selectCode(TaskScheduler *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 noCode(tsched); + } +} + +__code +schedEntry(TaskScheduler *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); + /* + ID id = tsched->running->id; + tsched->schedtasks = + removeTask(tsched->schedtasks, 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->schedtasks = _listMoveLasttoFirst(tsched->schedtasks); + goto selectCode(tsched, NOWAIT); + } +} + + diff -r 5a3e2b0622fd -r 91a07e20e06d Fifo/Scheduler.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fifo/Scheduler.h Fri Dec 25 17:53:11 2009 +0900 @@ -0,0 +1,26 @@ +#ifndef _TASKSCHEDULER_H +#define _TASKSCHEDULER_H +#include +#include "List.h" +#include "Task.h" +typedef uint32_t ID; + +typedef struct _SchedTask { + ID id; // task identifier; + Taskrun nextcode; + void *rbuff; + void *wbuff; +} SchedTask; + +typedef struct _scheduler { + SchedTask *running; + List *runnable; + //Scheduler schedule; +} TaskScheduler; + + +__code initScheduler(__code (*)(TaskScheduler *,void *), void *); +__code addCode(TaskScheduler *, ID, Taskrun, void *, void *); +__code selectCode(TaskScheduler *); + +#endif /* _TASKSCHEDULER_H */ diff -r 5a3e2b0622fd -r 91a07e20e06d Fifo/TaskManager.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fifo/TaskManager.cbc Fri Dec 25 17:53:11 2009 +0900 @@ -0,0 +1,209 @@ +#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); +} + + + diff -r 5a3e2b0622fd -r 91a07e20e06d Fifo/TaskManager.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fifo/TaskManager.h Fri Dec 25 17:53:11 2009 +0900 @@ -0,0 +1,23 @@ +#ifndef _TASKMANAGER_H +#define _TASKMANAGER_H +#include +#include "List.h" +#include "Task.h" +#include "interface.h" + +typedef struct _SchedTask { + Task *task; + Taskrun nextcode; + void *rbuff; + void *wbuff; +} SchedTask; + +typedef struct _TaskManager { + List *waitingList; // list of tasks waiting for others. + //List *activeList; + List *schedTasks; // list of schedtasks executing now. + List *exitTasks; // list of schedtasks which finished. + SchedTask *running; +} TaskManager; + +#endif /* !_TASKMANAGER_H */ diff -r 5a3e2b0622fd -r 91a07e20e06d Fifo/TaskManager.o Binary file Fifo/TaskManager.o has changed diff -r 5a3e2b0622fd -r 91a07e20e06d Fifo/interface.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Fifo/interface.h Fri Dec 25 17:53:11 2009 +0900 @@ -0,0 +1,12 @@ +#ifndef _INTERFACE_H +#define _INTERFACE_H +// included by user. + +typedef __code (*Taskrun)(void*, void*, void*); +//extern __code (*scheduler)(void*,Taskrun,void*,void*); + +#define ENDTASK ((Taskrun)NULL) + +#endif /* _INTERFACE_H */ + + diff -r 5a3e2b0622fd -r 91a07e20e06d Task.cbc --- a/Task.cbc Fri Dec 25 17:51:13 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,46 +0,0 @@ -#include -#include "List.h" -#include "Task.h" - - -/* - * User interfaces. - */ - -Task * -createTask(int id, char *name) -{ - Task *task; - if (!name) name = "(no name)"; - - task = malloc(sizeof(Task)); - 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 *a, Task *b) -{ - /* set a waiting for b. */ - a->waitee = _listAddFirst(a->waitee, b); - b->waiter = _listAddFirst(b->waiter, a); -} - diff -r 5a3e2b0622fd -r 91a07e20e06d TaskInterface.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskInterface.cbc Fri Dec 25 17:53:11 2009 +0900 @@ -0,0 +1,52 @@ +#include "TaskManager.h" +#include "TaskScheduler.h" +#include "taskinit.h" + +extern AbstractLayer *ablayer; + +Task * +createTask(int id, char *name) +{ + Task *task; + if (!name) name = "(no name)"; + + task = malloc(sizeof(Task)); + 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. */ + a->waitee = _listAddFirst(a->waitee, b); + b->waiter = _listAddFirst(b->waiter, a); +} + +void +taskSpawn(Task *task) +{ + //tm->waitingList = _listAddFirst(tm->waitingList, task); + ablayer->spawnedTasks = _listAddFirst(ablayer->spawnedTasks, task); + return ; +} + + diff -r 5a3e2b0622fd -r 91a07e20e06d TaskManager.cbc --- a/TaskManager.cbc Fri Dec 25 17:51:13 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,200 +0,0 @@ -#include -#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; -} - - diff -r 5a3e2b0622fd -r 91a07e20e06d TaskManager.h --- a/TaskManager.h Fri Dec 25 17:51:13 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,49 +0,0 @@ -#ifndef _TASKMANAGER_H -#define _TASKMANAGER_H -#include -#include "List.h" -#include "Task.h" - -typedef struct _TaskManager { - List *waitingList; - List *activeList; -} TaskManager; - -__code initTaskManager(__code(*ret)(TaskManager*,void*), void *arg); -__code addNewTask(TaskManager *, Task *); -__code finishTask(TaskManager *, Task *); -__code noEvent(TaskManager *); -__code getTask(TaskManager *, ListIter *); -__code executed(TaskManager *, ListIter *, Task *); -#if 0 -typedef List TaskList; -typedef uint32_t TaskTypeID; - -/* C++CeriumでのTaskObjectにあたる */ -typedef struct _tasktype { - //Taskrun run; - char *name; - enum cpu cputype; -} TaskType; - -/* C++CeriumでのHTaskにあたるのかな */ -typedef struct _Task { - TaskType tasktype; - unsigned int id; // is it needed? - - void *rbuff; - void *wbuff; - size_t rsize; - size_t wsize; - - TaskList waiter; // List of tasks waiting for me :-P - TaskList waitee; // List of tasks keep me waiting :-( -} Task; - -/* defined in USERs space. */ -/* but generated by Cerium automatically. */ -extern int max_tasktypes; -extern TaskType taskTypes[]; -#endif - -#endif /* !_TASKMANAGER_H */ diff -r 5a3e2b0622fd -r 91a07e20e06d TaskManagerAbst.cbc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManagerAbst.cbc Fri Dec 25 17:53:11 2009 +0900 @@ -0,0 +1,197 @@ +#include +#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 ; +} + diff -r 5a3e2b0622fd -r 91a07e20e06d TaskScheduler.cbc --- a/TaskScheduler.cbc Fri Dec 25 17:51:13 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,91 +0,0 @@ -//#include "Task.h" -#include -#include -#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); - -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); - } -} - - diff -r 5a3e2b0622fd -r 91a07e20e06d TaskScheduler.h --- a/TaskScheduler.h Fri Dec 25 17:51:13 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,26 +0,0 @@ -#ifndef _TASKSCHEDULER_H -#define _TASKSCHEDULER_H -#include -#include "List.h" -#include "Task.h" -typedef uint32_t ID; - -typedef struct _SchedTask { - ID id; // task identifier; - Taskrun nextcode; - void *rbuff; - void *wbuff; -} SchedTask; - -typedef struct _scheduler { - SchedTask *running; - List *runnable; - //Scheduler schedule; -} TaskScheduler; - - -__code initScheduler(__code (*)(TaskScheduler *,void *), void *); -__code addCode(TaskScheduler *, ID, Taskrun, void *, void *); -__code selectCode(TaskScheduler *); - -#endif /* _TASKSCHEDULER_H */