Mercurial > hg > Game > Cerium
changeset 308:b85b920628e2 draft
remove SchedTaskImpl
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 08 Jun 2009 19:36:48 +0900 |
parents | 3fc86ddf5d1c |
children | 77a136420f36 |
files | TaskManager/Makefile.cell TaskManager/kernel/schedule/SchedTask.cc TaskManager/kernel/schedule/SchedTaskImpl.cc include/TaskManager/SchedTask.h include/TaskManager/SchedTaskImpl.h |
diffstat | 5 files changed, 773 insertions(+), 808 deletions(-) [+] |
line wrap: on
line diff
--- a/TaskManager/Makefile.cell Mon Jun 08 19:32:38 2009 +0900 +++ b/TaskManager/Makefile.cell Mon Jun 08 19:36:48 2009 +0900 @@ -12,7 +12,6 @@ $(CELL_SPE_DIR)/SchedTask.cc \ $(CELL_SPE_DIR)/Scheduler.cc\ $(CELL_SPE_DIR)/SchedNop.cc \ - $(CELL_SPE_DIR)/SchedTaskImpl.cc \ $(CELL_SPE_DIR)/TaskGroup.cc CELL_SPE_SCHEDULE_OBJ = $(CELL_SPE_SCHEDULE_SRC:.cc=.o)
--- a/TaskManager/kernel/schedule/SchedTask.cc Mon Jun 08 19:32:38 2009 +0900 +++ b/TaskManager/kernel/schedule/SchedTask.cc Mon Jun 08 19:36:48 2009 +0900 @@ -1,8 +1,559 @@ +#include <stdlib.h> +#include <string.h> #include "SchedTask.h" +#include "SchedTask.h" +#include "SchedTaskList.h" +#include "SchedNop2Ready.h" +#include "DmaManager.h" +#include "error.h" +#include "TaskManager.h" -SchedTask* +extern Scheduler::TaskObject task_list[MAX_TASK_OBJECT]; + +//#define NO_PIPELINE + +SchedTask * createSchedTask(TaskPtr task) { - return createSchedTaskImpl(task); + return task_list[task->command](); +} + + +SchedTask::SchedTask() +{ + __list = NULL; + __task = NULL; + __inListData = NULL; + __outListData = NULL; + __readbuf = NULL; + __writebuf = NULL; + __scheduler = NULL; + __taskGroup = NULL; + __renew_flag = 0; + __cur_index = 0; + __flag_renewTask = SCHED_TASK_NORMAL; + + ex_init = &SchedTask::ex_init_normal; + ex_read = &SchedTask::ex_read_normal; + ex_exec = &SchedTask::ex_exec_normal; + ex_write = &SchedTask::ex_write_normal; + ex_next = &SchedTask::ex_next_normal; + + run_func = &SchedTask::run; +} + +/** + * dma_store の wait を行う + * このタスクが RenewTask だった場合、 + * __inListData や __outListData は + * Scheduler の持つ、使い回しの buffer ではなく + * 新たに allocate されたものなので、ここで free する + */ +SchedTask::~SchedTask(void) +{ + if (__flag_renewTask == SCHED_TASK_RENEW) { + free(__inListData); + free(__outListData); + + /** + * __list != NULL の場合、 + * この Task が __list の最後の Task になるので (SchedTask::next 参照) + * このタイミングで __list を解放する + * (free に渡されるアドレスが正しいものとなる)。 + * それ以外の Task では当然解放しない。 + * __list == NULL なので、free に渡しても無問題 + */ + free(__list); + } + + delete smanager; +} + +/** + * このタスクを Renew Task とし、それに応じた関数をセットする + */ +void +SchedTask::__setRenew(void) +{ + __flag_renewTask = SCHED_TASK_RENEW; + + ex_init = &SchedTask::ex_init_renew; + ex_read = &SchedTask::ex_read_renew; + ex_exec = &SchedTask::ex_exec_renew; + ex_write = &SchedTask::ex_write_renew; + ex_next = &SchedTask::ex_next_renew; +} + +void +SchedTask::__init__(TaskListPtr _list, TaskPtr _task, int index, + ListDataPtr rbuf, ListDataPtr wbuf, Scheduler* sc) +{ + __list = _list; + __task = _task; + __inListData = rbuf; + __outListData = wbuf; + __scheduler = sc; + __cur_index = index; + + smanager = new STaskManager(this); + + __scheduler->mainMem_wait(); + + (this->*ex_init)(); +} + +/** + * PPE 内で生成されたタスクの ex_init() + */ +void +SchedTask::ex_init_normal(void) +{ + __scheduler->dma_load(__inListData, (uint32)__task->inData, + sizeof(ListData), DMA_READ_IN_LIST); + __scheduler->dma_load(__outListData, (uint32)__task->outData, + sizeof(ListData), DMA_READ_OUT_LIST); +#if defined(NO_PIPELINE) + __scheduler->dma_wait(DMA_READ_IN_LIST); + __scheduler->dma_wait(DMA_READ_OUT_LIST); +#endif + + __taskGroup = new TaskGroup; + __taskGroup->command = __task->self; +} + +/** + * SPE 内で生成されたタスクの ex_init() + * 各データは SPE 内の create_task 時に生成もしくは引き継がれているので + * ex_init_normal() と違い、ここでは値を渡すだけ + */ +void +SchedTask::ex_init_renew(void) +{ + __inListData = __task->inData; + __outListData = __task->outData; + __taskGroup = (TaskGroupPtr)__task->self; +} + +/** + * [Todo] + * データの読み込み場所を readbuf ではなく、 + * ユーザ自身で決めれるようになるといいかもしれない。 + * + * # TaskManager が勝手に消すことなく、 + * # ユーザが SPE 上に持ち続けることができるため。 + * # もちろん管理はユーザに任せるわけだ。 + */ +void +SchedTask::read(void) +{ + __debug("[SchedTask:%s]\n", __FUNCTION__); + +#if !defined(NO_PIPELINE) + __scheduler->dma_wait(DMA_READ_IN_LIST); + __scheduler->dma_wait(DMA_READ_OUT_LIST); +#endif + + __writebuf = __scheduler->allocate(__outListData->size); + + // 読むデータが一つもなければ無視 + if (__inListData->length == 0) return; + + // load Input Data + __readbuf = __scheduler->allocate(__inListData->size); + __scheduler->dma_loadList(__inListData, __readbuf, DMA_READ); + +#if defined(NO_PIPELINE) + __scheduler->dma_wait(DMA_READ); +#endif + + (this->*ex_read)(); +} + +void +SchedTask::exec(void) +{ + __debug("[SchedTask:%s]\n", __FUNCTION__); + +#if !defined(NO_PIPELINE) + __scheduler->dma_wait(DMA_READ); +#endif + + //run(__readbuf, __writebuf); + (this->*run_func)(__readbuf, __writebuf); + + free(__readbuf); + + if (__taskGroup->status() != 0) { + __task->self = __taskGroup->command; + delete __taskGroup; + __taskGroup = NULL; + } + + + // 書き込む領域がなければ無視 + if (__outListData->length > 0) { + __scheduler->dma_storeList(__outListData, __writebuf, DMA_WRITE); + +#if defined(NO_PIPELINE) + __scheduler->dma_wait(DMA_WRITE); + free(__writebuf); +#endif + } + + (this->*ex_exec)(); +} + +void +SchedTask::write(void) +{ + __debug("[SchedTask:%s]\n", __FUNCTION__); + +#if !defined(NO_PIPELINE) + __scheduler->dma_wait(DMA_WRITE); + free(__writebuf); +#endif + + if (__task->self == MY_SPE_NOP) return; + + (this->*ex_write)(); +} + +/** + * PPE 内で生成されたタスクの ex_read() + */ +void +SchedTask::ex_read_normal(void) +{ +} + +/** + * SPE 内で生成されたタスクの ex_read() + */ +void +SchedTask::ex_read_renew(void) +{ +} + +/** + * PPE 内で生成されたタスクの ex_exec() + */ +void +SchedTask::ex_exec_normal(void) +{ +} + +/** + * SPE 内で生成されたタスクの ex_exec() + */ +void +SchedTask::ex_exec_renew(void) +{ +} + + + +/** + * PPE 内で生成されたタスクの ex_write() + * + * このタスク内で新たにタスクが生成され、 + * 且つそのタスクの終了を待つ必要がある場合、 + * PPE に終了したことは知らせない(command は送信しない) + */ +void +SchedTask::ex_write_normal(void) +{ + /** + * このタスク内で新たにタスクが生成されなかった + * or 生成されたが、そのタスクの終了を待つ必要は無い + */ + if (__renew_flag == 0) { + __scheduler->mail_write(__task->self); + } } +/** + * SPE 内で生成されたタスクの ex_write() + * + * A <- 親タスク + * | \ + * B C <- SPE 内で生成されたタスク + * + * A は SPE 内で B, C を生成したとする。 + * B と C が終了したら、A が PPE に送るはずだったコマンドが + * 子タスクに引き継がれているので、最後に実行された子タスクが + * PPE に mail 送信する。 + */ +void +SchedTask::ex_write_renew(void) +{ + uint32 cmd; + + __taskGroup->remove(__task); + cmd = __taskGroup->status(); + + // タスク内で作られた全てのタスクが終了した + if (cmd != 0) { + delete __taskGroup; + __scheduler->mail_write(cmd); + } +} + +SchedTaskBase* +SchedTask::next(Scheduler *m, SchedTaskBase *p) +{ + __debug("[SchedTask:%s]\n", __FUNCTION__); + + delete p; + + return (this->*ex_next)(); +} + +SchedTaskBase* +SchedTask::ex_next_normal(void) +{ + if (__cur_index < __list->length) { + SchedTaskBase *nextSched; + + nextSched = __scheduler->get_nextRenewTaskList(); + + // RenewTask がある + if (nextSched) { + __scheduler->set_backupTaskList(__list); + __scheduler->set_backupTaskListIndex(__cur_index); + return nextSched; + } else { + TaskPtr nextTask = &__list->tasks[__cur_index++]; + nextSched = createSchedTask(nextTask); + ((SchedTask*)nextSched)->__init__(__list, nextTask, __cur_index, + __scheduler->get_curReadBuf(), + __scheduler->get_curWriteBuf(), + __scheduler); + return nextSched; + } + } else { + uint32 nextList = (uint32)__list->next; + + if (nextList == 0) { + return new SchedNop2Ready(__scheduler); + } else { + return createSchedTaskList(nextList, __scheduler, + SCHED_TASKLIST_NORMAL); + } + } +} + +/** + * + */ +SchedTaskBase* +SchedTask::ex_next_renew(void) +{ + TaskPtr nextTask; + SchedTask *nextSched; + + if (__cur_index < __list->length) { + nextTask = &__list->tasks[__cur_index++]; + nextSched = createSchedTask(nextTask); + + // RenewTaskList を実行中なので + nextSched->__setRenew(); + nextSched->__init__(__list, nextTask, __cur_index, + __scheduler->get_curReadBuf(), + __scheduler->get_curWriteBuf(), + __scheduler); + + /** + * この理由は SchedTask:~SchedTask() で + */ + __list = NULL; + return nextSched; + } else { + SchedTaskBase *nextList; + + nextList = __scheduler->get_nextRenewTaskList(); + + if (nextList) { + return nextList; + } else { + TaskListPtr nextList = __scheduler->get_backupTaskList(); + + // 中断した TaskList がある + if (nextList) { + __cur_index = __scheduler->get_backupTaskListIndex(); + + nextTask = &nextList->tasks[__cur_index++]; + nextSched = createSchedTask(nextTask); + + nextSched->__init__(nextList, nextTask, __cur_index, + __scheduler->get_curReadBuf(), + __scheduler->get_curWriteBuf(), + __scheduler); + return nextSched; + } else { + return new SchedNop2Ready(__scheduler); + } + } + } +} + +int +SchedTask::get_cpuid(void) +{ + return __scheduler->id; +} + +/** + * task->add_inData で与えられた順番に対応する index (0〜n-1) で、 + * buffer から対応するデータを返す。 + */ +void* +SchedTask::get_input(void *buff, int index) +{ + if (buff != NULL) { + return (void*)((int)buff + __inListData->bound[index]); + } else { + return NULL; + } +} + +/** + * get_input(index) のアドレスを返す + */ +uint32 +SchedTask::get_inputAddr(int index) +{ + return __inListData->element[index].addr; +} + +/** + * get_input(index) のサイズを返す + */ +int +SchedTask::get_inputSize(int index) +{ + return __inListData->element[index].size; +} + +/** + * write buffer の領域を返す。 + */ +void* +SchedTask::get_output(void *buff, int index) +{ + if (buff != NULL) { + return (void*)((int)buff + __outListData->bound[index]); + } else { + return NULL; + } +} + +/** + * get_output(index) のアドレスを返す + */ +uint32 +SchedTask::get_outputAddr(int index) +{ + return __outListData->element[index].addr; +} + +/** + * get_output(index) のサイズを返す + */ +int +SchedTask::get_outputSize(int index) +{ + return __outListData->element[index].size; +} + +int +SchedTask::get_param(int index) +{ + return __task->param[index]; +} + +TaskPtr +SchedTask::create_task(int cmd) +{ + TaskListPtr taskList = __scheduler->get_renewListBuf(); + TaskPtr p = &taskList->tasks[taskList->length++]; + p->command = cmd; + + p->inData = (ListData*)__scheduler->allocate(sizeof(ListData)); + p->outData = (ListData*)__scheduler->allocate(sizeof(ListData)); + + p->inData->clear(); + p->outData->clear(); + + p->self = MY_SPE_NOP; + p->param_size = 0; + + return p; +} + +/** + * 生成したタスクが終了してから、メインスケジューラ(PPE) に + * タスクが終了した旨を知らせる。 + * + * @param[in] waitTask タスク内で生成したタスク + */ +void +SchedTask::wait_task(TaskPtr waitTask) +{ + waitTask->self = (uint32)__taskGroup; + + __scheduler->add_groupTask(__taskGroup, waitTask); + + __renew_flag++; +} + +void* +SchedTask::global_alloc(int id, int size) { + return __scheduler->global_alloc(id, size); +} + +void* +SchedTask::global_get(int id) { + return __scheduler->global_get(id); +} + +void +SchedTask::global_free(int id) { + __scheduler->global_free(id); +} + +void +SchedTask::mainMem_alloc(int id, int size) { + __scheduler->mainMem_alloc(id, size); +} + +void +SchedTask::mainMem_wait(void) { + __scheduler->mainMem_wait(); +} + +void* +SchedTask::mainMem_get(int id) { + return __scheduler->mainMem_get(id); +} + +void* +SchedTask::allocate(int size) { + return __scheduler->allocate(size); +} + +void +SchedTask::dma_load(void *buf, uint32 addr, uint32 size, uint32 mask) { + __scheduler->dma_load(buf, addr, size, mask); +} + +void +SchedTask::dma_store(void *buf,uint32 addr, uint32 size, uint32 mask) { + __scheduler->dma_store(buf, addr, size, mask); +} + +void +SchedTask::dma_wait(uint32 mask) { + __scheduler->dma_wait(mask); +} + +/* end */
--- a/TaskManager/kernel/schedule/SchedTaskImpl.cc Mon Jun 08 19:32:38 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,559 +0,0 @@ -#include <stdlib.h> -#include <string.h> -#include "SchedTaskImpl.h" -#include "SchedTask.h" -#include "SchedTaskList.h" -#include "SchedNop2Ready.h" -#include "DmaManager.h" -#include "error.h" -#include "TaskManager.h" - -extern Scheduler::TaskObject task_list[MAX_TASK_OBJECT]; - -//#define NO_PIPELINE - -SchedTask * -createSchedTask(TaskPtr task) -{ - return task_list[task->command](); -} - - -SchedTaskImpl::SchedTaskImpl() -{ - __list = NULL; - __task = NULL; - __inListData = NULL; - __outListData = NULL; - __readbuf = NULL; - __writebuf = NULL; - __scheduler = NULL; - __taskGroup = NULL; - __renew_flag = 0; - __cur_index = 0; - __flag_renewTask = SCHED_TASK_NORMAL; - - ex_init = &SchedTaskImpl::ex_init_normal; - ex_read = &SchedTaskImpl::ex_read_normal; - ex_exec = &SchedTaskImpl::ex_exec_normal; - ex_write = &SchedTaskImpl::ex_write_normal; - ex_next = &SchedTaskImpl::ex_next_normal; - - run_func = &SchedTaskImpl::run; -} - -/** - * dma_store の wait を行う - * このタスクが RenewTask だった場合、 - * __inListData や __outListData は - * Scheduler の持つ、使い回しの buffer ではなく - * 新たに allocate されたものなので、ここで free する - */ -SchedTaskImpl::~SchedTaskImpl(void) -{ - if (__flag_renewTask == SCHED_TASK_RENEW) { - free(__inListData); - free(__outListData); - - /** - * __list != NULL の場合、 - * この Task が __list の最後の Task になるので (SchedTaskImpl::next 参照) - * このタイミングで __list を解放する - * (free に渡されるアドレスが正しいものとなる)。 - * それ以外の Task では当然解放しない。 - * __list == NULL なので、free に渡しても無問題 - */ - free(__list); - } - - delete smanager; -} - -/** - * このタスクを Renew Task とし、それに応じた関数をセットする - */ -void -SchedTaskImpl::__setRenew(void) -{ - __flag_renewTask = SCHED_TASK_RENEW; - - ex_init = &SchedTaskImpl::ex_init_renew; - ex_read = &SchedTaskImpl::ex_read_renew; - ex_exec = &SchedTaskImpl::ex_exec_renew; - ex_write = &SchedTaskImpl::ex_write_renew; - ex_next = &SchedTaskImpl::ex_next_renew; -} - -void -SchedTaskImpl::__init__(TaskListPtr _list, TaskPtr _task, int index, - ListDataPtr rbuf, ListDataPtr wbuf, Scheduler* sc) -{ - __list = _list; - __task = _task; - __inListData = rbuf; - __outListData = wbuf; - __scheduler = sc; - __cur_index = index; - - smanager = new STaskManager(this); - - __scheduler->mainMem_wait(); - - (this->*ex_init)(); -} - -/** - * PPE 内で生成されたタスクの ex_init() - */ -void -SchedTaskImpl::ex_init_normal(void) -{ - __scheduler->dma_load(__inListData, (uint32)__task->inData, - sizeof(ListData), DMA_READ_IN_LIST); - __scheduler->dma_load(__outListData, (uint32)__task->outData, - sizeof(ListData), DMA_READ_OUT_LIST); -#if defined(NO_PIPELINE) - __scheduler->dma_wait(DMA_READ_IN_LIST); - __scheduler->dma_wait(DMA_READ_OUT_LIST); -#endif - - __taskGroup = new TaskGroup; - __taskGroup->command = __task->self; -} - -/** - * SPE 内で生成されたタスクの ex_init() - * 各データは SPE 内の create_task 時に生成もしくは引き継がれているので - * ex_init_normal() と違い、ここでは値を渡すだけ - */ -void -SchedTaskImpl::ex_init_renew(void) -{ - __inListData = __task->inData; - __outListData = __task->outData; - __taskGroup = (TaskGroupPtr)__task->self; -} - -/** - * [Todo] - * データの読み込み場所を readbuf ではなく、 - * ユーザ自身で決めれるようになるといいかもしれない。 - * - * # TaskManager が勝手に消すことなく、 - * # ユーザが SPE 上に持ち続けることができるため。 - * # もちろん管理はユーザに任せるわけだ。 - */ -void -SchedTaskImpl::read(void) -{ - __debug("[SchedTask:%s]\n", __FUNCTION__); - -#if !defined(NO_PIPELINE) - __scheduler->dma_wait(DMA_READ_IN_LIST); - __scheduler->dma_wait(DMA_READ_OUT_LIST); -#endif - - __writebuf = __scheduler->allocate(__outListData->size); - - // 読むデータが一つもなければ無視 - if (__inListData->length == 0) return; - - // load Input Data - __readbuf = __scheduler->allocate(__inListData->size); - __scheduler->dma_loadList(__inListData, __readbuf, DMA_READ); - -#if defined(NO_PIPELINE) - __scheduler->dma_wait(DMA_READ); -#endif - - (this->*ex_read)(); -} - -void -SchedTaskImpl::exec(void) -{ - __debug("[SchedTask:%s]\n", __FUNCTION__); - -#if !defined(NO_PIPELINE) - __scheduler->dma_wait(DMA_READ); -#endif - - //run(__readbuf, __writebuf); - (this->*run_func)(__readbuf, __writebuf); - - free(__readbuf); - - if (__taskGroup->status() != 0) { - __task->self = __taskGroup->command; - delete __taskGroup; - __taskGroup = NULL; - } - - - // 書き込む領域がなければ無視 - if (__outListData->length > 0) { - __scheduler->dma_storeList(__outListData, __writebuf, DMA_WRITE); - -#if defined(NO_PIPELINE) - __scheduler->dma_wait(DMA_WRITE); - free(__writebuf); -#endif - } - - (this->*ex_exec)(); -} - -void -SchedTaskImpl::write(void) -{ - __debug("[SchedTask:%s]\n", __FUNCTION__); - -#if !defined(NO_PIPELINE) - __scheduler->dma_wait(DMA_WRITE); - free(__writebuf); -#endif - - if (__task->self == MY_SPE_NOP) return; - - (this->*ex_write)(); -} - -/** - * PPE 内で生成されたタスクの ex_read() - */ -void -SchedTaskImpl::ex_read_normal(void) -{ -} - -/** - * SPE 内で生成されたタスクの ex_read() - */ -void -SchedTaskImpl::ex_read_renew(void) -{ -} - -/** - * PPE 内で生成されたタスクの ex_exec() - */ -void -SchedTaskImpl::ex_exec_normal(void) -{ -} - -/** - * SPE 内で生成されたタスクの ex_exec() - */ -void -SchedTaskImpl::ex_exec_renew(void) -{ -} - - - -/** - * PPE 内で生成されたタスクの ex_write() - * - * このタスク内で新たにタスクが生成され、 - * 且つそのタスクの終了を待つ必要がある場合、 - * PPE に終了したことは知らせない(command は送信しない) - */ -void -SchedTaskImpl::ex_write_normal(void) -{ - /** - * このタスク内で新たにタスクが生成されなかった - * or 生成されたが、そのタスクの終了を待つ必要は無い - */ - if (__renew_flag == 0) { - __scheduler->mail_write(__task->self); - } -} - -/** - * SPE 内で生成されたタスクの ex_write() - * - * A <- 親タスク - * | \ - * B C <- SPE 内で生成されたタスク - * - * A は SPE 内で B, C を生成したとする。 - * B と C が終了したら、A が PPE に送るはずだったコマンドが - * 子タスクに引き継がれているので、最後に実行された子タスクが - * PPE に mail 送信する。 - */ -void -SchedTaskImpl::ex_write_renew(void) -{ - uint32 cmd; - - __taskGroup->remove(__task); - cmd = __taskGroup->status(); - - // タスク内で作られた全てのタスクが終了した - if (cmd != 0) { - delete __taskGroup; - __scheduler->mail_write(cmd); - } -} - -SchedTaskBase* -SchedTaskImpl::next(Scheduler *m, SchedTaskBase *p) -{ - __debug("[SchedTask:%s]\n", __FUNCTION__); - - delete p; - - return (this->*ex_next)(); -} - -SchedTaskBase* -SchedTaskImpl::ex_next_normal(void) -{ - if (__cur_index < __list->length) { - SchedTaskBase *nextSched; - - nextSched = __scheduler->get_nextRenewTaskList(); - - // RenewTask がある - if (nextSched) { - __scheduler->set_backupTaskList(__list); - __scheduler->set_backupTaskListIndex(__cur_index); - return nextSched; - } else { - TaskPtr nextTask = &__list->tasks[__cur_index++]; - nextSched = createSchedTask(nextTask); - ((SchedTask*)nextSched)->__init__(__list, nextTask, __cur_index, - __scheduler->get_curReadBuf(), - __scheduler->get_curWriteBuf(), - __scheduler); - return nextSched; - } - } else { - uint32 nextList = (uint32)__list->next; - - if (nextList == 0) { - return new SchedNop2Ready(__scheduler); - } else { - return createSchedTaskList(nextList, __scheduler, - SCHED_TASKLIST_NORMAL); - } - } -} - -/** - * - */ -SchedTaskBase* -SchedTaskImpl::ex_next_renew(void) -{ - TaskPtr nextTask; - SchedTask *nextSched; - - if (__cur_index < __list->length) { - nextTask = &__list->tasks[__cur_index++]; - nextSched = createSchedTask(nextTask); - - // RenewTaskList を実行中なので - nextSched->__setRenew(); - nextSched->__init__(__list, nextTask, __cur_index, - __scheduler->get_curReadBuf(), - __scheduler->get_curWriteBuf(), - __scheduler); - - /** - * この理由は SchedTask:~SchedTask() で - */ - __list = NULL; - return nextSched; - } else { - SchedTaskBase *nextList; - - nextList = __scheduler->get_nextRenewTaskList(); - - if (nextList) { - return nextList; - } else { - TaskListPtr nextList = __scheduler->get_backupTaskList(); - - // 中断した TaskList がある - if (nextList) { - __cur_index = __scheduler->get_backupTaskListIndex(); - - nextTask = &nextList->tasks[__cur_index++]; - nextSched = createSchedTask(nextTask); - - nextSched->__init__(nextList, nextTask, __cur_index, - __scheduler->get_curReadBuf(), - __scheduler->get_curWriteBuf(), - __scheduler); - return nextSched; - } else { - return new SchedNop2Ready(__scheduler); - } - } - } -} - -int -SchedTaskImpl::get_cpuid(void) -{ - return __scheduler->id; -} - -/** - * task->add_inData で与えられた順番に対応する index (0〜n-1) で、 - * buffer から対応するデータを返す。 - */ -void* -SchedTaskImpl::get_input(void *buff, int index) -{ - if (buff != NULL) { - return (void*)((int)buff + __inListData->bound[index]); - } else { - return NULL; - } -} - -/** - * get_input(index) のアドレスを返す - */ -uint32 -SchedTaskImpl::get_inputAddr(int index) -{ - return __inListData->element[index].addr; -} - -/** - * get_input(index) のサイズを返す - */ -int -SchedTaskImpl::get_inputSize(int index) -{ - return __inListData->element[index].size; -} - -/** - * write buffer の領域を返す。 - */ -void* -SchedTaskImpl::get_output(void *buff, int index) -{ - if (buff != NULL) { - return (void*)((int)buff + __outListData->bound[index]); - } else { - return NULL; - } -} - -/** - * get_output(index) のアドレスを返す - */ -uint32 -SchedTaskImpl::get_outputAddr(int index) -{ - return __outListData->element[index].addr; -} - -/** - * get_output(index) のサイズを返す - */ -int -SchedTaskImpl::get_outputSize(int index) -{ - return __outListData->element[index].size; -} - -int -SchedTaskImpl::get_param(int index) -{ - return __task->param[index]; -} - -TaskPtr -SchedTaskImpl::create_task(int cmd) -{ - TaskListPtr taskList = __scheduler->get_renewListBuf(); - TaskPtr p = &taskList->tasks[taskList->length++]; - p->command = cmd; - - p->inData = (ListData*)__scheduler->allocate(sizeof(ListData)); - p->outData = (ListData*)__scheduler->allocate(sizeof(ListData)); - - p->inData->clear(); - p->outData->clear(); - - p->self = MY_SPE_NOP; - p->param_size = 0; - - return p; -} - -/** - * 生成したタスクが終了してから、メインスケジューラ(PPE) に - * タスクが終了した旨を知らせる。 - * - * @param[in] waitTask タスク内で生成したタスク - */ -void -SchedTaskImpl::wait_task(TaskPtr waitTask) -{ - waitTask->self = (uint32)__taskGroup; - - __scheduler->add_groupTask(__taskGroup, waitTask); - - __renew_flag++; -} - -void* -SchedTaskImpl::global_alloc(int id, int size) { - return __scheduler->global_alloc(id, size); -} - -void* -SchedTaskImpl::global_get(int id) { - return __scheduler->global_get(id); -} - -void -SchedTaskImpl::global_free(int id) { - __scheduler->global_free(id); -} - -void -SchedTaskImpl::mainMem_alloc(int id, int size) { - __scheduler->mainMem_alloc(id, size); -} - -void -SchedTaskImpl::mainMem_wait(void) { - __scheduler->mainMem_wait(); -} - -void* -SchedTaskImpl::mainMem_get(int id) { - return __scheduler->mainMem_get(id); -} - -void* -SchedTaskImpl::allocate(int size) { - return __scheduler->allocate(size); -} - -void -SchedTaskImpl::dma_load(void *buf, uint32 addr, uint32 size, uint32 mask) { - __scheduler->dma_load(buf, addr, size, mask); -} - -void -SchedTaskImpl::dma_store(void *buf,uint32 addr, uint32 size, uint32 mask) { - __scheduler->dma_store(buf, addr, size, mask); -} - -void -SchedTaskImpl::dma_wait(uint32 mask) { - __scheduler->dma_wait(mask); -} - -/* end */
--- a/include/TaskManager/SchedTask.h Mon Jun 08 19:32:38 2009 +0900 +++ b/include/TaskManager/SchedTask.h Mon Jun 08 19:36:48 2009 +0900 @@ -1,26 +1,236 @@ #ifndef INCLUDED_SCHED_TASK #define INCLUDED_SCHED_TASK -#include "SchedTaskImpl.h" - -class SchedTask : public SchedTaskImpl { -public: +#include "base.h" +#include "Scheduler.h" +#include "SchedTaskBase.h" +#include "ListData.h" +#include "TaskGroup.h" - /* variables */ - - virtual ~SchedTask() { - } - +class SchedTask : public SchedTaskBase { +public: /* constructor */ + SchedTask(); + virtual ~SchedTask(); BASE_NEW_DELETE(SchedTask); +private: + /* variables */ + + // Task を実行するスケジューラ自身 + Scheduler *__scheduler; + + // 現在スケジューラが実行している TaskList と、このタスクに対応する Task + TaskListPtr __list; + TaskPtr __task; + + // read/write 用の ListData + ListDataPtr __inListData; + ListDataPtr __outListData; + + /** + * read データ、write 用のバッファ + * readbuf には タスク登録時に設定した入力データが入っている。 + * writebuf にデータを描き込んでおくと、 + * タスク登録時に設定した出力先に書き込む + */ + void *__readbuf; + void *__writebuf; + + // Task の、Tasklist での位置。(task = &list[cur_index-1]) + int __cur_index; + + // タスク内で生成されたタスクのグループ + TaskGroup *__taskGroup; + + // このタスク内で生成されたタスクの数 + int __renew_flag; + + // このタスクが SPE 内で生成されたタスクか否か 1: Yes, 0: No + int __flag_renewTask; + + // タスクがメインメモリ側で生成されたものか、 + // SPE で生成されたものかによって、データの扱いが変わってくる。 + // そのために if (__flag_renewTask) を連発するのはよくないので + // 関数ポインタで持っておく + void (SchedTask::*ex_init)(); + void (SchedTask::*ex_read)(); + void (SchedTask::*ex_exec)(); + void (SchedTask::*ex_write)(); + SchedTaskBase* (SchedTask::*ex_next)(); + + /* functions */ + + // override + void read(); + void exec(); + void write(); + SchedTaskBase* next(Scheduler *, SchedTaskBase *); + // ここをユーザが継承して // それぞれのタスクに対応した処理を記述する - virtual int run(void* r, void *w) { return 0;} + virtual int run(void* r, void *w) { return 0; } + + int (SchedTask::*run_func)(void* r, void *w); + + //--- System API --- + SchedTask* get_nextTask(TaskListPtr list); + + /** + * PPE で生成されたタスクに対する + * __init__, read,exec,write,next の付属(?)処理 + */ + void ex_init_normal(); + void ex_read_normal(); + void ex_exec_normal(); + void ex_write_normal(); + SchedTaskBase* ex_next_normal(); + + /** + * SPE で生成されたタスクに対する + * __inti__, ead,exec,write,next の付属(?)処理 + */ + void ex_init_renew(); + void ex_read_renew(); + void ex_exec_renew(); + void ex_write_renew(); + SchedTaskBase* ex_next_renew(); + +public: + /* functions */ + + void __setRenew(); + void __init__(TaskListPtr _list, TaskPtr _task, int index, + ListDataPtr rbuf, ListDataPtr wbuf, Scheduler* sc); + + //--- User API --- + int get_cpuid(); + + void* get_input(void *buff, int index); + void* get_output(void *buff, int index); + uint32 get_inputAddr(int index); + uint32 get_outputAddr(int index); + int get_inputSize(int index); + int get_outputSize(int index); + int get_param(int index); + + TaskPtr create_task(int cmd); + void wait_task(TaskPtr waitTask); + + void* global_alloc(int id, int size); + void* global_get(int id); + void global_free(int id); + + void mainMem_alloc(int id, int size); + void mainMem_wait(); + void* mainMem_get(int id); + + void *allocate(int size); + + void dma_load(void *buf, uint32 addr, uint32 size, uint32 mask); + void dma_store(void *buf,uint32 addr, uint32 size, uint32 mask); + void dma_wait(uint32 mask); + +private: + class STaskManager { + public: + STaskManager(SchedTask *_t) { + outer = _t; + } + + BASE_NEW_DELETE(STaskManager); + + SchedTask *outer; + int get_cpuid() { + return outer->get_cpuid(); + } + + void* get_input(int index) { + return outer->get_input(outer->__readbuf, index); + } + + void* get_output(int index) { + return outer->get_output(outer->__writebuf, index); + } + + uint32 get_inputAddr(int index) { + return outer->get_inputAddr(index); + } + + uint32 get_outputAddr(int index) { + return outer->get_outputAddr(index); + } + + uint32 get_inputSize(int index) { + return outer->get_inputSize(index); + } + + uint32 get_outputSize(int index) { + return outer->get_outputSize(index); + } + + int get_param(int index) { + return outer->get_param(index); + } + + TaskPtr create_task(int cmd) { + return outer->create_task(cmd); + } + + void wait_task(TaskPtr waitTask) { + outer->wait_task(waitTask); + } + + void* global_alloc(int id, int size) { + return outer->global_alloc(id, size); + } + + void* global_get(int id) { + return outer->global_get(id); + } + + void global_free(int id) { + outer->global_free(id); + } + + void mainMem_alloc(int id, int size) { + outer->mainMem_alloc(id, size); + } + + void mainMem_wait() { + outer->mainMem_wait(); + } + + void* mainMem_get(int id) { + return outer->mainMem_get(id); + } + + void *allocate(int size) { + return outer->allocate(size); + } + + void dma_load(void *buf, uint32 addr, uint32 size, uint32 mask) { + outer->dma_load(buf, addr, size, mask); + } + + void dma_store(void *buf,uint32 addr, uint32 size, uint32 mask) { + outer->dma_store(buf, addr, size, mask); + } + + void dma_wait(uint32 mask) { + outer->dma_wait(mask); + } + }; + + STaskManager *smanager; }; +const int SCHED_TASK_NORMAL = 0; +const int SCHED_TASK_RENEW = 1; + extern SchedTask* createSchedTask(TaskPtr); #endif +
--- a/include/TaskManager/SchedTaskImpl.h Mon Jun 08 19:32:38 2009 +0900 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,236 +0,0 @@ -#ifndef INCLUDED_SCHED_TASK_IMPL -#define INCLUDED_SCHED_TASK_IMPL - -#include "base.h" -#include "Scheduler.h" -#include "SchedTaskBase.h" -#include "ListData.h" -#include "TaskGroup.h" - -class SchedTaskImpl : public SchedTaskBase { -public: - /* constructor */ - SchedTaskImpl(); - virtual ~SchedTaskImpl(); - - BASE_NEW_DELETE(SchedTask); - -private: - /* variables */ - - // Task を実行するスケジューラ自身 - Scheduler *__scheduler; - - // 現在スケジューラが実行している TaskList と、このタスクに対応する Task - TaskListPtr __list; - TaskPtr __task; - - // read/write 用の ListData - ListDataPtr __inListData; - ListDataPtr __outListData; - - /** - * read データ、write 用のバッファ - * readbuf には タスク登録時に設定した入力データが入っている。 - * writebuf にデータを描き込んでおくと、 - * タスク登録時に設定した出力先に書き込む - */ - void *__readbuf; - void *__writebuf; - - // Task の、Tasklist での位置。(task = &list[cur_index-1]) - int __cur_index; - - // タスク内で生成されたタスクのグループ - TaskGroup *__taskGroup; - - // このタスク内で生成されたタスクの数 - int __renew_flag; - - // このタスクが SPE 内で生成されたタスクか否か 1: Yes, 0: No - int __flag_renewTask; - - // タスクがメインメモリ側で生成されたものか、 - // SPE で生成されたものかによって、データの扱いが変わってくる。 - // そのために if (__flag_renewTask) を連発するのはよくないので - // 関数ポインタで持っておく - void (SchedTaskImpl::*ex_init)(); - void (SchedTaskImpl::*ex_read)(); - void (SchedTaskImpl::*ex_exec)(); - void (SchedTaskImpl::*ex_write)(); - SchedTaskBase* (SchedTaskImpl::*ex_next)(); - - /* functions */ - - // override - void read(); - void exec(); - void write(); - SchedTaskBase* next(Scheduler *, SchedTaskBase *); - - // ここをユーザが継承して - // それぞれのタスクに対応した処理を記述する - virtual int run(void* r, void *w) { return 0; } - - int (SchedTaskImpl::*run_func)(void* r, void *w); - - //--- System API --- - SchedTaskImpl* get_nextTask(TaskListPtr list); - - /** - * PPE で生成されたタスクに対する - * __init__, read,exec,write,next の付属(?)処理 - */ - void ex_init_normal(); - void ex_read_normal(); - void ex_exec_normal(); - void ex_write_normal(); - SchedTaskBase* ex_next_normal(); - - /** - * SPE で生成されたタスクに対する - * __inti__, ead,exec,write,next の付属(?)処理 - */ - void ex_init_renew(); - void ex_read_renew(); - void ex_exec_renew(); - void ex_write_renew(); - SchedTaskBase* ex_next_renew(); - -public: - /* functions */ - - void __setRenew(); - void __init__(TaskListPtr _list, TaskPtr _task, int index, - ListDataPtr rbuf, ListDataPtr wbuf, Scheduler* sc); - - //--- User API --- - int get_cpuid(); - - void* get_input(void *buff, int index); - void* get_output(void *buff, int index); - uint32 get_inputAddr(int index); - uint32 get_outputAddr(int index); - int get_inputSize(int index); - int get_outputSize(int index); - int get_param(int index); - - TaskPtr create_task(int cmd); - void wait_task(TaskPtr waitTask); - - void* global_alloc(int id, int size); - void* global_get(int id); - void global_free(int id); - - void mainMem_alloc(int id, int size); - void mainMem_wait(); - void* mainMem_get(int id); - - void *allocate(int size); - - void dma_load(void *buf, uint32 addr, uint32 size, uint32 mask); - void dma_store(void *buf,uint32 addr, uint32 size, uint32 mask); - void dma_wait(uint32 mask); - -private: - class STaskManager { - public: - STaskManager(SchedTaskImpl *_t) { - outer = _t; - } - - BASE_NEW_DELETE(STaskManager); - - SchedTaskImpl *outer; - - int get_cpuid() { - return outer->get_cpuid(); - } - - void* get_input(int index) { - return outer->get_input(outer->__readbuf, index); - } - - void* get_output(int index) { - return outer->get_output(outer->__writebuf, index); - } - - uint32 get_inputAddr(int index) { - return outer->get_inputAddr(index); - } - - uint32 get_outputAddr(int index) { - return outer->get_outputAddr(index); - } - - uint32 get_inputSize(int index) { - return outer->get_inputSize(index); - } - - uint32 get_outputSize(int index) { - return outer->get_outputSize(index); - } - - int get_param(int index) { - return outer->get_param(index); - } - - TaskPtr create_task(int cmd) { - return outer->create_task(cmd); - } - - void wait_task(TaskPtr waitTask) { - outer->wait_task(waitTask); - } - - void* global_alloc(int id, int size) { - return outer->global_alloc(id, size); - } - - void* global_get(int id) { - return outer->global_get(id); - } - - void global_free(int id) { - outer->global_free(id); - } - - void mainMem_alloc(int id, int size) { - outer->mainMem_alloc(id, size); - } - - void mainMem_wait() { - outer->mainMem_wait(); - } - - void* mainMem_get(int id) { - return outer->mainMem_get(id); - } - - void *allocate(int size) { - return outer->allocate(size); - } - - void dma_load(void *buf, uint32 addr, uint32 size, uint32 mask) { - outer->dma_load(buf, addr, size, mask); - } - - void dma_store(void *buf,uint32 addr, uint32 size, uint32 mask) { - outer->dma_store(buf, addr, size, mask); - } - - void dma_wait(uint32 mask) { - outer->dma_wait(mask); - } - }; - - STaskManager *smanager; -}; - -const int SCHED_TASK_NORMAL = 0; -const int SCHED_TASK_RENEW = 1; - -extern SchedTask* createSchedTaskImpl(TaskPtr); - -#endif -