Mercurial > hg > Game > Cerium
annotate TaskManager/kernel/ppe/TaskManagerImpl.cc @ 941:fc6cfaae6de7 draft
add no_auto_free flag on HTask
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sat, 31 Jul 2010 17:50:38 +0900 |
parents | e01b551f25d6 |
children | 9ed1c4a877ca |
rev | line source |
---|---|
5 | 1 #include <stdio.h> |
3 | 2 #include "TaskManagerImpl.h" |
46 | 3 #include "types.h" |
4 #include "error.h" | |
546 | 5 #include "SchedTask.h" |
619 | 6 #include "Scheduler.h" |
634 | 7 #include "SysTask.h" |
8 #include "SysFunc.h" | |
806 | 9 #include <string.h> |
10 | |
619 | 11 |
220 | 12 static HTaskPtr systask_start; |
109 | 13 static HTaskPtr systask_finish; |
42 | 14 |
550 | 15 static void |
16 noaction(SchedTask *s, void *read, void *write) | |
3 | 17 { |
18 } | |
19 | |
835 | 20 TaskManagerImpl::TaskManagerImpl(int num) |
21 : machineNum(num){ | |
853 | 22 // 実行可能なHTaskのリスト |
498
bce667ff20b9
double linked HTaskInfo/HTask
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
497
diff
changeset
|
23 activeTaskQueue = new HTaskInfo(); |
853 | 24 // wait_forで止まっているHTaskのリスト。必要ないが、Dead lock detection に使う |
498
bce667ff20b9
double linked HTaskInfo/HTask
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
497
diff
changeset
|
25 waitTaskQueue = new HTaskInfo(); |
853 | 26 // HTask の factory. HTaskInfo ならなんでもいい。 |
498
bce667ff20b9
double linked HTaskInfo/HTask
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
497
diff
changeset
|
27 htaskImpl = waitTaskQueue ; // any HTaskInfo |
853 | 28 // Task の dependency を表現する double linked list. HTaskInfo とは別に必要。 |
498
bce667ff20b9
double linked HTaskInfo/HTask
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
497
diff
changeset
|
29 taskQueueImpl = new TaskQueueInfo(); |
480
75e4afa40da2
TaskQueueInfo initiaization...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
479
diff
changeset
|
30 } |
50 | 31 |
220 | 32 /** |
298 | 33 * 一番最初に PPE で実行される systask_start |
220 | 34 */ |
42 | 35 void |
499 | 36 TaskManagerImpl::systask_init() |
42 | 37 { |
109 | 38 systask_register(); |
897
6bd218d3f643
add return address in SimpleTask for debugging.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
855
diff
changeset
|
39 systask_start = create_task(StartTask,0,0,0,0,__builtin_return_address(0)); |
6bd218d3f643
add return address in SimpleTask for debugging.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
855
diff
changeset
|
40 systask_finish = create_task(FinishTask,0,0,0,0,__builtin_return_address(0)); |
220 | 41 |
42 systask_start->spawn(); | |
43 | |
634 | 44 // すべての Task が FinishTask を wait_for すると、 |
45 // あらゆる Task が FinishTask の waiting task queue を操作する | |
46 // ことになる。それは、重すぎる。PPE/SPE Task が終了した時点で、 | |
47 // TaskManager が実行する方が安い。 | |
48 // append_waitTask(systask_finish); | |
49 } | |
50 | |
51 HTaskPtr | |
897
6bd218d3f643
add return address in SimpleTask for debugging.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
855
diff
changeset
|
52 TaskManagerImpl::create_task(int cmd,memaddr rbuf, long r_size, memaddr wbuf, long w_size, void *from) { |
634 | 53 HTaskPtr new_task; |
54 | |
55 new_task = htaskImpl->create(cmd, rbuf, r_size, wbuf, w_size); | |
56 new_task->post_func = noaction; | |
57 new_task->mimpl = this; | |
897
6bd218d3f643
add return address in SimpleTask for debugging.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
855
diff
changeset
|
58 new_task->from = (memaddr)from; |
634 | 59 |
60 return new_task; | |
42 | 61 } |
62 | |
3 | 63 HTaskPtr |
897
6bd218d3f643
add return address in SimpleTask for debugging.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
855
diff
changeset
|
64 TaskManagerImpl::create_task(int cmd,void *from) |
3 | 65 { |
66 HTaskPtr new_task; | |
67 | |
703 | 68 // for compatibility |
69 new_task = htaskImpl->create(TaskArray1); | |
70 new_task->post_func = noaction; | |
71 new_task->mimpl = this; | |
736 | 72 new_task->create_task_array(cmd,1,8,8,8); |
713
97adb3fe85c6
remove SIMPLE_TASK conditional
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
704
diff
changeset
|
73 // rbuf, r_size were set |
704
ec6c897448ca
Compatibility mode works.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
703
diff
changeset
|
74 new_task->command = TaskArray1; |
897
6bd218d3f643
add return address in SimpleTask for debugging.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
855
diff
changeset
|
75 new_task->from = (memaddr)from; |
63 | 76 |
3 | 77 return new_task; |
78 } | |
79 | |
800
54f0180cea0f
run16 word count ( not yet worked. )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
736
diff
changeset
|
80 HTaskPtr |
897
6bd218d3f643
add return address in SimpleTask for debugging.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
855
diff
changeset
|
81 TaskManagerImpl::create_task_array(int id, int num_task, int num_param, int num_inData, int num_outData, void *from) |
800
54f0180cea0f
run16 word count ( not yet worked. )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
736
diff
changeset
|
82 { |
897
6bd218d3f643
add return address in SimpleTask for debugging.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
855
diff
changeset
|
83 HTaskPtr ta = create_task(TaskArray,0,0,0,0, from); |
800
54f0180cea0f
run16 word count ( not yet worked. )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
736
diff
changeset
|
84 ta->create_task_array(id, num_task, num_param, num_inData, num_outData) ; |
54f0180cea0f
run16 word count ( not yet worked. )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
736
diff
changeset
|
85 return ta; |
54f0180cea0f
run16 word count ( not yet worked. )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
736
diff
changeset
|
86 } |
54f0180cea0f
run16 word count ( not yet worked. )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
736
diff
changeset
|
87 |
3 | 88 /** |
298 | 89 * task の依存関係を設定 |
90 * master task が終わってから、slave task を実行するように | |
109 | 91 * master->wait_for(slave); |
3 | 92 */ |
93 void | |
94 TaskManagerImpl::set_task_depend(HTaskPtr master, HTaskPtr slave) | |
547 | 95 { |
3 | 96 TaskQueuePtr m, s; |
941
fc6cfaae6de7
add no_auto_free flag on HTask
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
940
diff
changeset
|
97 if (!master->self) return; |
547 | 98 |
475
4e0308d2ba73
BufferManager removed.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
373
diff
changeset
|
99 m = taskQueueImpl->create(master); |
4e0308d2ba73
BufferManager removed.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
373
diff
changeset
|
100 s = taskQueueImpl->create(slave); |
547 | 101 |
479
bf2d2625485e
Double Linked List base TaskQueue
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
475
diff
changeset
|
102 master->wait_me->addLast(s); |
bf2d2625485e
Double Linked List base TaskQueue
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
475
diff
changeset
|
103 slave->wait_i->addLast(m); |
481
f9ffcffb6d09
Double linked list modification done (tested on Mac OS X)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
480
diff
changeset
|
104 s->waiter = m; |
547 | 105 } |
106 | |
3 | 107 /** |
298 | 108 * タスクを実行可能キューまたは待機キューへ追加する。 |
109 * 依存関係が満たされていれば active, まだだったら wait へ。 | |
109 | 110 * task->spawn(); |
111 */ | |
3 | 112 void |
18 | 113 TaskManagerImpl::spawn_task(HTaskPtr task) |
3 | 114 { |
109 | 115 // waiter // master |
116 // waitee // slave | |
480
75e4afa40da2
TaskQueueInfo initiaization...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
479
diff
changeset
|
117 if (task->wait_i->empty()) { |
498
bce667ff20b9
double linked HTaskInfo/HTask
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
497
diff
changeset
|
118 append_activeTask(task); |
3 | 119 } else { |
498
bce667ff20b9
double linked HTaskInfo/HTask
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
497
diff
changeset
|
120 append_waitTask(task); |
3 | 121 } |
122 } | |
42 | 123 |
800
54f0180cea0f
run16 word count ( not yet worked. )
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
736
diff
changeset
|
124 |
109 | 125 /** |
298 | 126 * Task を実行可能キューに追加する |
109 | 127 */ |
128 void | |
498
bce667ff20b9
double linked HTaskInfo/HTask
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
497
diff
changeset
|
129 TaskManagerImpl::append_activeTask(HTaskPtr q) |
109 | 130 { |
479
bf2d2625485e
Double Linked List base TaskQueue
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
475
diff
changeset
|
131 activeTaskQueue->addLast(q); |
109 | 132 } |
133 | |
134 /** | |
298 | 135 * タスクが実行する CPU を選択する |
109 | 136 * |
298 | 137 * 現在は CPU_PPE, CPU_SPE, SPE_ANY, SPE_0, SPE_1, ..., SPE_5 |
138 * types.h に書いてます。 | |
109 | 139 */ |
65 | 140 void |
141 TaskManagerImpl::set_task_cpu(HTaskPtr task, CPU_TYPE type) | |
142 { | |
664 | 143 if (machineNum==0) |
144 task->cpu_type = CPU_PPE ; | |
145 else | |
146 task->cpu_type = type; | |
65 | 147 } |
148 | |
940
e01b551f25d6
unknown dead lock still...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
939
diff
changeset
|
149 #if 0 |
e01b551f25d6
unknown dead lock still...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
939
diff
changeset
|
150 static void |
e01b551f25d6
unknown dead lock still...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
939
diff
changeset
|
151 check_wait(TaskManagerImpl *tm, TaskQueueInfo *wait_i) { |
e01b551f25d6
unknown dead lock still...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
939
diff
changeset
|
152 for(TaskQueue *t = wait_i->getFirst(); t; t = wait_i->getNext(t)) { |
e01b551f25d6
unknown dead lock still...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
939
diff
changeset
|
153 if (!tm->waitTaskQueue->find(t->task)) { |
e01b551f25d6
unknown dead lock still...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
939
diff
changeset
|
154 printf("stray waiting task%d %lx\n",t->task->command, (long)t->task); |
e01b551f25d6
unknown dead lock still...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
939
diff
changeset
|
155 } else if (tm->activeTaskQueue->find(t->task)) { |
e01b551f25d6
unknown dead lock still...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
939
diff
changeset
|
156 printf(" active task%d in waiting queue %lx\n",t->task->command, (long)t->task); |
e01b551f25d6
unknown dead lock still...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
939
diff
changeset
|
157 } else |
e01b551f25d6
unknown dead lock still...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
939
diff
changeset
|
158 printf("."); |
e01b551f25d6
unknown dead lock still...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
939
diff
changeset
|
159 } |
e01b551f25d6
unknown dead lock still...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
939
diff
changeset
|
160 } |
e01b551f25d6
unknown dead lock still...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
939
diff
changeset
|
161 #endif |
e01b551f25d6
unknown dead lock still...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
939
diff
changeset
|
162 |
109 | 163 /** |
830 | 164 * @brief 終了したタスクから依存の処理とか |
298 | 165 * post_func() はこのタスクが終了したら実行する関数。 |
109 | 166 * |
298 | 167 * @param [task] 終了したタスク |
109 | 168 */ |
169 void | |
647
7ba4ad4538b1
MailManager rewrite. not yet worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
639
diff
changeset
|
170 TaskManagerImpl::check_task_finish(HTaskPtr me, HTaskInfo *wait_queue) |
42 | 171 { |
497 | 172 while(TaskQueue *p = me->wait_me->poll()) { |
499 | 173 HTaskPtr you = p->task; |
497 | 174 TaskQueueInfo *wait_i = you->wait_i; |
479
bf2d2625485e
Double Linked List base TaskQueue
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
475
diff
changeset
|
175 // 相手の wait queue から自分(を指しているTaskQueue)を削除 |
bf2d2625485e
Double Linked List base TaskQueue
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
475
diff
changeset
|
176 wait_i->remove(p->waiter); |
bf2d2625485e
Double Linked List base TaskQueue
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
475
diff
changeset
|
177 // queue を free する |
493 | 178 wait_i->free_(p->waiter); |
483
5f4ffff2c2aa
renew task worked. but not test_nogl...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
481
diff
changeset
|
179 |
497 | 180 if (wait_i->empty()) { |
647
7ba4ad4538b1
MailManager rewrite. not yet worked.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
639
diff
changeset
|
181 wait_queue->remove(you); |
499 | 182 append_activeTask(you); |
497 | 183 } |
184 | |
940
e01b551f25d6
unknown dead lock still...
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
939
diff
changeset
|
185 wait_i->free_(p); // p->wait_i, p->wait_me は再利用される |
479
bf2d2625485e
Double Linked List base TaskQueue
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
475
diff
changeset
|
186 } |
bf2d2625485e
Double Linked List base TaskQueue
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
475
diff
changeset
|
187 |
939 | 188 // me を誰かが持っていて、me が finish した後に、 |
189 // me->wait_for(i) とか、やられると気まずい。 | |
190 // 特に、me が他人に再利用されていると。そういう時には、 | |
191 // このfreeをコメントアウトしてみる。 | |
192 | |
193 // id かななんかでチェックした方が良いが... | |
194 | |
195 me->self = 0; | |
941
fc6cfaae6de7
add no_auto_free flag on HTask
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
940
diff
changeset
|
196 if (!me->flag.no_auto_free) |
fc6cfaae6de7
add no_auto_free flag on HTask
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
940
diff
changeset
|
197 htaskImpl->free_(me); |
109 | 198 } |
42 | 199 |
830 | 200 /** |
201 * @brief 終了したタスクリストの依存の処理 | |
202 * @param [task] 終了したタスク | |
203 */ | |
204 void | |
205 TaskManagerImpl::check_task_list_finish(SchedTask *s, TaskListPtr list, HTaskInfo *wait_queue) | |
206 { | |
855 | 207 for(int i = 0;i<list->length;i++) { |
831
b3c004fe6bc3
CheckTaskList Mail working
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
830
diff
changeset
|
208 SimpleTaskPtr task = &list->tasks[i]; |
830 | 209 HTask *me = (HTask*)task->self; |
210 me->post_func(s, me->post_arg1, me->post_arg2); | |
211 if (task->command==TaskArray1) { | |
831
b3c004fe6bc3
CheckTaskList Mail working
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
830
diff
changeset
|
212 int next = ((task->r_size)/sizeof(SimpleTask))+1; |
830 | 213 // assert(next<list->length); |
214 i+=next; | |
215 } | |
833
577bde5d0cec
poling (may recurse..)
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
831
diff
changeset
|
216 s->polling(); |
830 | 217 check_task_finish(me, wait_queue); |
218 } | |
219 } | |
109 | 220 |
830 | 221 /** |
222 * @brief waitTaskqueue への挿入 。必須ではない。 | |
223 * 現状では、dead lock 検出にしか使ってない | |
224 * | |
225 * @param [task] 終了したタスク | |
226 */ | |
109 | 227 void |
498
bce667ff20b9
double linked HTaskInfo/HTask
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
497
diff
changeset
|
228 TaskManagerImpl::append_waitTask(HTaskPtr q) |
109 | 229 { |
479
bf2d2625485e
Double Linked List base TaskQueue
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
475
diff
changeset
|
230 waitTaskQueue ->addLast(q); |
109 | 231 } |
232 | |
830 | 233 /** |
234 @brief htask を DMA でCPUに渡すための TaskList に入れる (copy) | |
235 @param htask | |
236 @param taskList | |
237 TaskList は自動的に延長される | |
238 */ | |
806 | 239 void |
240 TaskManagerImpl::set_taskList(HTaskPtr htask, TaskListInfoPtr taskList) { | |
809 | 241 TaskListPtr list ; |
242 if ( taskList->empty() ) { | |
243 list = taskList->create(); | |
244 taskList->addLast(list); | |
245 } else | |
246 list = taskList->getLast(); | |
806 | 247 SimpleTaskPtr task = &list->tasks[list->length++]; |
248 if (htask->command==TaskArray1) { | |
249 // compatibility | |
250 int next = ((htask->r_size)/sizeof(SimpleTask))+1; | |
251 if (list->length+next>=TASK_MAX_SIZE) { | |
252 list->length--; | |
809 | 253 TaskListPtr newList = taskList->create(); |
806 | 254 taskList->addLast(newList); |
255 list = newList; | |
256 task = &list->tasks[list->length++]; | |
257 } | |
258 Task *array = (Task*)&list->tasks[list->length]; | |
259 list->length += next; | |
260 if (list->length>=TASK_MAX_SIZE) { | |
261 perror("task array1 overflow\n"); | |
262 } | |
263 memcpy(array, htask->rbuf, htask->r_size); | |
264 free(htask->rbuf); | |
831
b3c004fe6bc3
CheckTaskList Mail working
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
830
diff
changeset
|
265 // htask->rbuf = 0; htask->r_size = 0; we need this... |
806 | 266 *task = *(SimpleTask*)htask; |
267 } else { | |
268 *task = *(SimpleTask*)htask; | |
269 } | |
270 if (list->length >= TASK_MAX_SIZE) { | |
809 | 271 TaskListPtr newList = taskList->create(); |
806 | 272 taskList->addLast(newList); |
273 list = newList; | |
274 } | |
275 } | |
276 | |
54 | 277 |
619 | 278 |
479
bf2d2625485e
Double Linked List base TaskQueue
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
475
diff
changeset
|
279 /* end */ |