Mercurial > hg > Game > CbCTaskManager
changeset 2:803d6bf22e6d
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 | 4595d57d8dd6 |
files | List.c List.h Task.cbc Task.h TaskManager.cbc TaskManager.h TaskQueue.c TaskScheduler.cbc TaskScheduler.h memo.txt test/list/Makefile test/list/testiter.c test/list/testlist.c test/manager/taskinit.cbc test/manager/taskinit.h test/manager/testmanager.cbc test/scheduler/test_sched.cbc |
diffstat | 17 files changed, 856 insertions(+), 279 deletions(-) [+] |
line wrap: on
line diff
--- a/List.c Sun Dec 20 20:46:53 2009 +0900 +++ b/List.c Tue Dec 22 16:19:56 2009 +0900 @@ -1,22 +1,45 @@ #include<stdlib.h> +/* TODO: malloc. */ +#include"List.h" -#include"List.h" +/* + * doubly-linked list. + * interfaces of these routines is based on glib. + * + * Usage: + * create new list. + * list = NULL + * add new data + * list = _listAddFirst(list, data) + * remove data from the list + * list = _listRemove(list, data) + * get n-th data + * data = _listGetnthData(list, n) + * + * + * NOTE: + * Although `struct List' is a doubly-linked List, the List + * is made as a Ring. An User's variable is treated as a + * head of the list. And head->prev is last. And then if + * list have only one data, both next and prev field of + * head will point to oneself. + * If the variable is NULL, it means no data. + */ List * _listAddFirst(List* top, void *data) { List *newlist; + List *last; + newlist = malloc(sizeof(struct _List)); + newlist->data = data; + if (!top) { - newlist = malloc(sizeof(struct _List)); - newlist->data = data; newlist->next = newlist; newlist->prev = newlist; return newlist; } - List *last = top->prev; - - newlist = malloc(sizeof(struct _List)); - newlist->data = data; + last = top->prev; newlist->next = top; newlist->prev = last; @@ -70,7 +93,7 @@ return top->prev->data; } -void * +List * _listMoveLasttoFirst(List *top) { if (!top) return NULL; @@ -78,7 +101,8 @@ } void -_listApply(List *top, ApplyFn fn, void *arg) { +_listApply(List *top, ApplyFn fn, void *arg) +{ List *t = top; do { fn(t->data, arg); @@ -86,9 +110,93 @@ } while ( t!=top ); } +/* + * Iterator's functions. + * + * iter = _listIterator(list); + * while ( (data=_listIterNext(iter)!=NULL ) { + * exe(data); + * if (data...) { + * list = _listIterRemove(iter); + * } + * } + */ +ListIter * +_listIterator(List *top) +{ + ListIter *iter; + iter = malloc(sizeof(struct _ListIter)); + iter->head = top; + iter->next = top; + return iter; +} +void * +_listIterNext(ListIter *iter) +{ + void *rtn; + if (!iter->next) return NULL; + + rtn = iter->next->data; + iter->next = iter->next->next; + if (iter->next==iter->head) { + iter->next = NULL; + } + return rtn; +} + +void +_listIterEnd(ListIter *iter) +{ + free(iter); +} + +List * +_listIterRemoveCurrent(ListIter *iter) +{ + List *cur, *p, *n; + if (!iter->head) return NULL; + else if (!iter->next) cur = iter->head->prev; + else cur = iter->next->prev; + + if (cur==iter->head) { + if (cur->next==iter->head) { + free(iter->head); + return NULL; + } + iter->head = iter->head->next; + } + cur->prev->next = cur->next; + cur->next->prev = cur->prev; + + free(cur); + return iter->head; +} +/* + * for DEBUG + */ +int +_listRingCheck(List *head) +{ + List *cur = head; + if (cur->prev->next!=cur) return 0; + if (cur->next->prev!=cur) return 0; + do { + if (cur->prev->next!=cur) return 0; + if (cur->next->prev!=cur) return 0; + cur = cur->prev; + } while (cur!=head); + if (cur->prev->next!=cur) return 0; + if (cur->next->prev!=cur) return 0; + cur = cur->next; + if (cur->prev->next!=cur) return 0; + if (cur->next->prev!=cur) return 0; + + return 1; +} +
--- a/List.h Sun Dec 20 20:46:53 2009 +0900 +++ b/List.h Tue Dec 22 16:19:56 2009 +0900 @@ -7,11 +7,25 @@ struct _List *prev; } List; +typedef struct _ListIter { + struct _List *head; + struct _List *next; +} ListIter; + List * _listAddFirst(List*, void *); List * _listRemove(List *, void *); void * _listGetnthData(List *, int); +void * _listGetLastData(List *); +List * _listMoveLasttoFirst(List *); typedef int (*ApplyFn)(void*,void*); void _listApply(List *, ApplyFn, void *); + +ListIter * _listIterator(List *); +void * _listIterNext(ListIter *); +void _listIterEnd(ListIter *); +List * _listIterRemoveCurrent(ListIter *); + + #endif /* !_LIST_H */
--- a/Task.cbc Sun Dec 20 20:46:53 2009 +0900 +++ b/Task.cbc Tue Dec 22 16:19:56 2009 +0900 @@ -1,107 +1,46 @@ - - -typedef __code (*Scheduler)(); -typedef __code (*Taskrun)(Scheduler, void*, void*); - -typedef struct _Task { - Taskrun run; +#include <stdlib.h> +#include "List.h" +#include "Task.h" - TaskList waiter; // List of tasks waiting for me :-P - TaskList waitee; // List of tasks keep me waiting :-( -} Task; - - -typedef struct _TaskList { - Task *task; - struct _TaskList *next; - struct _TaskList *prev; -} TaskList; /* - * use this function like below. - * list = listAddFirst(list, task); + * User interfaces. */ -TaskList * -listAddFirst(TaskList* top, Task *task) + +Task * +createTask(int id, char *name) { - if (!top) { - newlist = malloc(sizeof(struct _TaskList)); - newlist->task = task; - newlist->next = newlist; - newlist->prev = newlist; - return newlist; - } - TaskList *last = top->prev; + Task *task; + if (!name) name = "(no name)"; - newlist = malloc(sizeof(struct _TaskList)); - newlist->task = task; - newlist->next = top; - newlist->prev = last; + 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; - top->prev = newlist; - last->next = newlist; - return newlist; + return task; } -TaskList * -listAddLast(TaskList* top, Task *task) +void +taskSetData(Task *task, void *rbuff, int rsize, void *wbuff, int wsize) { - /* - if (!top) { - newlist = malloc(sizeof(struct _TaskList)); - newlist->task = task; - newlist->next = newlist; - newlist->prev = newlist; - return newlist; - } - TaskList *last = top->prev; - - newlist = malloc(sizeof(struct _TaskList)); - newlist->task = task; - newlist->next = top; - newlist->prev = last; - - top->prev = newlist; - last->next = newlist; - return newlist; - */ + task->rbuff = rbuff; + task->wbuff = wbuff; + task->rsize = rsize; + task->wsize = wsize; } -TaskList * -listRemove(TaskList *top, Task *task) +void +taskSetWait(Task *a, Task *b) { - TaskList *t; - if (top->task==task) { - if (top->next==top) { - free(top); - return NULL; - } - TaskList *newtop = top->next; - top->next->prev = top->prev; - top->prev->next = top->next; - free(top); - return newtop; - } - for (t=top->next; t!=top; t=t->next) { - if (t->task==task) { - t->next->prev = t->prev; - t->prev->next = t->next; - free(t); - return top; - } - } - return top; + /* set a waiting for b. */ + a->waitee = _listAddFirst(a->waitee, b); + b->waiter = _listAddFirst(b->waiter, a); } -typedef int (*ApplyFn)(Task*,void*); - -listApply(TaskList *top, ApplyFn fn, void *arg) { - t = top; - do { - fn(t->task, arg); - t = t->next; - } while ( t!=top ); -} - - -
--- a/Task.h Sun Dec 20 20:46:53 2009 +0900 +++ b/Task.h Tue Dec 22 16:19:56 2009 +0900 @@ -1,16 +1,56 @@ #ifndef _TASK_H #define _TASK_H +// ユーザ側でもこのヘッダファイルをインクルードする +#include "List.h" -typedef __code (*Taskrun)(__code(*)(void*,void*,void*), void*, void*); -typedef __code (*Scheduler)(__code(*)(void*,void*,void*), void*, void*); +/* used by User'sTask. */ +typedef __code (*Taskrun)(void*, void*, void*); +//typedef __code (*Scheduler)(TaskScheduler*,__code(*)(void*,void*,void*), void*, void*); +//typedef __code (*Taskrun)(_code(*)(void*,void*,void*), void*, void*); +//typedef __code (*Scheduler)(__code(*)(void*,void*,void*), void*, void*); //typedef __code (*Scheduler)(Taskrun, void*, void*); //typedef __code (*Taskrun)(Scheduler, void*, void*); #define END (NULL) +/* C++CeriumでのTaskObjectにあたる */ +typedef struct _TaskType { + Taskrun code; + char *name; +} TaskType; + + +/* defined by user automatically. */ +extern const int max_tasktype; +extern const TaskType tasktypes[]; + enum cpu { - ANY = 0, + ANY = 0, // not implemented yet. MAIN, SUB, }; +/* C++CeriumでのHTaskにあたるのかな */ +typedef struct _Task { + char *name; // task name. + int typeid; // index of tasktypes array. + int id; // task identifier. + + void *rbuff; + void *wbuff; + int rsize; + int wsize; + List *waiter; // List of tasks waiting for me :-P + List *waitee; // List of tasks keep me waiting :-( + + enum cpu cpu; +} Task; + +/* user interfaces. */ +extern Task * createTask (int, char *); +extern void taskSetData (Task *, void *, int, void *, int); +extern void taskSetWait (Task *, Task *); + +extern __code (*scheduler)(void*,Taskrun,void*,void*); + #endif /* _TASK_H */ +
--- a/TaskManager.cbc Sun Dec 20 20:46:53 2009 +0900 +++ b/TaskManager.cbc Tue Dec 22 16:19:56 2009 +0900 @@ -1,78 +1,187 @@ +#include <assert.h> #include "TaskManager.h" +#include "Task.h" +#include "List.h" +// TODO: malloc -TaskQueue waitingQueue; -TaskQueue activeQueue; +extern __code checkEvent(TaskManager *); +extern __code executeTask(TaskManager*, ListIter*, Task*); + +typedef List TaskList; /* * TaskManager's main loop. * * while (1) { - * checkFinishedTask(); // to scheduler. - * wait2active(); - * while (actQisnotempty) { - * task = pollFirst(actQ); - * executeTask(task); // to scheduler. + * 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. + * } + * } * } * } */ -__code TManagerStart() -/* active, waitngタスクリストを整理 */ + +/* 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) { - list = activeQueue; - goto executeTasklist(list); + 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 executeTasklist() -/* */ +__code +getTask(TaskManager *manager, ListIter *iter) { - if (0 < activeQueue->length) { - goto TManagerLoop(); - } - task = pollFirst(activeQueue); - - /* - * rbuff, wbuffの用意 - */ - goto task->run(TManagerReturnEntry, rbuff, wbuff); - /* Taskへ */ + 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 TManagerReturnEntry() -/* Taskから戻ってくるコードセグメント */ +__code +executed(TaskManager *manager, ListIter *iter, Task *task) { - /* - * 依存していたtaskに通知? - */ - goto executeTasklist(list->cdr); + 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 TManagerLoop() +__code +finishTask_iter(TaskManager *manager, Task *task, ListIter *iter) { - /* - * waitingTaskからactiveTaskへ - */ + 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); + } +} - goto TManagerStart(); +__code +finishTask_end(TaskManager *manager, Task *task) +{ + /* TODO: free(task) */ + assert (!task->waiter); + assert (!task->waitee); + free(task); + goto start(manager); } -__code sched() -{ - TaskList *t = waiter; - Task *t; - for (; t!=;); -} + /* belows is Interfaces for Users. */ -/* it may be replace to code segment. but how? */ +/* it may be to code segment. but how? */ +/* and may be moved to AbstractLayer. */ -Task *newTask(TaskTypeID typeid) +Task *newTask(int typeid) { - static int id=0; // 今は使ってない… 使う? - task = allocate(sizeof(Task)); + Task *task; + static int id=0; + task = malloc(sizeof(Task)); - task->tasktype = tasktypes[typeid]; + //task->tasktype = tasktypes[typeid]; task->id = id; task->waiter = NULL; task->waitee = NULL; @@ -84,12 +193,8 @@ { task->rbuff = rbuff; task->wbuff = wbuff; - task->rsize = rsize; - task->wsize = wsize; -} - -void spawn(Task *task) -{ + task->rsize = rs; + task->wsize = ws; }
--- a/TaskManager.h Sun Dec 20 20:46:53 2009 +0900 +++ b/TaskManager.h Tue Dec 22 16:19:56 2009 +0900 @@ -2,7 +2,20 @@ #define _TASKMANAGER_H #include <stdlib.h> #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; @@ -31,5 +44,6 @@ /* but generated by Cerium automatically. */ extern int max_tasktypes; extern TaskType taskTypes[]; +#endif #endif /* !_TASKMANAGER_H */
--- a/TaskQueue.c Sun Dec 20 20:46:53 2009 +0900 +++ b/TaskQueue.c Tue Dec 22 16:19:56 2009 +0900 @@ -1,17 +1,19 @@ -#include"TaskList.h" +#include <stdlib.h> +// TODO: malloc +#include "List.h" +#include "Queue.h" -typedef struct _TaskQueue { - TaskList *head; - TaskList *tail; +typedef struct _Queue { + List *head; + List *tail; int length; -} TaskQueue; +} Queue; -TaskQueue * -newTaskQueue() +Queue * +newQueue() { - TaskQueue *queue; - /* TODO: mallocはあとで独自実装に書き直し! */ - malloc(sizeof(struct _TaskQueue)); + Queue *queue; + malloc(sizeof(struct _Queue)); queue->head = NULL; queue->tail = NULL; queue->length = 0; @@ -19,11 +21,11 @@ } void -queueAddFirst(TaskQueue *queue, Task *) +_QaddFirst(Queue *queue, void *) { - TaskList *oldhead = queue->head; - TaskList *newlist; - newlist = malloc(sizeof(struct _TaskList)); + List *oldhead = queue->head; + List *newlist; + newlist = malloc(sizeof(struct _List)); if (oldhead) { oldhead->prev = newlist; @@ -36,11 +38,11 @@ } void -queueAddLast(TaskQueue *queue, Task *task) +_QaddLast(Queue *queue, void *task) { - TaskList *oldtail = queue->tail; - TaskList *newlist; - newlist = malloc(sizeof(struct _TaskList)); + List *oldtail = queue->tail; + List *newlist; + newlist = malloc(sizeof(struct _List)); if (oldtail) { oldtail->next = newlist; @@ -52,12 +54,12 @@ return ; } -Task * -queuePollFirst(TaskQueue *queue) +void * +_QpollFirst(Queue *queue) { - TaskList *first = queue->head; - TaskList *second; - Task *task; + List *first = queue->head; + List *second; + void *task; if (!first) return NULL; second = first->next; @@ -70,12 +72,12 @@ return task; } -Task * -queuePollLast(TaskQueue *queue) +void * +_QpollLast(Queue *queue) { - TaskList *first = queue->tail; - TaskList *second; - Task *task; + List *first = queue->tail; + List *second; + void *task; if (!first) return NULL; second = first->prev;
--- a/TaskScheduler.cbc Sun Dec 20 20:46:53 2009 +0900 +++ b/TaskScheduler.cbc Tue Dec 22 16:19:56 2009 +0900 @@ -4,96 +4,88 @@ #include "TaskScheduler.h" #include "List.h" -enum { +enum wait{ NOWAIT=0, WAIT=1, }; -__code checkNewCode(); +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のがいいか -typedef struct _segment { - ID id; // task identifier; - Taskrun nextcode; - void *rbuff; - void *wbuff; -} SchedTask; +__code schedEntry(TaskScheduler *tsched, Taskrun nextcode, void *rbuff, void *wbuff); -typedef struct _scheduler { - /* it may be Singleton. */ - - SchedTask *running; - SchedTaskList *runnable; - -} TaskScheduler; - -__code schedEntry(Taskrun nextcode, void *rbuff, void *wbuff); - -static TaskScheduler *schedule; +//static TaskScheduler *tsched; extern void *allocate(size_t); __code -initScheduler(__code (*ret)(void *), void *arg) +initScheduler(__code (*ret)(TaskScheduler*,void*), void *arg) { - schedule = allocate(sizeof(TaskScheduler)); - schedule->runnable = NULL; - schedule->running = NULL; - goto ret(arg); + TaskScheduler *tsched; + tsched = allocate(sizeof(TaskScheduler)); + tsched->runnable = NULL; + tsched->running = NULL; + //tsched->schedule = SchedEntry; + scheduler = schedEntry; + goto ret(tsched, arg); } __code -addCode(ID id, Taskrun code0, void *rbuff, void *wbuff) +addCode(TaskScheduler *tsched, ID id, Taskrun code0, void *rbuff, void *wbuff) { - SchedTask *newcs; - newcs = allocate(sizeof(SchedTask)); - newcs->nextcode = code0; - newcs->rbuff = rbuff; //taskの遷移で引数が変化しないならいならい - newcs->wbuff = wbuff; + SchedTask *newst; + newst = allocate(sizeof(SchedTask)); //これはAbstractLayerで生成してもいいのだが… + newst->nextcode = code0; + newst->rbuff = rbuff; //taskの遷移で引数が変化しないならいならい + newst->wbuff = wbuff; - schedule->runnable = addSchedTask(schedule->runnable, newcs); + /* regist new task to runnable list. */ + tsched->runnable = addSchedTask(tsched->runnable, newst); - goto selectCode(); + goto selectCode(tsched); } __code -selectCode() +selectCode(TaskScheduler *tsched) { SchedTask *task; - if (schedule->runnable) { - task = _listGetLastData(schedule->runnable); - schedule->running = task; + if (tsched->runnable) { + task = (SchedTask*)_listGetLastData(tsched->runnable); + tsched->running = task; - goto task->nextcode((void*)schedEntry, task->rbuff, task->wbuff); + /* goto user-defined task. */ + goto task->nextcode(tsched, task->rbuff, task->wbuff); } else { + /* no task we have. */ //goto checkNewCode(); - goto checkNewCode(WAIT); + goto checkNewCode(tsched, WAIT); } } __code -schedEntry(Taskrun nextcode, void *rbuff, void *wbuff) +schedEntry(TaskScheduler *tsched, Taskrun nextcode, void *rbuff, void *wbuff) { - /* nextcode==NULLならTaskは終わったと判断 */ - /* scheduled */ + /* schedulerd */ if ( nextcode==NULL ) { - ID id = schedule->running->id; - schedule->runnable = - removeTask(schedule->runnable, schedule->running); - free(schedule->running); - schedule->running = NULL; - goto exitCode(id); + /* 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 { - SchedTaskList list; /* save the next code segment for the task. */ - schedule->running->nextcode = nextcode; - schedule->running->rbuff = rbuff; - schedule->running->wbuff = wbuff; + tsched->running->nextcode = nextcode; + tsched->running->rbuff = rbuff; + tsched->running->wbuff = wbuff; /* move last task to first to be fair. */ - schedule->runnable = _listMoveLasttoFirst(schedule->runnable); - goto checkNewCode(NOWAIT); + tsched->runnable = _listMoveLasttoFirst(tsched->runnable); + goto checkNewCode(tsched, NOWAIT); } }
--- a/TaskScheduler.h Sun Dec 20 20:46:53 2009 +0900 +++ b/TaskScheduler.h Tue Dec 22 16:19:56 2009 +0900 @@ -1,11 +1,26 @@ #ifndef _TASKSCHEDULER_H #define _TASKSCHEDULER_H #include <stdint.h> +#include "List.h" #include "Task.h" typedef uint32_t ID; -__code initScheduler(__code (*)(void *), void *); -__code addCode(ID, Taskrun, void *, void *); -__code selectCode(); +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 */
--- a/memo.txt Sun Dec 20 20:46:53 2009 +0900 +++ b/memo.txt Tue Dec 22 16:19:56 2009 +0900 @@ -25,19 +25,39 @@ o ?set_depend (used by wait_for of Task) o spawn_task (used by spawn of Task) -Scheduler +TaskScheduler o TaskManagerに指示されたTaskを実際に実行する o CPU管理 - o 実行環境毎にコードがちがう - (pthread用、Cell用、クラスタ用、Fifo..) - o 一度に指示されたものを実行する必要はない o Taskが終了したらTaskManagerに通知する - * TaskManagerのためのインターフェイス - o initialize - o executeTask(Task *) - o checkFInishedTask - o numTask - o numCPU + * AbstractLayerからのインターフェイス + o initScheduler() + o addCode(SchedTask *) + o selectCode() + +AbstractLayer + o TaskManagerとSchedulerの中間レイヤ + o 実行環境ごとに全部違う Cell, Fifo, pthread, cluster.. + o TaskManagerに指示されたタスクをSchedulerに渡す + o その際、clusterやCellならデータの転送処理などを受け持つ + o Schedulerから終了したタスクの通知も受け付ける + * Schedulerとのインタフェイス + -> checkNewCode() + -> exitCode() + <- initScheduler() + <- addCode() + <- selectCode() + * TaskManagerとのインタフェイス + o checkAction() + -> TM::addNewTask() + -> TM::finishTask() + -> TM::noAction() + o executeTask(Task*) + -> TM::executeTaskret() // なんかいい名前を… + * Userインタフェイス(Fifoやpthreadの場合は直接TaskManagerでもいい) + o newTask() + o spawn() + o setData() + o allocate() MailManager o Schedulerとおなじく環境依存
--- a/test/list/Makefile Sun Dec 20 20:46:53 2009 +0900 +++ b/test/list/Makefile Tue Dec 22 16:19:56 2009 +0900 @@ -3,10 +3,13 @@ INCLUDE = -I../../ CFLAGS = -g -O0 $(INCLUDE) +all: testlist testiter .c.o: $(CC) -c $(CFLAGS) -o $@ $< testlist: testlist.o ../../List.o $(CC) -o $@ $^ +testiter: testiter.o ../../List.o + $(CC) -o $@ $^
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/list/testiter.c Tue Dec 22 16:19:56 2009 +0900 @@ -0,0 +1,84 @@ +#include<stdio.h> +#include<stdlib.h> +#include<string.h> +#include<assert.h> + +#include"List.h" + +void printList(List *list); +int test0(); +int _listRingCheck(List *head); + +int +main(int argc, char **argv) +{ + test0(); + return 0; +} + +int +test0() +{ + char *data = "abcdefghijklmnopqrstuvwxyz"; + List *list=NULL; + ListIter *iter=NULL; + int i; + char input; + + for (i=0; data[i]!='\0'; i++) { + list = _listAddFirst(list, (void*)data[i]); + } + printList(list); + assert(_listRingCheck(list)); + + + iter = _listIterator(list); + while ((data=_listIterNext(iter))!=NULL) { + int c=(int)data; + printf("%c ", c); + } + _listIterEnd(iter); + printf("\n"); + + + i=0; + iter = _listIterator(list); + while ((data=_listIterNext(iter))!=NULL) { + if (i%2==1) { + list = _listIterRemoveCurrent(iter); + } + i++; + } + _listIterEnd(iter); + printf("\n"); + assert(_listRingCheck(list)); + + iter = _listIterator(list); + while ((data=_listIterNext(iter))!=NULL) { + int c=(int)data; + printf("%c ", c); + } + _listIterEnd(iter); + printf("\n"); + + return 0; +} + + +int printOne(void *data,void *arg) +{ + char c = (char)data; + printf("%c ", c); + return 1; +} +void +printList(List *list) +{ + _listApply(list, printOne, NULL); + printf("\n"); +} + + + + +
--- a/test/list/testlist.c Sun Dec 20 20:46:53 2009 +0900 +++ b/test/list/testlist.c Tue Dec 22 16:19:56 2009 +0900 @@ -28,6 +28,12 @@ printf("%s\n", s); list = _listRemove(list, s); } + } else if (strncmp(buff, "s:", 2)==0) { + int count; + count = atoi(buff+2); + for (;count>0; count--) { + list = _listMoveLasttoFirst(list); + } } else { newstr = strdup(buff); list = _listAddFirst(list, newstr);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/manager/taskinit.cbc Tue Dec 22 16:19:56 2009 +0900 @@ -0,0 +1,1 @@ +../../taskinit.cbc \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/manager/taskinit.h Tue Dec 22 16:19:56 2009 +0900 @@ -0,0 +1,1 @@ +../../taskinit.h \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/manager/testmanager.cbc Tue Dec 22 16:19:56 2009 +0900 @@ -0,0 +1,138 @@ +#include <stdio.h> +#include <stdlib.h> + +#include "List.h" +#include "Task.h" +#include "TaskManager.h" + +#include "taskinit.h" + +#define __DEBUG(f, args...) \ + fprintf(stderr, "in %s: "f, __FUNCTION__, ## args) + + +extern int main (int, char **); +extern __code teststart (); +__code retinit(TaskManager *, void *); +extern __code checkEvent (); +extern __code executeTask (TaskManager *, ListIter *, Task *); + +__code end(); + + +#define NUM 16 +Task *tasks[NUM]; +int stat[NUM]; + +__code taskA(Scheduler scheduler, void *rbuff, void *wbuff) +{ + goto scheduler(END, NULL, NULL); +} +__code taskB(Scheduler scheduler, void *rbuff, void *wbuff) +{ + goto scheduler(END, NULL, NULL); +} + + +int +main(int argc, char **argv) +{ + goto teststart(); + return 0; +} + +__code +teststart() +{ + int i; + /* + tasks[0] = createTask(TASK_A, NULL); + tasks[1] = createTask(TASK_B, NULL); + tasks[2] = createTask(TASK_B, NULL); + tasks[3] = createTask(TASK_A, NULL); + tasks[4] = createTask(TASK_B, NULL); + tasks[5] = createTask(TASK_B, NULL); + tasks[6] = createTask(TASK_B, NULL); + taskSetWait(tasks[2], tasks[0]); + taskSetWait(tasks[3], tasks[0]); + taskSetWait(tasks[3], tasks[1]); + taskSetWait(tasks[4], tasks[2]); + taskSetWait(tasks[5], tasks[2]); + taskSetWait(tasks[5], tasks[3]); + taskSetWait(tasks[6], tasks[4]); + taskSetWait(tasks[6], tasks[5]); + */ + for (i=0; i<NUM; i++) { + tasks[i] = createTask(TASK_A, NULL); + } + taskSetWait(tasks[0], tasks[1]); + for (i=1; 2*i<NUM; i++) { + taskSetWait(tasks[i], tasks[2*i]); + if (2*i+1<NUM) + taskSetWait(tasks[i], tasks[2*i+1]); + } + + goto initTaskManager(retinit, NULL); +} + +__code +retinit(TaskManager *manager, void *arg) +{ + goto checkEvent(manager); +} + +__code +checkEvent(TaskManager *manager) +{ + int i; + static int count=0; + if (count<NUM) { + count++; + __DEBUG("new task %d added\n", NUM-count); + goto addNewTask(manager, tasks[NUM-count]); + } + for (i=0; i<NUM; i++) { + if (stat[i]==1) { + stat[i]=2; + __DEBUG("finish task %d\n", i); + goto finishTask(manager, tasks[i]); + } + } + + for (i=0; i<NUM; i++) { + if (stat[i]!=2) break; + } + + if (i==NUM) { + __DEBUG("all tasks finished.\n"); + goto end(); + } + + __DEBUG("noevent.\n"); + goto noEvent(manager); +} + +__code +end() +{ + exit(0); +} + +__code +executeTask(TaskManager *manager, ListIter *iter, Task *task) +{ + int i; + const TaskType *type; + type = &tasktypes[task->typeid]; + + __DEBUG("task %s[%s] is executed.\n", task->name, type->name); + for (i=0; i<NUM; i++) { + if (tasks[i]==task) { + stat[i] = 1; + } + } + + goto executed(manager, iter, task); + //goto code(scheduler, task->rbuff, task->wbuff); +} +
--- a/test/scheduler/test_sched.cbc Sun Dec 20 20:46:53 2009 +0900 +++ b/test/scheduler/test_sched.cbc Tue Dec 22 16:19:56 2009 +0900 @@ -2,24 +2,104 @@ #include <stdlib.h> #include "Task.h" -#include "TaskScheduler.h" #define __DEBUG(f, args...) \ fprintf(stderr, "in %s: "f, __FUNCTION__, ## args) -__code task0(Scheduler scheduler, void *rbuff, void *wbuff); -__code task1 (Scheduler scheduler, void *rbuff, void *wbuff); -__code task2 (Scheduler scheduler, void *rbuff, void *wbuff); + +void * allocate (size_t size); + +__code taskA_0(void *tsched, void *rbuff, void *wbuff); +__code taskA_1(void *tsched, void *rbuff, void *wbuff); +__code taskA_2(void *tsched, void *rbuff, void *wbuff); +__code task0 (void *tsched, void *rbuff, void *wbuff); +__code task1 (void *tsched, void *rbuff, void *wbuff); +__code task2 (void *tsched, void *rbuff, void *wbuff); int main (int argc, char **argv); -__code startcode (void *arg); -__code checkNewCode (); -__code exitCode (); - +__code startcode (void *tsched, void *arg); +__code checkNewCode (void *tsched, int wait); +__code exitCode (void *tsched, int id); void * allocate (size_t size); #define NUM 3 __code -task0(Scheduler scheduler, void *rbuff, void *wbuff) +taskA_0(void *tsched, void *rbuff, void *wbuff) +{ + int i,j; + double *t; + int *count=rbuff; + + t = wbuff; + double *result[NUM] = { t, t+3, t+6 }; + for (i=0; i<NUM; i++) { + for (j=0; j<NUM; j++) { + if (i==j) result[i][j] = 1.0; + else result[i][j] = 0.0; + } + } + + t = (double*)(count+1); + double *base[NUM] = { t, t+3, t+6 }; + printf("count = %d\n", *count); + printf("base = \n"); + for (i=0; i<NUM; i++) { + printf("%lf, %lf, %lf\n", base[i][0], base[i][1], base[i][2]); + } + + goto scheduler(tsched, taskA_1,rbuff,wbuff); +} +__code +taskA_1(void *tsched, void *rbuff, void *wbuff) +{ + int i,j,k; + int *count = rbuff; + double *t; + double prod[NUM][NUM]; + + t = (double*)(count+1); + double *base[NUM] = { t, t+3, t+6 }; + t = wbuff; + double *result[NUM] = { t, t+3, t+6 }; + + if (*count <= 0) { + //__DEBUG("task end\n", *count); + goto scheduler(tsched, taskA_2,rbuff,wbuff); + } + for (i=0; i<NUM; i++) { + for (j=0; j<NUM; j++) { + prod[i][j] = 0; + for (k=0; k<NUM; k++) { + prod[i][j] += result[j][k] * base[k][i]; + } + } + } + for (i=0; i<NUM; i++) { + for (j=0; j<NUM; j++) { + result[i][j] = prod[i][j]; + } + } + + //__DEBUG("count=%d\n", *count); + (*count)--; + goto scheduler(tsched, taskA_1, rbuff, wbuff); +} +__code +taskA_2(void *tsched, void *rbuff, void *wbuff) +{ + int i; + double *t; + + t = wbuff; + double *result[NUM] = { t, t+3, t+6 }; + printf("result = \n"); + for (i=0; i<NUM; i++) { + printf("%lf, %lf, %lf\n", result[i][0], result[i][1], result[i][2]); + } + + goto scheduler(tsched, END,NULL,NULL); +} +__code +task0(void *tsched, void *rbuff, void *wbuff) { int i,j; double *in = rbuff; @@ -40,10 +120,10 @@ __DEBUG("%3.2lf %3.2lf %3.2lf\n", in[0],in[1],in[2]); __DEBUG("%3.2lf %3.2lf %3.2lf\n", out[0],out[1],out[2]); //goto task1(scheduler, wbuff, rbuff); - goto scheduler(task1, wbuff, rbuff); + goto scheduler(tsched, task1, wbuff, rbuff); } __code -task1(Scheduler scheduler, void *rbuff, void *wbuff) +task1(void *tsched, void *rbuff, void *wbuff) { int i,j; double *in = rbuff; @@ -63,11 +143,11 @@ __DEBUG("%p %p\n", rbuff, wbuff); __DEBUG("%3.2lf %3.2lf %3.2lf\n", in[0],in[1],in[2]); __DEBUG("%3.2lf %3.2lf %3.2lf\n", out[0],out[1],out[2]); - //goto task2(scheduler, wbuff, rbuff); - goto scheduler(task2, wbuff, rbuff); + //goto task2(tsched, wbuff, rbuff); + goto scheduler(tsched, task2, wbuff, rbuff); } __code -task2(Scheduler scheduler, void *rbuff, void *wbuff) +task2(void *tsched, void *rbuff, void *wbuff) { int i,j; double *in = rbuff; @@ -87,59 +167,73 @@ __DEBUG("%p %p\n", rbuff, wbuff); __DEBUG("%3.2lf %3.2lf %3.2lf\n", in[0],in[1],in[2]); __DEBUG("%3.2lf %3.2lf %3.2lf\n", out[0],out[1],out[2]); - goto scheduler(END, rbuff, wbuff); + goto scheduler(tsched, END, rbuff, wbuff); } +#include "TaskScheduler.h" int main(int argc, char **argv) { __DEBUG("\n"); goto initScheduler(startcode, NULL); - return 0; } __code -startcode(void *arg) { +startcode(void *tsched, void *arg) { + int i,j; double *readbuff, *writebuff; - readbuff = malloc(sizeof(double)*NUM); - writebuff = malloc(sizeof(double)*NUM); + readbuff = malloc(sizeof(int)+sizeof(double)*NUM*NUM); + writebuff = malloc(sizeof(double)*NUM*NUM); + + int *count = (int*)readbuff; + double *t = (double*)(count+1); + double *base[NUM] = { t, t+3, t+6 }; - readbuff[0] = 2.00; - readbuff[1] = 3.00; - readbuff[2] = 4.00; + *count = 2; + for (i=0; i<NUM; i++) { + for (j=0; j<NUM; j++) { + if (i==j) base[i][j] = 1.0; + else base[i][j] = 0.0; + } + } + base[0][0] = 2.0; + base[2][1] = 0.5; + __DEBUG("id=0 added.\n"); - goto addCode(0, task0, readbuff, writebuff); + goto addCode(tsched, 0, taskA_0, readbuff, writebuff); } __code -checkNewCode(int wait) +checkNewCode(void *tsched, int wait) { static int t = 0; double *readbuff, *writebuff; - readbuff = malloc(sizeof(double)*NUM); - writebuff = malloc(sizeof(double)*NUM); if (wait) { __DEBUG("all tasks finished\n"); exit(0); } + /* if (t==0) { + readbuff = malloc(sizeof(double)*NUM); + writebuff = malloc(sizeof(double)*NUM); t++; __DEBUG("id=1 added.\n"); - goto addCode(1, task0, readbuff, writebuff); + goto addCode(tsched, 1, taskA, readbuff, writebuff); } + */ __DEBUG("no code added.\n"); - goto selectCode(); + goto selectCode(tsched); } __code -exitCode(int id) +exitCode(void *tsched, int id) { __DEBUG("exit task%d\n", id); - goto selectCode(); + goto selectCode(tsched); } void * @@ -155,3 +249,4 @@ +