comparison TaskManager/Cell/SpeThreads.cc @ 109:028ffc9c0375 draft

Cerium cvs version
author gongo@gendarme.local
date Wed, 12 Nov 2008 17:39:33 +0900
parents 5a1a5f4c28fd
children 18c42658e0e7
comparison
equal deleted inserted replaced
108:6f3b3dd3c095 109:028ffc9c0375
1 #include <stdlib.h>
1 #include "types.h" 2 #include "types.h"
2 #include "SpeThreads.h" 3 #include "SpeThreads.h"
3 4
4 SpeThreads::SpeThreads(int num) : spe_num(num) {} 5 SpeThreads::SpeThreads(int num) : spe_num(num) {}
5 6
7 { 8 {
8 unsigned int mail = MY_SPE_COMMAND_EXIT; 9 unsigned int mail = MY_SPE_COMMAND_EXIT;
9 int ret; 10 int ret;
10 11
11 for (int i = 0; i < spe_num; i++) { 12 for (int i = 0; i < spe_num; i++) {
12 send_mail(i, &mail); 13 send_mail(i, &mail, 1);
13 } 14 }
14
15 printf("****** SpeThreads 1 ********\n");
16 15
17 for (int i = 0; i < spe_num; i++) { 16 for (int i = 0; i < spe_num; i++) {
18 pthread_join(threads[i], NULL); 17 pthread_join(threads[i], NULL);
19 ret = spe_context_destroy(spe_ctx[i]); 18 ret = spe_context_destroy(spe_ctx[i]);
20 if (ret) { 19 if (ret) {
21 perror("[~SpeThreads] spe_context_destroy"); 20 perror("[~SpeThreads] spe_context_destroy");
22 } 21 }
23 } 22 }
24 23
25 printf("****** SpeThreads 2 ********\n");
26
27 spe_image_close(spe_handle); 24 spe_image_close(spe_handle);
28 25
29 delete [] spe_ctx; 26 delete [] spe_ctx;
30 delete [] threads; 27 delete [] threads;
31 delete [] args; 28 delete [] args;
32
33
34 printf("****** SpeThreads 3 ********\n");
35 } 29 }
36 30
37 void* 31 void*
38 SpeThreads::spe_thread_run(void *arg) 32 SpeThreads::spe_thread_run(void *arg)
39 { 33 {
40 unsigned int entry = SPE_DEFAULT_ENTRY; 34 unsigned int entry = SPE_DEFAULT_ENTRY;
41 spe_context_ptr_t ctx = (spe_context_ptr_t)arg; 35 //spe_context_ptr_t ctx = (spe_context_ptr_t)arg;
36 thread_arg_t *arg_t = (thread_arg_t *)arg;
37
38 spe_stop_info_t stop_info;
39 unsigned long long status;
42 40
43 spe_context_run(ctx, &entry, 0, NULL, NULL, NULL); 41 spe_context_run(arg_t->ctx, &entry, 0, (void*)arg_t->speid, NULL, &stop_info);
42
43 status = ((stop_info.result.spe_exit_code & 0xff) << 8)
44 | (stop_info.result.spe_signal_code & 0xff);
45
46 printf("[SPE %d] ", arg_t->speid);
47 switch(stop_info.stop_reason) {
48 case SPE_EXIT:
49 printf("SPE_EXIT stop_info.result.stop_exit_code=0x%x\n", stop_info.result.spe_exit_code);
50 break;
51 case SPE_STOP_AND_SIGNAL:
52 printf("SPE_STOP_AND_SIGNAL stop_info.result.stop_signal_code=%d\n", stop_info.result.spe_signal_code);
53 break;
54 case SPE_RUNTIME_ERROR:
55 printf("SPE_RUNTIME_ERROR stop_info.result.spe_runtime_error=%d\n", stop_info.result.spe_runtime_error);
56 break;
57 case SPE_RUNTIME_EXCEPTION:
58 printf("SPE_RUNTIME_EXCEPTION stop_info.result.spe_runtime_exception=%d\n", stop_info.result.spe_runtime_exception);
59 break;
60 }
44 61
45 pthread_exit(NULL); 62 pthread_exit(NULL);
46 } 63 }
47 64
48 void* 65 void*
60 } 77 }
61 78
62 void 79 void
63 SpeThreads::init(void) 80 SpeThreads::init(void)
64 { 81 {
65 int i; 82 spe_handle = spe_image_open(SPE_ELF);
66 83
67 spe_handle = spe_image_open(SPE_ELF); 84 if (spe_handle == NULL) {
85 perror("spe_image_open");
86 exit(EXIT_FAILURE);
87 }
68 88
69 spe_ctx = new spe_context_ptr_t[spe_num]; 89 spe_ctx = new spe_context_ptr_t[spe_num];
70 threads = new pthread_t[spe_num]; 90 threads = new pthread_t[spe_num];
71 args = new thread_arg_t[spe_num]; 91 args = new thread_arg_t[spe_num];
72 92
73 for (i = 0; i < spe_num; i++) { 93 for (int i = 0; i < spe_num; i++) {
74 args[i].speid = i; 94 args[i].speid = i;
75 spe_ctx[i] = spe_context_create(0, NULL); 95 spe_ctx[i] = spe_context_create(0, NULL);
76 spe_program_load(spe_ctx[i], spe_handle); 96 spe_program_load(spe_ctx[i], spe_handle);
77 args[i].ctx = spe_ctx[i]; 97 args[i].ctx = spe_ctx[i];
78 } 98 }
79 99
80 for (i = 0; i < spe_num; i++) { 100 for (int i = 0; i < spe_num; i++) {
101 #if 0
81 pthread_create(&threads[i], NULL, 102 pthread_create(&threads[i], NULL,
82 &frontend_thread_run, (void*)&args[i]); 103 &frontend_thread_run, (void*)&args[i]);
104 #else
105 pthread_create(&threads[i], NULL,
106 //&spe_thread_run, (void*)spe_ctx[i]);
107 &spe_thread_run, (void*)&args[i]);
108 #endif
83 } 109 }
84 } 110 }
85 111
112 /**
113 * SPE からのメールを受信する。
114 *
115 * @param [speid] SPE ID
116 *
117 * @return Received 32-bit mailbox messages
118 * if ([ret] < 0) no data read
119 */
86 int 120 int
87 SpeThreads::get_mail(int speid) 121 SpeThreads::get_mail(int speid)
88 { 122 {
89 unsigned int ret; 123 unsigned int ret = (unsigned int)(-1);
90 124
91 if (spe_out_mbox_read(spe_ctx[speid], &ret, 1) > 0) { 125 spe_out_mbox_read(spe_ctx[speid], &ret, 1);
92 return (int)ret; 126 return ret;
93 } else {
94 return -1;
95 }
96 } 127 }
97 128
129 /**
130 * Inbound Mailbox
131 * メール送信 PPE -> SPE
132 *
133 * なるべく NONBLOCKING なんだけど、
134 * Inbound Mailbox キューに空きがないと送信できないので
135 * 送信する数だけ空いているか確認してから送る。相手無い場合は待つ。
136 * 結局 BLOCKING よりたちの悪い busy_wait かよとか思ったり。
137 *
138 * @param [speid] SPE ID
139 * @param [data] Send 32-bit mailbox messages
140 * @param [num] The number of messages
141 */
98 void 142 void
99 SpeThreads::send_mail(int speid, unsigned int *data) 143 SpeThreads::send_mail(int speid, unsigned int *data, int num)
100 { 144 {
101 spe_in_mbox_write(spe_ctx[speid], data, 1, SPE_MBOX_ANY_NONBLOCKING); 145 while (spe_in_mbox_status(spe_ctx[speid]) < num);
146 spe_in_mbox_write(spe_ctx[speid], data, num, SPE_MBOX_ANY_NONBLOCKING);
102 } 147 }