Mercurial > hg > Members > kono > Cerium
diff TaskManager/kernel/ppe/TaskManagerImpl.cc @ 109:5c194c71eca8
Cerium cvs version
author | gongo@gendarme.local |
---|---|
date | Wed, 12 Nov 2008 17:39:33 +0900 |
parents | 588ab5f0e659 |
children | 44e3bf914155 |
line wrap: on
line diff
--- a/TaskManager/kernel/ppe/TaskManagerImpl.cc Wed Nov 12 17:29:35 2008 +0900 +++ b/TaskManager/kernel/ppe/TaskManagerImpl.cc Wed Nov 12 17:39:33 2008 +0900 @@ -2,48 +2,35 @@ #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) +noaction(void *p) { } -TaskManagerImpl::TaskManagerImpl(int num) : machineNum(num) {} - -TaskManagerImpl::~TaskManagerImpl(void) -{ - delete mailManager; - delete scheduler; - delete bufferManager; -} +TaskManagerImpl::TaskManagerImpl(int num) + : machineNum(num), activeTaskQueue(NULL), waitTaskQueue(NULL) {} void -TaskManagerImpl::init(void) +TaskManagerImpl::systask_init(void) { - mailManager = new MailManager(); - mailManager->init(20); + systask_register(); - scheduler = new MainScheduler(); - scheduler->init(); - scheduler->set_mailManager(mailManager); + systask_finish = create_task(SYSTASK_FINISH); + append_waitTask(systask_finish); } HTaskPtr -//TaskManagerImpl::create_task(int cmd, int size, DmaBuffer *in_addr, -// DmaBuffer *out_addr, void (*func)(void)) -TaskManagerImpl::create_task(int cmd, int size, unsigned int in_addr, - unsigned int out_addr, void (*func)(void)) +TaskManagerImpl::create_task(int cmd) { HTaskPtr new_task; - new_task = bufferManager->create_task(cmd, size, in_addr, out_addr); - - if (func == NULL) { - new_task->post_func = noaction; - } else { - new_task->post_func = func; - } - + new_task = bufferManager->create_task(cmd); + new_task->post_func = noaction; new_task->mimpl = this; return new_task; @@ -52,6 +39,7 @@ /** * task の依存関係を設定 * master task が終わってから、slave task を実行するように + * master->wait_for(slave); */ void TaskManagerImpl::set_task_depend(HTaskPtr master, HTaskPtr slave) @@ -61,158 +49,186 @@ m = bufferManager->create_taskQueue(master); s = bufferManager->create_taskQueue(slave); - master->wait_me = TaskQueueInfo::append(master->wait_me, s); - slave->wait_i = TaskQueueInfo::append(slave->wait_i, m); + master->wait_me = TaskQueue::append(master->wait_me, s); + slave->wait_i = TaskQueue::append(slave->wait_i, m); } +/** + * タスクを実行可能キューまたは待機キューへ追加する。 + * 依存関係が満たされていれば active, まだだったら wait へ。 + * task->spawn(); + */ void TaskManagerImpl::spawn_task(HTaskPtr task) { + // waiter // master + // waitee // slave if (task->wait_i == NULL) { - bufferManager->append_activeTask(task); + append_activeTask(task); } else { - bufferManager->append_waitTask(task); + append_waitTask(task); } + + systask_finish->wait_for(task); } +/** + * Task を実行可能キューに追加する + */ +void +TaskManagerImpl::append_activeTask(HTaskPtr task) +{ + TaskQueuePtr q; + + q = bufferManager->create_taskQueue(task); + activeTaskQueue = TaskQueue::append(activeTaskQueue, 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; } -TaskListPtr -TaskManagerImpl::set_task(void) +/** + * 終了したタスクから依存の処理とか + * post_func() はこのタスクが終了したら実行する関数。 + * 今のところ使ってないっす + * + * @param [task] 終了したタスク + */ +void +TaskManagerImpl::check_task_finish(HTaskPtr task) { - // ここ...直すかな - TaskListPtr list; - TaskQueuePtr queue; - TaskQueuePtr d; - HTaskPtr htask; - TaskPtr task; + notify_wait_taskQueue(task, task->wait_me); + task->post_func(task->post_arg); + bufferManager->free_task(task); +} - queue = bufferManager->activeTaskQueue; - if (queue == NULL) { - return NULL; +/** + * 終了したタスク [depend] を待っている TaskList に + * 終わった事を知らせる(削除する + */ +void +TaskManagerImpl::notify_wait_taskQueue(HTaskPtr depend, TaskQueuePtr list) +{ + TaskQueuePtr p; + HTaskPtr task; + + p = list; // wait task list + + while (p) { + task = (HTaskPtr)p->task; + task->wait_i = remove_taskQueue_eq_task(task->wait_i, depend); + p = p->next; } - bufferManager->clear_taskList(); - - while (queue) { - list = bufferManager->get_available_taskList(); - htask = queue->task; - d = queue; - queue = queue->next; + remove_taskQueue_all(list); +} + +void +TaskManagerImpl::append_waitTask(HTaskPtr task) +{ + TaskQueuePtr q; + + q = bufferManager->create_taskQueue(task); + waitTaskQueue = TaskQueue::append(waitTaskQueue, q); +} + +/** + * waitQueue の中で依存関係を満たしたタスクは + * activeQueue へ移す + */ +void +TaskManagerImpl::wakeup_waitTask(void) +{ + TaskQueuePtr p, tmp; - task = &list->tasks[list->length++]; - task->command = htask->command; + p = waitTaskQueue; + while (p) { + HTaskPtr task = (HTaskPtr)p->task; + tmp = p; + p = p->next; + if (task->wait_i == NULL) { + append_activeTask(task); + waitTaskQueue = remove_taskQueue(waitTaskQueue, tmp); + } + } +} + +void +TaskManagerImpl::remove_taskQueue_all(TaskQueuePtr list) +{ + TaskQueuePtr p = list; + TaskQueuePtr p1; + + while (p != NULL) { + p1 = p->next; + bufferManager->free_taskQueue(p); + p = p1; + } +} -#if 0 - // Fix me !!!!! - // ださい - // かっこいい class 判定がないものか。typeinfoだっけ? - // in,out にあるのが DmaBuffer 以外だったら通信させない決まりにしたい - if (htask->in_addr != 0) { - htask->in_addr->get_buffer(&task->in_addr); - } else { - task->in_addr = 0; +/** + * [list] が持つ queue->task の中に [task] と同じ奴があれば + * 削除する。まあ remove_taskQueue() の HTask で比較するverです。 + * こういうのはオーバーロードでやるもんなのかな? + */ +TaskQueuePtr +TaskManagerImpl::remove_taskQueue_eq_task(TaskQueuePtr list, HTaskPtr task) +{ + TaskQueuePtr p = list; + TaskQueuePtr p1; + + if (p == NULL) return p; + + if (p->task == task) { + list = list->next; + bufferManager->free_taskQueue(p); + } else { + p1 = p->next; + while (p1 && p1->task && p1->task != task) { + p1 = p1->next; + p = p->next; + } + if (p1) { + p->next = p1->next; + bufferManager->free_taskQueue(p1); } - if (htask->out_addr != 0) { - htask->out_addr->get_buffer(&task->out_addr); - } else { - task->out_addr = 0; + } + + return list; +} + +TaskQueuePtr +TaskManagerImpl::remove_taskQueue(TaskQueuePtr list, TaskQueuePtr q) +{ + TaskQueuePtr p = list; + TaskQueuePtr p1; + + if (!p) return p; + + if (p == q) { + list = list->next; + bufferManager->free_taskQueue(p); + } else { + p1 = p->next; + while (p1 && p1 != q) { + p1 = p1->next; + p = p->next; } -#else - task->in_addr = htask->in_addr; - task->out_addr = htask->out_addr; -#endif - task->in_size = htask->in_size; - task->self = htask; - - bufferManager->free_taskQueue(d); + if (p1) { + p->next = p1->next; + bufferManager->free_taskQueue(p1); + } } - bufferManager->activeTaskQueue = NULL; return list; } -void -TaskManagerImpl::run(void) -{ - TaskListPtr list; - MailQueuePtr list_mail; // task list - MailQueuePtr sentinel; // 番兵 - MailQueuePtr in_mail_list = NULL; - MailQueuePtr out_mail_list = NULL; - - // 暫定 - list = set_task(); - - list_mail = mailManager->create((unsigned int)list); - in_mail_list = MailManager::append_mailQueue(in_mail_list, list_mail); - - - // Fix me - // spe で仕事中のタスクがあったとしても - // ppe 側で active なリストが無くなれば、 - // たとえ spe の task を待つ wait なリストがあったとしても - // loop を抜けて終わってしまう。 - // ppe側のタスクだけじゃなく、spe 側も全て終わったっていう判定が必要だな。 - // この do-while の一つ外でいいかなー - do { - sentinel = mailManager->create(MY_SPE_COMMAND_EXIT); - in_mail_list = MailManager::append_mailQueue(in_mail_list, sentinel); - - scheduler->send_mailList(in_mail_list); - scheduler->run(); - out_mail_list = scheduler->recv_mailList(); - - // out_mail_list には、ppe scheduler からの mail がある - in_mail_list = mail_check(out_mail_list); - } while (in_mail_list); -} - -/** - * PPE Scheduler からのメールをチェックする - */ -MailQueuePtr -TaskManagerImpl::mail_check(MailQueuePtr mail_list) -{ - MailQueuePtr q = mail_list; - MailQueuePtr d; - MailQueuePtr ret = NULL; - unsigned int data; - TaskListPtr next_list; - - while (q) { - data = q->data; - - if (data == MY_SPE_STATUS_READY) { - __debug_ppe("[FIFO] finish\n"); - next_list = set_task(); - if (next_list != NULL) { - d = mailManager->create((unsigned int)next_list); - ret = MailManager::append_mailQueue(ret, d); - } - } else { - __debug_ppe("[PPE] recv from : 0x%x\n", data); - bufferManager->check_task_finish((HTaskPtr)data); - } - - d = q; - q = q->next; - - mailManager->free(d); - } - - return ret; -} - -/** - * 型名指定するには template だけど... - */ -DmaBuffer* -TaskManagerImpl::allocate(int size) -{ - return new DmaBuffer(size); -}