Mercurial > hg > Game > Cerium
view TaskManager/kernel/ppe/TaskManagerImpl.cc @ 496:67fb962f58fa draft
PS3 double linked TaskQueue worked.
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 10 Oct 2009 20:32:55 +0900 |
parents | f2816cf264ae |
children | 3429986b8a28 |
line wrap: on
line source
#include <stdio.h> #include "TaskManagerImpl.h" #include "types.h" #include "error.h" #include "../sys_task/SysTask.h" static HTaskPtr systask_start; static HTaskPtr systask_finish; void noaction(void *p) { } TaskManagerImpl::TaskManagerImpl(int num) : machineNum(num) { activeTaskQueue = new TaskQueueInfo(); waitTaskQueue = new TaskQueueInfo(); taskQueueImpl = new TaskQueueInfo(); } /** * 一番最初に PPE で実行される systask_start * 一番最後に、全てのタスクの終了を待つ systask_finish * 番兵的な意味で実装 */ void TaskManagerImpl::systask_init(void) { systask_register(); systask_start = create_task(SYSTASK_START); systask_finish = create_task(SYSTASK_FINISH); systask_start->spawn(); // systask_finish で spawn すると // systask_finish->wait_for(systask_finish); // とかなって無限ループになるので、 // これだけは明示的に append_waitTask() で TaskQueuePtr q = taskQueueImpl->create(systask_finish); append_waitTask(q); } HTaskPtr TaskManagerImpl::create_task(int cmd) { HTaskPtr new_task; new_task = htaskImpl->create(cmd); new_task->post_func = noaction; new_task->mimpl = this; return new_task; } /** * task の依存関係を設定 * master task が終わってから、slave task を実行するように * master->wait_for(slave); */ void TaskManagerImpl::set_task_depend(HTaskPtr master, HTaskPtr slave) { TaskQueuePtr m, s; m = taskQueueImpl->create(master); s = taskQueueImpl->create(slave); master->wait_me->addLast(s); slave->wait_i->addLast(m); s->waiter = m; } /** * タスクを実行可能キューまたは待機キューへ追加する。 * 依存関係が満たされていれば active, まだだったら wait へ。 * task->spawn(); */ void TaskManagerImpl::spawn_task(HTaskPtr task) { // waiter // master // waitee // slave TaskQueuePtr q = taskQueueImpl->create(task); if (task->wait_i->empty()) { append_activeTask(q); } else { append_waitTask(q); } systask_finish->wait_for(task); } /** * Task を実行可能キューに追加する */ void TaskManagerImpl::append_activeTask(TaskQueuePtr q) { activeTaskQueue->addLast(q); } /** * タスクが実行する CPU を選択する * * 現在は CPU_PPE, CPU_SPE, SPE_ANY, SPE_0, SPE_1, ..., SPE_5 * types.h に書いてます。 */ void TaskManagerImpl::set_task_cpu(HTaskPtr task, CPU_TYPE type) { task->cpu_type = type; } /** * 終了したタスクから依存の処理とか * post_func() はこのタスクが終了したら実行する関数。 * * @param [task] 終了したタスク */ void TaskManagerImpl::check_task_finish(HTaskPtr task) { while(TaskQueue *p = task->wait_me->poll()) { HTaskPtr htask = (HTaskPtr)p->task; TaskQueueInfo *wait_i = htask->wait_i; // 相手の wait queue から自分(を指しているTaskQueue)を削除 wait_i->remove(p->waiter); // queue を free する wait_i->free_(p->waiter); wait_i->free_(p); } task->post_func(task->post_arg); htaskImpl->free(task); } void TaskManagerImpl::append_waitTask(TaskQueuePtr q) { waitTaskQueue ->addLast(q); } /** * waitQueue の中で依存関係を満たしたタスクは * activeQueue へ移す */ void TaskManagerImpl::wakeup_waitTask(void) { for(TaskQueuePtr p = waitTaskQueue->getFirst(); p;) { HTaskPtr task = (HTaskPtr)p->task; if (task->wait_i->empty()) { TaskQueuePtr next = waitTaskQueue->getNext(p); waitTaskQueue->remove(p); append_activeTask(p); p = next; } else { p = waitTaskQueue->getNext(p); } } } /* end */