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