750a877e2014534fc465e7cf3d8b6b92cf212533
[projects/modsched/linux.git] / framework / modules / rr_module.c
1 /*
2  * rr_module.c
3  *      a simple round robin scheduler
4  *
5  *  Created on: 14.06.2013
6  *      Author: Rene Sechting
7  */
8
9 //#include "mod_sched_framework.h"
10 #include <fw.h>
11
12 void subscribe_to_topic(int i,void *dingens);
13
14 struct rq{
15         fw_list_head_t          queue;
16         struct fw_task          *curr;
17         struct fw_task          *idle;
18 };
19
20 struct rr_info{
21         struct fw_list_head head;
22         struct fw_task *task;
23         int on_rq;
24 };
25
26 static unsigned long offset;
27 static struct rq *rr_rq;
28 static struct fw_task *idle;
29
30 static int module_id;
31
32 //static void rr_print_rq(){
33 //      struct fw_list_head *pos;
34 //      struct rr_info *dingens;
35 //      fw_printf("rq: ");
36 //      for(pos = rr_rq->queue->next;pos != rr_rq->queue;pos = pos->next){
37 //              dingens = (struct rr_info *)pos;
38 //              dingens->task
39 //              fw_printf("task: %p |", dingens->task);
40 //      }
41 //      fw_print("\n");
42 //}
43
44 static struct fw_task *task_received(struct fw_task *task)
45 {
46         struct rr_info *rq_ele;
47 //      if(system_state == SYSTEM_RUNNING)
48 //              fw_printf("new task %d\n", fw_get_pid(task));
49 //      rq_ele = (struct rr_info*)((unsigned long)task+offset);
50 //      fw_list_add_tail(&rq_ele->head, &rr_rq->queue);
51
52         rq_ele = (struct rr_info *)fw_malloc(sizeof(struct rr_info));
53         task->module_data[module_id] = (void *)rq_ele;
54         rq_ele->task = task;
55         fw_list_add_tail(&rq_ele->head, &rr_rq->queue);
56
57         rq_ele->on_rq = 1;
58
59         return NULL;
60 }
61
62 static struct fw_task *task_finished(struct fw_task *finished)
63 {
64         struct rr_info *next_elem;
65         struct fw_task *task;
66 //      fw_printf("task finished %d\n",fw_get_pid(finished));
67
68 //      next_elem = (struct rr_info *)((unsigned long)finished+offset);
69 //      next_elem->on_rq = 0;
70         if(!fw_list_empty(&rr_rq->queue)){
71                 //get the next task running!
72                 next_elem = (struct rr_info *)__fw_list_pop(&(rr_rq->queue));
73                 task = next_elem->task;
74                 rr_rq->curr = task;
75                 fw_dispatch(task);
76                 return task;
77         }else{
78                 //every task is done, go to idle mode
79                 rr_rq->curr = idle;
80                 fw_dispatch(idle);
81                 return idle;
82         }
83 }
84
85 static struct fw_task *tick_received(void)
86 {
87         struct fw_task *task = rr_rq->curr;
88         struct rr_info *next_elem;
89 //      if(system_state == SYSTEM_RUNNING)
90 //              fw_printf(".");
91
92 //      rr_print_rq();
93
94         if(fw_list_empty(&rr_rq->queue)){
95 //              fw_printf("kein kontextwechsel\n");
96                 fw_dispatch(task);
97                 return NULL;
98         }
99
100         if((task == idle)&&!fw_list_empty(&rr_rq->queue)){
101                 next_elem = (struct rr_info *)__fw_list_pop(&(rr_rq->queue));
102 //              task = (struct fw_task*)((unsigned long)next_elem-offset);
103                 task = next_elem->task;
104                 rr_rq->curr = task;
105                 fw_dispatch(task);
106                 return task;
107         }else if(!fw_list_empty(&rr_rq->queue)){
108                 if(task!=idle){
109                         //insert curr task to queue
110                         next_elem = (struct rr_info*)task->module_data[module_id];
111 //                      next_elem = (struct rr_info*)((unsigned long)task+offset);
112                         fw_list_add_tail(&next_elem->head,&rr_rq->queue);
113                         next_elem->on_rq = 1;
114                 }
115                 //get the new task out of da queue and schedule the hell out of it
116 //              next_elem = NULL;
117                 next_elem = (struct rr_info *)__fw_list_pop(&(rr_rq->queue));
118 //              task = (struct fw_task*)((unsigned long)next_elem-offset);
119                 task = next_elem->task;
120                 next_elem->on_rq = 0;
121                 rr_rq->curr = task;
122                 fw_dispatch(task);
123                 return task;
124         }
125         rr_rq->curr = idle;
126         fw_dispatch(idle);
127         return idle;
128 }
129
130 static struct fw_task *task_yielded(struct fw_task *yielded)
131 {
132
133 //      fw_printf("yield-state: %d",fw_get_state(yielded));
134         struct rr_info *next_elem;
135 //      struct rr_info *pos;
136         struct fw_task *task;
137 //      fw_printf("task has yielded %d\n",fw_get_pid(yielded));
138 //      next_elem = (struct rr_info *) ((unsigned long)yielded + offset);
139         next_elem = (struct rr_info*)yielded->module_data[module_id];
140         next_elem->on_rq = 0;
141 //      next_elem = NULL;
142         if(!fw_list_empty(&rr_rq->queue)){
143                 next_elem = (struct rr_info *)__fw_list_pop(&(rr_rq->queue));
144                 next_elem->on_rq = 0;
145 //              task = (struct fw_task*)((unsigned long)next_elem-offset);
146                 task = next_elem->task;
147                 rr_rq->curr = task;
148                 fw_dispatch(task);
149                 return task;
150         }else{
151                 rr_rq->curr = idle;
152                 fw_dispatch(idle);
153                 return idle;
154         }
155 }
156
157 static struct fw_task *wake_up_task(struct fw_task *wake_up)
158 {
159 //      if(system_state == SYSTEM_RUNNING)
160 //              fw_printf("aufwachen!!! %d\n",fw_get_pid(wake_up));
161 //      struct rr_info *to_wake_up = (struct rr_info*)((unsigned long)wake_up+offset);
162         struct rr_info *to_wake_up = (struct rr_info*)wake_up->module_data[module_id];
163         if(!to_wake_up->on_rq){
164                 fw_list_add_tail(&to_wake_up->head,&(rr_rq->queue));
165                 to_wake_up->on_rq = 1;
166         }
167         return NULL;
168 }
169
170 //__init_module(init_sched_rr_module)
171 int init_sched_rr_module(void)
172 {
173         fw_printf("ROUND_ROBIN_MODULE INITIALIZING\n");
174         module_id = fw_register_module();
175         if(module_id == -1)
176                 return -1;
177         rr_rq = (struct rq*)fw_malloc(sizeof(struct rq));
178         idle = fw_idle_task;
179         rr_rq->idle = idle;
180         rr_rq->curr = idle;
181         FW_LIST_INIT(rr_rq->queue);
182         subscribe_to_topic(1, &task_received);
183         subscribe_to_topic(2, &task_finished);
184         subscribe_to_topic(3, &tick_received);
185         subscribe_to_topic(4, &task_yielded);
186         subscribe_to_topic(0, &wake_up_task);
187         fw_printf("SCHEDULER INITIALIZED!\n");
188
189         return 0;
190 }