5
|
1 #include <stdio.h>
|
3
|
2 #include "TaskManagerImpl.h"
|
46
|
3 #include "types.h"
|
|
4 #include "error.h"
|
109
|
5 #include "../sys_task/SysTask.h"
|
|
6
|
220
|
7 static HTaskPtr systask_start;
|
109
|
8 static HTaskPtr systask_finish;
|
42
|
9
|
3
|
10 void
|
109
|
11 noaction(void *p)
|
3
|
12 {
|
|
13 }
|
|
14
|
109
|
15 TaskManagerImpl::TaskManagerImpl(int num)
|
|
16 : machineNum(num), activeTaskQueue(NULL), waitTaskQueue(NULL) {}
|
50
|
17
|
220
|
18 /**
|
298
|
19 * 一番最初に PPE で実行される systask_start
|
|
20 * 一番最後に、全てのタスクの終了を待つ systask_finish
|
|
21 * 番兵的な意味で実装
|
220
|
22 */
|
42
|
23 void
|
109
|
24 TaskManagerImpl::systask_init(void)
|
42
|
25 {
|
109
|
26 systask_register();
|
42
|
27
|
220
|
28 systask_start = create_task(SYSTASK_START);
|
109
|
29 systask_finish = create_task(SYSTASK_FINISH);
|
220
|
30
|
|
31 systask_start->spawn();
|
|
32
|
298
|
33 // systask_finish で spawn すると
|
220
|
34 // systask_finish->wait_for(systask_finish);
|
298
|
35 // とかなって無限ループになるので、
|
|
36 // これだけは明示的に append_waitTask() で
|
109
|
37 append_waitTask(systask_finish);
|
42
|
38 }
|
|
39
|
3
|
40 HTaskPtr
|
109
|
41 TaskManagerImpl::create_task(int cmd)
|
3
|
42 {
|
|
43 HTaskPtr new_task;
|
|
44
|
109
|
45 new_task = bufferManager->create_task(cmd);
|
|
46 new_task->post_func = noaction;
|
63
|
47 new_task->mimpl = this;
|
|
48
|
3
|
49 return new_task;
|
|
50 }
|
|
51
|
|
52 /**
|
298
|
53 * task の依存関係を設定
|
|
54 * master task が終わってから、slave task を実行するように
|
109
|
55 * master->wait_for(slave);
|
3
|
56 */
|
|
57 void
|
|
58 TaskManagerImpl::set_task_depend(HTaskPtr master, HTaskPtr slave)
|
|
59 {
|
|
60 TaskQueuePtr m, s;
|
|
61
|
58
|
62 m = bufferManager->create_taskQueue(master);
|
|
63 s = bufferManager->create_taskQueue(slave);
|
3
|
64
|
109
|
65 master->wait_me = TaskQueue::append(master->wait_me, s);
|
|
66 slave->wait_i = TaskQueue::append(slave->wait_i, m);
|
3
|
67 }
|
|
68
|
109
|
69 /**
|
298
|
70 * タスクを実行可能キューまたは待機キューへ追加する。
|
|
71 * 依存関係が満たされていれば active, まだだったら wait へ。
|
109
|
72 * task->spawn();
|
|
73 */
|
3
|
74 void
|
18
|
75 TaskManagerImpl::spawn_task(HTaskPtr task)
|
3
|
76 {
|
109
|
77 // waiter // master
|
|
78 // waitee // slave
|
3
|
79 if (task->wait_i == NULL) {
|
109
|
80 append_activeTask(task);
|
3
|
81 } else {
|
109
|
82 append_waitTask(task);
|
3
|
83 }
|
109
|
84
|
|
85 systask_finish->wait_for(task);
|
3
|
86 }
|
42
|
87
|
109
|
88 /**
|
298
|
89 * Task を実行可能キューに追加する
|
109
|
90 */
|
|
91 void
|
|
92 TaskManagerImpl::append_activeTask(HTaskPtr task)
|
|
93 {
|
|
94 TaskQueuePtr q;
|
|
95
|
|
96 q = bufferManager->create_taskQueue(task);
|
|
97 activeTaskQueue = TaskQueue::append(activeTaskQueue, q);
|
|
98 }
|
|
99
|
|
100 /**
|
298
|
101 * タスクが実行する CPU を選択する
|
109
|
102 *
|
298
|
103 * 現在は CPU_PPE, CPU_SPE, SPE_ANY, SPE_0, SPE_1, ..., SPE_5
|
|
104 * types.h に書いてます。
|
109
|
105 */
|
65
|
106 void
|
|
107 TaskManagerImpl::set_task_cpu(HTaskPtr task, CPU_TYPE type)
|
|
108 {
|
|
109 task->cpu_type = type;
|
|
110 }
|
|
111
|
109
|
112 /**
|
298
|
113 * 終了したタスクから依存の処理とか
|
|
114 * post_func() はこのタスクが終了したら実行する関数。
|
|
115 * 今のところ使ってないっす
|
109
|
116 *
|
298
|
117 * @param [task] 終了したタスク
|
109
|
118 */
|
|
119 void
|
|
120 TaskManagerImpl::check_task_finish(HTaskPtr task)
|
42
|
121 {
|
109
|
122 notify_wait_taskQueue(task, task->wait_me);
|
|
123 task->post_func(task->post_arg);
|
|
124 bufferManager->free_task(task);
|
|
125 }
|
42
|
126
|
109
|
127 /**
|
298
|
128 * 終了したタスク [depend] を待っている TaskList に
|
|
129 * 終わった事を知らせる(削除する
|
109
|
130 */
|
|
131 void
|
|
132 TaskManagerImpl::notify_wait_taskQueue(HTaskPtr depend, TaskQueuePtr list)
|
|
133 {
|
|
134 TaskQueuePtr p;
|
|
135 HTaskPtr task;
|
|
136
|
|
137 p = list; // wait task list
|
|
138
|
|
139 while (p) {
|
|
140 task = (HTaskPtr)p->task;
|
|
141 task->wait_i = remove_taskQueue_eq_task(task->wait_i, depend);
|
|
142 p = p->next;
|
42
|
143 }
|
|
144
|
109
|
145 remove_taskQueue_all(list);
|
|
146 }
|
|
147
|
|
148 void
|
|
149 TaskManagerImpl::append_waitTask(HTaskPtr task)
|
|
150 {
|
|
151 TaskQueuePtr q;
|
|
152
|
|
153 q = bufferManager->create_taskQueue(task);
|
|
154 waitTaskQueue = TaskQueue::append(waitTaskQueue, q);
|
|
155 }
|
|
156
|
|
157 /**
|
298
|
158 * waitQueue の中で依存関係を満たしたタスクは
|
|
159 * activeQueue へ移す
|
109
|
160 */
|
|
161 void
|
|
162 TaskManagerImpl::wakeup_waitTask(void)
|
|
163 {
|
|
164 TaskQueuePtr p, tmp;
|
42
|
165
|
109
|
166 p = waitTaskQueue;
|
|
167 while (p) {
|
|
168 HTaskPtr task = (HTaskPtr)p->task;
|
|
169 tmp = p;
|
|
170 p = p->next;
|
|
171 if (task->wait_i == NULL) {
|
|
172 append_activeTask(task);
|
|
173 waitTaskQueue = remove_taskQueue(waitTaskQueue, tmp);
|
|
174 }
|
|
175 }
|
|
176 }
|
|
177
|
|
178 void
|
|
179 TaskManagerImpl::remove_taskQueue_all(TaskQueuePtr list)
|
|
180 {
|
|
181 TaskQueuePtr p = list;
|
|
182 TaskQueuePtr p1;
|
|
183
|
|
184 while (p != NULL) {
|
|
185 p1 = p->next;
|
|
186 bufferManager->free_taskQueue(p);
|
|
187 p = p1;
|
|
188 }
|
|
189 }
|
54
|
190
|
109
|
191 /**
|
298
|
192 * [list] が持つ queue->task の中に [task] と同じ奴があれば
|
|
193 * 削除する。まあ remove_taskQueue() の HTask で比較するverです。
|
|
194 * こういうのはオーバーロードでやるもんなのかな?
|
109
|
195 */
|
|
196 TaskQueuePtr
|
|
197 TaskManagerImpl::remove_taskQueue_eq_task(TaskQueuePtr list, HTaskPtr task)
|
|
198 {
|
|
199 TaskQueuePtr p = list;
|
|
200 TaskQueuePtr p1;
|
|
201
|
|
202 if (p == NULL) return p;
|
|
203
|
|
204 if (p->task == task) {
|
|
205 list = list->next;
|
|
206 bufferManager->free_taskQueue(p);
|
|
207 } else {
|
|
208 p1 = p->next;
|
|
209 while (p1 && p1->task && p1->task != task) {
|
|
210 p1 = p1->next;
|
|
211 p = p->next;
|
|
212 }
|
|
213 if (p1) {
|
|
214 p->next = p1->next;
|
|
215 bufferManager->free_taskQueue(p1);
|
54
|
216 }
|
109
|
217 }
|
|
218
|
|
219 return list;
|
|
220 }
|
|
221
|
|
222 TaskQueuePtr
|
|
223 TaskManagerImpl::remove_taskQueue(TaskQueuePtr list, TaskQueuePtr q)
|
|
224 {
|
|
225 TaskQueuePtr p = list;
|
|
226 TaskQueuePtr p1;
|
|
227
|
|
228 if (!p) return p;
|
|
229
|
|
230 if (p == q) {
|
|
231 list = list->next;
|
|
232 bufferManager->free_taskQueue(p);
|
|
233 } else {
|
|
234 p1 = p->next;
|
|
235 while (p1 && p1 != q) {
|
|
236 p1 = p1->next;
|
|
237 p = p->next;
|
54
|
238 }
|
109
|
239 if (p1) {
|
|
240 p->next = p1->next;
|
|
241 bufferManager->free_taskQueue(p1);
|
|
242 }
|
46
|
243 }
|
42
|
244
|
|
245 return list;
|
|
246 }
|
|
247
|