2
|
1 #include <assert.h>
|
0
|
2 #include "TaskManager.h"
|
2
|
3 #include "Task.h"
|
|
4 #include "List.h"
|
|
5 // TODO: malloc
|
0
|
6
|
2
|
7 extern __code checkEvent(TaskManager *);
|
|
8 extern __code executeTask(TaskManager*, ListIter*, Task*);
|
|
9
|
|
10 typedef List TaskList;
|
0
|
11
|
|
12 /*
|
|
13 * TaskManager's main loop.
|
|
14 *
|
|
15 * while (1) {
|
2
|
16 * while switch checkEvent() {
|
|
17 * newTask:
|
|
18 * add task to waiting.
|
|
19 * finishTask:
|
|
20 * remove task from active.
|
|
21 * }
|
|
22 * foreach task in waitinglist {
|
|
23 * if (!task_has_waitee) {
|
|
24 * move task to active from waiting.
|
|
25 * executeTask(task)
|
|
26 * }
|
|
27 * }
|
|
28 * }
|
|
29 *
|
|
30 * CPUがfullでないかをTaskManager側でケアするならこっちに変更かな
|
|
31 * while (1) {
|
|
32 * while switch checkAction() {
|
|
33 * newTask:
|
|
34 * add task to waiting or ready.
|
|
35 * finishTask:
|
|
36 * remove task from running.
|
|
37 * }
|
|
38 * if (cpu ready) {
|
|
39 * foreach task in readylist {
|
|
40 * executeTask(task)
|
|
41 * move task to running from ready.
|
|
42 * }
|
|
43 * }
|
|
44 * foreach task in waitinglist {
|
|
45 * if (!task_has_waitee) {
|
|
46 * if (CPU ready) {
|
|
47 * executeTask(task)
|
|
48 * move task to running from waiting.
|
|
49 * } else {
|
|
50 * move task to running from ready.
|
|
51 * }
|
|
52 * }
|
0
|
53 * }
|
|
54 * }
|
|
55 */
|
2
|
56
|
|
57 /* statics */
|
|
58 __code initTaskManager (__code(*ret)(TaskManager*,void*), void *arg);
|
|
59 __code start (TaskManager *manager);
|
|
60 __code addNewTask (TaskManager *manager, Task *task);
|
|
61 __code finishTask (TaskManager *manager, Task *task);
|
|
62 __code noEvent (TaskManager *manager);
|
|
63 __code getTask (TaskManager *manager, ListIter *iter);
|
|
64 __code executed (TaskManager *manager, ListIter *iter, Task *task);
|
|
65 __code cannotExecute (TaskManager *manager, Task *task);
|
|
66 __code finishTask_1 (TaskManager *manager, Task *task);
|
|
67 __code finishTask_iter (TaskManager *manager, Task *task, ListIter *iter);
|
|
68 __code finishTask_end (TaskManager *manager, Task *task);
|
|
69 void setData (Task *task, void *rbuff, size_t rs, void *wbuff, size_t ws);
|
|
70
|
|
71 __code
|
|
72 initTaskManager(__code(*ret)(TaskManager*,void*), void *arg)
|
0
|
73 {
|
2
|
74 TaskManager *manager;
|
|
75 manager = malloc(sizeof(TaskManager));
|
|
76 goto ret(manager, arg);
|
|
77 }
|
|
78
|
|
79 __code
|
|
80 start(TaskManager *manager)
|
|
81 {
|
|
82 goto checkEvent(manager);
|
|
83 }
|
|
84 __code
|
|
85 addNewTask(TaskManager *manager, Task *task)
|
|
86 {
|
|
87 /* receive a Task which has already been created in AbstractLayer. */
|
|
88 /* but It must be freed in TaskManager. */
|
|
89 manager->waitingList = _listAddFirst(manager->waitingList, task);
|
|
90 goto start(manager);
|
|
91 }
|
|
92
|
|
93 __code
|
|
94 finishTask(TaskManager *manager, Task *task)
|
|
95 {
|
|
96 goto finishTask_1(manager, task);
|
|
97 }
|
|
98
|
|
99 __code
|
|
100 noEvent(TaskManager *manager)
|
|
101 {
|
|
102 ListIter *iter;
|
|
103 iter = _listIterator(manager->waitingList);
|
|
104 goto getTask(manager, iter);
|
0
|
105 }
|
|
106
|
2
|
107 __code
|
|
108 getTask(TaskManager *manager, ListIter *iter)
|
0
|
109 {
|
2
|
110 Task *task;
|
|
111 task = (Task*)_listIterNext(iter);
|
|
112 if (!task)
|
|
113 /* iteration finished. */
|
|
114 goto start(manager);
|
|
115 if (task->waitee)
|
|
116 /* the task has been waiting yet. */
|
|
117 goto getTask(manager, iter);
|
|
118 else
|
|
119 /* the task is ready! */
|
|
120 goto executeTask(manager, iter, task);
|
0
|
121 }
|
|
122
|
2
|
123 __code
|
|
124 executed(TaskManager *manager, ListIter *iter, Task *task)
|
0
|
125 {
|
2
|
126 manager->waitingList = _listIterRemoveCurrent(iter);
|
|
127 manager->activeList = _listAddFirst(manager->activeList, task);
|
|
128 goto getTask(manager, iter);
|
|
129 }
|
|
130 /*
|
|
131 __code cannotExecute(TaskManager *manager, Task *task) { }
|
|
132 */
|
|
133
|
|
134
|
|
135 __code
|
|
136 finishTask_1(TaskManager *manager, Task *task)
|
|
137 {
|
|
138 ListIter *iter;
|
|
139
|
|
140 manager->activeList = _listRemove(manager->activeList, task);
|
|
141 iter = _listIterator(task->waiter);
|
|
142 goto finishTask_iter(manager, task, iter);
|
0
|
143 }
|
|
144
|
2
|
145 __code
|
|
146 finishTask_iter(TaskManager *manager, Task *task, ListIter *iter)
|
0
|
147 {
|
2
|
148 Task *waiter;
|
|
149 waiter = _listIterNext(iter);
|
|
150 if (waiter) {
|
|
151 waiter->waitee = _listRemove(waiter->waitee, task);
|
|
152 task->waiter = _listIterRemoveCurrent(iter);
|
|
153 goto finishTask_iter(manager, task, iter);
|
|
154 } else {
|
|
155 _listIterEnd(iter);
|
|
156 goto finishTask_end(manager, task);
|
|
157 }
|
|
158 }
|
0
|
159
|
2
|
160 __code
|
|
161 finishTask_end(TaskManager *manager, Task *task)
|
|
162 {
|
|
163 /* TODO: free(task) */
|
|
164 assert (!task->waiter);
|
|
165 assert (!task->waitee);
|
|
166 free(task);
|
|
167 goto start(manager);
|
0
|
168 }
|
|
169
|
|
170
|
2
|
171
|
0
|
172
|
|
173
|
|
174 /* belows is Interfaces for Users. */
|
2
|
175 /* it may be to code segment. but how? */
|
|
176 /* and may be moved to AbstractLayer. */
|
0
|
177
|
2
|
178 Task *newTask(int typeid)
|
0
|
179 {
|
2
|
180 Task *task;
|
|
181 static int id=0;
|
|
182 task = malloc(sizeof(Task));
|
0
|
183
|
2
|
184 //task->tasktype = tasktypes[typeid];
|
0
|
185 task->id = id;
|
|
186 task->waiter = NULL;
|
|
187 task->waitee = NULL;
|
|
188
|
|
189 return task;
|
|
190 }
|
|
191
|
|
192 void setData(Task *task, void *rbuff, size_t rs, void *wbuff, size_t ws)
|
|
193 {
|
|
194 task->rbuff = rbuff;
|
|
195 task->wbuff = wbuff;
|
2
|
196 task->rsize = rs;
|
|
197 task->wsize = ws;
|
0
|
198 }
|
|
199
|
|
200
|