//#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); //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); } }