changeset 1179:5393bebe0956 draft

CpuThreads update
author Daichi TOMA
date Tue, 21 Jun 2011 19:50:53 +0900
parents cb8161fd0af1
children 2e20d2bb55c6
files TaskManager/Cell/CellTaskManagerImpl.cc TaskManager/Cell/CellTaskManagerImpl.h TaskManager/Cell/spe/SpeTaskManagerImpl.cc TaskManager/CpuThreadsTest/CpuThreadsTest.cc TaskManager/Fifo/FifoTaskManagerImpl.cc TaskManager/Makefile TaskManager/Makefile.def TaskManager/Makefile.parallel TaskManager/kernel/ppe/CpuThreads.cc TaskManager/kernel/ppe/CpuThreads.h TaskManager/kernel/ppe/HTask.cc TaskManager/kernel/ppe/Threads.h example/Simple/Makefile.def example/Simple/Makefile.macosx
diffstat 14 files changed, 353 insertions(+), 360 deletions(-) [+]
line wrap: on
line diff
--- a/TaskManager/Cell/CellTaskManagerImpl.cc	Sat Jun 18 03:25:31 2011 +0900
+++ b/TaskManager/Cell/CellTaskManagerImpl.cc	Tue Jun 21 19:50:53 2011 +0900
@@ -11,68 +11,63 @@
 #include "types.h"
 #include "SysFunc.h"
 
-static void send_alloc_reply(CellTaskManagerImpl *tm, int id,  SpeThreads *speThreads);
+static void send_alloc_reply(CellTaskManagerImpl *tm, int id,
+		CpuThreads *speThreads);
 
-CellTaskManagerImpl::~CellTaskManagerImpl()
-{
+CellTaskManagerImpl::~CellTaskManagerImpl() {
 
+	delete speThreads;
+	delete[] speTaskList;
 
-    delete speThreads;
-    delete [] speTaskList;
-
-    delete ppeManager;
+	delete ppeManager;
 }
 
-void
-CellTaskManagerImpl::init(int spuIdle_)
-{
-    spe_running = 0;
-    spuIdle = spuIdle_;
-    
-    speThreads = new SpeThreads(machineNum);
-    speThreads->init();
+void CellTaskManagerImpl::init(int spuIdle_) {
+	spe_running = 0;
+	spuIdle = spuIdle_;
 
-    // 実行される Task 用の パイプライン用のダブルバッファ
-    speTaskList   = new QueueInfo<TaskList>*[machineNum]; // spe上の走っている Task の配列
-    taskListInfo  = new QueueInfo<TaskList>*[machineNum]; // 次に走る Task の配列
+	//speThreads = new SpeThreads(machineNum);
+	//speThreads->init();
+
+	// 実行される Task 用の パイプライン用のダブルバッファ
+	speTaskList = new QueueInfo<TaskList>*[machineNum]; // spe上の走っている Task の配列
+	taskListInfo = new QueueInfo<TaskList>*[machineNum]; // 次に走る Task の配列
 
 
-    for (int i = 0; i < machineNum; i++) {
-	taskListInfo[i] = new QueueInfo<TaskList>(taskListPool);
-	speTaskList[i] = new QueueInfo<TaskList>(taskListPool);
-    }
+	for (int i = 0; i < machineNum; i++) {
+		taskListInfo[i] = new QueueInfo<TaskList> (taskListPool);
+		speTaskList[i] = new QueueInfo<TaskList> (taskListPool);
+	}
 
-    // PPE 側の管理をする Manager
-    ppeManager = new FifoTaskManagerImpl(machineNum);
-    // 大半のTaskQueueInfoは、共有される
-    MainScheduler *mscheduler = new MainScheduler;
-    set_scheduler(mscheduler);
-    ppeManager->init(mscheduler, this); // ここで HTaskInfo が共有される。
+	// PPE 側の管理をする Manager
+	ppeManager = new FifoTaskManagerImpl(machineNum);
+	// 大半のTaskQueueInfoは、共有される
+	MainScheduler *mscheduler = new MainScheduler;
+	set_scheduler(mscheduler);
+	ppeManager->init(mscheduler, this); // ここで HTaskInfo が共有される。
 
-    // 実行可能な HTask のリスト。 FifoTaskManager と共有される
-    activeTaskQueue = ppeManager->activeTaskQueue;
-    // HTask の factory。 HTaskInfo ならなんでもいい。
-    htaskImpl = activeTaskQueue ; // any HTaskInfo 
+	// 実行可能な HTask のリスト。 FifoTaskManager と共有される
+	activeTaskQueue = ppeManager->activeTaskQueue;
+	// HTask の factory。 HTaskInfo ならなんでもいい。
+	htaskImpl = activeTaskQueue; // any HTaskInfo
+
 
-   
-    ppeManager->get_scheduler()->set_manager(this);
+	ppeManager->get_scheduler()->set_manager(this);
 
-    // Task 内からManager->task_create() とかするときに必要なTaskManager。
-    // 現状では ppe 側からしか動かない
-    // spe 側から Task create できない
-    schedTaskManager = new SchedTask();
-    schedTaskManager->init(0,0,0,ppeManager->get_scheduler(),0);
-    ppeManager->schedTaskManager = schedTaskManager;
+	// Task 内からManager->task_create() とかするときに必要なTaskManager。
+	// 現状では ppe 側からしか動かない
+	// spe 側から Task create できない
+	schedTaskManager = new SchedTask();
+	schedTaskManager->init(0, 0, 0, ppeManager->get_scheduler(), 0);
+	ppeManager->schedTaskManager = schedTaskManager;
 }
 
-void
-CellTaskManagerImpl::append_activeTask(HTaskPtr task)
-{
-    if (task->cpu_type == CPU_PPE) {
-        ppeManager->append_activeTask(task);
-    } else {
-        activeTaskQueue->addLast(task);
-    }
+void CellTaskManagerImpl::append_activeTask(HTaskPtr task) {
+	if (task->cpu_type == CPU_PPE) {
+		ppeManager->append_activeTask(task);
+	} else {
+		activeTaskQueue->addLast(task);
+	}
 }
 
 // SPE_ANY が指定されていた時に
@@ -86,251 +81,231 @@
  * ここの activeTaskQueue は FifoTaskManagerImpl のと意味が違い、
  * spe に渡される Task だけ入っている
  */
-void
-CellTaskManagerImpl::set_runTaskList(QueueInfo<HTask> *activeTaskQueue)
-{
-    int speid;
-    HTaskPtr htask = activeTaskQueue->getFirst();
-    while (htask != NULL) {
+void CellTaskManagerImpl::set_runTaskList(QueueInfo<HTask> *activeTaskQueue) {
+	int speid;
+	HTaskPtr htask = activeTaskQueue->getFirst();
+	while (htask != NULL) {
 
-      if (htask->cpu_type == CPU_PPE) {
+		if (htask->cpu_type == CPU_PPE) {
+
+			htask = activeTaskQueue->getNext(htask);
 
-	htask = activeTaskQueue->getNext(htask);
-	  
-      } else{
-	if (htask->cpu_type == SPE_ANY) {
-	  speid = cur_anySpeid++;
-	} else {
-	// -1 してるのは
-	// htask->cpu_type - CPU_SPE で
-	// SPE0 = 1, SPE1 = 2, ... SPE5 = 6 ってなってるので
-	// 配列的 (SPE0 = arr[0], SPE1 = arr[1]) にするため
-	    speid = htask->cpu_type - CPU_SPE - 1;
+		} else {
+			if (htask->cpu_type == SPE_ANY) {
+				speid = cur_anySpeid++;
+			} else {
+				// -1 してるのは
+				// htask->cpu_type - CPU_SPE で
+				// SPE0 = 1, SPE1 = 2, ... SPE5 = 6 ってなってるので
+				// 配列的 (SPE0 = arr[0], SPE1 = arr[1]) にするため
+				speid = htask->cpu_type - CPU_SPE - 1;
+			}
+
+			speid %= machineNum;
+			set_taskList(htask, taskListInfo[speid]);
+
+			HTaskPtr next = activeTaskQueue->getNext(htask);
+			activeTaskQueue->remove(htask);
+			htask = next;
+
+		}
 	}
-
-      speid %= machineNum;
-      set_taskList(htask, taskListInfo[speid]);
-
-      HTaskPtr next = activeTaskQueue->getNext(htask);
-      activeTaskQueue->remove(htask);
-      htask = next;
-
-      }
-    }
 }
 
-void
-CellTaskManagerImpl::sendTaskList()
-{
-    for (int id = 0; id < machineNum; id++)  {
-	mail_check(id);
-	if (!speTaskList[id]->empty()) {
-	    continue; // まだ、走ってる
+void CellTaskManagerImpl::sendTaskList() {
+	for (int id = 0; id < machineNum; id++) {
+		mail_check(id);
+		if (!speTaskList[id]->empty()) {
+			continue; // まだ、走ってる
+		}
+		if (!taskListInfo[id]->empty()) {
+			// SPE に送る TaskList の準備
+			send_taskList(id);
+			spe_running++;
+		}
 	}
-	if (! taskListInfo[id]->empty() ) {
-	    // SPE に送る TaskList の準備
-	    send_taskList(id);
-	    spe_running++;
-	}	
-    }
 }
 
-void
-CellTaskManagerImpl::poll()
-{
-    set_runTaskList(activeTaskQueue);
-    // TaskList 待ちの SPE に TaskList を送る
-    sendTaskList();
+void CellTaskManagerImpl::poll() {
+	set_runTaskList(activeTaskQueue);
+	// TaskList 待ちの SPE に TaskList を送る
+	sendTaskList();
 }
 
-
-void
-CellTaskManagerImpl::debug_check_spe_idle(QueueInfo<HTask> * activeTaskQueue, int spe_running_)
-{
-	printf("spu_idle! spe_running = %d : activeTaskQueue->length = %d \n"
-		, spe_running_, activeTaskQueue->length());
+void CellTaskManagerImpl::debug_check_spe_idle(
+		QueueInfo<HTask> * activeTaskQueue, int spe_running_) {
+	printf("spu_idle! spe_running = %d : activeTaskQueue->length = %d \n",
+			spe_running_, activeTaskQueue->length());
 	HTaskPtr task = activeTaskQueue->getFirst();
 	int tmp_i = 0;
 	do {
-		printf("task_name = %s ,",ppeManager->get_task_name(task));
+		printf("task_name = %s ,", ppeManager->get_task_name(task));
 		printf("cpu = [%d], count = %d", task->cpu_type, tmp_i);
 		tmp_i++;
 	} while ((task = activeTaskQueue->getNext(task)) != 0);
 	printf("\n");
 }
 
-void
-CellTaskManagerImpl::run()
-{
-    int spu_limit = spuIdle;
-    if (machineNum==0) {
-       ppeManager->run();
-       return;
-    }
- 
-     do {
+void CellTaskManagerImpl::run() {
+	int spu_limit = spuIdle;
+	if (machineNum == 0) {
+		ppeManager->run();
+		return;
+	}
+
+	do {
 
-       // PPE side
-       ppeManager->poll();
-       // SPE side
-       do {
-	 poll();
-       } while (ppeManager->activeTaskQueue->empty() && spe_running >0 );
-       
-       if (spe_running < spu_limit) {
-	 debug_check_spe_idle(ppeManager->activeTaskQueue, spe_running);
-       } 
-       
-     } while (!ppeManager->activeTaskQueue->empty() || 
-	      !activeTaskQueue->empty() ||
-	      spe_running >0); 
-     if (!waitTaskQueue->empty()) {
-       show_dead_lock_info();
-     }
-     
+		// PPE side
+		ppeManager->poll();
+		// SPE side
+		do {
+			poll();
+		} while (ppeManager->activeTaskQueue->empty() && spe_running > 0);
+
+		if (spe_running < spu_limit) {
+			debug_check_spe_idle(ppeManager->activeTaskQueue, spe_running);
+		}
+
+	} while (!ppeManager->activeTaskQueue->empty() || !activeTaskQueue->empty()
+			|| spe_running > 0);
+	if (!waitTaskQueue->empty()) {
+		show_dead_lock_info();
+	}
+
 }
 
-
-static void
-loop_check(HTask *p,HTask *me, int depth)
-{
-    if (p==me) printf("*%lx ",(long)p); // loop
-    if (depth==0) return;
-    QueueInfo<TaskQueue> *w = p->wait_i;
-    if (w) {
-	for( TaskQueue *q = w->getFirst(); q; q = w->getNext(q)) {
-	    loop_check(q->task,me, depth-1);
+static void loop_check(HTask *p, HTask *me, int depth) {
+	if (p == me)
+		printf("*%lx ", (long) p); // loop
+	if (depth == 0)
+		return;
+	QueueInfo<TaskQueue> *w = p->wait_i;
+	if (w) {
+		for (TaskQueue *q = w->getFirst(); q; q = w->getNext(q)) {
+			loop_check(q->task, me, depth - 1);
+		}
 	}
-    }
 }
 
-void
-CellTaskManagerImpl::show_dead_lock_info()
-{
-    get_scheduler()-> printf("Dead lock detected\n   ppe queue %d\n",
-	ppeManager->activeTaskQueue->length());
-    // 確か waitQueue は共通...
-    // get_scheduler()-> printf("   wait queue %d\n",ppeManager->waitTaskQueue->length()); 
-    get_scheduler()-> printf("   wait queue %d\n",waitTaskQueue->length()); 
-    for( HTask *p = waitTaskQueue->getFirst(); p; p = waitTaskQueue->getNext(p)) {
-	printf("  Waiting task%d %lx",p->command, (long)p);
-	QueueInfo<TaskQueue> *w = p->wait_i;
-	if (w) {
-	    for( TaskQueue *q = w->getFirst(); q; q = w->getNext(q)) {
-		printf("    waiting task%d %lx",q->task->command, (long)q->task);
-		if (!waitTaskQueue->find(q->task)) {
-		    printf("!"); // stray task
+void CellTaskManagerImpl::show_dead_lock_info() {
+	get_scheduler()-> printf("Dead lock detected\n   ppe queue %d\n",
+			ppeManager->activeTaskQueue->length());
+	// 確か waitQueue は共通...
+	// get_scheduler()-> printf("   wait queue %d\n",ppeManager->waitTaskQueue->length());
+	get_scheduler()-> printf("   wait queue %d\n", waitTaskQueue->length());
+	for (HTask *p = waitTaskQueue->getFirst(); p; p = waitTaskQueue->getNext(p)) {
+		printf("  Waiting task%d %lx", p->command, (long) p);
+		QueueInfo<TaskQueue> *w = p->wait_i;
+		if (w) {
+			for (TaskQueue *q = w->getFirst(); q; q = w->getNext(q)) {
+				printf("    waiting task%d %lx", q->task->command,
+						(long) q->task);
+				if (!waitTaskQueue->find(q->task)) {
+					printf("!"); // stray task
+				}
+				loop_check(q->task, p, 10);
+			}
 		}
-		loop_check(q->task,p, 10);
-	    }
+		printf("\n");
 	}
-        printf("\n");
-    }
-    get_scheduler()-> printf("   spe queue %d\n",activeTaskQueue->length()); 
-    for (int i = 0; i < machineNum; i++)  {
-	get_scheduler()-> printf("   spe %d send %d wait %d\n",i, 
-		  speTaskList[i]->length(), taskListInfo[i]->length());
-    }
+	get_scheduler()-> printf("   spe queue %d\n", activeTaskQueue->length());
+	for (int i = 0; i < machineNum; i++) {
+		get_scheduler()-> printf("   spe %d send %d wait %d\n", i,
+				speTaskList[i]->length(), taskListInfo[i]->length());
+	}
 }
 
 /**
  * SPE からのメールをチェックする
  */
 
-void
-CellTaskManagerImpl::mail_check(int id)
-{
-    memaddr data;
+void CellTaskManagerImpl::mail_check(int id) {
+	memaddr data;
 
-    // SPE Scheduler からの mail check
-    while (speThreads->has_mail(id, 1, &data)) {				
-	if (data == (memaddr)MY_SPE_STATUS_READY) {
-	    //  MY_SPE_STATUS_READY: SPE が持ってた Task 全て終了
-	    // freeAll する前に循環リストに戻す
-	    speTaskList[id]->getLast()->next = speTaskList[id];
-	    speTaskList[id]->freeAll();
-	    spe_running--;
-// printf("SPE %d status ready, %d running\n",id, spe_running);
-	} else if (data == (memaddr)MY_SPE_COMMAND_MALLOC) {
-	    // MY_SPE_COMMAND_MALLOC   SPE からのmain memory request
-	    send_alloc_reply(this, id, speThreads);
-	} else if (data > (memaddr)MY_SPE_NOP) {
+	// SPE Scheduler からの mail check
+	while (speThreads->has_mail(id, 1, &data)) {
+		if (data == (memaddr) MY_SPE_STATUS_READY) {
+			//  MY_SPE_STATUS_READY: SPE が持ってた Task 全て終了
+			// freeAll する前に循環リストに戻す
+			speTaskList[id]->getLast()->next = speTaskList[id];
+			speTaskList[id]->freeAll();
+			spe_running--;
+			// printf("SPE %d status ready, %d running\n",id, spe_running);
+		} else if (data == (memaddr) MY_SPE_COMMAND_MALLOC) {
+			// MY_SPE_COMMAND_MALLOC   SPE からのmain memory request
+			send_alloc_reply(this, id, speThreads);
+		} else if (data > (memaddr) MY_SPE_NOP) {
 #ifdef TASK_LIST_MAIL
-	    TaskListPtr list = (TaskListPtr)data;
-	    check_task_list_finish(schedTaskManager, list, waitTaskQueue);
+			TaskListPtr list = (TaskListPtr)data;
+			check_task_list_finish(schedTaskManager, list, waitTaskQueue);
 #else
-	    // 終了したタスク(PPEにあるのでアドレス)
-	    HTaskPtr task = (HTaskPtr)data;
+			// 終了したタスク(PPEにあるのでアドレス)
+			HTaskPtr task = (HTaskPtr) data;
 #if 0
-	    if (task->cpu_type != CPU_SPE) {
-		const char *name = get_task_name(task);
-		if (name != NULL) {
-		  printf("[SPE] ");
-		  printf("Task id : %d, ", task->command);
-		  printf("Task name : %s\n", name);
-		}
-	    }
+			if (task->cpu_type != CPU_SPE) {
+				const char *name = get_task_name(task);
+				if (name != NULL) {
+					printf("[SPE] ");
+					printf("Task id : %d, ", task->command);
+					printf("Task name : %s\n", name);
+				}
+			}
 #endif
 #ifndef NOT_CHECK
-	
 
-	    if (task != NULL) {
-	      //SPE で処理された Task が返ってくるはず。それがもし、type PPE なら・・・
-	      if (task->cpu_type == CPU_PPE) {
-		printf("attention : PPE task run on SPE\n");
-		printf("Task id : %d\n", task->command);
-		const char *name = get_task_name(task);
-		if (name != NULL) {	       
-		  printf("Task name : %s\n", name);
-		}
-	      }
-	    }
+			if (task != NULL) {
+				//SPE で処理された Task が返ってくるはず。それがもし、type PPE なら・・・
+				if (task->cpu_type == CPU_PPE) {
+					printf("attention : PPE task run on SPE\n");
+					printf("Task id : %d\n", task->command);
+					const char *name = get_task_name(task);
+					if (name != NULL) {
+						printf("Task name : %s\n", name);
+					}
+				}
+			}
 
 #endif
-	    
-	    task->post_func(schedTaskManager, task->post_arg1, task->post_arg2);
-	    check_task_finish(task, waitTaskQueue);
+
+			task->post_func(schedTaskManager, task->post_arg1, task->post_arg2);
+			check_task_finish(task, waitTaskQueue);
 #endif
+		}
+		// MY_SPE_NOP: 特に意味のないコマンド
 	}
-	// MY_SPE_NOP: 特に意味のないコマンド
-    }
 }
 
-void
-CellTaskManagerImpl::polling()
-{
-    // may  call recursively check_task_list_finish() 
-    // we need fifo here
-    for (int i = 0; i < machineNum; i++)  {
-	mail_check(i);
-    }
+void CellTaskManagerImpl::polling() {
+	// may  call recursively check_task_list_finish()
+	// we need fifo here
+	for (int i = 0; i < machineNum; i++) {
+		mail_check(i);
+	}
 }
 
-static void
-send_alloc_reply(CellTaskManagerImpl *tm, int id, SpeThreads *speThreads)
-{
+static void send_alloc_reply(CellTaskManagerImpl *tm, int id,
+		CpuThreads *speThreads) {
+
+	/**
+	 * info[0] = alloc_id; (CellScheduler::mainMem_alloc 参照)
+	 * info[1] = alloc_addr;
+	 */
+	memaddr alloc_info[2];
+	long alloc_size;
+	long command;
 
-    /**
-     * info[0] = alloc_id; (CellScheduler::mainMem_alloc 参照)
-     * info[1] = alloc_addr;
-     */
-    memaddr alloc_info[2];
-    long alloc_size;
-    long command;
-    
-    speThreads->get_mail(id, 2, alloc_info);
-    command = (long)alloc_info[0];
-    alloc_size = (long)alloc_info[1];
+	speThreads->get_mail(id, 2, alloc_info);
+	command = (long) alloc_info[0];
+	alloc_size = (long) alloc_info[1];
 
-    
-    alloc_info[1] = (memaddr)tm->allocate(alloc_size);
-    //__debug_ppe("[PPE] MALLOCED 0x%lx from [SPE %d]\n", alloc_info[1],id);
-    // 今のところ何もしてない。どうも、この allocate を free 
-    // するのは、SPE task が返した値を見て行うらしい。それは、
-    // 忘れやすいのではないか?
-    speThreads->add_output_tasklist(command, alloc_info[1], alloc_size);
+	alloc_info[1] = (memaddr) tm->allocate(alloc_size);
+	//__debug_ppe("[PPE] MALLOCED 0x%lx from [SPE %d]\n", alloc_info[1],id);
+	// 今のところ何もしてない。どうも、この allocate を free
+	// するのは、SPE task が返した値を見て行うらしい。それは、
+	// 忘れやすいのではないか?
+	speThreads->add_output_tasklist(command, alloc_info[1], alloc_size);
 
-    speThreads->send_mail(id, 2, alloc_info);
+	speThreads->send_mail(id, 2, alloc_info);
 }
 
 /**
@@ -341,52 +316,49 @@
  * SPE で実行終了した speTaskList  と
  * これから実行する taskListInfo  のバッファを入れ替える
  */
-void
-CellTaskManagerImpl::send_taskList(int id)
-{
-    // speTaskList は走り終わった ppe の Task の List. 
-    // taskListInfo はこれから走る Task の List. 
-    // 交換して実行する
-    QueueInfo<TaskList> *tmp = taskListInfo[id];
-    taskListInfo[id] = speTaskList[id];
-    speTaskList[id] = tmp;
+void CellTaskManagerImpl::send_taskList(int id) {
+	// speTaskList は走り終わった ppe の Task の List.
+	// taskListInfo はこれから走る Task の List.
+	// 交換して実行する
+	QueueInfo<TaskList> *tmp = taskListInfo[id];
+	taskListInfo[id] = speTaskList[id];
+	speTaskList[id] = tmp;
 
-    // speTaskList は本来は循環リストなのだけど、実行中は線形リストである。
-    // spe の Task が終了した時点でなおす。
-    tmp->getLast()->next = 0;
-    TaskListPtr p = tmp->getFirst();
-// printf("SPE %d task list sending\n",id);
-    speThreads->send_mail(id, 1, (memaddr *)&p);
-// printf("SPE %d task list sent\n",id);
+	// speTaskList は本来は循環リストなのだけど、実行中は線形リストである。
+	// spe の Task が終了した時点でなおす。
+	tmp->getLast()->next = 0;
+	TaskListPtr p = tmp->getFirst();
+	// printf("SPE %d task list sending\n",id);
+	speThreads->send_mail(id, 1, (memaddr *) &p);
+	// printf("SPE %d task list sent\n",id);
 }
 
 void CellTaskManagerImpl::show_profile() {
-    for (int id = 0; id < machineNum; id++) {	    
-	HTaskPtr t = schedTaskManager->create_task(ShowTime,0,0,0,0);
-	t->set_cpu((CPU_TYPE)(id+2));
-	t->spawn();
-    }
+	for (int id = 0; id < machineNum; id++) {
+		HTaskPtr t = schedTaskManager->create_task(ShowTime, 0, 0, 0, 0);
+		t->set_cpu((CPU_TYPE) (id + 2));
+		t->spawn();
+	}
 }
 
 void CellTaskManagerImpl::start_profile() {
-    for (int id = 0; id < machineNum; id++) {	    
-	HTaskPtr t = schedTaskManager->create_task(StartProfile,0,0,0,0);
-	t->set_cpu((CPU_TYPE)(id+2));
-	t->spawn();
-    }
+	for (int id = 0; id < machineNum; id++) {
+		HTaskPtr t = schedTaskManager->create_task(StartProfile, 0, 0, 0, 0);
+		t->set_cpu((CPU_TYPE) (id + 2));
+		t->spawn();
+	}
 }
 
-void CellTaskManagerImpl::print_arch() 
-{
-    printf("CellTaskManager\n");
+void CellTaskManagerImpl::print_arch() {
+	printf("CellTaskManager\n");
 }
 
-
-
 #ifdef __CERIUM_CELL__
 TaskManagerImpl*
 create_impl(int num)
 {
-    return new CellTaskManagerImpl(num);
+	CpuThreads* cpus = new SpeThreads(machineNum);
+	cpus->init();
+	return new CellTaskManagerImpl(num,cpus);
 }
 #endif // __CERIUM_CELL
--- a/TaskManager/Cell/CellTaskManagerImpl.h	Sat Jun 18 03:25:31 2011 +0900
+++ b/TaskManager/Cell/CellTaskManagerImpl.h	Tue Jun 21 19:50:53 2011 +0900
@@ -3,19 +3,19 @@
 
 #include "TaskManagerImpl.h"
 #include "FifoTaskManagerImpl.h"
-#include "SpeThreads.h"
+#include "CpuThreads.h"
 
 class CellTaskManagerImpl : public TaskManagerImpl {
 public:
     /* constructor */
-    CellTaskManagerImpl(int num) : TaskManagerImpl(num) {}
+    CellTaskManagerImpl(int num, CpuThreads *cpus) : TaskManagerImpl(num) {}
     ~CellTaskManagerImpl();
 
     /* variables */
     QueueInfo<TaskList> **taskListInfo;
     QueueInfo<TaskList> **speTaskList;  // running task
 
-    SpeThreads *speThreads;
+    CpuThreads *speThreads;
     FifoTaskManagerImpl *ppeManager;
     int spe_running;
     int spuIdle;
--- a/TaskManager/Cell/spe/SpeTaskManagerImpl.cc	Sat Jun 18 03:25:31 2011 +0900
+++ b/TaskManager/Cell/spe/SpeTaskManagerImpl.cc	Tue Jun 21 19:50:53 2011 +0900
@@ -20,6 +20,7 @@
 void SpeTaskManagerImpl::print_arch() { printf("SpeTaskManagerImpl\n"); }
 
 // Odd
+#ifndef __CERIUM_FIFO__
 
 TaskManagerImpl::TaskManagerImpl(int i) {}
 void TaskManagerImpl::append_activeTask(HTask* p) {}
@@ -33,3 +34,4 @@
 void TaskManagerImpl::spawn_task(HTaskPtr) {}
 void TaskManagerImpl::set_task_cpu(HTaskPtr, CPU_TYPE) {}
 
+#endif
--- a/TaskManager/CpuThreadsTest/CpuThreadsTest.cc	Sat Jun 18 03:25:31 2011 +0900
+++ b/TaskManager/CpuThreadsTest/CpuThreadsTest.cc	Tue Jun 21 19:50:53 2011 +0900
@@ -1,10 +1,15 @@
 #include <stdio.h>
 #include "TaskManager/CpuThreads.h"
+#include "TaskManager/CellTaskManagerImpl.h"
 
 static void
 test1() {
-	CpuThreadsPtr m = new CpuThreads(3);
-	m->init();
+	int num = 1;
+	CpuThreadsPtr c = new CpuThreads(num);
+	c->init();
+	CellTaskManagerImpl *m = new CellTaskManagerImpl(num,c);
+	m->init(0);
+	delete c;
 	delete m;
 }
 
--- a/TaskManager/Fifo/FifoTaskManagerImpl.cc	Sat Jun 18 03:25:31 2011 +0900
+++ b/TaskManager/Fifo/FifoTaskManagerImpl.cc	Tue Jun 21 19:50:53 2011 +0900
@@ -2,6 +2,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include "FifoTaskManagerImpl.h"
+#include "CellTaskManagerImpl.h"
 #include "QueueInfo.h"
 #include "TaskList.h"
 #include "Scheduler.h"
@@ -10,6 +11,7 @@
 #include "error.h"
 #include "SchedNop.h"
 #include "SysFunc.h"
+#include "CpuThreads.h"
 
 extern  QueueInfo<TaskList> *taskListPool;
 
@@ -313,7 +315,13 @@
 TaskManagerImpl*
 create_impl(int num)
 {
+	if (num == 0) {
     return new FifoTaskManagerImpl(num);
+	} else {
+		CpuThreadsPtr cpus = new CpuThreads(num);
+		cpus->init();
+		return new CellTaskManagerImpl(num,cpus);
+	}
 }
 #endif // __CERIUM_FIFO__
 
--- a/TaskManager/Makefile	Sat Jun 18 03:25:31 2011 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,52 +0,0 @@
-include ./Makefile.def
-
-TAGS       = gtags
-TAGSOPTION = 
-TAGSFILE   = GPATH GRTAGS GSYMS GTAGS
-
-default: fifo
-
-fifo: FORCE
-	@$(MAKE) -f Makefile.fifo
-
-fifo64: FORCE
-	@$(MAKE) -f Makefile.fifo ABIBIT=64
-
-depend: FORCE
-	@$(MAKE) -f Makefile.fifo depend
-
-cell: FORCE
-	@$(MAKE) -f Makefile.cell
-
-FORCE:
-	-mkdir -p ../include/TaskManager
-	rsync `find . -name Test -prune -or -name '*.h' -print` ../include/TaskManager
-
-distclean: clean
-	rm -f $(TAGSFILE)
-	$(MAKE) -f Makefile.cell celldistclean
-	$(MAKE) -f Makefile.fifo fifodistclean
-
-clean:
-	rm -f *~ \#*
-	rm -f $(TARGET)
-	cd $(KERN_DIR);         rm -f *~ \#*
-	cd $(KERN_PPE_DIR);     rm -f *~ \#*
-	cd $(KERN_SPE_DIR);     rm -f *~ \#*
-	cd $(KERN_SCHED_DIR);   rm -f *~ \#*
-	cd $(KERN_MEM_DIR);   rm -f *~ \#*
-	cd $(KERN_SYSTASK_DIR); rm -f *~ \#*
-	cd $(KERN_MEM_DIR); rm -f *~ \#*
-	cd $(IMPL_FIFO_DIR);    rm -f *~ \#*
-	cd $(IMPL_CELL_DIR);    rm -f *~ \#*
-	rm -f $(KERN_MAIN_OBJS) $(KERN_PPE_OBJS) $(KERN_SPE_OBJS) \
-	$(KERN_SCHED_OBJS) $(KERN_SYSTASK_OBJS) $(KERN_MEM_OBJS)
-	rm -f $(IMPL_FIFO_OBJS) $(IMPL_CELL_OBJS)
-	$(MAKE) -f Makefile.cell cellclean
-	$(MAKE) -f Makefile.fifo fifoclean
-	rm -rf *.a ../include	
-
-tags:
-	$(TAGS) $(TAGSOPTION)
-
--include ./Makefile.dep
--- a/TaskManager/Makefile.def	Sat Jun 18 03:25:31 2011 +0900
+++ b/TaskManager/Makefile.def	Tue Jun 21 19:50:53 2011 +0900
@@ -23,14 +23,18 @@
 IMPL_FIFO_SRCS = $(wildcard $(IMPL_FIFO_DIR)/*.cc)
 IMPL_FIFO_OBJS = $(IMPL_FIFO_SRCS:.cc=.o)
 
+IMPL_PARALLEL_DIR  = Parallel
+IMPL_PARALLEL_SRCS = $(IMPL_FIFO_SRCS) $(wildcard $(IMPL_PARALLEL_DIR)/*.cc)
+IMPL_PARALLEL_OBJS = $(IMPL_PARALLEL_SRCS:.cc=.o)
+
 IMPL_CELL_DIR  = Cell
 IMPL_CELL_SRCS = $(IMPL_FIFO_SRCS) $(wildcard $(IMPL_CELL_DIR)/*.cc)
 IMPL_CELL_OBJS = $(IMPL_CELL_SRCS:.cc=.o)
 
 ABIBIT = 64
 
-#OPT = -g -DMAIL_QUEUE -DNOT_CHECK #-DTASK_LIST_MAIL #-DEARLY_TOUCH -DUSE_CACHE
-OPT = -O9 -DMAIL_QUEUE -DNOT_CHECK #-DTASK_LIST_MAIL #-DEARLY_TOUCH -DUSE_CACHE 
+OPT = -g -O0 -DMAIL_QUEUE -DNOT_CHECK #-DTASK_LIST_MAIL #-DEARLY_TOUCH -DUSE_CACHE
+#OPT = -O9 -DMAIL_QUEUE -DNOT_CHECK #-DTASK_LIST_MAIL #-DEARLY_TOUCH -DUSE_CACHE 
 
 
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TaskManager/Makefile.parallel	Tue Jun 21 19:50:53 2011 +0900
@@ -0,0 +1,30 @@
+include ./Makefile.def
+TARGET = libParallelManager.a
+CFLAGS += -DHAS_POSIX_MEMALIGN
+
+.SUFFIXES: .cc .o
+
+EXTRA_CFLAGS = -D__CERIUM_FIFO__ 
+
+.cc.o:
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) -c $< -o $@
+
+
+all: default
+default: $(TARGET)
+
+ALL_OBJS = $(KERN_MAIN_OBJS) $(KERN_PPE_OBJS) $(KERN_SCHED_OBJS) $(KERN_SYSTASK_OBJS) $(IMPL_FIFO_OBJS) $(KERN_MEM_OBJS) Cell/spe/SpeTaskManagerImpl.o Cell/CellTaskManagerImpl.o
+
+Makefile.dep: 
+	make -f Makefile.parallel depend
+
+depend:
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(INCLUDE) $(ALL_OBJS:.o=.cc) -MM  > Makefile.dep
+
+$(TARGET): $(ALL_OBJS)
+	ar crus $@ $(ALL_OBJS)
+
+paralleldistclean: parallelclean
+	rm -f $(TARGET)
+
+parallelclean:
\ No newline at end of file
--- a/TaskManager/kernel/ppe/CpuThreads.cc	Sat Jun 18 03:25:31 2011 +0900
+++ b/TaskManager/kernel/ppe/CpuThreads.cc	Tue Jun 21 19:50:53 2011 +0900
@@ -4,9 +4,10 @@
 #include "MainScheduler.h"
 #include "SysFunc.h"
 #include "SchedNop.h"
+#include "SpeTaskManagerImpl.h"
 
-SchedExternTask(ShowTime);
-SchedExternTask(StartProfile);
+//SchedExternTask(ShowTime);
+//SchedExternTask(StartProfile);
 
 
 CpuThreads::CpuThreads(int num, int start_id) : cpu_num(num), id_offset(start_id) {}
@@ -20,7 +21,12 @@
     }
 
     for (int i = 0; i < cpu_num; i++) {
-	pthread_join(threads[i], NULL);
+		pthread_join(threads[i], NULL);
+		sem_destroy(&sem[i]);
+	}
+
+    for (int i = 0; i < cpu_num; i++) {
+    	delete args[i].scheduler;
     }
 
     delete [] threads;
@@ -34,11 +40,14 @@
     cpu_thread_arg_t *argt = (cpu_thread_arg_t *) args;
     Scheduler *c_scheduler = argt->scheduler;
 
-    SchedRegister(ShowTime);
-    SchedRegister(StartProfile);
+    TaskManagerImpl *manager = new SpeTaskManagerImpl();
+    c_scheduler->init(manager);
+    c_scheduler->id = (int)argt->cpuid;
 
-    c_scheduler->init(argt->manager);
-    c_scheduler->id = (int)argt->cpuid;
+    manager->set_scheduler(c_scheduler);
+
+    //SchedRegister(ShowTime);
+    //SchedRegister(StartProfile);
 
     c_scheduler->run(new SchedNop());
     c_scheduler->finish();
@@ -47,6 +56,7 @@
 }
 
 void
+//CpuThreads::init()
 CpuThreads::init()
 {
     threads = new pthread_t[cpu_num];
@@ -60,7 +70,7 @@
 
     for (int i = 0; i < cpu_num; i++) {
 	pthread_create(&threads[i], NULL,
-		       &cpu_thread_run, (void*)&args[i]);
+		      &cpu_thread_run, (void*)&args[i]);
 	sem_init(&sem[i], 0, 1);
     }
 }
@@ -77,10 +87,9 @@
 CpuThreads::get_mail(int cpuid, int count, memaddr *ret)
 {   
     // need synchronization
-	int cpu = cpuid - 1;
-	sem_wait(&sem[cpu]);
+	sem_wait(&sem[cpuid]);
     *ret = args[cpuid-id_offset].scheduler->mail_read_from_host();
-	sem_post(&sem[cpu]);
+	sem_post(&sem[cpuid]);
     return 1;
 }
 
@@ -88,10 +97,9 @@
 CpuThreads::has_mail(int cpuid, int count, memaddr *ret)
 {
     // need synchronization
-	int cpu = cpuid - 1;
-	sem_wait(&sem[cpu]);
+	sem_wait(&sem[cpuid]);
     return  args[cpuid-id_offset].scheduler->has_mail_from_host();
-	sem_post(&sem[cpu]);
+	sem_post(&sem[cpuid]);
 }
 
 /**
@@ -113,11 +121,21 @@
 
 {
     // need synchronization
-	int cpu = cpuid - 1;
-	sem_wait(&sem[cpu]);
+	sem_wait(&sem[cpuid]);
     args[cpuid-id_offset].scheduler->mail_write_from_host(*data);
-	sem_post(&sem[cpu]);
+	sem_post(&sem[cpuid]);
 }
 
+void
+CpuThreads::add_output_tasklist(int command, memaddr buff, int alloc_size)
+{
+    /*
+     * output TaskList が無ければ新しく作る
+     * あれば TaskList に allocate した Task を追加
+     * command に対応した Task の初期化を実行する
+     * SPE に data が書き出し終わった後に PPE 側で初期化
+     */
+
+}
 
 /* end */
--- a/TaskManager/kernel/ppe/CpuThreads.h	Sat Jun 18 03:25:31 2011 +0900
+++ b/TaskManager/kernel/ppe/CpuThreads.h	Tue Jun 21 19:50:53 2011 +0900
@@ -18,14 +18,15 @@
 public:
     /* constructor */
     CpuThreads(int num = 1, int start_id = 0);
-    virtual ~CpuThreads();
+    ~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
+    virtual void init();
+    virtual int get_mail(int speid, int count, memaddr *ret); // BLOCKING
+    virtual int has_mail(int speid, int count, memaddr *ret); // NONBLOCK
+    virtual void send_mail(int speid, int num, memaddr *data); // BLOCKING
+    virtual void add_output_tasklist(int command, memaddr buff, int alloc_size);
 
 private:
     /* variables */
@@ -36,4 +37,6 @@
     int id_offset;
 };
 
+typedef CpuThreads *CpuThreadsPtr;
+
 #endif
--- a/TaskManager/kernel/ppe/HTask.cc	Sat Jun 18 03:25:31 2011 +0900
+++ b/TaskManager/kernel/ppe/HTask.cc	Tue Jun 21 19:50:53 2011 +0900
@@ -77,7 +77,7 @@
     r_size = Task::calc_size(num_param, num_inData, num_outData)*num_task;
     rbuf = (memaddr) mimpl->allocate(r_size);
     //printf("r_size %d\n",r_size);
-    bzero(rbuf,r_size);
+//    bzero(rbuf,r_size);
     Task *task = (Task*)rbuf;
     task->init(id, num_param,num_inData,num_outData);
 // task->print();
--- a/TaskManager/kernel/ppe/Threads.h	Sat Jun 18 03:25:31 2011 +0900
+++ b/TaskManager/kernel/ppe/Threads.h	Tue Jun 21 19:50:53 2011 +0900
@@ -2,7 +2,8 @@
 #define INCLUDED_THREADS
 
 #include <pthread.h>
-#include <base.h>
+#include "base.h"
+#include "types.h"
 
 
 class Threads {
@@ -14,7 +15,8 @@
     virtual ~Threads() {};
 
     /* functions */
-    virtual void init() = 0;
+    //virtual void init() = 0;
+    virtual void init() {};
     virtual int get_mail(int speid, int count, memaddr *ret) = 0; // BLOCKING
     virtual int has_mail(int speid, int count, memaddr *ret) = 0; // NONBLOCK
     virtual void send_mail(int speid, int num, memaddr *data) = 0; // BLOCKING
--- a/example/Simple/Makefile.def	Sat Jun 18 03:25:31 2011 +0900
+++ b/example/Simple/Makefile.def	Tue Jun 21 19:50:53 2011 +0900
@@ -1,6 +1,7 @@
 TARGET = twice
 
 # include/library path
+ABIBIT=64
 
 # ex  linux/ps3
 CERIUM = ../../../Cerium
--- a/example/Simple/Makefile.macosx	Sat Jun 18 03:25:31 2011 +0900
+++ b/example/Simple/Makefile.macosx	Tue Jun 21 19:50:53 2011 +0900
@@ -11,8 +11,8 @@
 TASK_SRCS = $(filter-out $(TASK_DIR)/$(TASK_SRCS_EXCLUDE),$(TASK_SRCS_TMP))
 TASK_OBJS = $(TASK_SRCS:.cc=.o)
 
-LIBS += -lFifoManager `sdl-config --libs`
-CC += -m32
+LIBS += -lParallelManager `sdl-config --libs`
+CC += -m$(ABIBIT)
 
 .SUFFIXES: .cc .o