Mercurial > hg > Game > Cerium
view TaskManager/Fifo/FifoTaskManagerImpl.cc @ 596:f1c2e11a2ef4 draft
add xdr_getpos
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 04 Nov 2009 22:52:06 +0900 |
parents | 5641d121818e |
children | 92b0d490e839 |
line wrap: on
line source
#include <stdio.h> #include <stdlib.h> #include <string.h> #include "FifoTaskManagerImpl.h" #include "Scheduler.h" #include "types.h" #include "error.h" FifoTaskManagerImpl::~FifoTaskManagerImpl() { delete mailManager; delete scheduler; delete taskListImpl ; delete taskQueueImpl ; delete htaskImpl ; } /** * MailManager は PPE スケジューラとのメール交換、 * FifoScheduler は PPE 側のスケジューラ * BufferManager は Task、TaskList などのメモリ管理(大層なことしてないが */ void FifoTaskManagerImpl::init() { mailManager = new MailManager(); mailManager->init(20); scheduler = new MainScheduler(); scheduler->init(); scheduler->set_mailManager(mailManager); scheduler->id = 0; taskListImpl = new TaskListInfo; taskQueueImpl = new TaskQueueInfo; htaskImpl = new HTaskInfo(); mainTaskList = taskListImpl->create(); } /** * これは CellTaskManagerImpl から呼ばれる。 * TaskList等 は共用で使うので引数に。 * CellTaskManagerImpl と FifoTaskManagerImpl が同時に * 上のデータにアクセスする事は(今は)ないのでこれでおk */ void FifoTaskManagerImpl::init(MainScheduler *_sched, TaskManagerImpl *tm) { mailManager = new MailManager(); mailManager->init(20); //scheduler = new MainScheduler(); scheduler = _sched; scheduler->init(); scheduler->set_mailManager(mailManager); taskListImpl = tm-> taskListImpl ; taskQueueImpl = tm-> taskQueueImpl ; htaskImpl = tm-> htaskImpl ; waitTaskQueue = NULL; // mail_check で外から設定される // waitTaskQueue = tm->waitTaskQueue; // activeTaskQueue = NULL; // CellTaskManagerImple 側を使う // waitTaskQueue = tm->waitTaskQueue; // activeQueue は? mainTaskList = taskListImpl->create(); } /** * スケジューラに渡す TaskList を取得する。 * * @return 実行タスクリスト * * ActiveTaskQueue (依存条件は満たし済み) のタスクを * 実行タスクリストに入れる */ TaskListPtr FifoTaskManagerImpl::get_runTaskList() { TaskListPtr list, list_top; TaskPtr task; // Task (SPE に送る Task) if (activeTaskQueue->empty()) { return NULL; } // PPE 側で実行される TaskList list_top = mainTaskList; // list_top->clear() とかの方がいいかもしれん。 list_top = taskListImpl->clear_taskList(list_top); list = list_top; // printf("active task queue length = %d\n",activeTaskQueue->length()); while (HTaskPtr htask = activeTaskQueue->poll()) { task = &list->tasks[list->length++]; #if 0 task->command = htask->command; task->inData = htask->inData; task->outData = htask->outData; task->self = (unsigned int)htask; // param は? #else // inData, outData を内蔵にしたので実は、結構でかくない? // 268 byte 程度だが... 不要な分(設定してない inData, outData, param // とかもコピーしてるね。rbuf/wbuf の意味を変えてしまったわけか。 memcpy(task, (Task*)htask, sizeof(Task)); #endif if (list->length >= TASK_MAX_SIZE) { TaskListPtr newList = taskListImpl->create(); list_top = TaskListInfo::append(list_top, newList); list = newList; } // activeTaskQueue->free_(htask); ここで free しないで、 // mail を待つ } mainTaskList = list_top; return list_top; } void FifoTaskManagerImpl::run() { TaskListPtr list; MailQueuePtr mail; list = get_runTaskList(); do { // list を実行する mail = schedule(list); // mail には、ppe scheduler からの mail がある mail_check(mail); // 依存関係を満たしたものは実行可能キューへ wakeup_waitTask(); list = get_runTaskList(); } while (list); } /** * @param [list] 実行タスクリスト * @return FifoScheduler からのメール * * [Tasklist] -> [番兵] -> scheduler->run を抜ける */ MailQueuePtr FifoTaskManagerImpl::schedule(TaskListPtr list) { MailQueuePtr list_mail; // task list MailQueuePtr sentinel; // 番兵 MailQueuePtr in_mail_list = NULL; MailQueuePtr out_mail_list = NULL; // TaskList のアドレス list_mail = mailManager->create((unsigned int)list); in_mail_list = MailManager::append_mailQueue(in_mail_list, list_mail); // EXIT_COMMAND (番兵的な意味で) sentinel = mailManager->create(MY_SPE_COMMAND_EXIT); in_mail_list = MailManager::append_mailQueue(in_mail_list, sentinel); // scheduler は受け取ったメールを元に実行する scheduler->send_mailList(in_mail_list); scheduler->run(); out_mail_list = scheduler->recv_mailList(); return out_mail_list; } /** * PPE Scheduler からのメールをチェックする * * @param [mail_list] * PPE 側で動く Scheduler からのメールリスト * 終了した Task や、その他(今はまだ実装してないけど)の情報が入ってる * * @return Scheduler が次に実行する Task List * NULL なら全てのタスクが実行終了したということ */ void FifoTaskManagerImpl::mail_check(MailQueuePtr mail_list, HTaskInfo *waitQueue) { waitTaskQueue = waitQueue; mail_check(mail_list); } void FifoTaskManagerImpl::mail_check(MailQueuePtr mail_list) { MailQueuePtr q = mail_list; MailQueuePtr d; unsigned int data; while (q) { data = q->data; /** * MY_SPE_STATUS_READY: SPE が持ってた Task 全て終了 * MY_SPE_NOP: 特に意味のないコマンド * それ以外:終了したタスク(PPEにあるのでアドレス * * MY_SPE_NOP が 0 なので、 * 下のように data > MY_SPE_NOP とかしています。 * 一目でよくわからない書き方なんで、直したいところですが。。。 */ if (data == MY_SPE_STATUS_READY) { __debug_ppe("mail_check(): Task List finish\n"); } else if (data > MY_SPE_NOP) { __debug_ppe("mail_check(): recv from 0x%x\n", data); check_task_finish((HTaskPtr)data); } d = q; q = q->next; mailManager->free(d); } } void* FifoTaskManagerImpl::allocate(int size, int alignment) { #ifdef __APPLE__ return malloc(size); #else void *buff; posix_memalign(&buff, alignment, size); return buff; #endif } void* FifoTaskManagerImpl::allocate(int size) { #ifdef __APPLE__ return malloc(size); #else void *buff; posix_memalign(&buff, DEFAULT_ALIGNMENT, size); return buff; #endif } Scheduler* FifoTaskManagerImpl::get_scheduler() { return scheduler; } /** * # # # # # # # # * Abstract Factory Pattern * # # # # # # # */ #ifdef __CERIUM_FIFO__ TaskManagerImpl* create_impl(int num) { return new FifoTaskManagerImpl(); } #endif // __CERIUM_FIFO__