Mercurial > hg > Members > kono > Cerium
annotate TaskManager/Cell/CellTaskManagerImpl.cc @ 635:8cc609285bbe
SimpleTask worked on Mac OS X
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 18 Nov 2009 18:36:25 +0900 |
parents | 8843edf37c0e |
children | 5530fa36d42e |
rev | line source |
---|---|
321 | 1 #define DEBUG |
2 #include "error.h" | |
57 | 3 #include <stdio.h> |
4 #include <stdlib.h> | |
5 #include <string.h> | |
6 #include "CellTaskManagerImpl.h" | |
476
926d6aff886c
CellBufferManager removed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
380
diff
changeset
|
7 #include "CellTaskListInfo.h" |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
8 #include "HTaskInfo.h" |
621 | 9 #include "SchedTask.h" |
635
8cc609285bbe
SimpleTask worked on Mac OS X
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
629
diff
changeset
|
10 #include "MainScheduler.h" |
57 | 11 #include "types.h" |
12 | |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
13 CellTaskManagerImpl::~CellTaskManagerImpl() |
67 | 14 { |
109 | 15 delete speThreads; |
16 delete [] speTaskList; | |
17 delete [] speTaskList_bg; | |
18 /** | |
321 | 19 * bufferManager は |
20 * ppeManager のなかで delete してもらう | |
109 | 21 */ |
22 // delete bufferManager; | |
23 delete [] flag_sendTaskList; | |
24 | |
25 delete ppeManager; | |
67 | 26 } |
27 | |
57 | 28 void |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
29 CellTaskManagerImpl::init() |
57 | 30 { |
476
926d6aff886c
CellBufferManager removed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
380
diff
changeset
|
31 taskListImpl = new CellTaskListInfo; |
926d6aff886c
CellBufferManager removed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
380
diff
changeset
|
32 taskListImpl->init(machineNum*2); |
926d6aff886c
CellBufferManager removed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
380
diff
changeset
|
33 |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
34 activeTaskQueue = new HTaskInfo(); |
481
4896dffad67c
Double linked list modification done (tested on Mac OS X)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
479
diff
changeset
|
35 |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
36 htaskImpl = activeTaskQueue ; // any HTaskInfo |
65 | 37 |
38 speThreads = new SpeThreads(machineNum); | |
39 speThreads->init(); | |
109 | 40 |
41 speTaskList = new TaskListPtr[machineNum]; | |
42 speTaskList_bg = new TaskListPtr[machineNum]; | |
476
926d6aff886c
CellBufferManager removed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
380
diff
changeset
|
43 |
109 | 44 for (int i = 0; i < machineNum; i++) { |
476
926d6aff886c
CellBufferManager removed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
380
diff
changeset
|
45 speTaskList[i] = taskListImpl->create(); |
926d6aff886c
CellBufferManager removed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
380
diff
changeset
|
46 speTaskList_bg[i] = taskListImpl->create(); |
109 | 47 } |
48 | |
49 flag_sendTaskList = new int[machineNum]; | |
50 for (int i = 0; i < machineNum; i++) { | |
51 flag_sendTaskList[i] = 1; | |
476
926d6aff886c
CellBufferManager removed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
380
diff
changeset
|
52 } |
321 | 53 // PPE 側の管理をする Manager |
109 | 54 ppeManager = new FifoTaskManagerImpl(machineNum); |
479
5bda98b0b56d
Double Linked List base TaskQueue
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
476
diff
changeset
|
55 // 大半のTaskQueueInfoは、共有される |
635
8cc609285bbe
SimpleTask worked on Mac OS X
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
629
diff
changeset
|
56 ppeManager->init(new MainScheduler, this); |
619 | 57 |
58 ppeManager->get_scheduler()->set_manager(this); | |
59 schedTaskManager = new SchedTask(); | |
60 schedTaskManager->init(0,0,0,ppeManager->get_scheduler()); | |
57 | 61 } |
62 | |
109 | 63 void |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
64 CellTaskManagerImpl::append_activeTask(HTaskPtr task) |
109 | 65 { |
66 if (task->cpu_type == CPU_PPE) { | |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
67 ppeManager->append_activeTask(task); |
109 | 68 } else { |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
69 activeTaskQueue->addLast(task); |
109 | 70 } |
71 } | |
72 | |
321 | 73 // SPE_ANY が指定されていた時に |
74 // これをインクリメントしつつ呼ぶことにする。 | |
75 // 乱数使ってもいいけどさ。 | |
109 | 76 int cur_anySpeid = 0; |
77 | |
78 /** | |
321 | 79 * ActiveTaskQueue から Task を |
80 * 各 SPE に渡す TaskList に入れる | |
109 | 81 * |
321 | 82 * ここの activeTaskQueue は FifoTaskManagerImpl のと意味が違い、 |
83 * spe に渡される Task だけ入っている | |
109 | 84 */ |
85 void | |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
86 CellTaskManagerImpl::set_runTaskList() |
70 | 87 { |
321 | 88 // ここ...直すかな |
70 | 89 TaskListPtr list; |
481
4896dffad67c
Double linked list modification done (tested on Mac OS X)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
479
diff
changeset
|
90 |
70 | 91 TaskPtr task; |
109 | 92 int speid; |
70 | 93 |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
94 while (HTaskPtr htask = activeTaskQueue->poll()) { |
70 | 95 |
109 | 96 if (htask->cpu_type == SPE_ANY) { |
97 speid = cur_anySpeid++; | |
98 cur_anySpeid = (cur_anySpeid < machineNum) | |
99 ? cur_anySpeid : 0; | |
70 | 100 } else { |
321 | 101 // -1 してるのは |
102 // htask->cpu_type - CPU_SPE で | |
103 // SPE0 = 1, SPE1 = 2, ... SPE5 = 6 ってなってるので | |
104 // 配列的 (SPE0 = arr[0], SPE1 = arr[1]) にするため | |
109 | 105 speid = htask->cpu_type - CPU_SPE - 1; |
106 | |
321 | 107 // SPU の数以上が指定されていれば |
108 // とりあえず MAX_USE_SPE_NUM (実際に動く SPE の最大数) で | |
109 // あまり求めてそれを使うことにする。 | |
110 // ここで判定するもんでもないか? | |
109 | 111 if (speid >= machineNum) { |
112 speid %= machineNum; | |
113 } | |
70 | 114 } |
109 | 115 |
116 list = speTaskList_bg[speid]; | |
117 | |
118 if (list->length >= TASK_MAX_SIZE) { | |
476
926d6aff886c
CellBufferManager removed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
380
diff
changeset
|
119 TaskListPtr newList = taskListImpl->create(); |
109 | 120 newList = TaskListInfo::append(newList, speTaskList_bg[speid]); |
121 speTaskList_bg[speid] = newList; | |
122 list = newList; | |
123 } | |
124 | |
125 task = &list->tasks[list->length++]; | |
629
8843edf37c0e
Cell 64 bit tried, but not yet worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
621
diff
changeset
|
126 TaskPtr stask = (TaskPtr) task; |
8843edf37c0e
Cell 64 bit tried, but not yet worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
621
diff
changeset
|
127 *stask = *(TaskPtr) htask; |
70 | 128 } |
109 | 129 } |
130 | |
131 void | |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
132 CellTaskManagerImpl::run() |
109 | 133 { |
134 TaskListPtr ppeTaskList = NULL; | |
135 MailQueuePtr ppeMail = NULL; | |
70 | 136 |
321 | 137 // PPE 側で動く TaskList です |
138 // FifoTaskManagerImpl::run と上手く合うように | |
139 // こんなことやってますよ | |
109 | 140 ppeTaskList = ppeManager->get_runTaskList(); |
141 if (!ppeTaskList) { | |
142 goto cont; | |
143 } | |
70 | 144 |
321 | 145 // SPE からの Mailbox Check は |
146 // PPE 側の schedule から抜けて来たときに行う | |
147 // (speThreads で Blocking Mailbox read と | |
148 // セマフォとか使ってやってもいいが、今はこの方式で) | |
109 | 149 do { |
150 ppeMail = ppeManager->schedule(ppeTaskList); | |
151 cont: | |
152 ppeTaskList = mail_check(ppeMail); | |
153 } while (ppeTaskList); | |
70 | 154 } |
155 | |
65 | 156 /** |
321 | 157 * SPE からのメールをチェックする |
109 | 158 * |
159 * @param [mail_list] | |
321 | 160 * PPE 側で動く Scheduler からのメールリスト |
161 * この中で PPE 側の mail check も行う | |
109 | 162 * |
321 | 163 * @return PPE Scheduler に対してのメール。 |
164 * 次に実行する TaskList のアドレスや、終了コマンドを送る | |
109 | 165 */TaskListPtr |
65 | 166 CellTaskManagerImpl::mail_check(MailQueuePtr mail_list) |
57 | 167 { |
321 | 168 // PPE Scheduler からの mail check |
485 | 169 ppeManager->mail_check(mail_list, waitTaskQueue); |
65 | 170 |
70 | 171 do { |
629
8843edf37c0e
Cell 64 bit tried, but not yet worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
621
diff
changeset
|
172 memaddr data; |
109 | 173 |
321 | 174 // SPE Scheduler からの mail check |
244 | 175 for (int id = 0; id < machineNum; id++) { |
176 while (speThreads->check_mail(id, 1, &data)) { | |
109 | 177 /** |
321 | 178 * MY_SPE_STATUS_READY: SPE が持ってた Task 全て終了 |
179 * MY_SPE_NOP: 特に意味のないコマンド | |
180 * それ以外:終了したタスク(PPEにあるのでアドレス | |
109 | 181 * |
321 | 182 * MY_SPE_NOP が 0 なので、 |
183 * 下のように data > MY_SPE_NOP とかしています。 | |
184 * 一目でよくわからない書き方なんで、直したいところですが。。。 | |
109 | 185 */ |
321 | 186 // 名前あとでちゃんと決めよう => MY_SPE_... とかじゃなくて |
629
8843edf37c0e
Cell 64 bit tried, but not yet worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
621
diff
changeset
|
187 if (data == (memaddr)MY_SPE_STATUS_READY) { |
334
20f2459041cb
[in test_render] push L key , call show_dma_wait, but incomplete.
e065746@localhost.localdomain
parents:
321
diff
changeset
|
188 //__debug_ppe("[SPE %d] finish\n", id); |
109 | 189 flag_sendTaskList[id] = 1; |
629
8843edf37c0e
Cell 64 bit tried, but not yet worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
621
diff
changeset
|
190 } else if (data == (memaddr)MY_SPE_COMMAND_MALLOC) { |
334
20f2459041cb
[in test_render] push L key , call show_dma_wait, but incomplete.
e065746@localhost.localdomain
parents:
321
diff
changeset
|
191 //__debug_ppe("[PPE] MALLOC COMMAND from [SPE %d]\n", id); |
109 | 192 |
193 /** | |
321 | 194 * info[0] = alloc_id; (CellScheduler::mainMem_alloc 参照) |
109 | 195 * info[1] = alloc_addr; |
196 */ | |
629
8843edf37c0e
Cell 64 bit tried, but not yet worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
621
diff
changeset
|
197 memaddr alloc_info[2]; |
8843edf37c0e
Cell 64 bit tried, but not yet worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
621
diff
changeset
|
198 long alloc_size; |
8843edf37c0e
Cell 64 bit tried, but not yet worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
621
diff
changeset
|
199 long command; |
109 | 200 |
244 | 201 speThreads->get_mail(id, 2, alloc_info); |
629
8843edf37c0e
Cell 64 bit tried, but not yet worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
621
diff
changeset
|
202 command = (long)alloc_info[0]; |
8843edf37c0e
Cell 64 bit tried, but not yet worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
621
diff
changeset
|
203 alloc_size = (long)alloc_info[1]; |
244 | 204 |
109 | 205 |
629
8843edf37c0e
Cell 64 bit tried, but not yet worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
621
diff
changeset
|
206 alloc_info[1] = (memaddr)allocate(alloc_size); |
244 | 207 /* |
321 | 208 * allocate された領域は今の SPE buffer にリンクとして接続する |
209 * ここでは TaskList を allocate(new) して登録してやろうか | |
244 | 210 */ |
109 | 211 |
629
8843edf37c0e
Cell 64 bit tried, but not yet worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
621
diff
changeset
|
212 //__debug_ppe("[PPE] MALLOCED 0x%lx from [SPE %d]\n", alloc_info[1],id); |
8843edf37c0e
Cell 64 bit tried, but not yet worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
621
diff
changeset
|
213 // 今のところ何もしてない。どうも、この allocate を free |
8843edf37c0e
Cell 64 bit tried, but not yet worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
621
diff
changeset
|
214 // するのは、SPE task が返した値を見て行うらしい。それは、 |
8843edf37c0e
Cell 64 bit tried, but not yet worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
621
diff
changeset
|
215 // 忘れやすいのではないか? |
300
0691f38195f6
remove TaskManager/Fifo/MainScheduler.o TaskManeger/Test/test_render/test_nogl
tkaito@localhost.localdomain
parents:
298
diff
changeset
|
216 speThreads->add_output_tasklist(command, alloc_info[1], alloc_size); |
273 | 217 |
621 | 218 speThreads->send_mail(id, 2, alloc_info); |
629
8843edf37c0e
Cell 64 bit tried, but not yet worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
621
diff
changeset
|
219 } else if (data > (memaddr)MY_SPE_NOP) { |
334
20f2459041cb
[in test_render] push L key , call show_dma_wait, but incomplete.
e065746@localhost.localdomain
parents:
321
diff
changeset
|
220 //__debug_ppe("[PPE] recv from [SPE %d] : 0x%x\n", id, data); |
619 | 221 HTaskPtr task = (HTaskPtr)data; |
222 task->post_func(schedTaskManager, task->post_arg1, task->post_arg2); | |
223 check_task_finish(task); | |
70 | 224 } |
65 | 225 } |
226 } | |
109 | 227 |
321 | 228 // 依存関係を満たしたタスクをアクティブに |
109 | 229 wakeup_waitTask(); |
230 | |
321 | 231 // SPE に送る TaskList の準備 |
109 | 232 set_runTaskList(); |
233 | |
321 | 234 // TaskList 待ちの SPE に TaskList を送る |
109 | 235 for (int i = 0; i < machineNum; i++) { |
236 if (flag_sendTaskList[i] == 1 && speTaskList_bg[i]->length >= 1 ) { | |
237 send_taskList(i); | |
238 } | |
239 } | |
70 | 240 |
321 | 241 // 現在の FifoTaskManager の仕様では |
242 // ・PPE で実行するタスクが無くなれば終了する | |
243 // であり、この場合もし SPE にタスクが残っていても | |
244 // メインループから抜けてプログラム終了となってしまうので | |
245 // ここでストップかけてます。 | |
481
4896dffad67c
Double linked list modification done (tested on Mac OS X)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
479
diff
changeset
|
246 } while (ppeManager->activeTaskQueue->empty() && !waitTaskQueue->empty()); |
109 | 247 |
248 return ppeManager->get_runTaskList(); | |
249 } | |
66 | 250 |
109 | 251 /** |
321 | 252 * 条件を満たしたら SPE に TaskList を送信する |
253 * 条件1. SPE が持ってた TaskList を終了して、次の TaskList を待ってる | |
254 * 条件2. SPE に送る TaskList に Task がある | |
109 | 255 * |
321 | 256 * SPE で実行終了した TaskList [speTaskList] と |
257 * これから実行する TaskList [speTaskList_bg] のバッファを入れ替える | |
258 * ついでに実行終了したやつは clear しておく。 | |
109 | 259 */ |
260 void | |
261 CellTaskManagerImpl::send_taskList(int id) | |
262 { | |
263 TaskListPtr tmp; | |
264 | |
265 tmp = speTaskList[id]; | |
266 speTaskList[id] = speTaskList_bg[id]; | |
267 speTaskList_bg[id] = tmp; | |
268 | |
476
926d6aff886c
CellBufferManager removed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
380
diff
changeset
|
269 taskListImpl->clear_taskList(speTaskList_bg[id]); |
109 | 270 |
629
8843edf37c0e
Cell 64 bit tried, but not yet worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
621
diff
changeset
|
271 speThreads->send_mail(id, 1, (memaddr *)&speTaskList[id]); |
109 | 272 flag_sendTaskList[id] = 0; |
57 | 273 } |
274 | |
65 | 275 |
109 | 276 void* |
506 | 277 CellTaskManagerImpl::allocate(int size, int alignment) |
278 { | |
635
8cc609285bbe
SimpleTask worked on Mac OS X
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
629
diff
changeset
|
279 if (size==0) return 0; |
506 | 280 void *buff; |
281 posix_memalign(&buff, alignment, size); | |
282 return buff; | |
283 } | |
284 | |
285 void* | |
109 | 286 CellTaskManagerImpl::allocate(int size) |
287 { | |
635
8cc609285bbe
SimpleTask worked on Mac OS X
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
629
diff
changeset
|
288 if (size==0) return 0; |
109 | 289 void *buff; |
290 | |
291 posix_memalign(&buff, DEFAULT_ALIGNMENT, size); | |
244 | 292 |
321 | 293 // bzero はコストが高いのでやりたくない |
506 | 294 // bzero(buff, size); |
109 | 295 |
296 return buff; | |
297 } | |
298 | |
380 | 299 Scheduler* |
300 CellTaskManagerImpl::get_scheduler() | |
301 { | |
302 return ppeManager->get_scheduler(); | |
303 } | |
304 | |
109 | 305 #ifdef __CERIUM_CELL__ |
57 | 306 TaskManagerImpl* |
307 create_impl(int num) | |
308 { | |
67 | 309 return new CellTaskManagerImpl(num); |
57 | 310 } |
109 | 311 #endif // __CERIUM_CELL |