changeset 811:df36d41d5135

merge
author yutaka@localhost.localdomain
date Sat, 22 May 2010 23:42:58 +0900
parents baeab6b5c0ab (current diff) 76a39ad68846 (diff)
children f3f982bc271c
files
diffstat 17 files changed, 681 insertions(+), 310 deletions(-) [+]
line wrap: on
line diff
--- 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 */
--- 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() {
--- 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);
 };
--- 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]);
     }
--- 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
--- 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 <kono@ie.u-ryukyu.ac.jp>
+
+   CpuThread を作るなら、create_task は、manager にメールで教えないとだめ。
+   CpuManager みたいなものを用意しないとダメか。
+
 2010-5-11 Shinji KONO <kono@ie.u-ryukyu.ac.jp>
 
     speTaskList_bg は追放するべきだと思われる。
--- 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 <stdlib.h>
 #include <string.h>
 #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
 
 
 /**
--- 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
 
--- 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)
--- /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 <pthread.h>
+#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
--- /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 <typename T> class Queue {
+public:
+
+    Queue<T>();
+
+    T *waiter;
+    T *next;
+    T *prev;
+
+    void init();
+};
+
+template <typename T> class QueueInfo : public Queue<T> {
+
+public:
+    /* constructor */
+    QueueInfo<T>();
+
+    BASE_NEW_DELETE(QueueInfo);
+
+    /* functions */
+    Queue<T> *create();
+
+    void free_(Queue<T> *queue);
+
+    void addFirst(Queue<T>* e);
+    void addLast(Queue<T>* e);
+    Queue<T>* getFirst();
+    Queue<T>* getLast();
+    int remove(Queue<T>* e);
+    Queue<T>* poll();
+    void moveToFirst(Queue<T>* e); // or use();
+    Queue<T>* get(int index);
+    Queue<T>* find(Queue<T> *task);
+    int empty();
+    void freePool() ;
+
+    // Iterator
+    Queue<T>* getNext(Queue<T>* q) ;
+    int length();
+
+private:
+    /* variables */
+
+    static QueueInfo<T> queuePool;
+    Queue<T>* first;
+    Queue<T>* last;
+
+    /* functions */
+    int extend_pool(int num);
+    void destroy();  
+};
+
+
+
+#ifdef CHECK
+#include <stdio.h>
+#endif
+#include <stdlib.h>
+
+
+// Singleton T Pool
+// you have to define it at where you want to use.
+// template<typename T>static QueueInfo<T> QueueInfo<T>::queuePool;   
+
+template<typename T>QueueInfo<T>::QueueInfo() {
+    // 最初の一つは自分
+    first = last = this;
+    this->next = this->prev = this;
+    this->waiter = NULL;
+}
+
+template<typename T>void
+QueueInfo<T>::freePool() { 
+    for(Queue<T> * p = queuePool.waiter; p; ) {
+	Queue<T> * next = p->waiter;
+	p->waiter = NULL;
+	free(p);
+	p = next;
+    }
+}
+
+template<typename T>int
+QueueInfo<T>::extend_pool(int num)
+{
+    Queue<T> * q = (Queue<T> *)malloc(sizeof(Queue<T>)*(num+1));
+
+    // First Queue is previous pool
+    q->waiter = this->waiter; this->waiter = q;
+    q++;
+
+    /* Connect all free queue in the pool */
+    Queue<T> * p = q;
+    for (; num-- > 0; p++) {
+	p->waiter = NULL;
+	queuePool.addLast(p);
+    }
+
+    return 0;
+}
+
+/**
+ * Task をプールから取って来て返す
+ *
+ * @param [cmd] タスクコマンド
+ */
+template<typename T>Queue<T> *
+QueueInfo<T>::create()
+{
+    Queue<T> * q =  queuePool.poll();
+    if (! q)  {
+	queuePool.extend_pool(64);
+	q = queuePool.poll();
+    }
+    q->init();
+    return q;
+}
+
+
+template<typename T>void
+QueueInfo<T>::free_(Queue<T> * q)
+{
+    q->waiter = NULL;
+    queuePool.addLast(q);
+}
+
+
+/*!
+  QueueInfo<T> は空にならない。最低1個は要素が入っていて
+  1個目は特別扱いする。getFirst すると first->next を返す
+ */
+
+/*!
+  最初の1個は特別扱いなので、それの後に追加していく
+ */
+template<typename T>void
+QueueInfo<T>::addFirst(Queue<T>* e)
+{
+    e->prev = first;
+    e->next = first->next;
+    first->next->prev = e;
+    first->next = e;
+}
+
+template<typename T>void
+QueueInfo<T>::addLast(Queue<T>* 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;
+}
+
+template<typename T>Queue<T>*
+QueueInfo<T>::getFirst()
+{
+    if (empty()) return NULL;
+    return first->next;
+}
+
+template<typename T>Queue<T>*
+QueueInfo<T>::getLast()
+{
+    if (empty()) return NULL;
+    return last;
+}
+
+template<typename T>int
+QueueInfo<T>::remove(Queue<T>* 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 を返す。
+ */
+
+template<typename T>Queue<T>*
+QueueInfo<T>::poll()
+{
+    Queue<T>* e = first->next;
+    if (e == this) {
+	return NULL;
+    }
+    remove(e);
+    return e;
+}
+
+template<typename T>void
+QueueInfo<T>::moveToFirst(Queue<T>* e)
+{
+    remove(e);
+    addFirst(e);
+}
+
+/*!
+  リスト内の指定された位置にある要素を返す。
+  要素数を超えた位置を指定した場合 NULL を返す。
+ */
+
+template<typename T>Queue<T>*
+QueueInfo<T>::get(int index)
+{
+    Queue<T>* e = first->next;
+    for (int i = 0; i < index; i++) {
+	if (e == this) return NULL;
+	e = e->next;
+    }
+    return e;
+}
+
+template<typename T>Queue<T>*
+QueueInfo<T>::find(Queue<T>* task)
+{
+    Queue<T>* e = first->next;
+    for(;;) {
+	if (e == this) return NULL;
+	if (e == task) break;
+	e = e->next;
+    }
+    return e;
+}
+
+template<typename T>int
+QueueInfo<T>::empty()
+{
+    return this->next == this;
+}
+
+template<typename T>Queue<T>*
+QueueInfo<T>::getNext(Queue<T>* q) 
+{
+    if (q->next==this) return NULL;
+    return q->next;
+}
+
+template<typename T>int
+QueueInfo<T>::length() 
+{
+    int i = 1;
+    if (empty()) return 0;
+    Queue<T>* e = first;
+    while((e = e->next) != this ) i++;
+    return i;
+}
+
+
+
+
+/* end */
+
+
+
+#endif
--- 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;
--- 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 <stdlib.h>
 #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;
-}
 
--- 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
+
--- 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 <string.h>
+
 
 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 */
--- 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)
     {
--- 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);