Mercurial > hg > Game > Cerium
view TaskManager/kernel/schedule/SchedTask.cc @ 180:e3b7776b1420 draft
いろいろ fix 。詳しくは TaskManager/Changelog、test_render/Changelog を
author | gongo@localhost.localdomain |
---|---|
date | Mon, 22 Dec 2008 16:09:57 +0900 |
parents | 028ffc9c0375 |
children | 8e9ada0c1ed0 |
line wrap: on
line source
#include <stdlib.h> #include <string.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]; SchedTask* CreateSchedTask(TaskListPtr taskList, Scheduler *sched) { TaskPtr task = &taskList->tasks[sched->curIndex_taskList++]; return task_list[task->command](taskList, task, sched->get_curReadBuf(), sched->get_curWriteBuf(), sched); } SchedTask::SchedTask(TaskListPtr _list, TaskPtr _task, ListDataPtr rbuf, ListDataPtr wbuf, Scheduler* sc) { __list = _list; __task = _task; __inListData = rbuf; __outListData = wbuf; __readbuf = NULL; __writebuf = NULL; __scheduler = sc; __taskGroup = NULL; __renew_flag = 0; smanager = new STaskManager(this); } SchedTask::~SchedTask(void) { if (__flag_renewTask) { /** * __inListData __outListData ϥȤΤΤʤΤ * ä¨ free 롣 */ free(__inListData); free(__outListData); /** * __list != NULL ξ硢 * Task __list κǸ Task ˤʤΤ (SchedTask::next ) * Υߥ __list * (free Ϥ륢ɥ쥹ΤȤʤ) * ʳ Task Ǥʤ * __list == NULL ʤΤǡfree ϤƤ̵ */ free(__list); } delete smanager; } void SchedTask::__init__(void) { /** * task->inData task->outData * PPE ΤΤSPE ΤΤä * ɥ쥹ȽǤгڤˤʤȻפ */ if (__flag_renewTask == 0) { __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); __taskGroup = new TaskGroup; __taskGroup->command = __task->self; ex_read = &SchedTask::ex_read_normal; ex_exec = &SchedTask::ex_exec_normal; ex_write = &SchedTask::ex_write_normal; } else { __inListData = __task->inData; __outListData = __task->outData; __taskGroup = (TaskGroupPtr)__task->self; ex_read = &SchedTask::ex_read_renew; ex_exec = &SchedTask::ex_exec_renew; ex_write = &SchedTask::ex_write_renew; } } /** * [Todo] * ǡɤ߹߾ readbuf ǤϤʤ * 桼ȤǷ褦ˤʤȤ⤷ʤ * * # TaskManager ˾äȤʤ * # 桼 SPE ˻³뤳ȤǤ뤿ᡣ * # ϥ桼Ǥ櫓 */ void SchedTask::read(void) { __debug("[SchedTask:%s]\n", __FUNCTION__); // wait for load inListData __scheduler->dma_wait(DMA_READ_IN_LIST); // ɤǡĤʤ̵ if (__inListData->length < 1 || __inListData->size == 0) return; // load Input Data __readbuf = __scheduler->allocate(__inListData->size); __scheduler->dma_loadList(__inListData, __readbuf, DMA_READ); (this->*ex_read)(); } void SchedTask::exec(void) { __debug("[SchedTask:%s]\n", __FUNCTION__); // wait for load outListData __scheduler->dma_wait(DMA_READ_OUT_LIST); __writebuf = __scheduler->allocate(__outListData->size); __debug(" task->command = %d\n", __task->command); __debug(" task->in_size = %d\n", __task->in_size); __debug(" task->in_addr = 0x%x\n", __task->in_addr); __debug(" task->out_addr = 0x%x\n", __task->out_addr); __debug(" list->next = 0x%x\n", (unsigned int)__list->next); __debug(" list->length = 0x%x\n", (unsigned int)__list->length); __scheduler->dma_wait(DMA_READ); run(__readbuf, __writebuf); free(__readbuf); if (__taskGroup->status() != 0) { __task->self = __taskGroup->command; delete __taskGroup; __taskGroup = NULL; } // ΰ褬פʤ̵ if (__outListData->size > 0 || __outListData->length > 0) { __scheduler->dma_storeList(__outListData, __writebuf, DMA_WRITE); // SchedTask::write(void) Ǥ wait ݤƤɡ // ºݤˤϤ wait ʤȤȽޤƤʤ // wait ϤƤϤʤʡ __scheduler->dma_wait(DMA_WRITE); } (this->*ex_exec)(); } void SchedTask::write(void) { __debug("[SchedTask:%s]\n", __FUNCTION__); //__scheduler->dma_wait(DMA_WRITE); free(__writebuf); /** * ΥSPE줿 * ΥνλԤɬפϤʤȤ꤬Ƥ뤿ᡢ * (wait_task() ƤФƤʤ) * ǽλ롣ex_write ϼ¹Ԥʤ */ 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; if (__scheduler->curIndex_taskList < __list->length) { SchedTask* schedTask = CreateSchedTask(__list, __scheduler); schedTask->__flag_renewTask = this->__flag_renewTask; schedTask->__init__(); /** * ͳ SchedTask:~SchedTask() */ __list = NULL; return schedTask; } else { uint32 nextList = (uint32)__list->next; if (nextList == 0) { return new SchedNop2Ready(__scheduler); } else { return new SchedTaskList(nextList, __scheduler); } } } /** * task->add_input Ϳ줿֤б index (0n-1) ǡ * buffer бǡ֤ */ void* SchedTask::get_input(void *buff, int index) { if (buff != NULL) { return (void*)((int)buff + __inListData->bound[index]); } else { return NULL; } } /** * write buffer ΰ֤ */ void* SchedTask::get_output(void *buff, int index) { if (buff != NULL) { return (void*)((int)buff + __outListData->bound[index]); } else { return NULL; } } 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); }