Mercurial > hg > Game > CbCTaskManager
view src/pthread/TaskManager.cbc @ 15:2e764a0ae8ff
bit modify.
author | kent <kent@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 09 Jan 2010 18:48:57 +0900 |
parents | 5f65da34f4f3 |
children | e89acebd97b1 |
line wrap: on
line source
#include "List.h" #include "Queue.h" #include "TaskManager.h" #include "Task.h" #include "Debug.h" typedef __code (*Scheduler)(struct _UserManager*,Taskrun,void*,void*); typedef struct _UserManager { Scheduler scheduler; TaskManager *manager; } UserManager; // used only in this file. /* defined in TaskManagerAbst. */ extern Task *createTask(int, char *); extern void taskSetData(Task*, void*, int, void*, int); extern void taskSpawn(UserManager*, 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); static __code selectCode (TaskManager *manager); static __code schedEntry(UserManager *user, 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); extern __code searchStartTask(TaskManager *manager); /* for Debug. */ void printTasks(TaskManager *manager); int main(int argc, char **argv) { goto startTaskManager(); } // TODO: some codes are moved to TaskManagerAbst. /* * Initialization */ __code startTaskManager() { TaskManager *manager; UserManager *umanager; manager = malloc(sizeof(TaskManager)); umanager= malloc(sizeof(UserManager)); manager->waitingList = NULL; manager->activeList = NULL; manager->schedTasks = NULL; manager->finishtaskQ = createQueue(1); manager->user = umanager; umanager->manager = manager; umanager->scheduler = schedEntry; goto startThreadManager(manager); } /* * Initialize all ThreadManager. */ __code startThreadManager(TaskManager *manager) { manager->thread_num = 3;//TODO manager->thread = malloc(sizeof(ThreadManager)*manager->thread_num); manager->thread_round = 0; goto startThreadManager_iter(manager, 0); } __code startThreadManager_iter(TaskManager *manager, int i) { if (i < manager->thread_num) { manager->thread[i].finishtaskQ = manager->finishtaskQ; manager->thread[i].newtaskQ = createQueue(1); manager->thread[i].thread_id = i; manager->thread[i].finishFlag = 0; manager->thread[i].schedTasks = NULL; manager->thread[i].running = NULL; pthread_create(&manager->thread[i].thread, NULL, threadbase, &manager->thread[i]); goto startThreadManager_iter(manager, i+1); } else { goto searchStartTask(manager); } } __code executeTask(TaskManager *manager, ListIter *iter, Task *task) { if (task->cpu==MAIN) { 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); } else { // どのthreadに渡すかが問題 // とりあえずラウンドロビン queueOffer(manager->thread[manager->thread_round].newtaskQ, task); manager->thread_round++; manager->thread_round %= manager->thread_num; } 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) { Task *task; //printTasks(manager); task = queuePoll(manager->finishtaskQ); if (task) { __DEBUG("task[%d] finished.\n", task->id); goto finishTask(manager, task); /*} else if (manager->newtasks) { */ } else { goto noEvent(manager); } } __code exitTaskManager(TaskManager *manager) { __DEBUG("all tasks finished!\n"); exit(0); } /* * Scheduler */ static __code selectCode(TaskManager *manager) { SchedTask *task; if (manager->schedTasks) { task = (SchedTask*)_listGetLastData(manager->schedTasks); manager->running = task; /* goto user-defined task. */ goto task->nextcode(manager->user, task->task->rbuff, task->task->wbuff); } else { /* no task we have. */ //goto checkNewCode(); goto checkEvent_real(manager); } } static __code schedEntry(UserManager *user, Taskrun nextcode, void *rbuff, void *wbuff) { TaskManager *manager = user->manager; /* schedulerd */ if ( nextcode==NULL ) { /* the task finished. */ Task *task; task = manager->running->task; manager->schedTasks = _listRemove(manager->schedTasks, manager->running); free(manager->running); queueOffer(manager->finishtaskQ, task); goto selectCode(manager); } else { /* save the next code segment for the task. */ manager->running->nextcode = nextcode; manager->running->rbuff = rbuff; manager->running->wbuff = wbuff; /* move last task to first to be fair. */ manager->schedTasks = _listMoveLasttoFirst(manager->schedTasks); goto selectCode(manager); } } /* * 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); } void taskSpawn(UserManager *user, Task *task) { TaskManager *manager = user->manager; manager->waitingList = _listAddFirst(manager->waitingList, task); //ablayer->spawnedTasks = _listAddFirst(ablayer->spawnedTasks, task); return ; }