Mercurial > hg > Members > kono > Cerium
annotate TaskManager/Cell/CellTaskManagerImpl.cc @ 809:76a39ad68846
fix
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 22 May 2010 23:23:29 +0900 |
parents | 8a6f1fa038de |
children | ff684304e1d3 |
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" |
672 | 12 #include "SysFunc.h" |
13 | |
720 | 14 static void send_alloc_reply(CellTaskManagerImpl *tm, int id, SpeThreads *speThreads); |
57 | 15 |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
16 CellTaskManagerImpl::~CellTaskManagerImpl() |
67 | 17 { |
109 | 18 delete speThreads; |
19 delete [] speTaskList; | |
20 | |
21 delete ppeManager; | |
67 | 22 } |
23 | |
57 | 24 void |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
25 CellTaskManagerImpl::init() |
57 | 26 { |
637 | 27 spe_running = 0; |
476
926d6aff886c
CellBufferManager removed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
380
diff
changeset
|
28 taskListImpl = new CellTaskListInfo; |
808 | 29 |
476
926d6aff886c
CellBufferManager removed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
380
diff
changeset
|
30 |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
31 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
|
32 |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
33 htaskImpl = activeTaskQueue ; // any HTaskInfo |
65 | 34 |
35 speThreads = new SpeThreads(machineNum); | |
36 speThreads->init(); | |
109 | 37 |
808 | 38 speTaskList = new TaskListInfoPtr[machineNum]; |
476
926d6aff886c
CellBufferManager removed
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
380
diff
changeset
|
39 |
109 | 40 for (int i = 0; i < machineNum; i++) { |
808 | 41 speTaskList[i] = new TaskListInfo(); |
109 | 42 } |
43 | |
321 | 44 // PPE 側の管理をする Manager |
109 | 45 ppeManager = new FifoTaskManagerImpl(machineNum); |
479
5bda98b0b56d
Double Linked List base TaskQueue
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
476
diff
changeset
|
46 // 大半のTaskQueueInfoは、共有される |
637 | 47 MainScheduler *mscheduler = new MainScheduler; |
48 ppeManager->init(mscheduler, this); | |
619 | 49 |
50 ppeManager->get_scheduler()->set_manager(this); | |
637 | 51 |
619 | 52 schedTaskManager = new SchedTask(); |
53 schedTaskManager->init(0,0,0,ppeManager->get_scheduler()); | |
57 | 54 } |
55 | |
109 | 56 void |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
57 CellTaskManagerImpl::append_activeTask(HTaskPtr task) |
109 | 58 { |
59 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
|
60 ppeManager->append_activeTask(task); |
109 | 61 } else { |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
62 activeTaskQueue->addLast(task); |
109 | 63 } |
64 } | |
65 | |
321 | 66 // SPE_ANY が指定されていた時に |
67 // これをインクリメントしつつ呼ぶことにする。 | |
68 // 乱数使ってもいいけどさ。 | |
109 | 69 int cur_anySpeid = 0; |
70 | |
71 /** | |
321 | 72 * ActiveTaskQueue から Task を |
73 * 各 SPE に渡す TaskList に入れる | |
109 | 74 * |
321 | 75 * ここの activeTaskQueue は FifoTaskManagerImpl のと意味が違い、 |
76 * spe に渡される Task だけ入っている | |
109 | 77 */ |
78 void | |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
79 CellTaskManagerImpl::set_runTaskList() |
70 | 80 { |
109 | 81 int speid; |
70 | 82 |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
83 while (HTaskPtr htask = activeTaskQueue->poll()) { |
70 | 84 |
109 | 85 if (htask->cpu_type == SPE_ANY) { |
86 speid = cur_anySpeid++; | |
87 cur_anySpeid = (cur_anySpeid < machineNum) | |
88 ? cur_anySpeid : 0; | |
70 | 89 } else { |
321 | 90 // -1 してるのは |
91 // htask->cpu_type - CPU_SPE で | |
92 // SPE0 = 1, SPE1 = 2, ... SPE5 = 6 ってなってるので | |
93 // 配列的 (SPE0 = arr[0], SPE1 = arr[1]) にするため | |
109 | 94 speid = htask->cpu_type - CPU_SPE - 1; |
95 | |
321 | 96 // SPU の数以上が指定されていれば |
97 // とりあえず MAX_USE_SPE_NUM (実際に動く SPE の最大数) で | |
98 // あまり求めてそれを使うことにする。 | |
99 // ここで判定するもんでもないか? | |
109 | 100 if (speid >= machineNum) { |
101 speid %= machineNum; | |
102 } | |
70 | 103 } |
808 | 104 set_taskList(htask, taskListInfo[speid]); |
70 | 105 } |
109 | 106 } |
107 | |
108 void | |
722 | 109 CellTaskManagerImpl::sendTaskList() |
721 | 110 { |
111 for (int i = 0; i < machineNum; i++) { | |
808 | 112 if ( taskListInfo[i]->length() > 0 ) { |
721 | 113 send_taskList(i); |
114 spe_running++; | |
115 } | |
116 } | |
117 } | |
118 | |
119 void | |
808 | 120 CellTaskManagerImpl::poll() |
121 { | |
122 mail_check(); | |
123 // SPE に送る TaskList の準備 | |
124 set_runTaskList(); | |
125 // TaskList 待ちの SPE に TaskList を送る | |
126 sendTaskList(); | |
127 } | |
128 | |
129 void | |
501
4a2c9ff53605
Cell inData/outData DMA removal
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
496
diff
changeset
|
130 CellTaskManagerImpl::run() |
109 | 131 { |
132 do { | |
719
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
133 // PPE side |
808 | 134 ppeManager->poll(); |
719
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
135 // SPE side |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
136 do { |
808 | 137 poll(); |
722 | 138 } while (ppeManager->activeTaskQueue->empty() && spe_running >0 ); |
808 | 139 } while (!ppeManager->taskListInfo->empty() || spe_running >0); |
721 | 140 if (!waitTaskQueue->empty()) { |
736 | 141 get_scheduler()->printf("Dead lock detected\n"); |
721 | 142 } |
70 | 143 } |
144 | |
65 | 145 /** |
321 | 146 * SPE からのメールをチェックする |
640
a909c50081c2
SimpeTask on Cell worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
638
diff
changeset
|
147 */ |
a909c50081c2
SimpeTask on Cell worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
638
diff
changeset
|
148 |
719
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
149 void |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
150 CellTaskManagerImpl::mail_check() |
57 | 151 { |
719
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
152 memaddr data; |
109 | 153 |
719
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
154 // SPE Scheduler からの mail check |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
155 for (int id = 0; id < machineNum; id++) { |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
156 while (speThreads->has_mail(id, 1, &data)) { |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
157 if (data == (memaddr)MY_SPE_STATUS_READY) { |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
158 // MY_SPE_STATUS_READY: SPE が持ってた Task 全て終了 |
808 | 159 speTaskList[id]->freeAll(); |
719
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
160 spe_running--; |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
161 } else if (data == (memaddr)MY_SPE_COMMAND_MALLOC) { |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
162 // MY_SPE_COMMAND_MALLOC SPE からのmain memory request |
720 | 163 send_alloc_reply(this, id, speThreads); |
719
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
164 } else if (data > (memaddr)MY_SPE_NOP) { |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
165 // 終了したタスク(PPEにあるのでアドレス) |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
166 HTaskPtr task = (HTaskPtr)data; |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
167 task->post_func(schedTaskManager, task->post_arg1, task->post_arg2); |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
168 check_task_finish(task,waitTaskQueue); |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
169 } |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
170 // MY_SPE_NOP: 特に意味のないコマンド |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
171 } |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
172 } |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
173 } |
109 | 174 |
719
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
175 static void |
720 | 176 send_alloc_reply(CellTaskManagerImpl *tm, int id, SpeThreads *speThreads) |
719
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
177 { |
273 | 178 |
719
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
179 /** |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
180 * info[0] = alloc_id; (CellScheduler::mainMem_alloc 参照) |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
181 * info[1] = alloc_addr; |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
182 */ |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
183 memaddr alloc_info[2]; |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
184 long alloc_size; |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
185 long command; |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
186 |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
187 speThreads->get_mail(id, 2, alloc_info); |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
188 command = (long)alloc_info[0]; |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
189 alloc_size = (long)alloc_info[1]; |
109 | 190 |
719
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
191 |
720 | 192 alloc_info[1] = (memaddr)tm->allocate(alloc_size); |
719
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
193 //__debug_ppe("[PPE] MALLOCED 0x%lx from [SPE %d]\n", alloc_info[1],id); |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
194 // 今のところ何もしてない。どうも、この allocate を free |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
195 // するのは、SPE task が返した値を見て行うらしい。それは、 |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
196 // 忘れやすいのではないか? |
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
197 speThreads->add_output_tasklist(command, alloc_info[1], alloc_size); |
109 | 198 |
719
cafffff0f45a
clean up scheduler main loop
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
718
diff
changeset
|
199 speThreads->send_mail(id, 2, alloc_info); |
109 | 200 } |
66 | 201 |
109 | 202 /** |
321 | 203 * 条件を満たしたら SPE に TaskList を送信する |
204 * 条件1. SPE が持ってた TaskList を終了して、次の TaskList を待ってる | |
205 * 条件2. SPE に送る TaskList に Task がある | |
109 | 206 * |
808 | 207 * SPE で実行終了した speTaskList と |
208 * これから実行する taskListInfo のバッファを入れ替える | |
109 | 209 */ |
210 void | |
211 CellTaskManagerImpl::send_taskList(int id) | |
212 { | |
808 | 213 if (taskListInfo[id]->empty()) return; |
214 TaskListInfoPtr tmp = taskListInfo[id]; | |
215 taskListInfo[id] = speTaskList[id]; | |
216 speTaskList[id] = tmp; | |
109 | 217 |
809 | 218 tmp->getLast()->next = 0; |
808 | 219 speThreads->send_mail(id, 1, (memaddr *)tmp->getFirst()); |
57 | 220 } |
221 | |
672 | 222 void CellTaskManagerImpl::show_profile() { |
223 for (int id = 0; id < machineNum; id++) { | |
224 HTaskPtr t = create_task(ShowTime); | |
225 t->set_cpu((CPU_TYPE)(id+2)); | |
226 t->spawn(); | |
227 } | |
228 } | |
229 | |
230 void CellTaskManagerImpl::start_profile() { | |
231 for (int id = 0; id < machineNum; id++) { | |
232 HTaskPtr t = create_task(StartProfile); | |
233 t->set_cpu((CPU_TYPE)(id+2)); | |
234 t->spawn(); | |
235 } | |
236 } | |
237 | |
380 | 238 |
109 | 239 #ifdef __CERIUM_CELL__ |
57 | 240 TaskManagerImpl* |
241 create_impl(int num) | |
242 { | |
67 | 243 return new CellTaskManagerImpl(num); |
57 | 244 } |
109 | 245 #endif // __CERIUM_CELL |