changeset 801:974cd68383b3

TaslListInfo
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 22 May 2010 18:20:16 +0900
parents 2708c4a7bade
children 3763d29f41a3
files TaskManager/Cell/CellTaskManagerImpl.cc TaskManager/Cell/SpeThreads.cc TaskManager/Cell/SpeThreads.h TaskManager/ChangeLog TaskManager/Fifo/FifoTaskManagerImpl.cc TaskManager/Fifo/FifoTaskManagerImpl.h TaskManager/kernel/ppe/CpuThreads.h TaskManager/kernel/ppe/QueueInfo.h TaskManager/kernel/ppe/TaskList.h TaskManager/kernel/ppe/TaskListInfo.cc TaskManager/kernel/ppe/TaskListInfo.h TaskManager/kernel/ppe/TaskManagerImpl.cc TaskManager/kernel/ppe/TaskManagerImpl.h
diffstat 13 files changed, 595 insertions(+), 220 deletions(-) [+]
line wrap: on
line diff
--- a/TaskManager/Cell/CellTaskManagerImpl.cc	Fri May 21 07:47:25 2010 +0900
+++ b/TaskManager/Cell/CellTaskManagerImpl.cc	Sat May 22 18:20:16 2010 +0900
@@ -91,8 +91,6 @@
 void
 CellTaskManagerImpl::set_runTaskList()
 {
-    TaskListPtr list;
-    SimpleTaskPtr task;
     int speid;
 
     while (HTaskPtr htask = activeTaskQueue->poll()) {
@@ -117,39 +115,8 @@
 	    }
 	}
 
-	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;
-        }
-
+	TaskListInfoPtr list = speTaskList_bg[speid];
+	set_taskList(htask, list);
     }
 }
 
@@ -171,7 +138,7 @@
 
     do {
         // PPE side
-	ppeTaskList =  ppeManager->get_runTaskList();
+	ppeTaskList =  ppeManager->set_runTaskList();
 	if (ppeTaskList)
 	    ppeManager->sendTaskList(ppeTaskList);
 	ppeManager->mail_check();
@@ -267,7 +234,6 @@
     taskListImpl->clear_taskList(speTaskList_bg[id]);
 
     speThreads->send_mail(id, 1, (memaddr *)&speTaskList[id]);
-    flag_sendTaskList[id] = 0;
 }
 
 void CellTaskManagerImpl::show_profile() {
--- a/TaskManager/Cell/SpeThreads.cc	Fri May 21 07:47:25 2010 +0900
+++ b/TaskManager/Cell/SpeThreads.cc	Sat May 22 18:20:16 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	Fri May 21 07:47:25 2010 +0900
+++ b/TaskManager/Cell/SpeThreads.h	Sat May 22 18:20:16 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	Fri May 21 07:47:25 2010 +0900
+++ b/TaskManager/ChangeLog	Sat May 22 18:20:16 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	Fri May 21 07:47:25 2010 +0900
+++ b/TaskManager/Fifo/FifoTaskManagerImpl.cc	Sat May 22 18:20:16 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"
@@ -36,11 +37,7 @@
     mainScheduler->id = 0;
     set_scheduler(mainScheduler);
 
-    taskListImpl  = new TaskListInfo;
-    // taskQueueImpl = new TaskQueueInfo;
-    // htaskImpl     = new HTaskInfo();
-
-    mainTaskList = taskListImpl->create();
+    taskListInfo  = new TaskListInfo;
 
     schedTaskManager = new SchedTask();
     schedTaskManager->init(0,0,0,mainScheduler);
@@ -66,7 +63,7 @@
     htaskImpl     = tm-> htaskImpl     ;
     waitTaskQueue     = tm->waitTaskQueue;   
 
-    mainTaskList = taskListImpl->create();
+    taskListInfo  = new TaskListInfo;
 
     schedTaskManager = new SchedTask();
     schedTaskManager->init(0,0,0,mainScheduler);
@@ -85,60 +82,17 @@
  * 実行タスクリストに入れる
  */
 TaskListPtr
-FifoTaskManagerImpl::get_runTaskList()
+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;
+    return taskListInfo->getFirst();
 }
 
 
@@ -147,7 +101,7 @@
 {
     TaskListPtr list;
 
-    while((list = get_runTaskList())) {
+    while((list = set_runTaskList())) {
         // list を実行する
         sendTaskList(list);
         // ppe scheduler からの mail を調べる
@@ -215,29 +169,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	Fri May 21 07:47:25 2010 +0900
+++ b/TaskManager/Fifo/FifoTaskManagerImpl.h	Sat May 22 18:20:16 2010 +0900
@@ -14,6 +14,7 @@
     /* variables */
     int machineNum;
     TaskListPtr mainTaskList;  // activeTask であるべきなんじゃないの?
+    TaskListInfoPtr taskListInfo;  // activeTask であるべきなんじゃないの?
 
     MailManager *mailManager;
     MainScheduler *mainScheduler;
@@ -29,7 +30,7 @@
 
     void mail_check();
 
-    TaskListPtr get_runTaskList(void);
+    TaskListPtr set_runTaskList();
     void sendTaskList(TaskListPtr);
 
     // call by user
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TaskManager/kernel/ppe/CpuThreads.h	Sat May 22 18:20:16 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 18:20:16 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	Fri May 21 07:47:25 2010 +0900
+++ b/TaskManager/kernel/ppe/TaskList.h	Sat May 22 18:20:16 2010 +0900
@@ -11,11 +11,11 @@
 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
 
 };
 
--- a/TaskManager/kernel/ppe/TaskListInfo.cc	Fri May 21 07:47:25 2010 +0900
+++ b/TaskManager/kernel/ppe/TaskListInfo.cc	Sat May 22 18:20:16 2010 +0900
@@ -2,122 +2,220 @@
 #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;
-
     return q;
 }
 
+
 void
-TaskListInfo::free(TaskListPtr q)
+TaskListInfo::free_(TaskListPtr q)
 {
-    q->next = freeTaskList;
-    freeTaskList = q;
+    q->waiter = NULL;
+    taskListPool.addLast(q);
+}
+
+
+/*!
+  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	Fri May 21 07:47:25 2010 +0900
+++ b/TaskManager/kernel/ppe/TaskListInfo.h	Sat May 22 18:20:16 2010 +0900
@@ -4,31 +4,47 @@
 #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);
 
-    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();
+
+private:
     /* variables */
-    TaskListPtr taskListPool;
-    TaskListPtr freeTaskList;
+
+    static TaskListInfo taskListPool;
+    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	Fri May 21 07:47:25 2010 +0900
+++ b/TaskManager/kernel/ppe/TaskManagerImpl.cc	Sat May 22 18:20:16 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,39 @@
     waitTaskQueue ->addLast(q);
 }
 
+void
+TaskManagerImpl::set_taskList(HTaskPtr htask, TaskListInfoPtr taskList) {
+    TaskListPtr 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 = taskListImpl->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 = taskListImpl->create();
+	taskList->addLast(newList);
+	list = newList;
+    }
+}
+
 
 
 /* end */
--- a/TaskManager/kernel/ppe/TaskManagerImpl.h	Fri May 21 07:47:25 2010 +0900
+++ b/TaskManager/kernel/ppe/TaskManagerImpl.h	Sat May 22 18:20:16 2010 +0900
@@ -51,6 +51,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)
     {