Mercurial > hg > Game > Cerium
diff TaskManager/kernel/ppe/CpuThreads.cc @ 817:c7d737993da7 draft
add CpuThreads.cc
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 23 May 2010 09:43:27 +0900 |
parents | |
children | fc4a96198ed3 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/kernel/ppe/CpuThreads.cc Sun May 23 09:43:27 2010 +0900 @@ -0,0 +1,111 @@ +#include <stdlib.h> +#include "types.h" +#include "CpuThreads.h" +#include "MainScheduler.h" +#include "SysFunc.h" +#include "SchedNop.h" + +SchedExternTask(ShowTime); +SchedExternTask(StartProfile); + + +CpuThreads::CpuThreads(int num, int start_id) : cpu_num(num), id_offset(start_id) {} + +CpuThreads::~CpuThreads() +{ + memaddr mail = (memaddr)MY_SPE_COMMAND_EXIT; + + for (int i = 0; i < cpu_num; i++) { + send_mail(i, 1, &mail); + } + + for (int i = 0; i < cpu_num; i++) { + pthread_join(threads[i], NULL); + } + + delete [] threads; + delete [] args; +} + +void * +CpuThreads::cpu_thread_run(void *args) +{ + cpu_thread_arg_t *argt = (cpu_thread_arg_t *) args; + Scheduler *c_scheduler = argt->scheduler; + + SchedRegister(ShowTime); + SchedRegister(StartProfile); + + c_scheduler->init(argt->manager); + c_scheduler->id = (int)argt->cpuid; + + c_scheduler->run(new SchedNop()); + c_scheduler->finish(); + + return NULL; +} + +void +CpuThreads::init() +{ + threads = new pthread_t[cpu_num]; + args = new cpu_thread_arg_t[cpu_num]; + + for (int i = 0; i < cpu_num; i++) { + args[i].cpuid = i + id_offset; + args[i].scheduler = new MainScheduler(); + } + + for (int i = 0; i < cpu_num; i++) { + pthread_create(&threads[i], NULL, + &cpu_thread_run, (void*)&args[i]); + } +} + +/** + * このCPU からのメールを受信する。 + * + * @param [cpuid] SPE ID + * + * @return Received 32-bit mailbox messages + * if ([ret] < 0) no data read + */ +int +CpuThreads::get_mail(int cpuid, int count, memaddr *ret) +{ + // need synchronization + *ret = args[cpuid-id_offset].scheduler->mail_read_from_host(); + return 1; +} + +int +CpuThreads::has_mail(int cpuid, int count, memaddr *ret) +{ + // need synchronization + return args[cpuid-id_offset].scheduler->has_mail_from_host(); +} + +/** + * Inbound Mailbox + * メール送信 Front End -> CPU + * + * なるべく NONBLOCKING なんだけど、 + * Inbound Mailbox キューに空きがないと送信できないので + * 送信する数だけ空いているか確認してから送る。空いて無い場合は待つ。 + * + * 結局待つんだよな。しかも ALL_BLOCKING って実は busy wait だったりするし + * + * @param [cpuid] SPE ID + * @param [data] Send 32-bit mailbox messages + * @param [num] The number of messages + */ +void +CpuThreads::send_mail(int cpuid, int num, memaddr *data) + +{ + // need synchronization + args[cpuid-id_offset].scheduler->mail_write_from_host(*data); +} + + +/* end */