diff TaskManager/Cell/CellTaskManagerImpl.cc @ 719:cafffff0f45a

clean up scheduler main loop
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sat, 19 Dec 2009 10:34:43 +0900
parents 31eb1f56d986
children dac59b74e02a
line wrap: on
line diff
--- a/TaskManager/Cell/CellTaskManagerImpl.cc	Sat Dec 19 09:50:37 2009 +0900
+++ b/TaskManager/Cell/CellTaskManagerImpl.cc	Sat Dec 19 10:34:43 2009 +0900
@@ -11,6 +11,7 @@
 #include "types.h"
 #include "SysFunc.h"
 
+static void send_alloc_reply(SpeThreads *speThreads);
 
 CellTaskManagerImpl::~CellTaskManagerImpl()
 {
@@ -157,123 +158,82 @@
 {
     TaskListPtr ppeTaskList = NULL;
 
-    // PPE 側で動く TaskList です
-    // FifoTaskManagerImpl::run と上手く合うように
-    // こんなことやってますよ
-    //
-    // 本来は、別 thread で動かすべきだろう...
-    ppeTaskList = ppeManager->get_runTaskList();
-    if (!ppeTaskList) {
-	goto cont;
-    }
-
-    // SPE からの Mailbox Check は
-    // PPE 側の schedule から抜けて来たときに行う
-    // (speThreads で Blocking Mailbox read と
-    // セマフォとか使ってやってもいいが、今はこの方式で)
-    //
-    // すべてのspe task が finish task を待つ場合は、ppeTaskList の
-    // 判定だけで十分だが、そうでない場合は、spe の task が残っているか
-    // どうかを調べる必要がある。
-    //
     do {
+        // PPE side
+	ppeTaskList =  ppeManager->get_runTaskList();
 	ppeManager->schedule(ppeTaskList);
-    cont:
-	ppeTaskList = mail_check(waitTaskQueue);
+	ppeManager->mail_check(waitTaskQueue);
+        // SPE side
+	do {
+	    mail_check(waitTaskQueue);
+	    // SPE に送る TaskList の準備
+	    set_runTaskList();
+	    // TaskList 待ちの SPE に TaskList を送る
+	    for (int i = 0; i < machineNum; i++)  {
+		if (flag_sendTaskList[i] == 1 && speTaskList_bg[i]->length >= 1 ) {
+		    send_taskList(i);
+		    spe_running++;
+		}
+	    }
+	} while (ppeManager->activeTaskQueue->empty() && !waitTaskQueue->empty());
     } while (ppeTaskList || spe_running >0);
 }
 
 /**
  * SPE からのメールをチェックする
- *
- * @param [mail_list]
- *        PPE 側で動く Scheduler からのメールリスト
- *        この中で PPE 側の mail check も行う
- *
- * @return PPE Scheduler に対してのメール。
- *         次に実行する TaskList のアドレスや、終了コマンドを送る
  */
 
-TaskListPtr
-CellTaskManagerImpl::mail_check(HTaskInfo *wait_queue)
+void
+CellTaskManagerImpl::mail_check()
 {
-    // PPE Scheduler からの mail check
-    ppeManager->mail_check(waitTaskQueue);
-
-    do {
-	memaddr data;
+    memaddr data;
 
-	// SPE Scheduler からの mail check
-	for (int id = 0; id < machineNum; id++) {	    
-	    while (speThreads->has_mail(id, 1, &data)) {				
-		/**
-		 * MY_SPE_STATUS_READY: SPE が持ってた Task 全て終了
-		 * MY_SPE_NOP: 特に意味のないコマンド
-		 * それ以外:終了したタスク(PPEにあるのでアドレス
-		 *
-		 * MY_SPE_NOP が 0 なので、
-		 * 下のように data > MY_SPE_NOP とかしています。
-		 * 一目でよくわからない書き方なんで、直したいところですが。。。
-		 */
-		// 名前あとでちゃんと決めよう => MY_SPE_... とかじゃなくて
-		if (data == (memaddr)MY_SPE_STATUS_READY) {
-		    //__debug_ppe("[SPE %d] finish\n", id);
-		    flag_sendTaskList[id] = 1;
-		    spe_running--;
-		} else if (data == (memaddr)MY_SPE_COMMAND_MALLOC) {
-		    //__debug_ppe("[PPE] MALLOC COMMAND from [SPE %d]\n", id);
+    // SPE Scheduler からの mail check
+    for (int id = 0; id < machineNum; id++) {	    
+	while (speThreads->has_mail(id, 1, &data)) {				
+	    if (data == (memaddr)MY_SPE_STATUS_READY) {
+		//  MY_SPE_STATUS_READY: SPE が持ってた Task 全て終了
+		flag_sendTaskList[id] = 1;
+		spe_running--;
+	    } else if (data == (memaddr)MY_SPE_COMMAND_MALLOC) {
+	        // MY_SPE_COMMAND_MALLOC   SPE からのmain memory request
+		send_alloc_reply(speThreads);
+	    } else if (data > (memaddr)MY_SPE_NOP) {
+	        // 終了したタスク(PPEにあるのでアドレス)
+		HTaskPtr task = (HTaskPtr)data;
+		task->post_func(schedTaskManager, task->post_arg1, task->post_arg2);
+		check_task_finish(task,waitTaskQueue);
+	    }
+	    // MY_SPE_NOP: 特に意味のないコマンド
+	}
+    }
+}
 
-		    /**
-		     * 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];
-
-		    
-		    alloc_info[1] = (memaddr)allocate(alloc_size);
-		    /*
-		     * allocate された領域は今の SPE buffer にリンクとして接続する
-		     * ここでは TaskList を allocate(new) して登録してやろうか
-		     */
-
-		    //__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);
+static void
+send_alloc_reply(SpeThreads *speThreads)
+{
 
-		    speThreads->send_mail(id, 2, alloc_info);
-		} else if (data > (memaddr)MY_SPE_NOP) {
-		    //__debug_ppe("[PPE] recv from [SPE %d] : 0x%x\n", id, data);
-		    HTaskPtr task = (HTaskPtr)data;
-		    task->post_func(schedTaskManager, task->post_arg1, task->post_arg2);
-		    check_task_finish(task,waitTaskQueue);
-		}
-	    }
-	}
-
-	// 依存関係を満たしたタスクをアクティブに
-	wakeup_waitTask();
+    /**
+     * 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];
 
-	// SPE に送る TaskList の準備
-	set_runTaskList();
+    
+    alloc_info[1] = (memaddr)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);
 
-	// TaskList 待ちの SPE に TaskList を送る
-	for (int i = 0; i < machineNum; i++)  {
-	    if (flag_sendTaskList[i] == 1 && speTaskList_bg[i]->length >= 1 ) {
-		send_taskList(i);
-		spe_running++;
-	    }
-	}
-    } while (ppeManager->activeTaskQueue->empty() && !waitTaskQueue->empty());
-	
-    return ppeManager->get_runTaskList();
+    speThreads->send_mail(id, 2, alloc_info);
 }
 
 /**