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