Mercurial > hg > Game > Cerium
changeset 719:cc1b7333de92 draft
clean up scheduler main loop
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 19 Dec 2009 10:34:43 +0900 |
parents | e78238b7c5d6 |
children | fc380dcad630 |
files | TaskManager/Cell/CellTaskManagerImpl.cc TaskManager/Fifo/FifoTaskManagerImpl.cc TaskManager/kernel/ppe/MailManager.cc TaskManager/kernel/ppe/TaskManagerImpl.cc TaskManager/kernel/ppe/TaskManagerImpl.h |
diffstat | 5 files changed, 71 insertions(+), 120 deletions(-) [+] |
line wrap: on
line diff
--- a/TaskManager/Cell/CellTaskManagerImpl.cc Sat Dec 19 09:50:37 2009 +0900 +++ b/TaskManager/Cell/CellTaskManagerImpl.cc Sat Dec 19 10:34:43 2009 +0900 @@ -11,6 +11,7 @@ #include "types.h" #include "SysFunc.h" +static void send_alloc_reply(SpeThreads *speThreads); CellTaskManagerImpl::~CellTaskManagerImpl() { @@ -157,123 +158,82 @@ { TaskListPtr ppeTaskList = NULL; - // PPE 側で動く TaskList です - // FifoTaskManagerImpl::run と上手く合うように - // こんなことやってますよ - // - // 本来は、別 thread で動かすべきだろう... - ppeTaskList = ppeManager->get_runTaskList(); - if (!ppeTaskList) { - goto cont; - } - - // SPE からの Mailbox Check は - // PPE 側の schedule から抜けて来たときに行う - // (speThreads で Blocking Mailbox read と - // セマフォとか使ってやってもいいが、今はこの方式で) - // - // すべてのspe task が finish task を待つ場合は、ppeTaskList の - // 判定だけで十分だが、そうでない場合は、spe の task が残っているか - // どうかを調べる必要がある。 - // do { + // PPE side + ppeTaskList = ppeManager->get_runTaskList(); ppeManager->schedule(ppeTaskList); - cont: - ppeTaskList = mail_check(waitTaskQueue); + ppeManager->mail_check(waitTaskQueue); + // SPE side + do { + mail_check(waitTaskQueue); + // SPE に送る TaskList の準備 + set_runTaskList(); + // TaskList 待ちの SPE に TaskList を送る + for (int i = 0; i < machineNum; i++) { + if (flag_sendTaskList[i] == 1 && speTaskList_bg[i]->length >= 1 ) { + send_taskList(i); + spe_running++; + } + } + } while (ppeManager->activeTaskQueue->empty() && !waitTaskQueue->empty()); } while (ppeTaskList || spe_running >0); } /** * SPE からのメールをチェックする - * - * @param [mail_list] - * PPE 側で動く Scheduler からのメールリスト - * この中で PPE 側の mail check も行う - * - * @return PPE Scheduler に対してのメール。 - * 次に実行する TaskList のアドレスや、終了コマンドを送る */ -TaskListPtr -CellTaskManagerImpl::mail_check(HTaskInfo *wait_queue) +void +CellTaskManagerImpl::mail_check() { - // PPE Scheduler からの mail check - ppeManager->mail_check(waitTaskQueue); - - do { - memaddr data; + memaddr data; - // SPE Scheduler からの mail check - for (int id = 0; id < machineNum; id++) { - while (speThreads->has_mail(id, 1, &data)) { - /** - * MY_SPE_STATUS_READY: SPE が持ってた Task 全て終了 - * MY_SPE_NOP: 特に意味のないコマンド - * それ以外:終了したタスク(PPEにあるのでアドレス - * - * MY_SPE_NOP が 0 なので、 - * 下のように data > MY_SPE_NOP とかしています。 - * 一目でよくわからない書き方なんで、直したいところですが。。。 - */ - // 名前あとでちゃんと決めよう => MY_SPE_... とかじゃなくて - if (data == (memaddr)MY_SPE_STATUS_READY) { - //__debug_ppe("[SPE %d] finish\n", id); - flag_sendTaskList[id] = 1; - spe_running--; - } else if (data == (memaddr)MY_SPE_COMMAND_MALLOC) { - //__debug_ppe("[PPE] MALLOC COMMAND from [SPE %d]\n", id); + // SPE Scheduler からの mail check + for (int id = 0; id < machineNum; id++) { + while (speThreads->has_mail(id, 1, &data)) { + if (data == (memaddr)MY_SPE_STATUS_READY) { + // MY_SPE_STATUS_READY: SPE が持ってた Task 全て終了 + flag_sendTaskList[id] = 1; + spe_running--; + } else if (data == (memaddr)MY_SPE_COMMAND_MALLOC) { + // MY_SPE_COMMAND_MALLOC SPE からのmain memory request + send_alloc_reply(speThreads); + } else if (data > (memaddr)MY_SPE_NOP) { + // 終了したタスク(PPEにあるのでアドレス) + HTaskPtr task = (HTaskPtr)data; + task->post_func(schedTaskManager, task->post_arg1, task->post_arg2); + check_task_finish(task,waitTaskQueue); + } + // MY_SPE_NOP: 特に意味のないコマンド + } + } +} - /** - * info[0] = alloc_id; (CellScheduler::mainMem_alloc 参照) - * info[1] = alloc_addr; - */ - memaddr alloc_info[2]; - long alloc_size; - long command; - - speThreads->get_mail(id, 2, alloc_info); - command = (long)alloc_info[0]; - alloc_size = (long)alloc_info[1]; - - - alloc_info[1] = (memaddr)allocate(alloc_size); - /* - * allocate された領域は今の SPE buffer にリンクとして接続する - * ここでは TaskList を allocate(new) して登録してやろうか - */ - - //__debug_ppe("[PPE] MALLOCED 0x%lx from [SPE %d]\n", alloc_info[1],id); - // 今のところ何もしてない。どうも、この allocate を free - // するのは、SPE task が返した値を見て行うらしい。それは、 - // 忘れやすいのではないか? - speThreads->add_output_tasklist(command, alloc_info[1], alloc_size); +static void +send_alloc_reply(SpeThreads *speThreads) +{ - speThreads->send_mail(id, 2, alloc_info); - } else if (data > (memaddr)MY_SPE_NOP) { - //__debug_ppe("[PPE] recv from [SPE %d] : 0x%x\n", id, data); - HTaskPtr task = (HTaskPtr)data; - task->post_func(schedTaskManager, task->post_arg1, task->post_arg2); - check_task_finish(task,waitTaskQueue); - } - } - } - - // 依存関係を満たしたタスクをアクティブに - wakeup_waitTask(); + /** + * info[0] = alloc_id; (CellScheduler::mainMem_alloc 参照) + * info[1] = alloc_addr; + */ + memaddr alloc_info[2]; + long alloc_size; + long command; + + speThreads->get_mail(id, 2, alloc_info); + command = (long)alloc_info[0]; + alloc_size = (long)alloc_info[1]; - // SPE に送る TaskList の準備 - set_runTaskList(); + + alloc_info[1] = (memaddr)allocate(alloc_size); + //__debug_ppe("[PPE] MALLOCED 0x%lx from [SPE %d]\n", alloc_info[1],id); + // 今のところ何もしてない。どうも、この allocate を free + // するのは、SPE task が返した値を見て行うらしい。それは、 + // 忘れやすいのではないか? + speThreads->add_output_tasklist(command, alloc_info[1], alloc_size); - // TaskList 待ちの SPE に TaskList を送る - for (int i = 0; i < machineNum; i++) { - if (flag_sendTaskList[i] == 1 && speTaskList_bg[i]->length >= 1 ) { - send_taskList(i); - spe_running++; - } - } - } while (ppeManager->activeTaskQueue->empty() && !waitTaskQueue->empty()); - - return ppeManager->get_runTaskList(); + speThreads->send_mail(id, 2, alloc_info); } /**
--- a/TaskManager/Fifo/FifoTaskManagerImpl.cc Sat Dec 19 09:50:37 2009 +0900 +++ b/TaskManager/Fifo/FifoTaskManagerImpl.cc Sat Dec 19 10:34:43 2009 +0900 @@ -27,14 +27,16 @@ void FifoTaskManagerImpl::init() { + // TaskManager から呼ばれるので、かなりの部分は初期化されている。 + mainScheduler = new MainScheduler(); mainScheduler->init(this); mainScheduler->id = 0; set_scheduler(mainScheduler); taskListImpl = new TaskListInfo; - taskQueueImpl = new TaskQueueInfo; - htaskImpl = new HTaskInfo(); + // taskQueueImpl = new TaskQueueInfo; + // htaskImpl = new HTaskInfo(); mainTaskList = taskListImpl->create(); @@ -60,7 +62,7 @@ taskListImpl = tm-> taskListImpl ; taskQueueImpl = tm-> taskQueueImpl ; htaskImpl = tm-> htaskImpl ; - waitTaskQueue = NULL; // mail_check で外から設定される + waitTaskQueue = tm->waitTaskQueue; mainTaskList = taskListImpl->create(); @@ -149,10 +151,8 @@ schedule(list); // ppe scheduler からの mail を調べる - mail_check(waitTaskQueue); + mail_check(); - // 依存関係を満たしたものは実行可能キューへ - wakeup_waitTask(); list = get_runTaskList(); } while (list); } @@ -191,7 +191,7 @@ * NULL なら全てのタスクが実行終了したということ */ void -FifoTaskManagerImpl::mail_check(HTaskInfo *wait_queue) +FifoTaskManagerImpl::mail_check() { while (mainScheduler->has_mail_from_host()) { memaddr data = mainScheduler->mail_read_from_host(); @@ -206,7 +206,7 @@ // 移されてから、wait_for されるという事態が起きることがある。 HTaskPtr task = (HTaskPtr)data; task->post_func(schedTaskManager, task->post_arg1, task->post_arg2); - check_task_finish(task, wait_queue); + check_task_finish(task, waitTaskQueue); } } }
--- a/TaskManager/kernel/ppe/MailManager.cc Sat Dec 19 09:50:37 2009 +0900 +++ b/TaskManager/kernel/ppe/MailManager.cc Sat Dec 19 10:34:43 2009 +0900 @@ -13,6 +13,7 @@ } MailManager::MailManager(unsigned int qsize) { + read = write = 0; calc_mask(qsize); queue = New(memaddr,size); }
--- a/TaskManager/kernel/ppe/TaskManagerImpl.cc Sat Dec 19 09:50:37 2009 +0900 +++ b/TaskManager/kernel/ppe/TaskManagerImpl.cc Sat Dec 19 10:34:43 2009 +0900 @@ -167,15 +167,6 @@ waitTaskQueue ->addLast(q); } -/** - * waitQueue の中で依存関係を満たしたタスクは - * activeQueue へ移す - */ -void -TaskManagerImpl::wakeup_waitTask() -{ - // done in check_task_finish -} /* end */
--- a/TaskManager/kernel/ppe/TaskManagerImpl.h Sat Dec 19 09:50:37 2009 +0900 +++ b/TaskManager/kernel/ppe/TaskManagerImpl.h Sat Dec 19 10:34:43 2009 +0900 @@ -40,7 +40,6 @@ virtual void append_waitTask(HTaskPtr); void check_task_finish(HTaskPtr task, HTaskInfo *wait_queue); - void wakeup_waitTask(); void systask_init();