diff TaskManager/Cell/SpeThreads.cc @ 109:5c194c71eca8

Cerium cvs version
author gongo@gendarme.local
date Wed, 12 Nov 2008 17:39:33 +0900
parents 5a1a5f4c28fd
children 1f4c3f3238e6
line wrap: on
line diff
--- a/TaskManager/Cell/SpeThreads.cc	Wed Nov 12 17:29:35 2008 +0900
+++ b/TaskManager/Cell/SpeThreads.cc	Wed Nov 12 17:39:33 2008 +0900
@@ -1,3 +1,4 @@
+#include <stdlib.h>
 #include "types.h"
 #include "SpeThreads.h"
 
@@ -9,11 +10,9 @@
     int ret;
 
     for (int i = 0; i < spe_num; i++) {
-	send_mail(i, &mail);
+	send_mail(i, &mail, 1);
     }
 
-    printf("******  SpeThreads 1 ********\n"); 
-
     for (int i = 0; i < spe_num; i++) {
 	pthread_join(threads[i], NULL);
 	ret = spe_context_destroy(spe_ctx[i]);
@@ -22,25 +21,43 @@
 	}
     }
 
-    printf("******  SpeThreads 2 ********\n"); 
-
     spe_image_close(spe_handle);
 
     delete [] spe_ctx;
     delete [] threads;
     delete [] args;
-
-
-    printf("******  SpeThreads 3 ********\n"); 
 }
 
 void*
 SpeThreads::spe_thread_run(void *arg)
 {
     unsigned int entry = SPE_DEFAULT_ENTRY;
-    spe_context_ptr_t ctx = (spe_context_ptr_t)arg;
+    //spe_context_ptr_t ctx = (spe_context_ptr_t)arg;
+    thread_arg_t *arg_t = (thread_arg_t *)arg;
+
+    spe_stop_info_t stop_info;
+    unsigned long long status;
+    
+    spe_context_run(arg_t->ctx, &entry, 0, (void*)arg_t->speid, NULL, &stop_info);
     
-    spe_context_run(ctx, &entry, 0, NULL, NULL, NULL);
+    status = ((stop_info.result.spe_exit_code & 0xff) << 8)
+	| (stop_info.result.spe_signal_code & 0xff);
+
+    printf("[SPE %d] ", arg_t->speid);
+    switch(stop_info.stop_reason) {
+    case SPE_EXIT:
+	printf("SPE_EXIT stop_info.result.stop_exit_code=0x%x\n", stop_info.result.spe_exit_code);
+	break;
+    case SPE_STOP_AND_SIGNAL:
+	printf("SPE_STOP_AND_SIGNAL stop_info.result.stop_signal_code=%d\n", stop_info.result.spe_signal_code);
+	break;
+    case SPE_RUNTIME_ERROR:
+	printf("SPE_RUNTIME_ERROR stop_info.result.spe_runtime_error=%d\n", stop_info.result.spe_runtime_error);
+	break;
+    case SPE_RUNTIME_EXCEPTION:
+	printf("SPE_RUNTIME_EXCEPTION stop_info.result.spe_runtime_exception=%d\n", stop_info.result.spe_runtime_exception);
+	break;
+    }
 
     pthread_exit(NULL);
 }
@@ -62,41 +79,69 @@
 void
 SpeThreads::init(void)
 {
-    int i;
+    spe_handle = spe_image_open(SPE_ELF);
 
-    spe_handle = spe_image_open(SPE_ELF);
+    if (spe_handle == NULL) {
+	perror("spe_image_open");
+	exit(EXIT_FAILURE);
+    }
 
     spe_ctx = new spe_context_ptr_t[spe_num];
     threads = new pthread_t[spe_num];
     args    = new thread_arg_t[spe_num];
 
-    for (i = 0; i < spe_num; i++) {
+    for (int i = 0; i < spe_num; i++) {
 	args[i].speid = i;
 	spe_ctx[i] = spe_context_create(0, NULL);
 	spe_program_load(spe_ctx[i], spe_handle);
 	args[i].ctx = spe_ctx[i];
     }
 
-    for (i = 0; i < spe_num; i++) {
+    for (int i = 0; i < spe_num; i++) {
+#if 0
 	pthread_create(&threads[i], NULL,
 		       &frontend_thread_run, (void*)&args[i]);
+#else
+	pthread_create(&threads[i], NULL,
+		       //&spe_thread_run, (void*)spe_ctx[i]);
+		       &spe_thread_run, (void*)&args[i]);
+#endif
     }
 }
 
+/**
+ * SPE からのメールを受信する。
+ *
+ * @param [speid] SPE ID
+ *
+ * @return Received 32-bit mailbox messages
+ *         if ([ret] < 0) no data read
+ */
 int
 SpeThreads::get_mail(int speid)
 {
-    unsigned int ret;
+    unsigned int ret = (unsigned int)(-1);
 
-    if (spe_out_mbox_read(spe_ctx[speid], &ret, 1) > 0) {
-	return (int)ret;
-    } else {
-	return -1;
-    }
+    spe_out_mbox_read(spe_ctx[speid], &ret, 1);
+    return ret;
 }
 
+/**
+ * Inbound Mailbox
+ * メール送信 PPE -> SPE
+ *
+ * なるべく NONBLOCKING なんだけど、
+ * Inbound Mailbox キューに空きがないと送信できないので
+ * 送信する数だけ空いているか確認してから送る。相手無い場合は待つ。
+ * 結局 BLOCKING よりたちの悪い busy_wait かよとか思ったり。
+ *
+ * @param [speid] SPE ID
+ * @param [data] Send 32-bit mailbox messages
+ * @param [num] The number of messages
+ */
 void
-SpeThreads::send_mail(int speid, unsigned int *data)
+SpeThreads::send_mail(int speid, unsigned int *data, int num)
 {
-    spe_in_mbox_write(spe_ctx[speid], data, 1, SPE_MBOX_ANY_NONBLOCKING);
+    while (spe_in_mbox_status(spe_ctx[speid]) < num);
+    spe_in_mbox_write(spe_ctx[speid], data, num, SPE_MBOX_ANY_NONBLOCKING);
 }