//#include "Task.h" #include #include #include "TaskScheduler.h" #include "List.h" enum { NOWAIT=0, WAIT=1, }; __code checkNewCode(); 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; typedef struct _scheduler { /* it may be Singleton. */ SchedTask *running; SchedTaskList *runnable; } TaskScheduler; __code schedEntry(Taskrun nextcode, void *rbuff, void *wbuff); static TaskScheduler *schedule; extern void *allocate(size_t); __code initScheduler(__code (*ret)(void *), void *arg) { schedule = allocate(sizeof(TaskScheduler)); schedule->runnable = NULL; schedule->running = NULL; goto ret(arg); } __code addCode(ID id, Taskrun code0, void *rbuff, void *wbuff) { SchedTask *newcs; newcs = allocate(sizeof(SchedTask)); newcs->nextcode = code0; newcs->rbuff = rbuff; //taskの遷移で引数が変化しないならいならい newcs->wbuff = wbuff; schedule->runnable = addSchedTask(schedule->runnable, newcs); goto selectCode(); } __code selectCode() { SchedTask *task; if (schedule->runnable) { task = _listGetLastData(schedule->runnable); schedule->running = task; goto task->nextcode((void*)schedEntry, task->rbuff, task->wbuff); } else { //goto checkNewCode(); goto checkNewCode(WAIT); } } __code schedEntry(Taskrun nextcode, void *rbuff, void *wbuff) { /* nextcode==NULLならTaskは終わったと判断 */ /* scheduled */ if ( nextcode==NULL ) { ID id = schedule->running->id; schedule->runnable = removeTask(schedule->runnable, schedule->running); free(schedule->running); schedule->running = NULL; goto exitCode(id); } else { SchedTaskList list; /* save the next code segment for the task. */ schedule->running->nextcode = nextcode; schedule->running->rbuff = rbuff; schedule->running->wbuff = wbuff; /* move last task to first to be fair. */ schedule->runnable = _listMoveLasttoFirst(schedule->runnable); goto checkNewCode(NOWAIT); } }