# HG changeset patch # User yutaka@localhost.localdomain # Date 1274539378 -32400 # Node ID df36d41d5135b3855421b2c8d96ea1dd2a600589 # Parent baeab6b5c0abcf867b1421b2c7012a363c0e94c2# Parent 76a39ad68846345bdb3461c8c7f859617477c2c6 merge diff -r baeab6b5c0ab -r df36d41d5135 TaskManager/Cell/CellTaskListInfo.cc --- a/TaskManager/Cell/CellTaskListInfo.cc Sat May 22 23:41:20 2010 +0900 +++ b/TaskManager/Cell/CellTaskListInfo.cc Sat May 22 23:42:58 2010 +0900 @@ -6,28 +6,26 @@ (TaskListPtr)((memaddr)(addr) + (size)) int -CellTaskListInfo::extend_pool(int num) +TaskListInfo::extend_pool(int num) { - TaskListPtr q = NULL; + TaskListPtr q; int unit_size; unit_size = (ROUND_UP_ALIGN(sizeof(TaskList), DEFAULT_ALIGNMENT)); posix_memalign((void**)&q, DEFAULT_ALIGNMENT, unit_size*(num+1)); - if (q == NULL) { - return -1; + // First Queue is previous pool + q->waiter = waiter; waiter = q; + q++; + + /* Connect all free queue in the pool */ + TaskListPtr p = q; + for (; num-- > 0; p++) { + p->waiter = NULL; + taskListPool.addLast(p); } - - q->next = taskListPool; - taskListPool = q; - - /* Connect all free pack_list in the pool */ - q = NEXT_ADDR(taskListPool, unit_size); // q = taskListPool + 1; - for (; --num > 0; q = NEXT_ADDR(q, unit_size)) { - q->next = NEXT_ADDR(q, unit_size); // q->next = q + 1; - } - q->next = freeTaskList; - freeTaskList = NEXT_ADDR(taskListPool, unit_size); return 0; } + +/* end */ diff -r baeab6b5c0ab -r df36d41d5135 TaskManager/Cell/CellTaskManagerImpl.cc --- a/TaskManager/Cell/CellTaskManagerImpl.cc Sat May 22 23:41:20 2010 +0900 +++ b/TaskManager/Cell/CellTaskManagerImpl.cc Sat May 22 23:42:58 2010 +0900 @@ -17,13 +17,6 @@ { delete speThreads; delete [] speTaskList; - delete [] speTaskList_bg; - /** - * bufferManager は - * ppeManager のなかで delete してもらう - */ - // delete bufferManager; - delete [] flag_sendTaskList; delete ppeManager; } @@ -33,7 +26,7 @@ { spe_running = 0; taskListImpl = new CellTaskListInfo; - taskListImpl->init(16); + activeTaskQueue = new HTaskInfo(); @@ -42,18 +35,12 @@ speThreads = new SpeThreads(machineNum); speThreads->init(); - speTaskList = new TaskListPtr[machineNum]; - speTaskList_bg = new TaskListPtr[machineNum]; + speTaskList = new TaskListInfoPtr[machineNum]; for (int i = 0; i < machineNum; i++) { - speTaskList[i] = taskListImpl->create(); - speTaskList_bg[i] = taskListImpl->create(); + speTaskList[i] = new TaskListInfo(); } - flag_sendTaskList = new int[machineNum]; - for (int i = 0; i < machineNum; i++) { - flag_sendTaskList[i] = 1; - } // PPE 側の管理をする Manager ppeManager = new FifoTaskManagerImpl(machineNum); // 大半のTaskQueueInfoは、共有される @@ -91,8 +78,6 @@ void CellTaskManagerImpl::set_runTaskList() { - TaskListPtr list; - SimpleTaskPtr task; int speid; while (HTaskPtr htask = activeTaskQueue->poll()) { @@ -116,40 +101,7 @@ speid %= machineNum; } } - - list = speTaskList_bg[speid]; - - if (list->length >= TASK_MAX_SIZE) { - TaskListPtr newList = taskListImpl->create(); - newList = TaskListInfo::append(newList, speTaskList_bg[speid]); - speTaskList_bg[speid] = newList; - list = newList; - } - - task = &list->tasks[list->length++]; - - if (htask->command==TaskArray1) { - // compatibility - // Task with ListData is stored in the ListData - int next = (htask->r_size)/sizeof(SimpleTask) + 1; - if (list->length+next>=TASK_MAX_SIZE) { - list->length--; - TaskListPtr newList = taskListImpl->create(); - newList = TaskListInfo::append(newList, speTaskList_bg[speid]); - speTaskList_bg[speid] = newList; - list = newList; - task = &list->tasks[list->length++]; - } - Task *array = (Task*)&list->tasks[list->length]; - list->length += next; - memcpy(array, htask->rbuf, htask->r_size); - free(htask->rbuf); - htask->rbuf = 0; htask->r_size = 0; - *task = *(SimpleTask*)htask; - } else { - *task = *(SimpleTask*)htask; - } - + set_taskList(htask, taskListInfo[speid]); } } @@ -157,7 +109,7 @@ CellTaskManagerImpl::sendTaskList() { for (int i = 0; i < machineNum; i++) { - if (flag_sendTaskList[i] == 1 && speTaskList_bg[i]->length >= 1 ) { + if ( taskListInfo[i]->length() > 0 ) { send_taskList(i); spe_running++; } @@ -165,25 +117,26 @@ } void +CellTaskManagerImpl::poll() +{ + mail_check(); + // SPE に送る TaskList の準備 + set_runTaskList(); + // TaskList 待ちの SPE に TaskList を送る + sendTaskList(); +} + +void CellTaskManagerImpl::run() { - TaskListPtr ppeTaskList = NULL; - do { // PPE side - ppeTaskList = ppeManager->get_runTaskList(); - if (ppeTaskList) - ppeManager->sendTaskList(ppeTaskList); - ppeManager->mail_check(); + ppeManager->poll(); // SPE side do { - mail_check(); - // SPE に送る TaskList の準備 - set_runTaskList(); - // TaskList 待ちの SPE に TaskList を送る - sendTaskList(); + poll(); } while (ppeManager->activeTaskQueue->empty() && spe_running >0 ); - } while (ppeTaskList || spe_running >0); + } while (!ppeManager->taskListInfo->empty() || spe_running >0); if (!waitTaskQueue->empty()) { get_scheduler()->printf("Dead lock detected\n"); } @@ -203,7 +156,7 @@ while (speThreads->has_mail(id, 1, &data)) { if (data == (memaddr)MY_SPE_STATUS_READY) { // MY_SPE_STATUS_READY: SPE が持ってた Task 全て終了 - flag_sendTaskList[id] = 1; + speTaskList[id]->freeAll(); spe_running--; } else if (data == (memaddr)MY_SPE_COMMAND_MALLOC) { // MY_SPE_COMMAND_MALLOC SPE からのmain memory request @@ -251,23 +204,19 @@ * 条件1. SPE が持ってた TaskList を終了して、次の TaskList を待ってる * 条件2. SPE に送る TaskList に Task がある * - * SPE で実行終了した TaskList [speTaskList] と - * これから実行する TaskList [speTaskList_bg] のバッファを入れ替える - * ついでに実行終了したやつは clear しておく。 + * SPE で実行終了した speTaskList と + * これから実行する taskListInfo のバッファを入れ替える */ void CellTaskManagerImpl::send_taskList(int id) { - TaskListPtr tmp; + if (taskListInfo[id]->empty()) return; + TaskListInfoPtr tmp = taskListInfo[id]; + taskListInfo[id] = speTaskList[id]; + speTaskList[id] = tmp; - tmp = speTaskList[id]; - speTaskList[id] = speTaskList_bg[id]; - speTaskList_bg[id] = tmp; - - taskListImpl->clear_taskList(speTaskList_bg[id]); - - speThreads->send_mail(id, 1, (memaddr *)&speTaskList[id]); - flag_sendTaskList[id] = 0; + tmp->getLast()->next = 0; + speThreads->send_mail(id, 1, (memaddr *)tmp->getFirst()); } void CellTaskManagerImpl::show_profile() { diff -r baeab6b5c0ab -r df36d41d5135 TaskManager/Cell/CellTaskManagerImpl.h --- a/TaskManager/Cell/CellTaskManagerImpl.h Sat May 22 23:41:20 2010 +0900 +++ b/TaskManager/Cell/CellTaskManagerImpl.h Sat May 22 23:42:58 2010 +0900 @@ -12,11 +12,10 @@ ~CellTaskManagerImpl(); /* variables */ - TaskListPtr *speTaskList; - TaskListPtr *speTaskList_bg; + TaskListInfoPtr *taskListInfo; + TaskListInfoPtr *speTaskList; // running task SpeThreads *speThreads; - int *flag_sendTaskList; FifoTaskManagerImpl *ppeManager; int spe_running; @@ -24,6 +23,7 @@ // system void init(); void run(); + void poll(); void mail_check(); void set_runTaskList(); void sendTaskList(); @@ -31,14 +31,6 @@ void show_profile() ; void start_profile() ; - // user - // int add_data(ListDataPtr, uint32, int); -#if 0 - void* allocate(int size); - void* allocate(int size,int align); - Scheduler* get_scheduler(); -#endif - private: void send_taskList(int id); }; diff -r baeab6b5c0ab -r df36d41d5135 TaskManager/Cell/SpeThreads.cc --- a/TaskManager/Cell/SpeThreads.cc Sat May 22 23:41:20 2010 +0900 +++ b/TaskManager/Cell/SpeThreads.cc Sat May 22 23:42:58 2010 +0900 @@ -3,18 +3,18 @@ #include "SpeThreads.h" #include "Scheduler.h" -SpeThreads::SpeThreads(int num) : spe_num(num) {} +SpeThreads::SpeThreads(int num) : cpu_num(num) {} SpeThreads::~SpeThreads(void) { memaddr mail = (memaddr)MY_SPE_COMMAND_EXIT; int ret; - for (int i = 0; i < spe_num; i++) { + for (int i = 0; i < cpu_num; i++) { send_mail(i, 1, &mail); } - for (int i = 0; i < spe_num; i++) { + for (int i = 0; i < cpu_num; i++) { pthread_join(threads[i], NULL); ret = spe_context_destroy(spe_ctx[i]); if (ret) { @@ -85,18 +85,18 @@ exit(EXIT_FAILURE); } - spe_ctx = new spe_context_ptr_t[spe_num]; - threads = new pthread_t[spe_num]; - args = new thread_arg_t[spe_num]; + spe_ctx = new spe_context_ptr_t[cpu_num]; + threads = new pthread_t[cpu_num]; + args = new thread_arg_t[cpu_num]; - for (int i = 0; i < spe_num; i++) { + for (int i = 0; i < cpu_num; i++) { args[i].speid = i; spe_ctx[i] = spe_context_create(0, NULL); spe_program_load(spe_ctx[i], spe_handle); args[i].ctx = spe_ctx[i]; } - for (int i = 0; i < spe_num; i++) { + for (int i = 0; i < cpu_num; i++) { pthread_create(&threads[i], NULL, &spe_thread_run, (void*)&args[i]); } diff -r baeab6b5c0ab -r df36d41d5135 TaskManager/Cell/SpeThreads.h --- a/TaskManager/Cell/SpeThreads.h Sat May 22 23:41:20 2010 +0900 +++ b/TaskManager/Cell/SpeThreads.h Sat May 22 23:42:58 2010 +0900 @@ -33,7 +33,7 @@ spe_context_ptr_t *spe_ctx; pthread_t *threads; thread_arg_t *args; - int spe_num; + int cpu_num; }; #endif diff -r baeab6b5c0ab -r df36d41d5135 TaskManager/ChangeLog --- a/TaskManager/ChangeLog Sat May 22 23:41:20 2010 +0900 +++ b/TaskManager/ChangeLog Sat May 22 23:42:58 2010 +0900 @@ -1,3 +1,8 @@ +2010-5-22 Shinji KONO + + CpuThread を作るなら、create_task は、manager にメールで教えないとだめ。 + CpuManager みたいなものを用意しないとダメか。 + 2010-5-11 Shinji KONO speTaskList_bg は追放するべきだと思われる。 diff -r baeab6b5c0ab -r df36d41d5135 TaskManager/Fifo/FifoTaskManagerImpl.cc --- a/TaskManager/Fifo/FifoTaskManagerImpl.cc Sat May 22 23:41:20 2010 +0900 +++ b/TaskManager/Fifo/FifoTaskManagerImpl.cc Sat May 22 23:42:58 2010 +0900 @@ -2,6 +2,7 @@ #include #include #include "FifoTaskManagerImpl.h" +#include "TaskListInfo.h" #include "Scheduler.h" #include "SchedTask.h" #include "types.h" @@ -15,7 +16,6 @@ { delete mainScheduler; - delete taskListImpl ; delete taskQueueImpl ; delete htaskImpl ; @@ -36,11 +36,8 @@ mainScheduler->id = 0; set_scheduler(mainScheduler); - taskListImpl = new TaskListInfo; - // taskQueueImpl = new TaskQueueInfo; - // htaskImpl = new HTaskInfo(); - - mainTaskList = taskListImpl->create(); + taskListInfo = new TaskListInfo; + ppeTaskList = new TaskListInfo; schedTaskManager = new SchedTask(); schedTaskManager->init(0,0,0,mainScheduler); @@ -61,12 +58,12 @@ mainScheduler->init(this); set_scheduler(mainScheduler); - taskListImpl = tm-> taskListImpl ; taskQueueImpl = tm-> taskQueueImpl ; htaskImpl = tm-> htaskImpl ; waitTaskQueue = tm->waitTaskQueue; - mainTaskList = taskListImpl->create(); + taskListInfo = new TaskListInfo; + ppeTaskList = new TaskListInfo; schedTaskManager = new SchedTask(); schedTaskManager->init(0,0,0,mainScheduler); @@ -84,75 +81,32 @@ * ActiveTaskQueue (依存条件は満たし済み) のタスクを * 実行タスクリストに入れる */ -TaskListPtr -FifoTaskManagerImpl::get_runTaskList() +void +FifoTaskManagerImpl::set_runTaskList() { - TaskListPtr list, list_top; - SimpleTaskPtr 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 (htask->command==TaskArray1) { - // compatibility - int next = ((htask->r_size)/sizeof(SimpleTask))+1; - if (list->length+next>=TASK_MAX_SIZE) { - list->length--; - TaskListPtr newList = taskListImpl->create(); - list_top = TaskListInfo::append(list_top, newList); - list = newList; - task = &list->tasks[list->length++]; - } - Task *array = (Task*)&list->tasks[list->length]; - list->length += next; - if (list->length>=TASK_MAX_SIZE) { - perror("task array1 overflow\n"); - } - memcpy(array, htask->rbuf, htask->r_size); - free(htask->rbuf); - htask->rbuf = 0; htask->r_size = 0; - *task = *(SimpleTask*)htask; - } else { - *task = *(SimpleTask*)htask; - } - if (list->length >= TASK_MAX_SIZE) { - TaskListPtr newList = taskListImpl->create(); - list_top = TaskListInfo::append(list_top, newList); - list = newList; - } - // activeTaskQueue->free_(htask); ここで free しないで、 - // mail を待つ + set_taskList(htask, taskListInfo ); } - - mainTaskList = list_top; - - return list_top; } +void +FifoTaskManagerImpl::poll() +{ + set_runTaskList(); + // list を実行する + sendTaskList(); + // ppe scheduler からの mail を調べる + mail_check(); +} void FifoTaskManagerImpl::run() { - TaskListPtr list; + do { + poll(); + } while(!activeTaskQueue->empty()) ; - while((list = get_runTaskList())) { - // list を実行する - sendTaskList(list); - // ppe scheduler からの mail を調べる - mail_check(); - } if (!waitTaskQueue->empty()) { get_scheduler()->printf("Dead lock detected\n"); } @@ -165,10 +119,15 @@ * [Tasklist] -> [番兵] -> scheduler->run を抜ける */ void -FifoTaskManagerImpl::sendTaskList(TaskListPtr list) +FifoTaskManagerImpl::sendTaskList() { + if (taskListInfo->empty()) return; + TaskListInfoPtr tmp = ppeTaskList; + ppeTaskList = taskListInfo; + taskListInfo = tmp; + ppeTaskList->getLast()->next = 0; // TaskList のアドレスを送る - mainScheduler->mail_write_from_host((memaddr)list); + mainScheduler->mail_write_from_host((memaddr)ppeTaskList->getFirst()); // EXIT_COMMAND (番兵的な意味で) // これを読むと、mainScheduler->run() から抜けて来る。 @@ -197,6 +156,7 @@ if (data == (memaddr)MY_SPE_STATUS_READY) { __debug_ppe("mail_check(): Task List finish\n"); + ppeTaskList->freeAll(); } else if (data == (memaddr)MY_SPE_COMMAND_EXIT) { __debug_ppe("mail_check(): Task List finish COMMAND\n"); } else if (data == (memaddr)MY_SPE_COMMAND_MALLOC) { @@ -215,29 +175,6 @@ } } -#if 0 -static void -send_alloc_reply(FifoTaskManagerImpl *tm, int id, MainScheduler *s) -{ - /** - * info[0] = alloc_id; (CellScheduler::mainMem_alloc 参照) - * info[1] = alloc_addr; - */ - memaddr alloc_info[2]; - long alloc_size; - long command; - - alloc_info[0] = s->mail_read_from_host(); - alloc_info[1] = s->mail_read_from_host(); - command = (long)alloc_info[0]; - alloc_size = (long)alloc_info[1]; - - alloc_info[1] = (memaddr)tm->allocate(alloc_size); - - s->mail_write_from_host(alloc_info[0]); - s->mail_write_from_host(alloc_info[1]); -} -#endif /** diff -r baeab6b5c0ab -r df36d41d5135 TaskManager/Fifo/FifoTaskManagerImpl.h --- a/TaskManager/Fifo/FifoTaskManagerImpl.h Sat May 22 23:41:20 2010 +0900 +++ b/TaskManager/Fifo/FifoTaskManagerImpl.h Sat May 22 23:42:58 2010 +0900 @@ -13,24 +13,26 @@ /* variables */ int machineNum; - TaskListPtr mainTaskList; // activeTask であるべきなんじゃないの? + TaskListInfoPtr taskListInfo; + TaskListInfoPtr ppeTaskList; // running task MailManager *mailManager; MainScheduler *mainScheduler; /* functions */ // call by system - void init(void); + void init(); void init(MainScheduler*, TaskManagerImpl*); - void run(void); + void poll(); // called from CellTaskManagerImpl + void run(); void show_profile() {}; void start_profile() {}; void mail_check(); - TaskListPtr get_runTaskList(void); - void sendTaskList(TaskListPtr); + void set_runTaskList(); + void sendTaskList(); // call by user diff -r baeab6b5c0ab -r df36d41d5135 TaskManager/Makefile.def --- a/TaskManager/Makefile.def Sat May 22 23:41:20 2010 +0900 +++ b/TaskManager/Makefile.def Sat May 22 23:42:58 2010 +0900 @@ -29,8 +29,8 @@ ABIBIT = 32 -OPT = -O9 -#OPT = -g +# OPT = -O9 +OPT = -g CC = g++ CFLAGS = -Wall `sdl-config --cflags` -m$(ABIBIT) $(OPT) diff -r baeab6b5c0ab -r df36d41d5135 TaskManager/kernel/ppe/CpuThreads.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/kernel/ppe/CpuThreads.h Sat May 22 23:42:58 2010 +0900 @@ -0,0 +1,36 @@ +#ifndef INCLUDED_CPU_THREADS +#define INCLUDED_CPU_THREADS + +#include +#include "TaskManagerImpl.h" +#include "MainScheduler.h" + +typedef struct cpu_arg { + int cpuid; + // should be syncrhonized + MainScheduler *scheduler; + TaskManagerImpl *manager; +} cpu_thread_arg_t; + +class CpuThreads { +public: + /* constructor */ + CpuThreads(int num = 1, int start_id = 0); + virtual ~CpuThreads(); + static void *cpu_thread_run(void *args); + + /* functions */ + void init(); + int get_mail(int speid, int count, memaddr *ret); // BLOCKING + int has_mail(int speid, int count, memaddr *ret); // NONBLOCK + void send_mail(int speid, int num, memaddr *data); // BLOCKING + +private: + /* variables */ + pthread_t *threads; + cpu_thread_arg_t *args; + int cpu_num; + int id_offset; +}; + +#endif diff -r baeab6b5c0ab -r df36d41d5135 TaskManager/kernel/ppe/QueueInfo.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/kernel/ppe/QueueInfo.h Sat May 22 23:42:58 2010 +0900 @@ -0,0 +1,286 @@ +#ifndef INCLUDED_QUEUE_INFO +#define INCLUDED_QUEUE_INFO + +#include "base.h" + +template class Queue { +public: + + Queue(); + + T *waiter; + T *next; + T *prev; + + void init(); +}; + +template class QueueInfo : public Queue { + +public: + /* constructor */ + QueueInfo(); + + BASE_NEW_DELETE(QueueInfo); + + /* functions */ + Queue *create(); + + void free_(Queue *queue); + + void addFirst(Queue* e); + void addLast(Queue* e); + Queue* getFirst(); + Queue* getLast(); + int remove(Queue* e); + Queue* poll(); + void moveToFirst(Queue* e); // or use(); + Queue* get(int index); + Queue* find(Queue *task); + int empty(); + void freePool() ; + + // Iterator + Queue* getNext(Queue* q) ; + int length(); + +private: + /* variables */ + + static QueueInfo queuePool; + Queue* first; + Queue* last; + + /* functions */ + int extend_pool(int num); + void destroy(); +}; + + + +#ifdef CHECK +#include +#endif +#include + + +// Singleton T Pool +// you have to define it at where you want to use. +// templatestatic QueueInfo QueueInfo::queuePool; + +templateQueueInfo::QueueInfo() { + // 最初の一つは自分 + first = last = this; + this->next = this->prev = this; + this->waiter = NULL; +} + +templatevoid +QueueInfo::freePool() { + for(Queue * p = queuePool.waiter; p; ) { + Queue * next = p->waiter; + p->waiter = NULL; + free(p); + p = next; + } +} + +templateint +QueueInfo::extend_pool(int num) +{ + Queue * q = (Queue *)malloc(sizeof(Queue)*(num+1)); + + // First Queue is previous pool + q->waiter = this->waiter; this->waiter = q; + q++; + + /* Connect all free queue in the pool */ + Queue * p = q; + for (; num-- > 0; p++) { + p->waiter = NULL; + queuePool.addLast(p); + } + + return 0; +} + +/** + * Task をプールから取って来て返す + * + * @param [cmd] タスクコマンド + */ +templateQueue * +QueueInfo::create() +{ + Queue * q = queuePool.poll(); + if (! q) { + queuePool.extend_pool(64); + q = queuePool.poll(); + } + q->init(); + return q; +} + + +templatevoid +QueueInfo::free_(Queue * q) +{ + q->waiter = NULL; + queuePool.addLast(q); +} + + +/*! + QueueInfo は空にならない。最低1個は要素が入っていて + 1個目は特別扱いする。getFirst すると first->next を返す + */ + +/*! + 最初の1個は特別扱いなので、それの後に追加していく + */ +templatevoid +QueueInfo::addFirst(Queue* e) +{ + e->prev = first; + e->next = first->next; + first->next->prev = e; + first->next = e; +} + +templatevoid +QueueInfo::addLast(Queue* e) +{ +#ifdef CHECK + if (find(e)) { + fprintf(stderr,"Add duplicate task %0x\n",(int)e); + return; + // ... + } +#endif + e->next = first; + e->prev = last; + last->next = e; + last = e; +} + +templateQueue* +QueueInfo::getFirst() +{ + if (empty()) return NULL; + return first->next; +} + +templateQueue* +QueueInfo::getLast() +{ + if (empty()) return NULL; + return last; +} + +templateint +QueueInfo::remove(Queue* e) +{ +#ifdef CHECK + if (!find(e)) { + fprintf(stderr,"Remove non existing task %0x\n",(int)e); + return 0; + // ... + } +#endif + e->prev->next = e->next; + e->next->prev = e->prev; + + if (first->next == e) { + first->next = e->next; + } + if (last == e) { + last = e->prev; + } + + e->prev = NULL; + e->next = NULL; + + return 1; +} + +/*! + リストの先頭を取得および削除する。リストが空の場合は NULL を返す。 + */ + +templateQueue* +QueueInfo::poll() +{ + Queue* e = first->next; + if (e == this) { + return NULL; + } + remove(e); + return e; +} + +templatevoid +QueueInfo::moveToFirst(Queue* e) +{ + remove(e); + addFirst(e); +} + +/*! + リスト内の指定された位置にある要素を返す。 + 要素数を超えた位置を指定した場合 NULL を返す。 + */ + +templateQueue* +QueueInfo::get(int index) +{ + Queue* e = first->next; + for (int i = 0; i < index; i++) { + if (e == this) return NULL; + e = e->next; + } + return e; +} + +templateQueue* +QueueInfo::find(Queue* task) +{ + Queue* e = first->next; + for(;;) { + if (e == this) return NULL; + if (e == task) break; + e = e->next; + } + return e; +} + +templateint +QueueInfo::empty() +{ + return this->next == this; +} + +templateQueue* +QueueInfo::getNext(Queue* q) +{ + if (q->next==this) return NULL; + return q->next; +} + +templateint +QueueInfo::length() +{ + int i = 1; + if (empty()) return 0; + Queue* e = first; + while((e = e->next) != this ) i++; + return i; +} + + + + +/* end */ + + + +#endif diff -r baeab6b5c0ab -r df36d41d5135 TaskManager/kernel/ppe/TaskList.h --- a/TaskManager/kernel/ppe/TaskList.h Sat May 22 23:41:20 2010 +0900 +++ b/TaskManager/kernel/ppe/TaskList.h Sat May 22 23:42:58 2010 +0900 @@ -11,12 +11,13 @@ public: BASE_NEW_DELETE(TaskList); - int length; // 4 byte + long length; // 4 byte TaskList *next; // 4 byte + TaskList *prev; // 4 byte + TaskList *waiter; // 4 byte SimpleTask tasks[TASK_MAX_SIZE]; // 24*TASK_MAX_SIZE - TaskList *output; // 4 byte - int a[1]; // padding + void init() { length = 0; } }; typedef TaskList* TaskListPtr; diff -r baeab6b5c0ab -r df36d41d5135 TaskManager/kernel/ppe/TaskListInfo.cc --- a/TaskManager/kernel/ppe/TaskListInfo.cc Sat May 22 23:41:20 2010 +0900 +++ b/TaskManager/kernel/ppe/TaskListInfo.cc Sat May 22 23:42:58 2010 +0900 @@ -2,122 +2,229 @@ #include #include "TaskListInfo.h" -TaskListInfo::TaskListInfo(void) - :taskListPool(NULL), freeTaskList(NULL) {} -TaskListInfo::~TaskListInfo(void) { destroy(); } +// Singleton TaskList Pool +TaskListInfo TaskListInfo::taskListPool; -int -TaskListInfo::init(int num) -{ - if (taskListPool == NULL) { - return extend_pool(num); +TaskListInfo::TaskListInfo() { + // 最初の一つは自分 + first = last = this; + next = prev = this; + waiter = NULL; +} + +void +TaskListInfo::freePool() { + for(TaskListPtr p = taskListPool.waiter; p; ) { + TaskListPtr next = p->waiter; + p->waiter = NULL; + free(p); + p = next; } - return 0; } int TaskListInfo::extend_pool(int num) { - TaskListPtr q = NULL; - - q = (TaskListPtr)malloc(sizeof(TaskList)*(num+1)); + TaskListPtr q = (TaskListPtr)malloc(sizeof(TaskList)*(num+1)); - if (q == NULL) { - return -1; - } + // First Queue is previous pool + q->waiter = waiter; waiter = q; + q++; - q->next = taskListPool; - taskListPool = q; - - /* Connect all free pack_list in the pool */ - for (q = taskListPool + 1; --num > 0; q++) { - q->next = q + 1; + /* Connect all free queue in the pool */ + TaskListPtr p = q; + for (; num-- > 0; p++) { + p->waiter = NULL; + taskListPool.addLast(p); } - q->next = freeTaskList; - freeTaskList = taskListPool + 1; return 0; } +/** + * Task をプールから取って来て返す + * + * @param [cmd] タスクコマンド + */ TaskListPtr -TaskListInfo::create(void) +TaskListInfo::create() { - TaskListPtr q; - - if (freeTaskList == NULL) { - extend_pool(10); + TaskListPtr q = taskListPool.poll(); + if (! q) { + taskListPool.extend_pool(64); + q = taskListPool.poll(); } - q = freeTaskList; - freeTaskList = freeTaskList->next; - - q->length = 0; - q->next = 0; - + q->init(); return q; } + void -TaskListInfo::free(TaskListPtr q) +TaskListInfo::free_(TaskListPtr q) +{ + q->waiter = NULL; + taskListPool.addLast(q); +} + +void +TaskListInfo::freeAll() { - q->next = freeTaskList; - freeTaskList = q; + TaskListPtr t; + if (getLast()->next==0) getLast()->next = this; + while((t=poll())) free_(t); +} + + +/*! + TaskListInfo は空にならない。最低1個は要素が入っていて + 1個目は特別扱いする。getFirst すると first->next を返す + */ + +/*! + 最初の1個は特別扱いなので、それの後に追加していく + */ +void +TaskListInfo::addFirst(TaskList* e) +{ + e->prev = first; + e->next = first->next; + first->next->prev = e; + first->next = e; } void -TaskListInfo::destroy(void) +TaskListInfo::addLast(TaskList* e) { - TaskListPtr q, tmp; +#ifdef CHECK + if (find(e)) { + fprintf(stderr,"Add duplicate task %0x\n",(int)e); + return; + // ... + } +#endif + e->next = first; + e->prev = last; + last->next = e; + last = e; +} + +TaskList* +TaskListInfo::getFirst() +{ + if (empty()) return NULL; + return first->next; +} - //for (q = taskListPool; q; q = q->next) { - q = taskListPool; - while (q) { - tmp = q->next; - free(q); - q = tmp; +TaskList* +TaskListInfo::getLast() +{ + if (empty()) return NULL; + return last; +} + +int +TaskListInfo::remove(TaskList* e) +{ +#ifdef CHECK + if (!find(e)) { + fprintf(stderr,"Remove non existing task %0x\n",(int)e); + return 0; + // ... } - freeTaskList = taskListPool = NULL; +#endif + e->prev->next = e->next; + e->next->prev = e->prev; + + if (first->next == e) { + first->next = e->next; + } + if (last == e) { + last = e->prev; + } + + e->prev = NULL; + e->next = NULL; + + return 1; } -TaskListPtr -TaskListInfo::append(TaskListPtr list, TaskListPtr q) +/*! + リストの先頭を取得および削除する。リストが空の場合は NULL を返す。 + */ + +TaskList* +TaskListInfo::poll() { - TaskListPtr p = list; + TaskList* e = first->next; + if (e == this) { + return NULL; + } + remove(e); + return e; +} + +void +TaskListInfo::moveToFirst(TaskList* e) +{ + remove(e); + addFirst(e); +} + +/*! + リスト内の指定された位置にある要素を返す。 + 要素数を超えた位置を指定した場合 NULL を返す。 + */ - if (!p) { - return q; - } else { - while (p->next) p = p->next; - p->next = q; - return list; +TaskList* +TaskListInfo::get(int index) +{ + TaskList* e = first->next; + for (int i = 0; i < index; i++) { + if (e == this) return NULL; + e = e->next; + } + return e; +} + +TaskList* +TaskListInfo::find(TaskList* task) +{ + TaskList* e = first->next; + for(;;) { + if (e == this) return NULL; + if (e == task) break; + e = e->next; } + return e; +} + +int +TaskListInfo::empty() +{ + return next == this; +} + +TaskList* +TaskListInfo::getNext(TaskList* q) +{ + if (q->next==this) return NULL; + return q->next; +} + +int +TaskListInfo::length() +{ + int i = 1; + if (empty()) return 0; + TaskList* e = first; + while((e = e->next) != this ) i++; + return i; } -TaskListPtr -TaskListInfo::clear_taskList(TaskListPtr list) -{ - TaskListPtr p, p1; - list->length = 0; - - p = list->next; - while (p) { - p1 = p; - p = p->next; - this->free(p1); - } - list->next = NULL; - return list; -} +/* end */ -int -TaskListInfo::length(TaskListPtr list) -{ - int i = 0; - if (!list) return i; - while((list=list->next)) i++; - return i; -} diff -r baeab6b5c0ab -r df36d41d5135 TaskManager/kernel/ppe/TaskListInfo.h --- a/TaskManager/kernel/ppe/TaskListInfo.h Sat May 22 23:41:20 2010 +0900 +++ b/TaskManager/kernel/ppe/TaskListInfo.h Sat May 22 23:42:58 2010 +0900 @@ -4,31 +4,48 @@ #include "types.h" #include "TaskList.h" -class TaskListInfo { +class TaskListInfo : public TaskList { public: /* constructor */ - TaskListInfo(void); - virtual ~TaskListInfo(void); + TaskListInfo(); + + BASE_NEW_DELETE(TaskListInfo); /* functions */ - int init(int num); - TaskListPtr create(void); - void free(TaskListPtr list); - static TaskListPtr append(TaskListPtr list, TaskListPtr q); - virtual int extend_pool(int num); - TaskListPtr clear_taskList(TaskListPtr list); + TaskListPtr create(); + + void free_(TaskListPtr queue); + void freeAll(); - static int length(TaskListPtr list); + void addFirst(TaskList* e); + void addLast(TaskList* e); + TaskList* getFirst(); + TaskList* getLast(); + int remove(TaskList* e); + TaskList* poll(); + void moveToFirst(TaskList* e); // or use(); + TaskList* get(int index); + TaskList* find(TaskList *task); + int empty(); + void freePool() ; -protected: + // Iterator + TaskList* getNext(TaskList* q) ; + int length(); + static TaskListInfo taskListPool; + +private: /* variables */ - TaskListPtr taskListPool; - TaskListPtr freeTaskList; + + TaskList* first; + TaskList* last; /* functions */ - void destroy(void); - -private: + int extend_pool(int num); + void destroy(); }; +typedef TaskListInfo *TaskListInfoPtr; + #endif + diff -r baeab6b5c0ab -r df36d41d5135 TaskManager/kernel/ppe/TaskManagerImpl.cc --- a/TaskManager/kernel/ppe/TaskManagerImpl.cc Sat May 22 23:41:20 2010 +0900 +++ b/TaskManager/kernel/ppe/TaskManagerImpl.cc Sat May 22 23:42:58 2010 +0900 @@ -6,6 +6,8 @@ #include "Scheduler.h" #include "SysTask.h" #include "SysFunc.h" +#include + static HTaskPtr systask_start; static HTaskPtr systask_finish; @@ -176,6 +178,44 @@ waitTaskQueue ->addLast(q); } +void +TaskManagerImpl::set_taskList(HTaskPtr htask, TaskListInfoPtr taskList) { + TaskListPtr list ; + if ( taskList->empty() ) { + list = taskList->create(); + taskList->addLast(list); + } else + list = taskList->getLast(); + SimpleTaskPtr task = &list->tasks[list->length++]; + if (htask->command==TaskArray1) { + // compatibility + int next = ((htask->r_size)/sizeof(SimpleTask))+1; + if (list->length+next>=TASK_MAX_SIZE) { + list->length--; + TaskListPtr newList = taskList->create(); + taskList->addLast(newList); + list = newList; + task = &list->tasks[list->length++]; + } + Task *array = (Task*)&list->tasks[list->length]; + list->length += next; + if (list->length>=TASK_MAX_SIZE) { + perror("task array1 overflow\n"); + } + memcpy(array, htask->rbuf, htask->r_size); + free(htask->rbuf); + htask->rbuf = 0; htask->r_size = 0; + *task = *(SimpleTask*)htask; + } else { + *task = *(SimpleTask*)htask; + } + if (list->length >= TASK_MAX_SIZE) { + TaskListPtr newList = taskList->create(); + taskList->addLast(newList); + list = newList; + } +} + /* end */ diff -r baeab6b5c0ab -r df36d41d5135 TaskManager/kernel/ppe/TaskManagerImpl.h --- a/TaskManager/kernel/ppe/TaskManagerImpl.h Sat May 22 23:41:20 2010 +0900 +++ b/TaskManager/kernel/ppe/TaskManagerImpl.h Sat May 22 23:42:58 2010 +0900 @@ -18,7 +18,6 @@ HTaskInfo *activeTaskQueue; HTaskInfo *waitTaskQueue; - TaskListInfo *taskListImpl; TaskQueueInfo *taskQueueImpl; HTaskInfo *htaskImpl; @@ -50,6 +49,7 @@ virtual void set_task_depend(HTaskPtr master, HTaskPtr slave); virtual void spawn_task(HTaskPtr); virtual void set_task_cpu(HTaskPtr, CPU_TYPE); + void set_taskList(HTaskPtr htask, TaskListInfoPtr taskList) ; void* allocate(int size, int alignment) { diff -r baeab6b5c0ab -r df36d41d5135 TaskManager/kernel/schedule/SchedTaskArray.cc --- a/TaskManager/kernel/schedule/SchedTaskArray.cc Sat May 22 23:41:20 2010 +0900 +++ b/TaskManager/kernel/schedule/SchedTaskArray.cc Sat May 22 23:42:58 2010 +0900 @@ -41,7 +41,8 @@ outListData.length = 0; outListData.element = 0; - atask = (TaskPtr)&savedTask->list->tasks[savedTask->cur_index]; + SimpleTaskPtr st = &savedTask->list->tasks[savedTask->cur_index]; + atask = (TaskPtr)st; array = 0; savedTask->cur_index += (atask->size()+sizeof(SimpleTask))/sizeof(SimpleTask);