changeset 482:25947fcfe880

Double linked list version. test_nogl is not working now... sorry.
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 05 Oct 2009 16:52:45 +0900
parents 4ae2a89dcded (current diff) 4896dffad67c (diff)
children 0b933bef0328
files TaskManager/Cell/spe/Task.cc TaskManager/Cell/spe/TaskList.cc TaskManager/Cell/spe/TaskQueue.cc TaskManager/kernel/ppe/SymTable.cc TaskManager/kernel/ppe/SymTable.h
diffstat 23 files changed, 278 insertions(+), 432 deletions(-) [+]
line wrap: on
line diff
--- a/TaskManager/Cell/CellTaskManagerImpl.cc	Mon Oct 05 02:28:08 2009 +0900
+++ b/TaskManager/Cell/CellTaskManagerImpl.cc	Mon Oct 05 16:52:45 2009 +0900
@@ -33,6 +33,8 @@
     taskListImpl = new CellTaskListInfo;
     taskListImpl->init(machineNum*2);
 
+    activeTaskQueue = new TaskQueueInfo();
+
     htaskImpl = new CellHTaskInfo;
     htaskImpl->init(TASK_MAX_SIZE*2);
 
@@ -53,19 +55,18 @@
     } 
     // PPE 側の管理をする Manager
     ppeManager = new FifoTaskManagerImpl(machineNum);
+    // 大半のTaskQueueInfoは、共有される
     ppeManager->init(new PpeScheduler, this);
 }
 
 void
 CellTaskManagerImpl::append_activeTask(HTaskPtr task)
 {
-    TaskQueuePtr q;
-
-    q = taskQueueImpl->create(task);
     if (task->cpu_type == CPU_PPE) {
         ppeManager->append_activeTask(task);
     } else {
-        activeTaskQueue = TaskQueue::append(activeTaskQueue, q);
+	TaskQueuePtr q = taskQueueImpl->create(task);
+        activeTaskQueue->addLast(q);
     }
 }
 
@@ -86,21 +87,18 @@
 {
     // ここ...直すかな
     TaskListPtr list;
-    TaskQueuePtr queue;
+    
     TaskQueuePtr d;
     HTaskPtr htask;
     TaskPtr task;
     int speid;
 
-    queue = activeTaskQueue;
-    if (queue == NULL) {
+    if (activeTaskQueue->empty()) {
 	return ;
     }
  
-    while (queue) {
+    while (TaskQueuePtr queue = activeTaskQueue->poll()) {
 	htask = (HTaskPtr)queue->task;
-	d = queue;
-	queue = queue->next;
 
 	if (htask->cpu_type == SPE_ANY) {
 	    speid = cur_anySpeid++;
@@ -138,10 +136,10 @@
 	task->outData  = htask->outData;
 	task->self     = (unsigned int)htask;
 #else
-	memcpy(task, htask, sizeof(Task));
+	memcpy(task, (Task*)htask, sizeof(Task));
 #endif
 
-	taskQueueImpl->free(d);
+	activeTaskQueue->free(queue);
     }
 
     activeTaskQueue = NULL;
@@ -185,7 +183,7 @@
 CellTaskManagerImpl::mail_check(MailQueuePtr mail_list)
 {
     // PPE Scheduler からの mail check
-    ppeManager->mail_check(mail_list, &waitTaskQueue);
+    ppeManager->mail_check(mail_list);
 
     do {
 	unsigned int data;
@@ -258,7 +256,7 @@
 	// であり、この場合もし SPE にタスクが残っていても
 	// メインループから抜けてプログラム終了となってしまうので
 	// ここでストップかけてます。
-    } while (!ppeManager->activeTaskQueue && waitTaskQueue);
+    } while (ppeManager->activeTaskQueue->empty() && !waitTaskQueue->empty());
 	
     return ppeManager->get_runTaskList();
 }
--- a/TaskManager/Cell/spe/Task.cc	Mon Oct 05 02:28:08 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-#include "Task.h"
-
-/**
- * タスクの入力データを追加する
- *
- * @param [addr] add input data
- * @param [size] size of data at [addr]
- *
- * @return if ([ret] == 0) ? success : failuer;
- */
-int
-Task::add_inData_t(unsigned int addr, int size)
-{
-    return add_data(this->inData, addr, size);
-}
-
-int
-Task::add_outData_t(unsigned int addr, int size)
-{
-    return add_data(this->outData, addr, size);
-}
-
-/**
- * エラーの時に -1 を返す、ってことするよりは
- * perror みたいにしたほうがわかりやすいかな。
- *
- * 現在は 3 個まで。
- * 本当は、3個以上にすると task->param[] には アドレスが入り
- * そのアドレスは メインメモリでアロケートされた int の集合。
- */
-int
-Task::add_param(int _param)
-{
-    if (param_size >= MAX_PARAMS) return -1;
-
-    this->param[param_size++] = _param;
-    return 0;
-}
-
-/*
- * エラーの時に -1 を返す、ってことするよりは
- * perror みたいにしたほうがわかりやすいかな。
- */
-int
-Task::add_data(ListDataPtr list, uint32 addr, int size)
-{
-    if (list->length >= MAX_LIST_DMA_SIZE) return -1;
-
-    list->bound[list->length] = list->size;
-
-    // size でも制限かけるべき?
-    list->size += size;
-
-    ListElementPtr elm = &list->element[list->length++];
-    elm->addr = addr;
-    elm->size = size;
-
-    return 0;
-}
--- a/TaskManager/Cell/spe/TaskList.cc	Mon Oct 05 02:28:08 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,16 +0,0 @@
-#include "TaskList.h"
-
-TaskListPtr
-TaskList::append(TaskListPtr list, TaskListPtr q)
-{
-    TaskListPtr p = list;
-
-    if (!p) {
-	return q;
-    } else {
-	while (p->next) p = p->next;
-	p->next = q;
-	return list;
-    }
-}
-
--- a/TaskManager/Cell/spe/TaskQueue.cc	Mon Oct 05 02:28:08 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,21 +0,0 @@
-#include "TaskQueue.h"
-
-TaskQueue::TaskQueue(TaskPtr q)
-{
-    task = q;
-    next = NULL;
-}
-
-TaskQueuePtr
-TaskQueue::append(TaskQueuePtr list, TaskQueuePtr q)
-{
-    TaskQueuePtr p = list;
-
-    if (!p) {
-	return q;
-    } else {
-	while(p->next) p = p->next;
-	p->next = q;
-	return list;
-    }
-}
--- a/TaskManager/ChangeLog	Mon Oct 05 02:28:08 2009 +0900
+++ b/TaskManager/ChangeLog	Mon Oct 05 16:52:45 2009 +0900
@@ -1,3 +1,7 @@
+2009-10-05 Shinji KONO <kono@ie.u-ryukyu.ac.jp>
+
+    TaskQueue のfree list の管理はシステムで一つであるべき。
+
 2009-10-02 Shinji KONO <kono@ie.u-ryukyu.ac.jp>
 
     DrawSpan で、~DrawSpan() で、allocate したデータを DMA_WAIT
--- a/TaskManager/Fifo/FifoTaskManagerImpl.cc	Mon Oct 05 02:28:08 2009 +0900
+++ b/TaskManager/Fifo/FifoTaskManagerImpl.cc	Mon Oct 05 16:52:45 2009 +0900
@@ -66,9 +66,12 @@
     taskListImpl  = tm-> taskListImpl  ;
     taskQueueImpl = tm-> taskQueueImpl ;
     htaskImpl     = tm-> htaskImpl     ;
+    waitTaskQueue     = tm->waitTaskQueue; 
+    // activeQueue は?
 
     mainTaskList = taskListImpl->create();
 
+
 }
 
 /**
@@ -83,13 +86,10 @@
 FifoTaskManagerImpl::get_runTaskList()
 {
     TaskListPtr list, list_top;
-    TaskQueuePtr queue;
-    TaskQueuePtr d;
     HTaskPtr htask; // HTask (PPE にある)
     TaskPtr task; // Task (SPE に送る Task)
 
-    queue = activeTaskQueue;
-    if (queue == NULL) {
+    if (activeTaskQueue->empty()) {
         return NULL;
     }
 
@@ -100,14 +100,12 @@
     list_top = taskListImpl->clear_taskList(list_top);
     list = list_top;
 
-    while (queue) {
+    while (TaskQueuePtr queue = activeTaskQueue->poll()) {
         htask = (HTaskPtr)queue->task;
-        d = queue;
-        queue = queue->next;
 
         task = &list->tasks[list->length++];
 
-        memcpy(task, htask, sizeof(Task));
+        memcpy(task, (Task*)htask, sizeof(Task));
 
         if (list->length >= TASK_MAX_SIZE) {
             TaskListPtr newList = taskListImpl->create();
@@ -115,10 +113,9 @@
             list = newList;
         }
 
-        taskQueueImpl->free(d);
+        activeTaskQueue->free(queue);
     }
 
-    activeTaskQueue = NULL;
     mainTaskList = list_top;
 
     return list_top;
@@ -219,13 +216,6 @@
     }
 }
 
-void
-FifoTaskManagerImpl::mail_check(MailQueuePtr mail_list, TaskQueuePtr *wait)
-{
-    waitTaskQueue = *wait;
-    mail_check(mail_list);
-}
-
 void*
 FifoTaskManagerImpl::allocate(int size)
 {
--- a/TaskManager/Fifo/FifoTaskManagerImpl.h	Mon Oct 05 02:28:08 2009 +0900
+++ b/TaskManager/Fifo/FifoTaskManagerImpl.h	Mon Oct 05 16:52:45 2009 +0900
@@ -13,7 +13,7 @@
 
     /* variables */
     int machineNum;
-    TaskListPtr mainTaskList;
+    TaskListPtr mainTaskList;  // activeTask であるべきなんじゃないの?
 
     MailManager *mailManager;
     MainScheduler *scheduler;
@@ -24,7 +24,6 @@
     void init(MainScheduler*, TaskManagerImpl*);
     void run(void);
     void mail_check(MailQueuePtr mail_list);
-    void mail_check(MailQueuePtr mail_list, TaskQueuePtr *waitQueue);
     TaskListPtr get_runTaskList(void);
     MailQueuePtr schedule(TaskListPtr);
 
--- a/TaskManager/Makefile.cell	Mon Oct 05 02:28:08 2009 +0900
+++ b/TaskManager/Makefile.cell	Mon Oct 05 16:52:45 2009 +0900
@@ -19,15 +19,17 @@
 
 CELL_SPE_SRCS =  \
     $(CELL_SPE_DIR)/CellDmaManager.cc   \
+    $(CELL_SPE_DIR)/CellScheduler.cc    \
+    $(CELL_SPE_DIR)/main.cc
+
+CELL_SPE_TASK_SRCS =  \
     $(CELL_SPE_DIR)/TaskList.cc \
-    $(CELL_SPE_DIR)/CellScheduler.cc    \
     $(CELL_SPE_DIR)/TaskQueue.cc \
-    $(CELL_SPE_DIR)/Task.cc            \
-    $(CELL_SPE_DIR)/main.cc
+    $(CELL_SPE_DIR)/Task.cc           
 
 # $(wildcard $(CELL_SPE_DIR)/*.cc)
 
-CELL_SPE_OBJS = $(CELL_SPE_SRCS:.cc=.o) $(CELL_SPE_SCHEDULE_OBJ)
+CELL_SPE_OBJS = $(CELL_SPE_SRCS:.cc=.o) $(CELL_SPE_SCHEDULE_OBJ) $(CELL_SPE_TASK_SRCS:.cc=.o)
 
 SPUCC = spu-g++
 
@@ -53,6 +55,8 @@
 $(CELL_SPE_SCHEDULE_SRC): kernel/schedule/*.cc
 	cp kernel/schedule/*.cc $(CELL_SPE_DIR)/
 	cp kernel/memory/*.cc $(CELL_SPE_DIR)/
+	cp kernel/ppe/{TaskList.cc,TaskQueue.cc,Task.cc} $(CELL_SPE_DIR)/
+
 $(CELL_SPE_OBJS): %.o : %.cc
 	$(SPUCC) $(CFLAGS) $(SPE_CFLAGS) $(INCLUDE) -c $< -o $@
 
@@ -61,7 +65,7 @@
 	rm -f $(SPETARGET)
 
 cellclean:
-	rm -f $(CELL_SPE_OBJS) $(CELL_SPE_SCHEDULE_SRC)
+	rm -f $(CELL_SPE_OBJS) $(CELL_SPE_SCHEDULE_SRC) $(CELL_SPE_TASK_SRCS)
 	(cd $(CELL_SPE_DIR); rm -f *~ \#*)
 
 
--- a/TaskManager/kernel/ppe/HTask.h	Mon Oct 05 02:28:08 2009 +0900
+++ b/TaskManager/kernel/ppe/HTask.h	Mon Oct 05 16:52:45 2009 +0900
@@ -6,6 +6,7 @@
 #include "Task.h"
 #include "TaskQueueInfo.h"
 
+class TaskQueueInfo;
 class TaskManagerImpl;
 
 /*!
@@ -23,12 +24,12 @@
 public:
     BASE_NEW_DELETE(HTask);
 
-    TaskQueuePtr wait_me;  // List of task waiting for me
-    TaskQueuePtr wait_i;   // List of task for which I am waiting
+    TaskQueueInfo *wait_me;  // List of task waiting for me
+    TaskQueueInfo *wait_i;   // List of task for which I am waiting
     void (*post_func)(void *arg);
     void *post_arg;
     CPU_TYPE cpu_type;
-    HTask *next;
+    HTask *next;             // free list 用
     TaskManagerImpl *mimpl;
 
     void spawn(void);
--- a/TaskManager/kernel/ppe/HTaskInfo.cc	Mon Oct 05 02:28:08 2009 +0900
+++ b/TaskManager/kernel/ppe/HTaskInfo.cc	Mon Oct 05 16:52:45 2009 +0900
@@ -37,12 +37,16 @@
     /* Connect all free queue in the pool */
     for (q = htaskPool + 1; --num > 0; q++) {
 	q->next = q + 1;
+	q->wait_me = new TaskQueueInfo();
+	q->wait_i = new TaskQueueInfo();
 	q->inData = (ListDataPtr)malloc(sizeof(ListData));
 	q->outData = (ListDataPtr)malloc(sizeof(ListData));
     }
     q->next = freeHTask;
     q->inData = (ListDataPtr)malloc(sizeof(ListData));
     q->outData = (ListDataPtr)malloc(sizeof(ListData));
+    q->wait_me = new TaskQueueInfo();
+    q->wait_i = new TaskQueueInfo();
 
     freeHTask = htaskPool + 1;
 
@@ -72,8 +76,6 @@
     q->self = (unsigned int)q;
     q->param_size = 0;
 
-    q->wait_me  = NULL;
-    q->wait_i   = NULL;
     q->post_func = NULL;
     q->mimpl     = NULL;
     q->cpu_type  = CPU_PPE;
--- a/TaskManager/kernel/ppe/SymTable.cc	Mon Oct 05 02:28:08 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +0,0 @@
-#include <string.h>
-#include "SymTable.h"
-
-SymTable::~SymTable(void)
-{
-    SymTbPtr tb;
-
-    for (int i = 0; i < symtb_index; i++) {
-	tb = &symtb[i];
-	delete [] tb->sym;
-    }
-
-    delete [] symtb;
-}
-
-void
-SymTable::init(void)
-{
-    symtb = new SymTb[SYM_MAX_SIZE];
-    symtb_index = 0;
-}
-
-void
-SymTable::set_symbol(const char *sym, FuncObject addr)
-{
-    SymTbPtr tb = &symtb[symtb_index++];
-
-    tb->sym = new char[strlen(sym)+1];
-    memcpy(tb->sym, sym, strlen(sym)+1);
-    tb->address = addr;
-}
-
-void
-SymTable::set_func(int id, FuncObject addr)
-{
-     SymTbPtr tb = &symtb[id];
-
-     tb->address = addr;
-}
-
-SymTable::FuncObject
-SymTable::get_address(int fd)
-{
-    if (fd >= symtb_index) {
-	// Fix me
-	// error process
-    }
-
-    return symtb[fd].address;
-}
-
-
-int
-SymTable::get_fd(const char *sym)
-{
-    SymTbPtr tb;
-
-    for (int i = 0; i < SYM_MAX_SIZE; i++) {
-	tb = &symtb[i];
-	if (strcmp(tb->sym, sym) == 0) {
-	    return i;
-	}
-    }
-
-    return -1;
-}
--- a/TaskManager/kernel/ppe/SymTable.h	Mon Oct 05 02:28:08 2009 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-#ifndef INCLUDED_SYMTABLE
-#define INCLUDED_SYMTABLE
-
-#define SYM_MAX_SIZE 64
-
-class SymTable {
-public:
-    ~SymTable(void);
-
-    typedef int (*FuncObject)(void *, void*);
-
-    typedef struct sym_table {
-	 char *sym;
-	 FuncObject address;
-    } SymTb, *SymTbPtr;
-
-    SymTbPtr symtb;
-    int symtb_index;
-
-    void init(void);
-    void set_symbol(const char *sym, FuncObject addr);
-    void set_func(int id, FuncObject addr);
-    int get_fd(const char *sym);
-    FuncObject get_address(int fd);
-};
-
-#endif
--- a/TaskManager/kernel/ppe/Task.cc	Mon Oct 05 02:28:08 2009 +0900
+++ b/TaskManager/kernel/ppe/Task.cc	Mon Oct 05 16:52:45 2009 +0900
@@ -31,6 +31,10 @@
 /**
  * エラーの時に -1 を返す、ってことするよりは
  * perror みたいにしたほうがわかりやすいかな。
+ *
+ * 現在は 3 個まで。
+ * 本当は、3個以上にすると task->param[] には アドレスが入り
+ * そのアドレスは メインメモリでアロケートされた int の集合。
  */
 int
 Task::add_param(int _param)
--- a/TaskManager/kernel/ppe/TaskManager.cc	Mon Oct 05 02:28:08 2009 +0900
+++ b/TaskManager/kernel/ppe/TaskManager.cc	Mon Oct 05 16:52:45 2009 +0900
@@ -90,3 +90,5 @@
 TaskManager::get_scheduler() {
     return m_impl->get_scheduler();
 }
+
+/* end */
--- a/TaskManager/kernel/ppe/TaskManagerImpl.cc	Mon Oct 05 02:28:08 2009 +0900
+++ b/TaskManager/kernel/ppe/TaskManagerImpl.cc	Mon Oct 05 16:52:45 2009 +0900
@@ -13,7 +13,11 @@
 }
 
 TaskManagerImpl::TaskManagerImpl(int num)
-    : machineNum(num), activeTaskQueue(NULL), waitTaskQueue(NULL) {}
+    : machineNum(num) {
+    activeTaskQueue = new TaskQueueInfo();
+    waitTaskQueue = new TaskQueueInfo();
+    taskQueueImpl = new TaskQueueInfo();
+}
 
 /**
  * 一番最初に PPE で実行される systask_start
@@ -62,8 +66,9 @@
     m = taskQueueImpl->create(master);
     s = taskQueueImpl->create(slave);
 
-    master->wait_me = TaskQueue::append(master->wait_me, s);
-    slave->wait_i   = TaskQueue::append(slave->wait_i, m);
+    master->wait_me->addLast(s);
+    slave->wait_i->addLast(m);
+    s->waiter = m;
 }
 
 /**
@@ -76,7 +81,7 @@
 {
     // waiter // master
     // waitee // slave
-    if (task->wait_i == NULL) {
+    if (task->wait_i->empty()) {
         append_activeTask(task);
     } else {
         append_waitTask(task);
@@ -91,10 +96,8 @@
 void
 TaskManagerImpl::append_activeTask(HTaskPtr task)
 {
-    TaskQueuePtr q;
-
-    q = taskQueueImpl->create(task);
-    activeTaskQueue = TaskQueue::append(activeTaskQueue, q);
+    TaskQueuePtr q = taskQueueImpl->create(task);
+    activeTaskQueue->addLast(q);
 }
 
 /**
@@ -112,46 +115,33 @@
 /**
  * 終了したタスクから依存の処理とか
  * post_func() はこのタスクが終了したら実行する関数。
- * 今のところ使ってないっす
  *
  * @param [task] 終了したタスク
  */
 void
 TaskManagerImpl::check_task_finish(HTaskPtr task)
 {
-    notify_wait_taskQueue(task, task->wait_me);
+    while(TaskQueue *p = task->wait_me->poll()) {
+	HTaskPtr htask = (HTaskPtr)p->task;
+	TaskQueueInfo *wait_i = htask->wait_i;
+	// 相手の wait queue から自分(を指しているTaskQueue)を削除
+	wait_i->remove(p->waiter);
+
+	// queue を free する
+	wait_i->free(p->waiter);
+	wait_i->free(p);
+    }
+
     task->post_func(task->post_arg);
     htaskImpl->free(task);
 }
 
-/**
- * 終了したタスク [depend] を待っている TaskList に
- * 終わった事を知らせる(削除する
- */
-void
-TaskManagerImpl::notify_wait_taskQueue(HTaskPtr depend, TaskQueuePtr list)
-{
-    TaskQueuePtr p;
-    HTaskPtr task;
-
-    p = list; // wait task list
-
-    while (p) {
-        task = (HTaskPtr)p->task;
-        task->wait_i = remove_taskQueue_eq_task(task->wait_i, depend);
-        p = p->next;
-    }
-
-    remove_taskQueue_all(list);
-}
 
 void
 TaskManagerImpl::append_waitTask(HTaskPtr task)
 {
-    TaskQueuePtr q;
-
-    q = taskQueueImpl->create(task);
-    waitTaskQueue = TaskQueue::append(waitTaskQueue, q);
+    TaskQueuePtr q = taskQueueImpl->create(task);
+    waitTaskQueue ->addLast(q);
 }
 
 /**
@@ -161,87 +151,12 @@
 void
 TaskManagerImpl::wakeup_waitTask(void)
 {
-    TaskQueuePtr p, tmp;
-
-    p = waitTaskQueue;
-    while (p) {
+    while (TaskQueuePtr p = waitTaskQueue->poll()) {
         HTaskPtr task = (HTaskPtr)p->task;
-        tmp = p;
-        p = p->next;
-        if (task->wait_i == NULL) {
-            append_activeTask(task);
-            waitTaskQueue = remove_taskQueue(waitTaskQueue, tmp);
+        if (task->wait_i->empty()) {
+	    activeTaskQueue->addLast(p);
         }
     }
 }
 
-void
-TaskManagerImpl::remove_taskQueue_all(TaskQueuePtr list)
-{
-    TaskQueuePtr p = list;
-    TaskQueuePtr p1;
-
-    while (p != NULL) {
-        p1 = p->next;
-        taskQueueImpl->free(p);
-        p = p1;
-    }
-}
-
-/**
- * [list] が持つ queue->task の中に [task] と同じ奴があれば
- * 削除する。まあ remove_taskQueue() の HTask で比較するverです。
- * こういうのはオーバーロードでやるもんなのかな?
- */
-TaskQueuePtr
-TaskManagerImpl::remove_taskQueue_eq_task(TaskQueuePtr list, HTaskPtr task)
-{
-    TaskQueuePtr p = list;
-    TaskQueuePtr p1;
-
-    if (p == NULL) return p;
-
-    if (p->task == task) {
-        list = list->next;
-        taskQueueImpl->free(p);
-    } else {
-        p1 = p->next;
-        while (p1 && p1->task && p1->task != task) {
-            p1 = p1->next;
-            p = p->next;
-        }
-        if (p1) {
-            p->next = p1->next;
-            taskQueueImpl->free(p1);
-        }
-    }
-
-    return list;
-}
-
-TaskQueuePtr
-TaskManagerImpl::remove_taskQueue(TaskQueuePtr list, TaskQueuePtr q)
-{
-    TaskQueuePtr p = list;
-    TaskQueuePtr p1;
-
-    if (!p) return p;
-
-    if (p == q) {
-        list = list->next;
-        taskQueueImpl->free(p);
-    } else {
-        p1 = p->next;
-        while (p1 && p1 != q) {
-            p1 = p1->next;
-            p = p->next;
-        }
-        if (p1) {
-            p->next = p1->next;
-            taskQueueImpl->free(p1);
-        }
-    }
-
-    return list;
-}
-
+/* end */
--- a/TaskManager/kernel/ppe/TaskManagerImpl.h	Mon Oct 05 02:28:08 2009 +0900
+++ b/TaskManager/kernel/ppe/TaskManagerImpl.h	Mon Oct 05 16:52:45 2009 +0900
@@ -11,35 +11,33 @@
 
 class TaskManagerImpl {
 public:
-    /* constructor */
-    TaskManagerImpl(int num = 1);
-    virtual ~TaskManagerImpl(void) {}
 
     /* variables */
     int machineNum;
-    TaskQueuePtr activeTaskQueue;
-    TaskQueuePtr waitTaskQueue;
+    TaskQueueInfo *activeTaskQueue;
+    TaskQueueInfo *waitTaskQueue;
 
     /* variables */
     TaskListInfo *taskListImpl;
     TaskQueueInfo *taskQueueImpl;
     HTaskInfo *htaskImpl;
 
+    /* constructor */
+    TaskManagerImpl(int num = 1) ;
+
+    virtual ~TaskManagerImpl() { }
+
     /* functions */
     // system
-    virtual void init(void) = 0;
-    virtual void run(void) = 0;
+    virtual void init() = 0;
+    virtual void run() = 0;
     virtual void append_activeTask(HTaskPtr);
     virtual void append_waitTask(HTaskPtr);
 
     void check_task_finish(HTaskPtr task);
-    void notify_wait_taskQueue(HTaskPtr depend, TaskQueuePtr list);
-    TaskQueuePtr remove_taskQueue(TaskQueuePtr list, TaskQueuePtr task);
-    TaskQueuePtr remove_taskQueue_eq_task(TaskQueuePtr list, HTaskPtr task);
-    void remove_taskQueue_all(TaskQueuePtr list);
-    void wakeup_waitTask(void);
+    void wakeup_waitTask();
 
-    void systask_init(void);
+    void systask_init();
 
     // user
     HTaskPtr create_task(int cmd);
--- a/TaskManager/kernel/ppe/TaskQueue.cc	Mon Oct 05 02:28:08 2009 +0900
+++ b/TaskManager/kernel/ppe/TaskQueue.cc	Mon Oct 05 16:52:45 2009 +0900
@@ -1,21 +1,10 @@
 #include "TaskQueue.h"
 
-TaskQueue::TaskQueue(TaskPtr q)
+TaskQueue::TaskQueue(Task *q)
 {
     task = q;
     next = NULL;
+    prev = NULL;
+    waiter = NULL;
 }
 
-TaskQueuePtr
-TaskQueue::append(TaskQueuePtr list, TaskQueuePtr q)
-{
-    TaskQueuePtr p = list;
-
-    if (!p) {
-	return q;
-    } else {
-	while(p->next) p = p->next;
-	p->next = q;
-	return list;
-    }
-}
--- a/TaskManager/kernel/ppe/TaskQueue.h	Mon Oct 05 02:28:08 2009 +0900
+++ b/TaskManager/kernel/ppe/TaskQueue.h	Mon Oct 05 16:52:45 2009 +0900
@@ -2,20 +2,21 @@
 #define INCLUDED_TASK_QUEUE
 
 #include "base.h"
-#include "Task.h"
 
-#include <stdio.h>
+class Task;
 
 class TaskQueue {
 public:
-    TaskQueue(TaskPtr q = NULL);
+    TaskQueue(Task *q = NULL);
 
     BASE_NEW_DELETE(TaskQueue);
 
-    TaskPtr task;
-    class TaskQueue *next;
+    Task *task;
+    TaskQueue *waiter;
 
-    static TaskQueue* append(TaskQueue* list, TaskQueue* q);
+    TaskQueue *next;
+    TaskQueue *prev;
+
 };
 
 typedef TaskQueue* TaskQueuePtr;
--- a/TaskManager/kernel/ppe/TaskQueueInfo.cc	Mon Oct 05 02:28:08 2009 +0900
+++ b/TaskManager/kernel/ppe/TaskQueueInfo.cc	Mon Oct 05 16:52:45 2009 +0900
@@ -2,8 +2,10 @@
 #include <stdlib.h>
 #include "TaskQueueInfo.h"
 
-TaskQueueInfo::TaskQueueInfo(void)
-    :taskQueuePool(NULL), freeTaskQueue(NULL) {}
+TaskQueueInfo::TaskQueueInfo()
+    :taskQueuePool(NULL), freeTaskQueue(NULL) {
+    init(32);
+}
 
 TaskQueueInfo::~TaskQueueInfo(void) { destroy(); }
 
@@ -11,8 +13,12 @@
 TaskQueueInfo::init(int num)
 {
     if (taskQueuePool == NULL) {
-	return extend_pool(num);
+	extend_pool(num);
     }
+    // 最初の一つは自分
+    first = last = this;
+    next = prev = this;
+    waiter = NULL;
     return 0;
 }
 
@@ -24,7 +30,7 @@
     q = (TaskQueuePtr)malloc(sizeof(TaskQueue)*(num+1));
 
     if (q == NULL) {
-	return -1;
+	return -1; // throw...
     }
     q->next = taskQueuePool;
     taskQueuePool = q;
@@ -45,13 +51,14 @@
     TaskQueuePtr q;
 
     if (freeTaskQueue == NULL) {
-	extend_pool(100);
+	extend_pool(64);
     }
     q = freeTaskQueue;
     freeTaskQueue = freeTaskQueue->next;
 
     q->task = task;
-    q->next = NULL;
+    q->next = q->prev = NULL;
+    q->waiter = NULL;
 
     return q;
 }
@@ -60,7 +67,9 @@
 void
 TaskQueueInfo::free(TaskQueuePtr q)
 {
+    if (!q) return;
     q->next = freeTaskQueue;
+    q->prev = NULL;
     freeTaskQueue = q;
 }
 
@@ -86,3 +95,124 @@
 
 
 }
+
+
+/*!
+  TaskQueueInfo は空にならない。最低1個は要素が入っていて
+  1個目は特別扱いする。getFirst すると first->next を返す
+ */
+
+/*!
+  最初の1個は特別扱いなので、それの後に追加していく
+ */
+void
+TaskQueueInfo::addFirst(TaskQueue* e)
+{
+    e->prev = first;
+    e->next = first->next;
+    first->next->prev = e;
+    first->next = e;
+}
+
+void
+TaskQueueInfo::addLast(TaskQueue* e)
+{
+    e->next = first;
+    e->prev = last;
+    last->next = e;
+    last = e;
+}
+
+TaskQueue*
+TaskQueueInfo::getFirst()
+{
+    if (empty()) return NULL;
+    return first->next;
+}
+
+TaskQueue*
+TaskQueueInfo::getLast()
+{
+    if (empty()) return NULL;
+    return last;
+}
+
+int
+TaskQueueInfo::remove(TaskQueue* e)
+{
+    if (!e) return 0;
+
+    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 を返す。
+ */
+
+TaskQueue*
+TaskQueueInfo::poll()
+{
+    TaskQueue* e = first->next;
+    if (e == this) {
+	return NULL;
+    }
+    remove(e);
+    return e;
+}
+
+void
+TaskQueueInfo::moveToFirst(TaskQueue* e)
+{
+    remove(e);
+    addFirst(e);
+}
+
+/*!
+  リスト内の指定された位置にある要素を返す。
+  要素数を超えた位置を指定した場合 NULL を返す。
+ */
+
+TaskQueue*
+TaskQueueInfo::get(int index)
+{
+    TaskQueue* e = first->next;
+    for (int i = 0; i < index; i++) {
+	if (e == this) return NULL;
+	e = e->next;
+    }
+    return e;
+}
+
+TaskQueue*
+TaskQueueInfo::find(Task* task)
+{
+    TaskQueue* e = first->next;
+    for(;;) {
+	if (e == this) return NULL;
+	if (e->task == task) return e;
+	e = e->next;
+    }
+    return e;
+}
+
+int
+TaskQueueInfo::empty()
+{
+    return next == this;
+}
+
+
+/* end */
--- a/TaskManager/kernel/ppe/TaskQueueInfo.h	Mon Oct 05 02:28:08 2009 +0900
+++ b/TaskManager/kernel/ppe/TaskQueueInfo.h	Mon Oct 05 16:52:45 2009 +0900
@@ -1,9 +1,10 @@
 #ifndef INCLUDED_TASK_QUEUE_INFO
 #define INCLUDED_TASK_QUEUE_INFO
 
+#include "Task.h"
 #include "TaskQueue.h"
 
-class TaskQueueInfo {
+class TaskQueueInfo : public TaskQueue {
 public:
     /* constructor */
     TaskQueueInfo();
@@ -11,13 +12,28 @@
 
     /* functions */
     int init(int num);
-    TaskQueuePtr create(TaskPtr task);
+    TaskQueuePtr create(Task *task);
     void free(TaskQueuePtr queue);
-    
+
+    void addFirst(TaskQueue* e);
+    void addLast(TaskQueue* e);
+    TaskQueue* getFirst();
+    TaskQueue* getLast();
+    int remove(TaskQueue* e);
+    TaskQueue* poll();
+    void moveToFirst(TaskQueue* e); // or use();
+    TaskQueue* get(int index);
+    TaskQueue* find(Task *task);
+    int empty();
+ 
 private:
     /* variables */
-    TaskQueuePtr taskQueuePool;
-    TaskQueuePtr freeTaskQueue;
+    TaskQueue* taskQueuePool;
+    TaskQueue* freeTaskQueue;
+
+    TaskQueue* first;
+    TaskQueue* last;
+
 
     /* functions */
     int extend_pool(int num);
--- a/TaskManager/kernel/schedule/TaskGroup.cc	Mon Oct 05 02:28:08 2009 +0900
+++ b/TaskManager/kernel/schedule/TaskGroup.cc	Mon Oct 05 16:52:45 2009 +0900
@@ -3,30 +3,15 @@
 void
 TaskGroup::add(TaskPtr add_task) {
     TaskQueuePtr q = new TaskQueue(add_task);
-    group = TaskQueue::append(group, q);
+    group->addLast(q);
 }
 
 void
 TaskGroup::remove(TaskPtr delete_task) {
-    TaskQueuePtr p = group;
-    TaskQueuePtr p1;
-
-    if (p == NULL) return;
-
-    if (p->task == delete_task) {
-	group = group->next;
-	delete p;
-    } else {
-	p1 = p->next;
-	while (p1 && p1->task != delete_task) {
-	    p1 = p1->next;
-	    p = p->next;
-	}
-	if (p1) {
-	    p->next = p1->next;
-	    delete p1;
-	}
-    }
+    // Task は TaskQueue を知らないので探し出す必要がある (HTask は知っている)
+    TaskQueue *p = group->find(delete_task);
+    group->remove(p);
+    group->free(p);
 }
 
 /**
@@ -36,20 +21,12 @@
  * command を返す。
  */
 unsigned int
-TaskGroup::status(void) {
+TaskGroup::status() {
     /**                                                                     
      * bool の                                                              
      *  true == 1;                                                          
      *  false == 0;                                                         
      * って保証されてるんだっけ?                                           
      */
-#if 1
-    return (group == NULL) * command;
-#else
-    if (group.empty()) {
-	return command;
-    } else {
-	return 0;
-    }
-#endif
+    return (group->empty()) * command;
 }
--- a/TaskManager/kernel/schedule/TaskGroup.h	Mon Oct 05 02:28:08 2009 +0900
+++ b/TaskManager/kernel/schedule/TaskGroup.h	Mon Oct 05 16:52:45 2009 +0900
@@ -2,17 +2,20 @@
 #define INCLUDED_TASK_GROUP
 
 #include "base.h"
-#include "TaskQueue.h"
+#include "TaskQueueInfo.h"
 
 class TaskGroup {
 public:
-    TaskGroup(void): group(NULL) {}
 
     BASE_NEW_DELETE(TaskGroup);
 
     unsigned int command;
-    TaskQueuePtr group;
+    TaskQueueInfo *group;
 
+    TaskGroup(): group() {
+	group = new TaskQueueInfo();
+    }
+ 
     /**
      * 待つ Task を追加
      */
--- a/example/dependency_task/main.cc	Mon Oct 05 02:28:08 2009 +0900
+++ b/example/dependency_task/main.cc	Mon Oct 05 16:52:45 2009 +0900
@@ -16,7 +16,7 @@
 void
 run_start(TaskManager *manager)
 {
-    HTaskPtr t_exec;
+    HTaskPtr t_exec[2];
     HTaskPtr t_print;
 
     idata = (int*)manager->allocate(sizeof(int)*length*2);
@@ -31,21 +31,23 @@
 
     // idata を二つに分けて計算する
     for (int i = 0; i < 2; i++) {
-	t_exec = manager->create_task(TASK_EXEC);
-	t_exec->add_inData(&idata[length*i], sizeof(int)*length);
-	t_exec->add_outData(&idata[length*i], sizeof(int)*length);
-	t_exec->add_param(length);
-	t_exec->add_param(13*(i+1));
-	t_exec->set_cpu(SPE_ANY);
+	t_exec[i] = manager->create_task(TASK_EXEC);
+	t_exec[i]->add_inData(&idata[length*i], sizeof(int)*length);
+	t_exec[i]->add_outData(&idata[length*i], sizeof(int)*length);
+	t_exec[i]->add_param(length);
+	t_exec[i]->add_param(13*(i+1));
+	t_exec[i]->set_cpu(SPE_ANY);
 
 	if (depend_flg)
-	    t_print->wait_for(t_exec);
-	
-	t_exec->spawn();
+	    t_print->wait_for(t_exec[i]);
     }
 
     // add Active Queue
     t_print->spawn();
+
+    for (int i = 0; i < 2; i++) {
+	t_exec[i]->spawn();
+    }
 }
 
 int