Mercurial > hg > Members > kono > Cerium
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); }