Mercurial > hg > Members > kono > Cerium
view TaskManager/Cell/SpeThreads.cc @ 629:8843edf37c0e
Cell 64 bit tried, but not yet worked.
Cell's list DMA is 32bit.
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 18 Nov 2009 13:32:58 +0900 |
parents | 5b178db5988a |
children | 7c9ded1ea750 |
line wrap: on
line source
#include <stdlib.h> #include "types.h" #include "SpeThreads.h" SpeThreads::SpeThreads(int num) : spe_num(num) {} SpeThreads::~SpeThreads(void) { memaddr mail = (memaddr)MY_SPE_COMMAND_EXIT; int ret; for (int i = 0; i < spe_num; i++) { send_mail(i, 1, &mail); } for (int i = 0; i < spe_num; i++) { pthread_join(threads[i], NULL); ret = spe_context_destroy(spe_ctx[i]); if (ret) { perror("[~SpeThreads] spe_context_destroy"); } } spe_image_close(spe_handle); delete [] spe_ctx; delete [] threads; delete [] args; } void* SpeThreads::spe_thread_run(void *arg) { unsigned int entry = SPE_DEFAULT_ENTRY; //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); status = ((stop_info.result.spe_exit_code & 0xff) << 8) | (stop_info.result.spe_signal_code & 0xff); 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 %d] SPE_STOP_AND_SIGNAL stop_info.result.stop_signal_code=%d\n", arg_t->speid, stop_info.result.spe_signal_code); break; case SPE_RUNTIME_ERROR: printf("[SPE %d] SPE_RUNTIME_ERROR stop_info.result.spe_runtime_error=%d\n", arg_t->speid, stop_info.result.spe_runtime_error); break; case SPE_RUNTIME_EXCEPTION: printf("[SPE %d] SPE_RUNTIME_EXCEPTION stop_info.result.spe_runtime_exception=%d\n", arg_t->speid, stop_info.result.spe_runtime_exception); break; } pthread_exit(NULL); } void* SpeThreads::frontend_thread_run(void *arg) { pthread_t thread; thread_arg_t *arg_t = (thread_arg_t *)arg; pthread_create(&thread, NULL, &spe_thread_run, (void*)arg_t->ctx); // mail read の blocking ができれば // ここで呼んだ方が早い。 pthread_exit(NULL); } void SpeThreads::init(void) { 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 (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 (int i = 0; i < spe_num; i++) { pthread_create(&threads[i], NULL, &spe_thread_run, (void*)&args[i]); } } /** * SPE からのメールを受信する。 * * @param [speid] SPE ID * * @return Received 32-bit mailbox messages * if ([ret] < 0) no data read */ int SpeThreads::get_mail(int speid, int count, memaddr *ret) { // only used in CellTaskManagerImpl (should be removed?) return spe_out_mbox_read(spe_ctx[speid], (unsigned int*)ret, count*(sizeof(memaddr)/sizeof(int))); } int SpeThreads::check_mail(int speid, int count, memaddr *ret) { /* * spe_out_mbox_status return only 1, waiting for multiple length * does not work. */ if (spe_out_mbox_status(spe_ctx[speid]) >= 1) { return spe_out_mbox_read(spe_ctx[speid], (unsigned int*)ret, count*(sizeof(memaddr)/sizeof(int))); } else { return 0; } } /** * Inbound Mailbox * メール送信 PPE -> SPE * * なるべく NONBLOCKING なんだけど、 * Inbound Mailbox キューに空きがないと送信できないので * 送信する数だけ空いているか確認してから送る。空いて無い場合は待つ。 * * 結局待つんだよな。しかも ALL_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, int num, memaddr *data) { spe_in_mbox_write(spe_ctx[speid], (unsigned int *)data, num*(sizeof(memaddr)/sizeof(int)), SPE_MBOX_ALL_BLOCKING); } void SpeThreads::add_output_tasklist(int command, memaddr buff, int alloc_size) { /* * output TaskList が無ければ新しく作る * あれば TaskList に allocate した Task を追加 * command に対応した Task の初期化を実行する * SPE に data が書き出し終わった後に PPE 側で初期化 */ } /* end */