Mercurial > hg > Game > Cerium
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 } |