changeset 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
files TaskManager/Cell/CellTaskManagerImpl.cc TaskManager/Fifo/FifoTaskManagerImpl.cc TaskManager/kernel/ppe/MailManager.cc TaskManager/kernel/ppe/TaskManagerImpl.cc TaskManager/kernel/ppe/TaskManagerImpl.h
diffstat 5 files changed, 71 insertions(+), 120 deletions(-) [+]
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);
 }
 
 /**
--- a/TaskManager/Fifo/FifoTaskManagerImpl.cc	Sat Dec 19 09:50:37 2009 +0900
+++ b/TaskManager/Fifo/FifoTaskManagerImpl.cc	Sat Dec 19 10:34:43 2009 +0900
@@ -27,14 +27,16 @@
 void
 FifoTaskManagerImpl::init()
 {
+    // TaskManager から呼ばれるので、かなりの部分は初期化されている。
+
     mainScheduler = new MainScheduler();
     mainScheduler->init(this);
     mainScheduler->id = 0;
     set_scheduler(mainScheduler);
 
     taskListImpl  = new TaskListInfo;
-    taskQueueImpl = new TaskQueueInfo;
-    htaskImpl     = new HTaskInfo();
+    // taskQueueImpl = new TaskQueueInfo;
+    // htaskImpl     = new HTaskInfo();
 
     mainTaskList = taskListImpl->create();
 
@@ -60,7 +62,7 @@
     taskListImpl  = tm-> taskListImpl  ;
     taskQueueImpl = tm-> taskQueueImpl ;
     htaskImpl     = tm-> htaskImpl     ;
-    waitTaskQueue     = NULL;   // mail_check で外から設定される
+    waitTaskQueue     = tm->waitTaskQueue;   
 
     mainTaskList = taskListImpl->create();
 
@@ -149,10 +151,8 @@
         schedule(list);
 
         // ppe scheduler からの mail を調べる
-        mail_check(waitTaskQueue);
+        mail_check();
 
-        // 依存関係を満たしたものは実行可能キューへ
-        wakeup_waitTask();
         list = get_runTaskList();
     } while (list);
 }
@@ -191,7 +191,7 @@
  *         NULL なら全てのタスクが実行終了したということ
  */
 void
-FifoTaskManagerImpl::mail_check(HTaskInfo *wait_queue)
+FifoTaskManagerImpl::mail_check()
 {
     while (mainScheduler->has_mail_from_host()) {
 	memaddr data = mainScheduler->mail_read_from_host();
@@ -206,7 +206,7 @@
 	    // 移されてから、wait_for されるという事態が起きることがある。
             HTaskPtr task = (HTaskPtr)data;
             task->post_func(schedTaskManager, task->post_arg1, task->post_arg2);
-            check_task_finish(task, wait_queue);
+            check_task_finish(task, waitTaskQueue);
         }
     }
 }
--- a/TaskManager/kernel/ppe/MailManager.cc	Sat Dec 19 09:50:37 2009 +0900
+++ b/TaskManager/kernel/ppe/MailManager.cc	Sat Dec 19 10:34:43 2009 +0900
@@ -13,6 +13,7 @@
 }
 
 MailManager::MailManager(unsigned int qsize) {
+    read = write = 0;
     calc_mask(qsize);
     queue = New(memaddr,size);
 }
--- a/TaskManager/kernel/ppe/TaskManagerImpl.cc	Sat Dec 19 09:50:37 2009 +0900
+++ b/TaskManager/kernel/ppe/TaskManagerImpl.cc	Sat Dec 19 10:34:43 2009 +0900
@@ -167,15 +167,6 @@
     waitTaskQueue ->addLast(q);
 }
 
-/**
- * waitQueue の中で依存関係を満たしたタスクは
- * activeQueue へ移す
- */
-void
-TaskManagerImpl::wakeup_waitTask()
-{
-  // done in check_task_finish   
-}
 
 
 /* end */
--- a/TaskManager/kernel/ppe/TaskManagerImpl.h	Sat Dec 19 09:50:37 2009 +0900
+++ b/TaskManager/kernel/ppe/TaskManagerImpl.h	Sat Dec 19 10:34:43 2009 +0900
@@ -40,7 +40,6 @@
     virtual void append_waitTask(HTaskPtr);
 
     void check_task_finish(HTaskPtr task, HTaskInfo *wait_queue);
-    void wakeup_waitTask();
 
     void systask_init();