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