Mercurial > hg > Game > Cerium
diff TaskManager/kernel/schedule/SchedTask.cc @ 547:e5431e658038 draft
continue..
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 20 Oct 2009 20:34:47 +0900 |
parents | d6ba5ede4fe7 |
children | fbcbcc5ad3b5 |
line wrap: on
line diff
--- a/TaskManager/kernel/schedule/SchedTask.cc Fri Oct 16 17:57:17 2009 +0900 +++ b/TaskManager/kernel/schedule/SchedTask.cc Tue Oct 20 20:34:47 2009 +0900 @@ -10,8 +10,6 @@ extern Scheduler::TaskObject task_list[MAX_TASK_OBJECT]; -//#define NO_PIPELINE - /** Task Object を作る */ @@ -54,12 +52,6 @@ this->stderr_ = stderr; this->stdin_ = stdin; - 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; - } /** @@ -67,87 +59,19 @@ */ SchedTask::~SchedTask() { - if (flag_renewTask == SCHED_TASK_RENEW) { - /** - * list != NULL の場合、 - * この Task が list の最後の Task になるので (SchedTask::next 参照) - * このタイミングで list を解放する - * (free に渡されるアドレスが正しいものとなる)。 - * それ以外の Task では当然解放しない。 - * list == NULL なので、free に渡しても無問題 - */ - free(list); - } - - } -/** - * このタスクを Renew Task とし、それに応じた関数をセットする - */ -void -SchedTask::setRenew() -{ - 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 = &_task->inData; - outListData = &_task->outData; scheduler = sc; cur_index = index; - scheduler->mainMem_wait(); - (this->*ex_init)(); -} - -/** - * PPE 内で生成されたタスクの ex_init() - */ -void -SchedTask::ex_init_normal() -{ -#if 0 - // task list に入れたので既に読んでいる? - // - 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 -#endif - - taskGroup = new TaskGroup; - taskGroup->command = (int)task->self; -} - -/** - * SPE 内で生成されたタスクの ex_init() - * 各データは SPE 内の create_task 時に生成もしくは引き継がれているので - * ex_init_normal() と違い、ここでは値を渡すだけ - */ -void -SchedTask::ex_init_renew() -{ - inListData = &task->inData; - outListData = &task->outData; - taskGroup = (TaskGroupPtr)task->self; } void @@ -155,83 +79,39 @@ { __debug("[SchedTask:%s]\n", __FUNCTION__); -#if 0 -#if !defined(NO_PIPELINE) - scheduler->dma_wait(DMA_READ_IN_LIST); - scheduler->dma_wait(DMA_READ_OUT_LIST); -#endif -#endif // object creation をSchedTask生成時にやらないので、 // exec の直前のread で十分に間に合う - if (cur_index < list->length) { - // load next task - loadSchedTask(scheduler, &list->tasks[cur_index]); - } - - writebuf = scheduler->allocate(outListData->size); + // next task の load + loadSchedTask(scheduler, &list->tasks[cur_index]); + writebuf = scheduler->allocate(wsize); // 読むデータが一つもなければ無視 - if (inListData->length == 0) return; + if (rsize == 0) return; // load Input Data - readbuf = scheduler->allocate(inListData->size); - scheduler->dma_loadList(inListData, readbuf, DMA_READ); + readbuf = scheduler->allocate(rsize); + read_tag = get_tag(); + scheduler->dma_load(readbuf, rsize, read_tag); -#if defined(NO_PIPELINE) - scheduler->dma_wait(DMA_READ); -#endif - - (this->*ex_read)(); } -/** - * PPE 内で生成されたタスクの ex_read() - * - * [Todo] - * データの読み込み場所を readbuf ではなく、 - * ユーザ自身で決めれるようになるといいかもしれない。 - * - * # TaskManager が勝手に消すことなく、 - * # ユーザが SPE 上に持ち続けることができるため。 - * # もちろん管理はユーザに任せるわけだ。 - */ -void -SchedTask::ex_read_normal() -{ -} void SchedTask::exec() { __debug("[SchedTask:%s]\n", __FUNCTION__); -#if !defined(NO_PIPELINE) - scheduler->dma_wait(DMA_READ); + scheduler->dma_wait(read_tag); task_list[task->command].wait(scheduler,task->command); -#endif - task_list[task->command].run(this, readbuf, writebuf); free(readbuf); - if (taskGroup->status() != 0) { - task->self = (int)taskGroup->command; - delete taskGroup; - taskGroup = NULL; + // 書き込む領域がなければ無視 + if (wsize->length > 0) { + write_tag = get_tag(); + scheduler->dma_store(writebuf, wsize, write_tag); } - - - // 書き込む領域がなければ無視 - 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 @@ -239,187 +119,27 @@ { __debug("[SchedTask:%s]\n", __FUNCTION__); -#if !defined(NO_PIPELINE) - scheduler->dma_wait(DMA_WRITE); + scheduler->dma_wait(write_tag); free(writebuf); -#endif - - if ((int)task->self == MY_SPE_NOP) return; - - (this->*ex_write)(); -} - - -/** - * SPE 内で生成されたタスクの ex_read() - */ -void -SchedTask::ex_read_renew() -{ - writebuf = scheduler->allocate(outListData->size); -} - -/** - * PPE 内で生成されたタスクの ex_exec() - */ -void -SchedTask::ex_exec_normal() -{ -} - -/** - * SPE 内で生成されたタスクの ex_exec() - */ -void -SchedTask::ex_exec_renew() -{ + (*post_func)(this,0,0); } - -/** - * PPE 内で生成されたタスクの ex_write() - * - * このタスク内で新たにタスクが生成され、 - * 且つそのタスクの終了を待つ必要がある場合、 - * PPE に終了したことは知らせない(command は送信しない) - */ -void -SchedTask::ex_write_normal() -{ - /** - * このタスク内で新たにタスクが生成されなかった - * or 生成されたが、そのタスクの終了を待つ必要は無い - */ - if (renew_flag == 0) { - scheduler->mail_write((int)task->self); - } -} - -/** - * SPE 内で生成されたタスクの ex_write() - * - * A <- 親タスク - * | \ - * B C <- SPE 内で生成されたタスク - * - * A は SPE 内で B, C を生成したとする。 - * B と C が終了したら、A が PPE に送るはずだったコマンドが - * 子タスクに引き継がれているので、最後に実行された子タスクが - * PPE に mail 送信する。 - */ -void -SchedTask::ex_write_renew() -{ - uint32 cmd; - - taskGroup->remove(task); - cmd = taskGroup->status(); - - // タスク内で作られた全てのタスクが終了した - if (cmd != 0) { - delete taskGroup; - scheduler->mail_write(cmd); - } -} - SchedTaskBase* SchedTask::next(Scheduler *scheduler, SchedTaskBase *p) { __debug("[SchedTask:%s]\n", __FUNCTION__); - // delete p; move to Scheduler - - return (this->*ex_next)(); -} - -SchedTaskBase* -SchedTask::ex_next_normal() -{ - 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(scheduler, nextTask); - ((SchedTask*)nextSched)->init(list, nextTask, cur_index, - // scheduler->get_curReadBuf(), - // scheduler->get_curWriteBuf(), - scheduler); - return nextSched; - } + TaskPtr nextTask = (Task*)activeQueue.poll(); + if (nextTask) { + SchedTask *nextSched = createSchedTask(scheduler, nextTask); + nextSched->init(list, nextTask, cur_index, scheduler); + return nextSched; } else { - uint32 nextList = (uint32)list->next; - - if (nextList == 0) { - return new SchedNop2Ready(scheduler); - } else { - return createSchedTaskList(nextList, scheduler, - SCHED_TASKLIST_NORMAL); - } + return new SchedNop2Ready(scheduler); } } -/** - * - */ -SchedTaskBase* -SchedTask::ex_next_renew() -{ - TaskPtr nextTask; - SchedTask *nextSched; - - if (cur_index < list->length) { - nextTask = &list->tasks[cur_index++]; - nextSched = createSchedTask(scheduler, 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(scheduler, 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() @@ -427,68 +147,6 @@ 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) @@ -500,22 +158,6 @@ SchedTask::create_task(int cmd) { HTaskPtr htask = scheduler->create_task(cmd); -#if 0 - TaskListPtr taskList = scheduler->get_renewListBuf(); - TaskPtr p = &taskList->tasks[taskList->length++]; - p->command = cmd; - - // already allocated - // p->inData = (ListData*)scheduler->allocate(sizeof(ListData)); - // p->outData = (ListData*)scheduler->allocate(sizeof(ListData)); - - p->inData.clear(); - p->outData.clear(); - - p->self = (int)MY_SPE_NOP; - p->param_size = 0; -#endif - return p; } @@ -524,13 +166,9 @@ * @param[in] waitTask タスク内で生成したタスクの登録(spawn()に相当) */ void -SchedTask::wait_task(TaskPtr waitTask) +SchedTask::spawn(HTaskPtr task) { - waitTask->self = (int)taskGroup; - - scheduler->add_groupTask(taskGroup, waitTask); - - renew_flag++; + activeQueue.addFirst(task); } void*