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