0
|
1 //#include "Task.h"
|
|
2 #include <stdint.h>
|
|
3 #include <stdlib.h>
|
|
4 #include "TaskScheduler.h"
|
|
5 #include "List.h"
|
|
6
|
2
|
7 enum wait{
|
1
|
8 NOWAIT=0,
|
|
9 WAIT=1,
|
|
10 };
|
2
|
11 extern __code checkNewCode(TaskScheduler *, enum wait);
|
|
12
|
|
13 __code (*scheduler)(void*,Taskrun,void*,void*);
|
0
|
14
|
|
15 typedef List SchedTaskList;
|
|
16 #define addSchedTask(a,b) (SchedTaskList*)_listAddFirst((List*)(a),(void*)(b))
|
|
17 #define removeTask(a,b) (SchedTaskList*)_listRemove((List*)(a),(void*)(b))
|
|
18 // inline functionのがいいか
|
|
19
|
2
|
20 __code schedEntry(TaskScheduler *tsched, Taskrun nextcode, void *rbuff, void *wbuff);
|
0
|
21
|
3
|
22 extern void *allocate(size_t);
|
0
|
23
|
|
24 __code
|
2
|
25 initScheduler(__code (*ret)(TaskScheduler*,void*), void *arg)
|
0
|
26 {
|
2
|
27 TaskScheduler *tsched;
|
|
28 tsched = allocate(sizeof(TaskScheduler));
|
|
29 tsched->runnable = NULL;
|
|
30 tsched->running = NULL;
|
|
31 //tsched->schedule = SchedEntry;
|
|
32 scheduler = schedEntry;
|
|
33 goto ret(tsched, arg);
|
0
|
34 }
|
|
35
|
|
36 __code
|
2
|
37 addCode(TaskScheduler *tsched, ID id, Taskrun code0, void *rbuff, void *wbuff)
|
0
|
38 {
|
2
|
39 SchedTask *newst;
|
|
40 newst = allocate(sizeof(SchedTask)); //これはAbstractLayerで生成してもいいのだが…
|
|
41 newst->nextcode = code0;
|
|
42 newst->rbuff = rbuff; //taskの遷移で引数が変化しないならいならい
|
|
43 newst->wbuff = wbuff;
|
0
|
44
|
2
|
45 /* regist new task to runnable list. */
|
|
46 tsched->runnable = addSchedTask(tsched->runnable, newst);
|
0
|
47
|
2
|
48 goto selectCode(tsched);
|
0
|
49 }
|
|
50
|
|
51 __code
|
2
|
52 selectCode(TaskScheduler *tsched)
|
0
|
53 {
|
|
54 SchedTask *task;
|
2
|
55 if (tsched->runnable) {
|
|
56 task = (SchedTask*)_listGetLastData(tsched->runnable);
|
|
57 tsched->running = task;
|
0
|
58
|
2
|
59 /* goto user-defined task. */
|
|
60 goto task->nextcode(tsched, task->rbuff, task->wbuff);
|
1
|
61 } else {
|
2
|
62 /* no task we have. */
|
1
|
63 //goto checkNewCode();
|
2
|
64 goto checkNewCode(tsched, WAIT);
|
1
|
65 }
|
0
|
66 }
|
|
67
|
|
68 __code
|
2
|
69 schedEntry(TaskScheduler *tsched, Taskrun nextcode, void *rbuff, void *wbuff)
|
0
|
70 {
|
2
|
71 /* schedulerd */
|
0
|
72 if ( nextcode==NULL ) {
|
2
|
73 /* the task finished. */
|
|
74 ID id = tsched->running->id;
|
|
75 tsched->runnable =
|
|
76 removeTask(tsched->runnable, tsched->running);
|
|
77 free(tsched->running);
|
|
78 tsched->running = NULL;
|
|
79 goto exitCode(tsched, id);
|
0
|
80 } else {
|
1
|
81 /* save the next code segment for the task. */
|
2
|
82 tsched->running->nextcode = nextcode;
|
|
83 tsched->running->rbuff = rbuff;
|
|
84 tsched->running->wbuff = wbuff;
|
1
|
85 /* move last task to first to be fair. */
|
2
|
86 tsched->runnable = _listMoveLasttoFirst(tsched->runnable);
|
|
87 goto checkNewCode(tsched, NOWAIT);
|
0
|
88 }
|
|
89 }
|
|
90
|
|
91
|