changeset 1499:622a7d053537 draft

cpu id etc
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 22 Aug 2012 17:42:33 +0900
parents 8034e0212281
children 60f8ba22a200
files TaskManager/Cell/CellTaskManagerImpl.cc TaskManager/ChangeLog TaskManager/Gpu/GpuScheduler.cc TaskManager/Gpu/GpuThreads.cc TaskManager/kernel/ppe/CpuThreads.cc TaskManager/kernel/ppe/CpuThreads.h TaskManager/kernel/ppe/Threads.h TaskManager/test/GpuRunTest/Makefile TaskManager/test/GpuRunTest/Makefile.bk
diffstat 9 files changed, 241 insertions(+), 252 deletions(-) [+]
line wrap: on
line diff
--- a/TaskManager/Cell/CellTaskManagerImpl.cc	Tue Aug 21 19:09:32 2012 +0900
+++ b/TaskManager/Cell/CellTaskManagerImpl.cc	Wed Aug 22 17:42:33 2012 +0900
@@ -15,63 +15,63 @@
 #include "GpuThreads.h"
 #endif
 static void send_alloc_reply(CellTaskManagerImpl *tm, int id,
-		Threads *speThreads);
+                Threads *speThreads);
 
 CellTaskManagerImpl::~CellTaskManagerImpl() {
 
-	delete speThreads;
-	delete[] speTaskList;
+    delete speThreads;
+    delete[] speTaskList;
 
-	delete ppeManager;
+    delete ppeManager;
 }
 
 void CellTaskManagerImpl::init(int spuIdle_,int useRefDma,int export_task_log) {
-	spe_running = 0;
-	spuIdle = spuIdle_;
+    spe_running = 0;
+    spuIdle = spuIdle_;
 
-	// 実行される Task 用の パイプライン用のダブルバッファ
-	speTaskList = new QueueInfo<TaskList>*[machineNum]; // spe上の走っている Task の配列
-	taskListInfo = new QueueInfo<TaskList>*[machineNum]; // 次に走る Task の配列
+    // 実行される 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, useRefDma); // ここで HTaskInfo が共有される。
+    // PPE 側の管理をする Manager
+    ppeManager = new FifoTaskManagerImpl(machineNum);
+    // 大半のTaskQueueInfoは、共有される
+    MainScheduler *mscheduler = new MainScheduler;
+    set_scheduler(mscheduler);
+    ppeManager->init(mscheduler, this, useRefDma); // ここで HTaskInfo が共有される。
 
-	speThreads->init();
+    speThreads->init();
 
-	// 実行可能な 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, ppeManager->get_scheduler(), 0);
-	ppeManager->schedTaskManager = schedTaskManager;
+    // Task 内からManager->task_create() とかするときに必要なTaskManager。
+    // 現状では ppe 側からしか動かない
+    // spe 側から Task create できない
+    schedTaskManager = new SchedTask();
+    schedTaskManager->init(0, 0, ppeManager->get_scheduler(), 0);
+    ppeManager->schedTaskManager = schedTaskManager;
 
-        _export_task_log = export_task_log;
+    _export_task_log = export_task_log;
 }
 
 void CellTaskManagerImpl::append_activeTask(HTaskPtr task) {
-	if (task->cpu_type == CPU_PPE) {
-		ppeManager->append_activeTask(task);
-	} else {
-		activeTaskQueue->addLast(task);
-	}
+    if (task->cpu_type == CPU_PPE) {
+        ppeManager->append_activeTask(task);
+    } else {
+        activeTaskQueue->addLast(task);
+    }
 }
 
 // SPE_ANY が指定されていた時に
@@ -86,35 +86,29 @@
  * spe に渡される Task だけ入っている
  */
 void CellTaskManagerImpl::set_runTaskList(QueueInfo<HTask> *activeTaskQueue) {
-	int speid;
-	HTaskPtr htask = activeTaskQueue->getFirst();
-	while (htask != NULL) {
-
-		if (htask->cpu_type == CPU_PPE) {
-            
-			htask = activeTaskQueue->getNext(htask);
-            
-		}  else {
+    int speid;
+    HTaskPtr htask = activeTaskQueue->getFirst();
+    while (htask != NULL) {
+        if (htask->cpu_type == CPU_PPE) {
+            htask = activeTaskQueue->getNext(htask);
+        }  else {
+            if (htask->cpu_type == SPE_ANY) {
+                speid = cur_anySpeid++;
 #ifdef __CERIUM_GPU__
-            speid = htask->cpu_type - 1;
-#else
-			if (htask->cpu_type == SPE_ANY) {
-				speid = cur_anySpeid++;
-			} else {
+            } else if (htask->cpu_type == GPU_0) {
+                speid = htask->cpu_type - 1;
+#endif
+            } 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;
             }
-#endif
             speid %= machineNum;
             
             set_taskList(htask, taskListInfo[speid]);
             
-            
-            
-            
             HTaskPtr next = activeTaskQueue->getNext(htask);
             activeTaskQueue->remove(htask);
             htask = next;
@@ -124,37 +118,37 @@
 }
 
 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++;
-		}
-	}
+    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++;
+        }
+    }
 }
 
 void CellTaskManagerImpl::poll() {
-	set_runTaskList(activeTaskQueue);
-	// TaskList 待ちの SPE に TaskList を送る
-	sendTaskList();
+    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());
-	HTaskPtr task = activeTaskQueue->getFirst();
-	int tmp_i = 0;
-	do {
-		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");
+                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("cpu = [%d], count = %d", task->cpu_type, tmp_i);
+        tmp_i++;
+    } while ((task = activeTaskQueue->getNext(task)) != 0);
+    printf("\n");
 }
 
 void CellTaskManagerImpl::run() {
@@ -184,44 +178,44 @@
 }
 
 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);
-		}
-	}
+    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
-				}
-				loop_check(q->task, p, 10);
-			}
-		}
-		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("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);
+            }
+        }
+        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());
+    }
 }
 
 /**
@@ -229,92 +223,92 @@
  */
 
 void CellTaskManagerImpl::mail_check(int id) {
-	memaddr data;
+    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);
-	}
+    // 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,
-		Threads *speThreads) {
+                Threads *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);
 }
 
 /**
@@ -326,36 +320,36 @@
  * これから実行する 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;
+    // 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 + SPE_0));
-		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 + SPE_0));
+        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 + SPE_0));
-		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 + SPE_0));
+        t->spawn();
+    }
 }
 
 void CellTaskManagerImpl::export_task_log() {
@@ -364,14 +358,14 @@
 }
 
 void CellTaskManagerImpl::print_arch() {
-	printf("CellTaskManager\n");
+        printf("CellTaskManager\n");
 }
 
 TaskListPtr CellTaskManagerImpl::createTaskList()
 {
     TaskListPtr tl = taskListInfo[0]->create();
     bzero(tl->tasks,sizeof(Task)*TASK_MAX_SIZE);
-	return tl;
+        return tl;
 }
 
 #if defined (__CERIUM_CELL__)||defined (__CERIUM_GPU__)
@@ -381,9 +375,10 @@
     Threads *cpus = new SpeThreads(num);
 #elif __CERIUM_GPU__    
     Threads *cpus = new CpuThreads(num, useRefDma);
+    num += 1; // for GPU
 #else    
     Threads *cpus = new CpuThreads(num, useRefDma);
 #endif
-	return new CellTaskManagerImpl(num, cpus);
+    return new CellTaskManagerImpl(num, cpus);
 }
 #endif // __CERIUM_CELL
--- a/TaskManager/ChangeLog	Tue Aug 21 19:09:32 2012 +0900
+++ b/TaskManager/ChangeLog	Wed Aug 22 17:42:33 2012 +0900
@@ -1,3 +1,10 @@
+2012-8-22 Shinji KONO <kono@ie.u-ryukyu.ac.jp>
+
+	Open CL の kernel の実行はできたが、Scheduler が終了しない。
+
+	cl command queue は二本用意して pipelining するべき。
+
+
 2012-7-15 Shinji KONO <kono@ie.u-ryukyu.ac.jp>
 
 	GpuTaskManager は明らかに不要。FifoManager は CellTaskManager の簡易版に過ぎない。
--- a/TaskManager/Gpu/GpuScheduler.cc	Tue Aug 21 19:09:32 2012 +0900
+++ b/TaskManager/Gpu/GpuScheduler.cc	Wed Aug 22 17:42:33 2012 +0900
@@ -54,10 +54,9 @@
             return ;
         }
         
-        TaskListPtr tasklist ;
-
         while (params_addr) {
-            tasklist = (TaskListPtr)connector->dma_load(this, params_addr, 
+            // since we are on the same memory space, we don't hae to use dma_load here
+            TaskListPtr tasklist = (TaskListPtr)connector->dma_load(this, params_addr, 
                                                         sizeof(TaskList), DMA_READ_TASKLIST);
             
             for (TaskPtr nextTask = tasklist->tasks; nextTask < tasklist->last(); nextTask = nextTask->next()) {
@@ -72,18 +71,14 @@
                                                sizeof(memaddr)*nextTask->param_count, NULL, NULL);
                 err |= clEnqueueWriteBuffer(command_queue, memin, CL_TRUE, 0, sizeof(memaddr)*nextTask->param_count, 
                                             nextTask->param(0), 0, NULL, NULL);
-fprintf(stderr,"err1 = %d\n",err);
                 err |= clSetKernelArg(kernel, param, sizeof(memaddr),(void *)&memin);
-fprintf(stderr,"err2 = %d\n",err);
                 
                 param++;
                 for(int i=0;i<nextTask->inData_count;i++) {
                     cl_mem memin = clCreateBuffer(context, CL_MEM_READ_ONLY, nextTask->inData(i)->size, NULL, NULL);
                     err |= clEnqueueWriteBuffer(command_queue, memin, CL_TRUE, 0, 
                                                 nextTask->inData(i)->size, nextTask->inData(i)->addr, 0, NULL, NULL);
-fprintf(stderr,"err3 = %d\n",err);
                     err |= clSetKernelArg(kernel,  param, sizeof(memaddr), (void *)&memin);
-fprintf(stderr,"err4 = %d\n",err);
 
                     param++;
                 }
@@ -95,7 +90,6 @@
                     err |= clSetKernelArg(kernel,  param, sizeof(memaddr), (void *)&memout[i]);
                     param++;
                 }
-                // set kernel arg
                 
                 cl_event ev = NULL;
                 clEnqueueTask(command_queue, kernel, 0, NULL, &ev);
@@ -105,20 +99,25 @@
                                                nextTask->outData(i)->size, nextTask->outData(i)->addr, 1, &ev, NULL);
                 }
             }
-        
             clFlush(command_queue); // waiting for queued task
+            connector->mail_write((memaddr)(tasklist->waiter));
             params_addr = (memaddr)tasklist->next;
         }
-        
-        connector->mail_write((memaddr)(tasklist->waiter));
     }
     // TaskArrayの処理
 }
 
+int
+not_ready(SchedTask* smanager, void* r, void *w)
+{
+    smanager->printf("GPU task not ready %d\n", smanager->atask->command);
+    return 0;
+}
+
 void
 GpuScheduler::load_kernel(int cmd)
 {
-    if (task_list[cmd].run != 0) return;
+    if (task_list[cmd].run == null_run) return;
 
     const char *filename = (const char *)task_list[cmd].kernel;
     const char *functionname = task_list[cmd].name;
@@ -161,7 +160,7 @@
 void
 gpu_register_task(int cmd, const char* filename, const char* functionname)
 {     
-    task_list[cmd].run = 0;  // not yet ready
+    task_list[cmd].run = not_ready;  // not yet ready
     task_list[cmd].load = null_loader;
     task_list[cmd].wait = null_loader;
     task_list[cmd].name = functionname;
--- a/TaskManager/Gpu/GpuThreads.cc	Tue Aug 21 19:09:32 2012 +0900
+++ b/TaskManager/Gpu/GpuThreads.cc	Wed Aug 22 17:42:33 2012 +0900
@@ -12,9 +12,11 @@
 
 GpuThreads::~GpuThreads()
 {
+    memaddr mail = (memaddr)MY_SPE_COMMAND_EXIT;
+    send_mail(0,1,&mail);
+
     delete threads;
     delete args;
-
 }
 
 void
--- a/TaskManager/kernel/ppe/CpuThreads.cc	Tue Aug 21 19:09:32 2012 +0900
+++ b/TaskManager/kernel/ppe/CpuThreads.cc	Wed Aug 22 17:42:33 2012 +0900
@@ -23,7 +23,7 @@
 #endif
     threads = new pthread_t[cpu_num];
     args    = new cpu_thread_arg_t[cpu_num];
-    wait	= new Sem(0);
+    wait    = new Sem(0);
 
 }
 
@@ -36,8 +36,8 @@
     }
 
     for (int i = 0; i < cpu_num; i++) {
-		pthread_join(threads[i], NULL);
-	}
+        pthread_join(threads[i], NULL);
+    }
 
     for (int i = 0; i < cpu_num; i++) {
     	delete args[i].scheduler;
@@ -83,12 +83,12 @@
     wait->sem_p();
 #endif
 
-	for (int i = 0; i < cpu_num; i++) {
-		args[i].cpuid = i + id_offset;
-		args[i].scheduler = new MainScheduler();
-		args[i].wait = wait;
-		args[i].useRefDma = use_refdma;
-	}
+    for (int i = 0; i < cpu_num; i++) {
+        args[i].cpuid = i + id_offset;
+        args[i].scheduler = new MainScheduler();
+        args[i].wait = wait;
+        args[i].useRefDma = use_refdma;
+    }
 
     for (int i = 0; i < cpu_num; i++) {
 	pthread_create(&threads[i], NULL,
@@ -112,7 +112,7 @@
 CpuThreads::get_mail(int cpuid, int count, memaddr *ret)
 {  
 #ifdef __CERIUM_GPU__
-    if (is_gpu()) return gpu->get_mail(cpuid, count, ret);
+    if (is_gpu(cpuid)) return gpu->get_mail(cpuid, count, ret);
 #endif
     *ret = args[cpuid-id_offset].scheduler->mail_read_from_host();
     return 1;
@@ -122,7 +122,7 @@
 CpuThreads::has_mail(int cpuid, int count, memaddr *ret)
 {
 #ifdef __CERIUM_GPU__
-    if (is_gpu()) return gpu->has_mail(cpuid, count, ret);
+    if (is_gpu(cpuid)) return gpu->has_mail(cpuid, count, ret);
 #endif
     if (args[cpuid-id_offset].scheduler->has_mail_from_host() != 0) {
         return get_mail(cpuid,count,ret);
@@ -149,7 +149,7 @@
 CpuThreads::send_mail(int cpuid, int num, memaddr *data)
 {
 #ifdef __CERIUM_GPU__
-    if (is_gpu()){
+    if (is_gpu(cpuid)){
         gpu->send_mail(cpuid, num, data);
         return;
     }
@@ -171,9 +171,8 @@
 
 
 int
-CpuThreads::is_gpu()
+CpuThreads::is_gpu(int cpuid)
 {
-    CPU_TYPE cpuid = task_list->cpu_type;
     if ( (cpuid < GPU_0)||(cpuid > GPU_3) ) {
         return 0;
         // cpuidがGPU以外なら0を返す
--- a/TaskManager/kernel/ppe/CpuThreads.h	Tue Aug 21 19:09:32 2012 +0900
+++ b/TaskManager/kernel/ppe/CpuThreads.h	Wed Aug 22 17:42:33 2012 +0900
@@ -31,7 +31,7 @@
     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);
-    virtual int is_gpu();
+    virtual int is_gpu(int cpuid);
 
 private:
     /* variables */
@@ -39,7 +39,7 @@
     cpu_thread_arg_t *args;
     SemPtr wait; //スレッド生成時の待ち用
     int cpu_num;
-	int use_refdma;
+    int use_refdma;
     int id_offset;
 #ifdef __CERIUM_GPU__
     GpuThreads *gpu;
--- a/TaskManager/kernel/ppe/Threads.h	Tue Aug 21 19:09:32 2012 +0900
+++ b/TaskManager/kernel/ppe/Threads.h	Wed Aug 22 17:42:33 2012 +0900
@@ -19,7 +19,8 @@
     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
-	virtual void add_output_tasklist(int command, memaddr buff, int alloc_size) = 0;
+    virtual void add_output_tasklist(int command, memaddr buff, int alloc_size) = 0;
+    virtual int is_gpu(int cpuid) { return 0; }
 
     /* variables */
     pthread_t *threads;
--- a/TaskManager/test/GpuRunTest/Makefile	Tue Aug 21 19:09:32 2012 +0900
+++ b/TaskManager/test/GpuRunTest/Makefile	Wed Aug 22 17:42:33 2012 +0900
@@ -13,6 +13,7 @@
 	$(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
 
 all: $(TARGET)
+gpu: all
 
 $(TARGET): $(OBJS)
 	$(CC) -o $@ $(OBJS) $(TASK_OBJS) $(LIBS)
--- a/TaskManager/test/GpuRunTest/Makefile.bk	Tue Aug 21 19:09:32 2012 +0900
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,15 +0,0 @@
-include ../../Makefile.def
-
-CPPFLAGS += -g -Wall -I../../../include/TaskManager -m$(ABIBIT)
-
-TARGET=GpuRunTest
-
-
-
-LIBS += ../../libGpuManager.a -framework opencl
-
-GpuRunTest : GpuRunTest.o
-	$(CC) $(CFLAGS) -o $@ $? $(LIBS)
-
-clean:
-	rm -rf *.o $(TARGET)