Mercurial > hg > Game > Cerium
annotate TaskManager/Cell/CellTaskManagerImpl.cc @ 1464:3f2230d79eba draft
TaskList no compile errors
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 14 Jul 2012 21:16:27 +0900 |
parents | 8cf62aea798f |
children | 840dee241530 |
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" | |
956
197b7e19a345
unified queue worked on Mac OS X
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
940
diff
changeset
|
7 #include "HTask.h" |
197b7e19a345
unified queue worked on Mac OS X
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
940
diff
changeset
|
8 #include "QueueInfo.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" |
672 | 12 #include "SysFunc.h" |
13 | |
1179 | 14 static void send_alloc_reply(CellTaskManagerImpl *tm, int id, |
1185
26dea600d4cd
fix CellTaskManagerImpl
Daichi TOMA <amothic@cr.ie.u-ryukyu.ac.jp>
parents:
1179
diff
changeset
|
15 Threads *speThreads); |
57 | 16 |
1179 | 17 CellTaskManagerImpl::~CellTaskManagerImpl() { |
1077 | 18 |
1179 | 19 delete speThreads; |
20 delete[] speTaskList; | |
1077 | 21 |
1179 | 22 delete ppeManager; |
67 | 23 } |
24 | |
1229
424c1f16e704
add args useRefDma
Daichi TOMA <e085740@ie.u-ryukyu.ac.jp>
parents:
1185
diff
changeset
|
25 void CellTaskManagerImpl::init(int spuIdle_,int useRefDma) { |
1179 | 26 spe_running = 0; |
27 spuIdle = spuIdle_; | |
109 | 28 |
1179 | 29 // 実行される Task 用の パイプライン用のダブルバッファ |
30 speTaskList = new QueueInfo<TaskList>*[machineNum]; // spe上の走っている Task の配列 | |
31 taskListInfo = new QueueInfo<TaskList>*[machineNum]; // 次に走る Task の配列 | |
476
5fc79ff9c257
CellBufferManager removed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
380
diff
changeset
|
32 |
1077 | 33 |
1179 | 34 for (int i = 0; i < machineNum; i++) { |
35 taskListInfo[i] = new QueueInfo<TaskList> (taskListPool); | |
36 speTaskList[i] = new QueueInfo<TaskList> (taskListPool); | |
37 } | |
109 | 38 |
1179 | 39 // PPE 側の管理をする Manager |
40 ppeManager = new FifoTaskManagerImpl(machineNum); | |
41 // 大半のTaskQueueInfoは、共有される | |
42 MainScheduler *mscheduler = new MainScheduler; | |
43 set_scheduler(mscheduler); | |
1229
424c1f16e704
add args useRefDma
Daichi TOMA <e085740@ie.u-ryukyu.ac.jp>
parents:
1185
diff
changeset
|
44 ppeManager->init(mscheduler, this, useRefDma); // ここで HTaskInfo が共有される。 |
1077 | 45 |
1362
6b4a0846afcb
Spe Threads Init moved
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents:
1229
diff
changeset
|
46 speThreads->init(); |
6b4a0846afcb
Spe Threads Init moved
Daichi TOMA <toma@cr.ie.u-ryukyu.ac.jp>
parents:
1229
diff
changeset
|
47 |
1179 | 48 // 実行可能な HTask のリスト。 FifoTaskManager と共有される |
49 activeTaskQueue = ppeManager->activeTaskQueue; | |
50 // HTask の factory。 HTaskInfo ならなんでもいい。 | |
51 htaskImpl = activeTaskQueue; // any HTaskInfo | |
52 | |
1077 | 53 |
1179 | 54 ppeManager->get_scheduler()->set_manager(this); |
637 | 55 |
1179 | 56 // Task 内からManager->task_create() とかするときに必要なTaskManager。 |
57 // 現状では ppe 側からしか動かない | |
58 // spe 側から Task create できない | |
59 schedTaskManager = new SchedTask(); | |
1464
3f2230d79eba
TaskList no compile errors
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
1462
diff
changeset
|
60 schedTaskManager->init(0, 0, ppeManager->get_scheduler(), 0); |
1179 | 61 ppeManager->schedTaskManager = schedTaskManager; |
57 | 62 } |
63 | |
1179 | 64 void CellTaskManagerImpl::append_activeTask(HTaskPtr task) { |
65 if (task->cpu_type == CPU_PPE) { | |
66 ppeManager->append_activeTask(task); | |
67 } else { | |
68 activeTaskQueue->addLast(task); | |
69 } | |
109 | 70 } |
71 | |
321 | 72 // SPE_ANY が指定されていた時に |
73 // これをインクリメントしつつ呼ぶことにする。 | |
940
e01b551f25d6
unknown dead lock still...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
939
diff
changeset
|
74 unsigned int cur_anySpeid = 0; |
109 | 75 |
76 /** | |
321 | 77 * ActiveTaskQueue から Task を |
938
20beb83a5a22
dead lock still remains. zombi problem?
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
937
diff
changeset
|
78 * 各 SPE に渡す (backgound) TaskList に入れる |
109 | 79 * |
321 | 80 * ここの activeTaskQueue は FifoTaskManagerImpl のと意味が違い、 |
81 * spe に渡される Task だけ入っている | |
109 | 82 */ |
1179 | 83 void CellTaskManagerImpl::set_runTaskList(QueueInfo<HTask> *activeTaskQueue) { |
84 int speid; | |
85 HTaskPtr htask = activeTaskQueue->getFirst(); | |
86 while (htask != NULL) { | |
70 | 87 |
1179 | 88 if (htask->cpu_type == CPU_PPE) { |
89 | |
90 htask = activeTaskQueue->getNext(htask); | |
70 | 91 |
1179 | 92 } else { |
93 if (htask->cpu_type == SPE_ANY) { | |
94 speid = cur_anySpeid++; | |
95 } else { | |
96 // -1 してるのは | |
97 // htask->cpu_type - CPU_SPE で | |
98 // SPE0 = 1, SPE1 = 2, ... SPE5 = 6 ってなってるので | |
99 // 配列的 (SPE0 = arr[0], SPE1 = arr[1]) にするため | |
100 speid = htask->cpu_type - CPU_SPE - 1; | |
101 } | |
102 | |
103 speid %= machineNum; | |
104 set_taskList(htask, taskListInfo[speid]); | |
105 | |
106 HTaskPtr next = activeTaskQueue->getNext(htask); | |
107 activeTaskQueue->remove(htask); | |
108 htask = next; | |
109 | |
110 } | |
70 | 111 } |
109 | 112 } |
113 | |
1179 | 114 void CellTaskManagerImpl::sendTaskList() { |
115 for (int id = 0; id < machineNum; id++) { | |
116 mail_check(id); | |
117 if (!speTaskList[id]->empty()) { | |
118 continue; // まだ、走ってる | |
119 } | |
120 if (!taskListInfo[id]->empty()) { | |
121 // SPE に送る TaskList の準備 | |
122 send_taskList(id); | |
123 spe_running++; | |
124 } | |
1057
8cd123d2f3ca
debug_check_spu_idle add. commandline option [-spuidle].
tkaito@henri
parents:
972
diff
changeset
|
125 } |
721 | 126 } |
127 | |
1179 | 128 void CellTaskManagerImpl::poll() { |
129 set_runTaskList(activeTaskQueue); | |
130 // TaskList 待ちの SPE に TaskList を送る | |
131 sendTaskList(); | |
808 | 132 } |
133 | |
1179 | 134 void CellTaskManagerImpl::debug_check_spe_idle( |
135 QueueInfo<HTask> * activeTaskQueue, int spe_running_) { | |
136 printf("spu_idle! spe_running = %d : activeTaskQueue->length = %d \n", | |
137 spe_running_, activeTaskQueue->length()); | |
1116
8e818d8fa36b
It's changed so that CreateSpan may move in the SPE.
tkaito@henri
parents:
1082
diff
changeset
|
138 HTaskPtr task = activeTaskQueue->getFirst(); |
8e818d8fa36b
It's changed so that CreateSpan may move in the SPE.
tkaito@henri
parents:
1082
diff
changeset
|
139 int tmp_i = 0; |
1057
8cd123d2f3ca
debug_check_spu_idle add. commandline option [-spuidle].
tkaito@henri
parents:
972
diff
changeset
|
140 do { |
1179 | 141 printf("task_name = %s ,", ppeManager->get_task_name(task)); |
1116
8e818d8fa36b
It's changed so that CreateSpan may move in the SPE.
tkaito@henri
parents:
1082
diff
changeset
|
142 printf("cpu = [%d], count = %d", task->cpu_type, tmp_i); |
8e818d8fa36b
It's changed so that CreateSpan may move in the SPE.
tkaito@henri
parents:
1082
diff
changeset
|
143 tmp_i++; |
1057
8cd123d2f3ca
debug_check_spu_idle add. commandline option [-spuidle].
tkaito@henri
parents:
972
diff
changeset
|
144 } while ((task = activeTaskQueue->getNext(task)) != 0); |
8cd123d2f3ca
debug_check_spu_idle add. commandline option [-spuidle].
tkaito@henri
parents:
972
diff
changeset
|
145 printf("\n"); |
8cd123d2f3ca
debug_check_spu_idle add. commandline option [-spuidle].
tkaito@henri
parents:
972
diff
changeset
|
146 } |
8cd123d2f3ca
debug_check_spu_idle add. commandline option [-spuidle].
tkaito@henri
parents:
972
diff
changeset
|
147 |
1179 | 148 void CellTaskManagerImpl::run() { |
149 int spu_limit = spuIdle; | |
150 if (machineNum == 0) { | |
151 ppeManager->run(); | |
152 return; | |
153 } | |
154 | |
155 do { | |
1125 | 156 |
1179 | 157 // PPE side |
158 ppeManager->poll(); | |
159 // SPE side | |
160 do { | |
161 poll(); | |
162 } while (ppeManager->activeTaskQueue->empty() && spe_running > 0); | |
163 | |
164 if (spe_running < spu_limit) { | |
165 debug_check_spe_idle(ppeManager->activeTaskQueue, spe_running); | |
166 } | |
167 | |
168 } while (!ppeManager->activeTaskQueue->empty() || !activeTaskQueue->empty() | |
169 || spe_running > 0); | |
170 if (!waitTaskQueue->empty()) { | |
171 show_dead_lock_info(); | |
172 } | |
173 | |
937
ecafd19a1d83
Sort working on spu cpu == 1 or -a case
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
936
diff
changeset
|
174 } |
ecafd19a1d83
Sort working on spu cpu == 1 or -a case
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
936
diff
changeset
|
175 |
1179 | 176 static void loop_check(HTask *p, HTask *me, int depth) { |
177 if (p == me) | |
178 printf("*%lx ", (long) p); // loop | |
179 if (depth == 0) | |
180 return; | |
181 QueueInfo<TaskQueue> *w = p->wait_i; | |
182 if (w) { | |
183 for (TaskQueue *q = w->getFirst(); q; q = w->getNext(q)) { | |
184 loop_check(q->task, me, depth - 1); | |
185 } | |
939 | 186 } |
187 } | |
188 | |
1179 | 189 void CellTaskManagerImpl::show_dead_lock_info() { |
190 get_scheduler()-> printf("Dead lock detected\n ppe queue %d\n", | |
191 ppeManager->activeTaskQueue->length()); | |
192 // 確か waitQueue は共通... | |
193 // get_scheduler()-> printf(" wait queue %d\n",ppeManager->waitTaskQueue->length()); | |
194 get_scheduler()-> printf(" wait queue %d\n", waitTaskQueue->length()); | |
195 for (HTask *p = waitTaskQueue->getFirst(); p; p = waitTaskQueue->getNext(p)) { | |
196 printf(" Waiting task%d %lx", p->command, (long) p); | |
197 QueueInfo<TaskQueue> *w = p->wait_i; | |
198 if (w) { | |
199 for (TaskQueue *q = w->getFirst(); q; q = w->getNext(q)) { | |
200 printf(" waiting task%d %lx", q->task->command, | |
201 (long) q->task); | |
202 if (!waitTaskQueue->find(q->task)) { | |
203 printf("!"); // stray task | |
204 } | |
205 loop_check(q->task, p, 10); | |
206 } | |
940
e01b551f25d6
unknown dead lock still...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
939
diff
changeset
|
207 } |
1179 | 208 printf("\n"); |
939 | 209 } |
1179 | 210 get_scheduler()-> printf(" spe queue %d\n", activeTaskQueue->length()); |
211 for (int i = 0; i < machineNum; i++) { | |
212 get_scheduler()-> printf(" spe %d send %d wait %d\n", i, | |
213 speTaskList[i]->length(), taskListInfo[i]->length()); | |
214 } | |
70 | 215 } |
216 | |
65 | 217 /** |
321 | 218 * SPE からのメールをチェックする |
640
ecf056ddd21a
SimpeTask on Cell worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
638
diff
changeset
|
219 */ |
ecf056ddd21a
SimpeTask on Cell worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
638
diff
changeset
|
220 |
1179 | 221 void CellTaskManagerImpl::mail_check(int id) { |
222 memaddr data; | |
109 | 223 |
1179 | 224 // SPE Scheduler からの mail check |
225 while (speThreads->has_mail(id, 1, &data)) { | |
226 if (data == (memaddr) MY_SPE_STATUS_READY) { | |
227 // MY_SPE_STATUS_READY: SPE が持ってた Task 全て終了 | |
228 // freeAll する前に循環リストに戻す | |
229 speTaskList[id]->getLast()->next = speTaskList[id]; | |
230 speTaskList[id]->freeAll(); | |
231 spe_running--; | |
232 // printf("SPE %d status ready, %d running\n",id, spe_running); | |
233 } else if (data == (memaddr) MY_SPE_COMMAND_MALLOC) { | |
234 // MY_SPE_COMMAND_MALLOC SPE からのmain memory request | |
235 send_alloc_reply(this, id, speThreads); | |
236 } else if (data > (memaddr) MY_SPE_NOP) { | |
830 | 237 #ifdef TASK_LIST_MAIL |
1179 | 238 TaskListPtr list = (TaskListPtr)data; |
239 check_task_list_finish(schedTaskManager, list, waitTaskQueue); | |
830 | 240 #else |
1179 | 241 // 終了したタスク(PPEにあるのでアドレス) |
242 HTaskPtr task = (HTaskPtr) data; | |
1151 | 243 #if 0 |
1179 | 244 if (task->cpu_type != CPU_SPE) { |
245 const char *name = get_task_name(task); | |
246 if (name != NULL) { | |
247 printf("[SPE] "); | |
248 printf("Task id : %d, ", task->command); | |
249 printf("Task name : %s\n", name); | |
250 } | |
251 } | |
1150 | 252 #endif |
1147 | 253 #ifndef NOT_CHECK |
254 | |
1179 | 255 if (task != NULL) { |
256 //SPE で処理された Task が返ってくるはず。それがもし、type PPE なら・・・ | |
257 if (task->cpu_type == CPU_PPE) { | |
258 printf("attention : PPE task run on SPE\n"); | |
259 printf("Task id : %d\n", task->command); | |
260 const char *name = get_task_name(task); | |
261 if (name != NULL) { | |
262 printf("Task name : %s\n", name); | |
263 } | |
264 } | |
265 } | |
1147 | 266 |
267 #endif | |
1179 | 268 |
269 task->post_func(schedTaskManager, task->post_arg1, task->post_arg2); | |
270 check_task_finish(task, waitTaskQueue); | |
830 | 271 #endif |
1179 | 272 } |
273 // MY_SPE_NOP: 特に意味のないコマンド | |
719
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
274 } |
cc1b7333de92
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
275 } |
109 | 276 |
1179 | 277 void CellTaskManagerImpl::polling() { |
278 // may call recursively check_task_list_finish() | |
279 // we need fifo here | |
280 for (int i = 0; i < machineNum; i++) { | |
281 mail_check(i); | |
282 } | |
833
577bde5d0cec
poling (may recurse..)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
830
diff
changeset
|
283 } |
577bde5d0cec
poling (may recurse..)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
830
diff
changeset
|
284 |
1179 | 285 static void send_alloc_reply(CellTaskManagerImpl *tm, int id, |
1185
26dea600d4cd
fix CellTaskManagerImpl
Daichi TOMA <amothic@cr.ie.u-ryukyu.ac.jp>
parents:
1179
diff
changeset
|
286 Threads *speThreads) { |
1179 | 287 |
288 /** | |
289 * info[0] = alloc_id; (CellScheduler::mainMem_alloc 参照) | |
290 * info[1] = alloc_addr; | |
291 */ | |
292 memaddr alloc_info[2]; | |
293 long alloc_size; | |
294 long command; | |
275 | 295 |
1179 | 296 speThreads->get_mail(id, 2, alloc_info); |
297 command = (long) alloc_info[0]; | |
298 alloc_size = (long) alloc_info[1]; | |
109 | 299 |
1179 | 300 alloc_info[1] = (memaddr) tm->allocate(alloc_size); |
301 //__debug_ppe("[PPE] MALLOCED 0x%lx from [SPE %d]\n", alloc_info[1],id); | |
302 // 今のところ何もしてない。どうも、この allocate を free | |
303 // するのは、SPE task が返した値を見て行うらしい。それは、 | |
304 // 忘れやすいのではないか? | |
305 speThreads->add_output_tasklist(command, alloc_info[1], alloc_size); | |
109 | 306 |
1179 | 307 speThreads->send_mail(id, 2, alloc_info); |
109 | 308 } |
66 | 309 |
109 | 310 /** |
321 | 311 * 条件を満たしたら SPE に TaskList を送信する |
312 * 条件1. SPE が持ってた TaskList を終了して、次の TaskList を待ってる | |
313 * 条件2. SPE に送る TaskList に Task がある | |
109 | 314 * |
808 | 315 * SPE で実行終了した speTaskList と |
316 * これから実行する taskListInfo のバッファを入れ替える | |
109 | 317 */ |
1179 | 318 void CellTaskManagerImpl::send_taskList(int id) { |
319 // speTaskList は走り終わった ppe の Task の List. | |
320 // taskListInfo はこれから走る Task の List. | |
321 // 交換して実行する | |
322 QueueInfo<TaskList> *tmp = taskListInfo[id]; | |
323 taskListInfo[id] = speTaskList[id]; | |
324 speTaskList[id] = tmp; | |
109 | 325 |
1179 | 326 // speTaskList は本来は循環リストなのだけど、実行中は線形リストである。 |
327 // spe の Task が終了した時点でなおす。 | |
328 tmp->getLast()->next = 0; | |
329 TaskListPtr p = tmp->getFirst(); | |
330 // printf("SPE %d task list sending\n",id); | |
331 speThreads->send_mail(id, 1, (memaddr *) &p); | |
332 // printf("SPE %d task list sent\n",id); | |
57 | 333 } |
334 | |
672 | 335 void CellTaskManagerImpl::show_profile() { |
1179 | 336 for (int id = 0; id < machineNum; id++) { |
337 HTaskPtr t = schedTaskManager->create_task(ShowTime, 0, 0, 0, 0); | |
338 t->set_cpu((CPU_TYPE) (id + 2)); | |
339 t->spawn(); | |
340 } | |
672 | 341 } |
342 | |
343 void CellTaskManagerImpl::start_profile() { | |
1179 | 344 for (int id = 0; id < machineNum; id++) { |
345 HTaskPtr t = schedTaskManager->create_task(StartProfile, 0, 0, 0, 0); | |
346 t->set_cpu((CPU_TYPE) (id + 2)); | |
347 t->spawn(); | |
348 } | |
672 | 349 } |
350 | |
1179 | 351 void CellTaskManagerImpl::print_arch() { |
352 printf("CellTaskManager\n"); | |
1067 | 353 } |
354 | |
1427
db5c022d871c
task array uses TaskList. (on going)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
1362
diff
changeset
|
355 TaskListPtr CellTaskManagerImpl::createTaskList() |
db5c022d871c
task array uses TaskList. (on going)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
1362
diff
changeset
|
356 { |
1462
8cf62aea798f
HTask/TaskList fix (on going)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
1427
diff
changeset
|
357 TaskListPtr tl = taskListInfo[0]->create(); |
8cf62aea798f
HTask/TaskList fix (on going)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
1427
diff
changeset
|
358 bzero(tl->tasks,sizeof(Task)*TASK_MAX_SIZE); |
8cf62aea798f
HTask/TaskList fix (on going)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
1427
diff
changeset
|
359 return tl; |
1427
db5c022d871c
task array uses TaskList. (on going)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
1362
diff
changeset
|
360 } |
db5c022d871c
task array uses TaskList. (on going)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
1362
diff
changeset
|
361 |
db5c022d871c
task array uses TaskList. (on going)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
1362
diff
changeset
|
362 |
109 | 363 #ifdef __CERIUM_CELL__ |
57 | 364 TaskManagerImpl* |
1229
424c1f16e704
add args useRefDma
Daichi TOMA <e085740@ie.u-ryukyu.ac.jp>
parents:
1185
diff
changeset
|
365 create_impl(int num, int useRefDma) |
57 | 366 { |
1185
26dea600d4cd
fix CellTaskManagerImpl
Daichi TOMA <amothic@cr.ie.u-ryukyu.ac.jp>
parents:
1179
diff
changeset
|
367 Threads *cpus = new SpeThreads(num); |
1179 | 368 return new CellTaskManagerImpl(num,cpus); |
57 | 369 } |
109 | 370 #endif // __CERIUM_CELL |