Rev 1202 | Rev 1205 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1199 | giacomo | 1 | #include <kernel/kern.h> |
2 | #include "parser.h" |
||
1200 | giacomo | 3 | #include "dosread.h" |
1199 | giacomo | 4 | |
1203 | giacomo | 5 | /* Memory pointers on loaded file */ |
1200 | giacomo | 6 | extern void *start; |
7 | extern void *end; |
||
8 | |||
1203 | giacomo | 9 | /* Calibration Loops */ |
10 | #define CALIBRATION_DELTA 1000000 |
||
11 | |||
12 | /* Activate task output */ |
||
13 | #define TASK_OUTPUT |
||
14 | |||
1202 | giacomo | 15 | struct timespec zero_time; |
1203 | giacomo | 16 | int cal_cycles = 0; |
17 | int cal_rit_start = 0; |
||
18 | int cal_rit_calc_const = 0; |
||
19 | int cal_rit_calc_mean = 0; |
||
20 | int cal_rit_calc_gauss = 0; |
||
1202 | giacomo | 21 | |
1203 | giacomo | 22 | /* Not Real-Time Task */ |
1201 | giacomo | 23 | TASK nrt_test_task(void *arg) |
24 | { |
||
1203 | giacomo | 25 | long long i,exec_cycles = 0; |
26 | int exec_1,exec_2,exec_3; |
||
27 | int act_1,act_2,act_3,next_act; |
||
28 | struct timespec next_time; |
||
29 | static int act= 0; |
||
30 | struct loader_task *l = (struct loader_task *)(arg); |
||
31 | |||
32 | act++; |
||
33 | |||
34 | #ifdef TASK_OUTPUT |
||
35 | cprintf("(Act %d Pid %d Grp %d Lev %d)",act,exec_shadow,l->group,l->task_level); |
||
36 | #endif |
||
1201 | giacomo | 37 | |
1203 | giacomo | 38 | act_1 = TIMESPEC2USEC(&l->act_par_2); |
39 | act_2 = TIMESPEC2USEC(&l->act_par_3); |
||
40 | act_3 = TIMESPEC2USEC(&l->act_par_4); |
||
1202 | giacomo | 41 | |
1203 | giacomo | 42 | if (l->act_type == PAR_ACT_PERIODIC) { |
43 | kern_gettime(&next_time); |
||
44 | ADDUSEC2TIMESPEC(act_1,&next_time); |
||
45 | kern_event_post(&next_time,(void *)((void *)task_activate),(void *)exec_shadow); |
||
46 | } |
||
1201 | giacomo | 47 | |
1203 | giacomo | 48 | if (l->act_type == PAR_ACT_MEAN) { |
49 | next_act = act_1 + rand() % act_2 - act_2/2; |
||
50 | kern_gettime(&next_time); |
||
51 | ADDUSEC2TIMESPEC(next_act,&next_time); |
||
52 | kern_event_post(&next_time,(void *)((void *)task_activate),(void *)exec_shadow); |
||
53 | } |
||
1202 | giacomo | 54 | |
1203 | giacomo | 55 | if (l->act_type == PAR_ACT_GAUSS) { |
1201 | giacomo | 56 | } |
1203 | giacomo | 57 | |
58 | if (l->act_type == PAR_ACT_GAUSS_MAX) { |
||
59 | } |
||
60 | |||
61 | exec_1 = TIMESPEC2USEC(&l->exec_par_1); |
||
62 | exec_2 = TIMESPEC2USEC(&l->exec_par_2); |
||
63 | exec_3 = TIMESPEC2USEC(&l->exec_par_3); |
||
64 | |||
65 | if (l->exec_type == PAR_EXEC_CONST) |
||
66 | exec_cycles = (long long)(exec_1 - cal_rit_start - cal_rit_calc_const) |
||
67 | * CALIBRATION_DELTA / cal_cycles; |
||
68 | |||
69 | if (l->exec_type == PAR_EXEC_MEAN) |
||
70 | exec_cycles = (long long)(exec_1 - cal_rit_start - cal_rit_calc_mean |
||
71 | + rand() % exec_2 - exec_2/2) * CALIBRATION_DELTA / cal_cycles; |
||
72 | |||
73 | if (l->exec_type == PAR_EXEC_GAUSS) |
||
74 | exec_cycles = 0; |
||
75 | |||
76 | if (l->exec_type == PAR_EXEC_GAUSS_MAX) |
||
77 | exec_cycles = 0; |
||
78 | |||
79 | for (i=0;i<exec_cycles;i++); |
||
80 | |||
1201 | giacomo | 81 | return NULL; |
1203 | giacomo | 82 | |
1201 | giacomo | 83 | } |
84 | |||
1203 | giacomo | 85 | /* Soft and hard Task */ |
1201 | giacomo | 86 | TASK test_task(void *arg) |
87 | { |
||
1203 | giacomo | 88 | long long i,exec_cycles = 0; |
89 | int exec_1,exec_2,exec_3; |
||
90 | int act_1,act_2,act_3,next_act; |
||
91 | struct timespec next_time; |
||
92 | static int act=0; |
||
93 | int extra_rit; |
||
94 | struct loader_task *l = (struct loader_task *)(arg); |
||
95 | |||
96 | act++; |
||
97 | |||
98 | #ifdef TASK_OUTPUT |
||
99 | cprintf("(Act %d Pid %d Grp %d Lev %d)",act,exec_shadow,l->group,l->task_level); |
||
100 | #endif |
||
1201 | giacomo | 101 | |
1203 | giacomo | 102 | act_1 = TIMESPEC2USEC(&l->act_par_2); |
103 | act_2 = TIMESPEC2USEC(&l->act_par_3); |
||
104 | act_3 = TIMESPEC2USEC(&l->act_par_4); |
||
105 | |||
106 | exec_1 = TIMESPEC2USEC(&l->exec_par_1); |
||
107 | exec_2 = TIMESPEC2USEC(&l->exec_par_2); |
||
108 | exec_3 = TIMESPEC2USEC(&l->exec_par_3); |
||
1202 | giacomo | 109 | |
1203 | giacomo | 110 | extra_rit = cal_rit_start; |
111 | |||
1201 | giacomo | 112 | while(1) { |
113 | |||
1203 | giacomo | 114 | task_testcancel(); |
1202 | giacomo | 115 | |
1203 | giacomo | 116 | if (l->act_type == PAR_ACT_MEAN) { |
117 | next_act = act_1 + rand() % act_2 - act_2/2; |
||
118 | kern_gettime(&next_time); |
||
119 | ADDUSEC2TIMESPEC(next_act,&next_time); |
||
120 | kern_event_post(&next_time,(void *)((void *)task_activate),(void *)exec_shadow); |
||
121 | } |
||
122 | |||
123 | if (l->act_type == PAR_ACT_GAUSS) { |
||
124 | } |
||
125 | |||
126 | if (l->act_type == PAR_ACT_GAUSS_MAX) { |
||
127 | } |
||
128 | |||
129 | if (l->exec_type == PAR_EXEC_CONST) |
||
130 | exec_cycles = (long long)(exec_1 - extra_rit - cal_rit_calc_const) |
||
131 | * CALIBRATION_DELTA / cal_cycles; |
||
132 | |||
133 | if (l->exec_type == PAR_EXEC_MEAN) |
||
134 | exec_cycles = (long long)(exec_1 - extra_rit - cal_rit_calc_mean |
||
135 | + rand() % exec_2 - exec_2/2) * CALIBRATION_DELTA / cal_cycles; |
||
136 | |||
137 | if (l->exec_type == PAR_EXEC_GAUSS) |
||
138 | exec_cycles = 0; |
||
139 | |||
140 | if (l->exec_type == PAR_EXEC_GAUSS_MAX) |
||
141 | exec_cycles = 0; |
||
142 | |||
143 | extra_rit = 0; |
||
144 | |||
145 | for (i=0;i<exec_cycles;i++); |
||
146 | |||
1201 | giacomo | 147 | task_endcycle(); |
1203 | giacomo | 148 | |
1201 | giacomo | 149 | } |
1203 | giacomo | 150 | |
1201 | giacomo | 151 | return NULL; |
1203 | giacomo | 152 | |
153 | } |
||
1201 | giacomo | 154 | |
1203 | giacomo | 155 | /* Delay Calibration */ |
156 | int calibrate_cycle() |
||
157 | { |
||
158 | long long i; |
||
159 | struct timespec start,end,diff; |
||
160 | int temp = 1234567; |
||
161 | int temp_1 = 1234567; |
||
162 | int temp_2 = 1234567; |
||
163 | |||
164 | kern_cli(); |
||
165 | kern_gettime(&start); |
||
166 | for (i=0;i<CALIBRATION_DELTA;i++); |
||
167 | kern_gettime(&end); |
||
168 | kern_sti(); |
||
169 | |||
170 | SUBTIMESPEC(&end,&start,&diff); |
||
171 | cal_cycles = TIMESPEC2USEC(&diff); |
||
172 | |||
173 | cprintf("Calibration usec/[%d cycles] = %d\n",CALIBRATION_DELTA,cal_cycles); |
||
174 | |||
175 | kern_cli(); |
||
176 | kern_gettime(&start); |
||
177 | temp = (long long)(temp_1) * CALIBRATION_DELTA / cal_cycles; |
||
178 | kern_gettime(&end); |
||
179 | kern_sti(); |
||
180 | |||
181 | SUBTIMESPEC(&end,&start,&diff); |
||
182 | cal_rit_calc_const = TIMESPEC2USEC(&diff); |
||
183 | |||
184 | kern_cli(); |
||
185 | kern_gettime(&start); |
||
186 | temp = (long long)(temp_1 + rand() % temp_2 - temp_2/2) * CALIBRATION_DELTA / cal_cycles; |
||
187 | kern_gettime(&end); |
||
188 | kern_sti(); |
||
189 | |||
190 | SUBTIMESPEC(&end,&start,&diff); |
||
191 | cal_rit_calc_mean = TIMESPEC2USEC(&diff); |
||
192 | |||
193 | kern_cli(); |
||
194 | kern_gettime(&start); |
||
195 | temp = TIMESPEC2USEC(&start); |
||
196 | kern_gettime(&end); |
||
197 | kern_sti(); |
||
198 | |||
199 | SUBTIMESPEC(&end,&start,&diff); |
||
200 | cal_rit_start = TIMESPEC2USEC(&diff) * 6 + cal_rit_calc_const; |
||
201 | |||
202 | cprintf("Calibration delay start = %d const = %d mean = %d gauss = %d\n", |
||
203 | cal_rit_start,cal_rit_calc_const,cal_rit_calc_mean,cal_rit_calc_gauss); |
||
204 | |||
205 | return 0; |
||
206 | |||
1201 | giacomo | 207 | } |
208 | |||
1203 | giacomo | 209 | /* Task create */ |
1201 | giacomo | 210 | void loader_task_create(struct loader_task *start_loader_task) |
211 | { |
||
212 | |||
213 | struct loader_task *current = start_loader_task; |
||
1203 | giacomo | 214 | char tmp[30]; |
1201 | giacomo | 215 | int i, total_task; |
1202 | giacomo | 216 | int total_group = 0; |
1201 | giacomo | 217 | PID p; |
218 | |||
219 | total_task = 0; |
||
220 | |||
221 | while (current != NULL) { |
||
222 | |||
1202 | giacomo | 223 | total_group++; |
224 | current->group = total_group; |
||
1203 | giacomo | 225 | current->bandwidth = 0; |
1202 | giacomo | 226 | |
1201 | giacomo | 227 | for (i=0; i < current->number; i++) { |
228 | |||
229 | if (current->task_type == PAR_TASK_NRT) { |
||
230 | NRT_TASK_MODEL nrt; |
||
231 | |||
232 | nrt_task_default_model(nrt); |
||
233 | nrt_task_def_save_arrivals(nrt); |
||
234 | nrt_task_def_arg(nrt,(void *)(current)); |
||
235 | nrt_task_def_ctrl_jet(nrt); |
||
236 | nrt_task_def_level(nrt,current->task_level); |
||
1202 | giacomo | 237 | nrt_task_def_group(nrt,total_group); |
1201 | giacomo | 238 | |
1203 | giacomo | 239 | sprintf(tmp,"NRT %d:%d",current->group,i); |
240 | p = task_create(tmp,nrt_test_task,&nrt,NULL); |
||
1201 | giacomo | 241 | if (p == NIL) { |
242 | cprintf("Error nrt task creating\n"); |
||
243 | sys_end(); |
||
244 | } |
||
245 | |||
246 | total_task++; |
||
247 | |||
248 | } |
||
249 | |||
250 | if (current->task_type == PAR_TASK_HARD) { |
||
251 | HARD_TASK_MODEL ht; |
||
252 | |||
253 | hard_task_default_model(ht); |
||
254 | hard_task_def_arg(ht,(void *)(current)); |
||
255 | hard_task_def_wcet(ht,TIMESPEC2USEC(¤t->wcet)); |
||
256 | hard_task_def_ctrl_jet(ht); |
||
257 | hard_task_def_level(ht,current->task_level); |
||
1202 | giacomo | 258 | hard_task_def_group(ht,total_group); |
1201 | giacomo | 259 | |
1203 | giacomo | 260 | if (current->act_type != PAR_ACT_PERIODIC) { |
261 | hard_task_def_mit(ht,TIMESPEC2USEC(¤t->deadline)); |
||
262 | current->bandwidth += MAX_BANDWIDTH / TIMESPEC2USEC(¤t->deadline) |
||
263 | * TIMESPEC2USEC(¤t->wcet); |
||
1201 | giacomo | 264 | hard_task_def_aperiodic(ht); |
265 | } else { |
||
1203 | giacomo | 266 | hard_task_def_mit(ht,TIMESPEC2USEC(¤t->act_par_2)); |
267 | current->bandwidth += MAX_BANDWIDTH / TIMESPEC2USEC(¤t->act_par_2) |
||
268 | * TIMESPEC2USEC(¤t->wcet); |
||
1201 | giacomo | 269 | } |
1203 | giacomo | 270 | |
271 | sprintf(tmp,"HARD %d:%d",current->group,i); |
||
272 | p = task_create(tmp,test_task,&ht,NULL); |
||
1201 | giacomo | 273 | if (p == NIL) { |
274 | cprintf("Error hard task creating\n"); |
||
275 | sys_end(); |
||
276 | } |
||
277 | |||
278 | total_task++; |
||
279 | |||
280 | } |
||
281 | |||
282 | if (current->task_type == PAR_TASK_SOFT) { |
||
283 | SOFT_TASK_MODEL st; |
||
284 | |||
285 | soft_task_default_model(st); |
||
286 | soft_task_def_save_arrivals(st); |
||
287 | soft_task_def_arg(st,(void *)(current)); |
||
288 | soft_task_def_met(st,TIMESPEC2USEC(¤t->wcet)); |
||
289 | soft_task_def_ctrl_jet(st); |
||
290 | soft_task_def_level(st,current->task_level); |
||
1202 | giacomo | 291 | soft_task_def_group(st,total_group); |
292 | |||
1201 | giacomo | 293 | if (current->act_type == PAR_ACT_PERIODIC) { |
294 | soft_task_def_period(st,TIMESPEC2USEC(¤t->act_par_2)); |
||
1203 | giacomo | 295 | current->bandwidth += MAX_BANDWIDTH / TIMESPEC2USEC(¤t->act_par_2) |
296 | * TIMESPEC2USEC(¤t->wcet); |
||
1201 | giacomo | 297 | } else if (current->act_type != PAR_ACT_SINGLE) { |
298 | soft_task_def_period(st,TIMESPEC2USEC(¤t->act_par_2)); |
||
1203 | giacomo | 299 | current->bandwidth += MAX_BANDWIDTH / TIMESPEC2USEC(¤t->act_par_2) |
300 | * TIMESPEC2USEC(¤t->wcet); |
||
1201 | giacomo | 301 | soft_task_def_aperiodic(st); |
302 | } else { |
||
1203 | giacomo | 303 | soft_task_def_period(st,TIMESPEC2USEC(¤t->wcet)*1000); |
304 | current->bandwidth += MAX_BANDWIDTH / 1000; |
||
1201 | giacomo | 305 | soft_task_def_aperiodic(st); |
306 | } |
||
1203 | giacomo | 307 | |
308 | sprintf(tmp,"SOFT %d:%d",current->group,i); |
||
309 | p = task_create(tmp,test_task,&st,NULL); |
||
1201 | giacomo | 310 | if (p == NIL) { |
311 | cprintf("Error soft task creating\n"); |
||
312 | sys_end(); |
||
313 | } |
||
314 | |||
315 | total_task++; |
||
316 | |||
317 | } |
||
318 | |||
319 | } |
||
320 | |||
1203 | giacomo | 321 | cprintf("Task group %d created. Worst case BW = %d.%d \n", |
322 | current->group,(int)( (long long)current->bandwidth * 100 / MAX_BANDWIDTH), |
||
323 | (int)( (long long)current->bandwidth* 100000 / MAX_BANDWIDTH % 1000)); |
||
324 | |||
1201 | giacomo | 325 | current = current->next; |
326 | |||
327 | } |
||
328 | |||
329 | cprintf("Created %d tasks\n",total_task); |
||
330 | |||
331 | } |
||
332 | |||
1203 | giacomo | 333 | /* Set the first extivation events */ |
1202 | giacomo | 334 | void loader_first_execution(struct loader_task *start_loader_task) |
335 | { |
||
336 | |||
337 | struct loader_task *current = start_loader_task; |
||
338 | struct timespec start_time; |
||
339 | |||
340 | while (current != NULL) { |
||
341 | |||
342 | ADDTIMESPEC(&zero_time,¤t->act_par_1,&start_time); |
||
343 | |||
344 | kern_event_post(&start_time, (void *)((void *)group_activate), (void *)(current->group)); |
||
345 | |||
346 | current = current->next; |
||
347 | |||
348 | } |
||
349 | |||
350 | } |
||
351 | |||
1199 | giacomo | 352 | int main() |
353 | { |
||
354 | |||
1200 | giacomo | 355 | struct loader_task *start_loader_task = NULL; |
356 | struct timespec total; |
||
1201 | giacomo | 357 | struct timespec end_time; |
1199 | giacomo | 358 | |
1201 | giacomo | 359 | line_reader(start, end, &total, &start_loader_task); |
1200 | giacomo | 360 | |
1203 | giacomo | 361 | srand(kern_gettime(NULL)); |
362 | |||
363 | calibrate_cycle(); |
||
364 | |||
1201 | giacomo | 365 | loader_task_create(start_loader_task); |
366 | |||
367 | kern_gettime(&zero_time); |
||
1202 | giacomo | 368 | |
369 | loader_first_execution(start_loader_task); |
||
370 | |||
1201 | giacomo | 371 | ADDTIMESPEC(&zero_time,&total,&end_time); |
372 | kern_event_post(&end_time,(void *)((void *)(sys_end)),NULL); |
||
373 | |||
1199 | giacomo | 374 | return 0; |
375 | |||
376 | } |