Rev 950 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1063 | tullio | 1 | |
2 | /* |
||
3 | * This program is free software; you can redistribute it and/or modify |
||
4 | * it under the terms of the GNU General Public License as published by |
||
5 | * the Free Software Foundation; either version 2 of the License, or |
||
6 | * (at your option) any later version. |
||
7 | * |
||
8 | * This program is distributed in the hope that it will be useful, |
||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
11 | * GNU General Public License for more details. |
||
12 | * |
||
13 | * You should have received a copy of the GNU General Public License |
||
14 | * along with this program; if not, write to the Free Software |
||
15 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
||
16 | * |
||
17 | */ |
||
18 | |||
949 | trimarchi | 19 | //===================================================================== |
20 | // FFFFFFIII RRRRR SSTTTTTTT |
||
21 | // FF IIR RR SS |
||
22 | // FF IR SS |
||
23 | // FFFFFF RRRR SSSSST |
||
24 | // FF FI RRR SS |
||
25 | // FF II RRR SS |
||
26 | // FF IIIIIR RS |
||
27 | // |
||
28 | // FIRST Scheduling Framework |
||
29 | // |
||
30 | //===================================================================== |
||
31 | |||
32 | |||
33 | |||
34 | #include <stdio.h> |
||
35 | #include <unistd.h> |
||
36 | #include <time.h> |
||
37 | #include <errno.h> |
||
38 | #include <pthread.h> |
||
39 | #include <sched.h> |
||
40 | #include <fsf.h> |
||
41 | |||
42 | #include "timespec_operations.h" |
||
43 | #include "fsf_os_compatibility.h" |
||
44 | |||
45 | //#include <debug_marte.h> |
||
46 | |||
47 | /* |
||
48 | |||
49 | * This is part of the common tests: |
||
50 | |||
51 | ** Test to get the time it takes the negotiation of contracts and |
||
52 | the maximum reacheable utilization |
||
53 | |||
54 | - Prepare the configuration files to accept up to 100 servers, |
||
55 | enable the acceptance test, set the service thread with 100s period |
||
56 | and 1s budget, and the scheduler priority to be 102 |
||
57 | |||
58 | - Fill a contract with the values: Cmin 1s, Cmax 50s, Tmax 100s, |
||
59 | Tmin 50s, INDETERMINATE workload, and the preemptibility level equal |
||
60 | to 101 minus the number of already accepted servers. Create a server |
||
61 | with that contract, and bound it to the main thread using the |
||
62 | fsf_negotiate_contract_for_myself primitive. |
||
63 | |||
64 | - then as a servered task, negotiates as much of the prepared contracts |
||
65 | as possible, taking the utilization given to each of the contracts |
||
66 | after each new contract is accepted and the time it took the |
||
67 | negotiation. |
||
68 | |||
69 | ** Test to get the time it takes re-negotiation of contracts and |
||
70 | the change of quality and importance |
||
71 | |||
72 | - change the last parragraph of the test above, so that contracts are |
||
73 | negotiated and bound at the same time to the ever running threads, |
||
74 | and also after each succesful negotiation, the contracts are |
||
75 | re-negotiated, and its quality and importance changed to the same |
||
76 | values. They are taken the utilization given to each server and the |
||
77 | time it took each operation. |
||
78 | |||
79 | */ |
||
80 | |||
81 | |||
82 | #define FSF_MAX_N_TIME_VALUES 1000 |
||
83 | |||
84 | #define N_SERVERS 10 |
||
85 | |||
86 | struct timespec instant_zero = {0,0}; |
||
87 | int main_priority = N_SERVERS+1; |
||
88 | struct timespec last_time = {0,0}; |
||
89 | fsf_server_id_t server[N_SERVERS]; |
||
90 | struct server_res_t { |
||
91 | struct timespec negotiation; |
||
92 | struct timespec renegotiation; |
||
93 | struct timespec change_q_and_i; |
||
94 | struct timespec cancellation; |
||
95 | double min_u, max_u, tot_u; |
||
96 | } server_res[N_SERVERS]; |
||
97 | |||
98 | int n_servers = 0; |
||
99 | pthread_t task[N_SERVERS]; |
||
100 | |||
101 | |||
102 | |||
103 | struct pseudo_printed_results { |
||
104 | char *s; |
||
105 | struct timespec t; |
||
106 | } res[FSF_MAX_N_TIME_VALUES]; |
||
107 | int res_index = 0; |
||
108 | |||
109 | |||
110 | extern int cal_cycles; |
||
111 | extern int calibrate_cycle(void); |
||
112 | extern void eat(TIME wait); |
||
113 | |||
114 | //put_time has been reduced in this experiment |
||
115 | //so that it just reports the real-time it is |
||
116 | struct timespec |
||
117 | put_time(const struct timespec *time, char *s) |
||
118 | { |
||
119 | struct timespec now = {0,0}; |
||
120 | int terror; |
||
121 | |||
122 | if ((terror=clock_gettime(CLOCK_REALTIME,&now))) |
||
123 | ERROR(terror,"clock_gettime failed"); |
||
124 | |||
125 | return now; |
||
126 | } /* End of put_time */ |
||
127 | |||
128 | /* |
||
129 | int |
||
130 | print_time_results() |
||
131 | { |
||
132 | struct timespec now = {0,0}; |
||
133 | struct timespec diff = {0,0}; |
||
134 | char *s = NULL; |
||
135 | int i; |
||
136 | |||
137 | printf("\n"); |
||
138 | for (i=0;i<res_index;i++) |
||
139 | { |
||
140 | now = res[i].t; |
||
141 | s = res[i].s; |
||
142 | if (s==NULL) s = " - timestamp - "; |
||
143 | diff = now; |
||
144 | decr_timespec(&diff, &last_time); |
||
145 | last_time = now; |
||
146 | printf("%-60s", s); |
||
147 | printf(" %2d %9d", now.tv_sec,now.tv_nsec); |
||
148 | printf(" [diff=%13.9f]\n", (double)diff.tv_sec+((double)diff.tv_nsec/(double)1000000000)); |
||
149 | } |
||
150 | |||
151 | return 0; |
||
152 | } / * End of print_time_results * / |
||
153 | */ |
||
154 | /* |
||
155 | int |
||
156 | fsf_priority_map (unsigned long plevel) |
||
157 | { |
||
158 | return plevel; |
||
159 | } |
||
160 | */ |
||
161 | |||
162 | void * fsf_indeterminate_server (void * arg) |
||
163 | { |
||
164 | |||
165 | //executes for ever |
||
166 | while (1) eat(1000000); |
||
167 | |||
168 | } /* End of fsf_indeterminate_server */ |
||
169 | |||
170 | |||
171 | |||
172 | int main() |
||
173 | { |
||
174 | struct sched_param param; |
||
175 | //struct timespec half_second={0,500000000}; |
||
176 | struct timespec tmp = {0,0}; |
||
177 | int terror = 0; |
||
178 | |||
179 | fsf_contract_parameters_t contract; |
||
180 | struct timespec budget_min = {1,0}; //{20,710678118}; |
||
181 | // struct timespec budget_min = {21,210678118}; |
||
182 | struct timespec period_max = {100,0}; |
||
183 | struct timespec budget_max = {50,0}; //{20,710678118}; |
||
184 | struct timespec period_min = {50,0}; |
||
185 | fsf_workload_t workload = FSF_INDETERMINATE; //FSF_BOUNDED; |
||
186 | |||
187 | bool d_equals_t = true; |
||
188 | struct timespec deadline = {0,0}; |
||
189 | int budget_overrun_sig_notify = FSF_NULL_SIGNAL; // 0 |
||
190 | union sigval budget_overrun_sig_value = {0}; |
||
191 | int deadline_miss_sig_notify = FSF_NULL_SIGNAL; // 0 |
||
192 | union sigval deadline_miss_sig_value = {0}; |
||
193 | |||
194 | fsf_granularity_t granularity = FSF_DEFAULT_GRANULARITY; // CONTINUOUS |
||
195 | fsf_utilization_set_t *utilization_set = FSF_NULL_UTILIZATION_SET; // NULL |
||
196 | int quality = 1; |
||
197 | int importance = FSF_DEFAULT_IMPORTANCE; // 1 |
||
198 | |||
199 | fsf_preemption_level_t preemption_level; |
||
200 | fsf_critical_sections_t *critical_sections = NULL; |
||
201 | |||
202 | struct timespec budget = {0,0}; |
||
203 | struct timespec period = {0,0}; |
||
204 | struct timespec start, end; |
||
205 | int i; |
||
206 | double u; |
||
207 | |||
208 | INITIALIZATION_CODE; |
||
209 | |||
210 | param.sched_priority = main_priority; |
||
211 | if ((terror=pthread_setschedparam (pthread_self(), SCHED_FIFO, ¶m))) |
||
212 | ERROR(terror,"pthread_setschedparam"); |
||
213 | |||
214 | instant_zero.tv_sec = 10000000; |
||
215 | instant_zero.tv_nsec = 10000000; |
||
216 | clock_settime(CLOCK_REALTIME,&instant_zero); |
||
217 | clock_gettime(CLOCK_REALTIME,&instant_zero); |
||
218 | last_time = instant_zero; |
||
219 | put_time(&instant_zero, "instant_zero"); |
||
220 | put_time(NULL, "printing point 1"); |
||
221 | put_time(NULL, "printing point 2"); |
||
222 | |||
223 | |||
224 | |||
225 | |||
226 | if ((terror=fsf_initialize_contract(&contract))) |
||
227 | { |
||
950 | trimarchi | 228 | fsf_printf(" Initialize fail for server A\n"); |
949 | trimarchi | 229 | ERROR(terror,"fsf_initialize_contract failed"); |
230 | } |
||
231 | |||
232 | if ((terror=fsf_set_contract_basic_parameters (&contract, |
||
233 | &budget_min, |
||
234 | &period_max, |
||
235 | workload))) |
||
236 | { |
||
950 | trimarchi | 237 | fsf_printf("Set_Basic_Parameters failed for server A\n"); |
949 | trimarchi | 238 | ERROR(terror,"set_contract_basic_parameters failed"); |
239 | } |
||
240 | |||
241 | if ((terror=fsf_set_contract_timing_requirements (&contract, |
||
242 | d_equals_t, |
||
243 | (d_equals_t?NULL:&deadline), |
||
244 | budget_overrun_sig_notify, |
||
245 | budget_overrun_sig_value, |
||
246 | deadline_miss_sig_notify, |
||
247 | deadline_miss_sig_value))) |
||
248 | { |
||
950 | trimarchi | 249 | fsf_printf("Set_Timing_Requirements failed for server A\n"); |
949 | trimarchi | 250 | ERROR(terror,"fsf_set_contract_timing_requirements failed"); |
251 | } |
||
252 | |||
253 | if ((terror=fsf_set_contract_reclamation_parameters (&contract, |
||
254 | &budget_max, |
||
255 | &period_min, |
||
256 | granularity, |
||
257 | utilization_set, |
||
258 | quality, |
||
259 | importance))) |
||
260 | { |
||
950 | trimarchi | 261 | fsf_printf("Set_Reclamation_Parameters failed for server A\n"); |
949 | trimarchi | 262 | ERROR(terror,"fsf_set_contract_reclamation_parameters failed"); |
263 | } |
||
264 | |||
265 | preemption_level = (fsf_preemption_level_t) param.sched_priority; |
||
266 | if ((terror=fsf_set_contract_synchronization_parameters (&contract, |
||
267 | critical_sections))) |
||
268 | { |
||
950 | trimarchi | 269 | fsf_printf("Set_Synchronization_Parameters failed for server A\n"); |
949 | trimarchi | 270 | ERROR(terror,"fsf_set_contract_synchronization_parameters failed"); |
271 | } |
||
272 | |||
273 | start = put_time(NULL, "start first server contract negotiation"); |
||
274 | terror = fsf_negotiate_contract_for_myself (&contract, &server[0]); |
||
275 | end = put_time(NULL, " end first server contract negotiation"); |
||
276 | if (terror) |
||
277 | { |
||
950 | trimarchi | 278 | fsf_printf("Negotiate_Contract failed for server 0\n"); |
949 | trimarchi | 279 | ERROR(terror,"fsf_negotiate_contract_for_myself failed"); |
280 | } |
||
281 | |||
282 | decr_timespec(&end, &start); |
||
283 | server_res[0].negotiation = end; |
||
284 | |||
285 | start = put_time(NULL, "start first server contract renegotiation"); |
||
286 | terror = fsf_renegotiate_contract (&contract, server[0]); |
||
287 | end = put_time(NULL, " end first server contract renegotiation"); |
||
288 | if (terror) |
||
289 | { |
||
950 | trimarchi | 290 | fsf_printf("ReNegotiate_Contract failed for server 0\n"); |
949 | trimarchi | 291 | ERROR(terror,"fsf_renegotiate_contract failed"); |
292 | } |
||
293 | |||
294 | decr_timespec(&end, &start); |
||
295 | server_res[0].renegotiation = end; |
||
296 | |||
297 | start = put_time(NULL, "start first server change quality and importance"); |
||
298 | terror = fsf_request_change_quality_and_importance(server[0],1,1); |
||
299 | end = put_time(NULL, " end first server change quality and importance"); |
||
300 | if (terror) |
||
301 | { |
||
950 | trimarchi | 302 | fsf_printf("Change quality and importancet failed for server 0\n"); |
949 | trimarchi | 303 | ERROR(terror,"fsf_renegotiate_contract failed"); |
304 | } |
||
305 | |||
306 | decr_timespec(&end, &start); |
||
307 | server_res[0].change_q_and_i = end; |
||
308 | |||
309 | tmp = server_res[0].renegotiation; |
||
310 | incr_timespec(&tmp, &server_res[0].negotiation); |
||
311 | |||
312 | //release the CPU for a while to get the quality change done |
||
313 | if ((terror=nanosleep(&tmp,NULL))) |
||
314 | ERROR(terror, "nanosleep failed"); |
||
315 | |||
316 | //set_break_point_here; |
||
317 | |||
318 | //ask for the utilization actually gotten |
||
319 | terror = fsf_get_budget_and_period (server[0], &budget, &period); |
||
320 | if (terror) |
||
321 | { |
||
950 | trimarchi | 322 | fsf_printf("fsf_get_budget_and_period failed for server 0\n"); |
949 | trimarchi | 323 | ERROR(terror,"fsf_get_budget_and_period failed"); |
324 | } |
||
325 | // put_time(&budget,"the budget gotten is: "); |
||
326 | // put_time(&period,"the period gotten is: "); |
||
327 | server_res[0].min_u = server_res[0].max_u = server_res[0].tot_u = t2d(budget) / t2d(period); |
||
328 | /* |
||
329 | budget_min.tv_sec = 1; |
||
330 | budget_min.tv_nsec = 0; |
||
331 | // budget_max = budget_min; |
||
332 | if ((terror=fsf_set_contract_basic_parameters (&contract, |
||
333 | &budget_min, |
||
334 | &period_max, |
||
335 | &budget_max, |
||
336 | &period_min, |
||
337 | workload))) |
||
338 | { |
||
339 | printf("Set_Basic_Parameters failed for a server \n"); |
||
340 | } |
||
341 | */ |
||
342 | while(++n_servers < N_SERVERS) { |
||
343 | |||
344 | //preparation of the rest of the servers |
||
345 | ////if (n_servers==27) set_break_point_here; |
||
346 | preemption_level = main_priority - n_servers; |
||
347 | if ((terror=fsf_set_contract_synchronization_parameters (&contract, |
||
348 | critical_sections))) |
||
349 | { |
||
950 | trimarchi | 350 | fsf_printf("Set_Synchronization_Parameters failed for server %d\n", n_servers); |
949 | trimarchi | 351 | ERROR(terror,"fsf_set_contract_synchronization_parameters failed"); |
352 | } |
||
353 | |||
354 | start = put_time(NULL, "start server contract negotiation"); |
||
355 | //terror=fsf_negotiate_contract_for_new_thread (&contract, &server[n_servers], &task[n_servers], NULL, fsf_indeterminate_server, NULL); |
||
356 | terror=fsf_negotiate_contract(&contract, &server[n_servers]); |
||
357 | end = put_time(NULL, " end server contract negotiation"); |
||
358 | if (terror) |
||
359 | { |
||
950 | trimarchi | 360 | fsf_printf("Negotiate_Contract failed for server %d\n", n_servers); |
949 | trimarchi | 361 | ERROR(terror,"fsf_negotiate_contract failed"); |
362 | } |
||
363 | |||
364 | if (!server[n_servers]) { |
||
950 | trimarchi | 365 | fsf_printf("The negotiation for the server number %d was not succesful!! (n_servers=%d)\n",n_servers+1, n_servers); |
949 | trimarchi | 366 | break; |
367 | } |
||
368 | |||
369 | ////set_break_point_here; |
||
370 | |||
371 | decr_timespec(&end, &start); |
||
372 | server_res[n_servers].negotiation = end; |
||
373 | |||
374 | start = put_time(NULL, "start server contract renegotiation"); |
||
375 | terror = fsf_renegotiate_contract (&contract, server[n_servers]); |
||
376 | end = put_time(NULL, " end server contract renegotiation"); |
||
377 | if (terror) |
||
378 | { |
||
379 | printf("ReNegotiate_Contract failed for server %d\n", n_servers); |
||
380 | ERROR(terror,"fsf_renegotiate_contract failed"); |
||
381 | } |
||
382 | |||
383 | decr_timespec(&end, &start); |
||
384 | server_res[n_servers].renegotiation = end; |
||
385 | |||
386 | start = put_time(NULL, "start first server change quality and importance"); |
||
387 | terror = fsf_request_change_quality_and_importance(server[n_servers],1,1); |
||
388 | end = put_time(NULL, " end first server change quality and importance"); |
||
389 | if (terror) |
||
390 | { |
||
950 | trimarchi | 391 | fsf_printf("Change quality and importancet failed for server %d\n", n_servers); |
949 | trimarchi | 392 | ERROR(terror,"fsf_request_change_quality_and_importance failed"); |
393 | } |
||
394 | |||
395 | decr_timespec(&end, &start); |
||
396 | server_res[n_servers].change_q_and_i = end; |
||
397 | |||
398 | tmp = server_res[n_servers].renegotiation; |
||
399 | incr_timespec(&tmp, &server_res[n_servers].negotiation); |
||
400 | |||
401 | //release the CPU for a while long enough to get the change done |
||
402 | if ((terror=nanosleep(&tmp,NULL))) |
||
403 | ERROR(terror, "nanosleep failed"); |
||
404 | |||
405 | ////set_break_point_here; |
||
406 | |||
407 | //ask for the utilization actually gotten |
||
408 | terror = fsf_get_budget_and_period (server[0], &budget, &period); |
||
409 | if (terror) |
||
410 | { |
||
950 | trimarchi | 411 | fsf_printf("fsf_get_budget_and_period failed for server 0\n"); |
949 | trimarchi | 412 | ERROR(terror,"fsf_get_budget_and_period failed"); |
413 | } |
||
414 | if (period.tv_sec==0 && period.tv_nsec==0) { |
||
950 | trimarchi | 415 | fsf_printf("while processing server %d, the period gotten for server %d is cero!!\n", n_servers, 0); |
949 | trimarchi | 416 | exit(-1); |
417 | } |
||
418 | u = t2d(budget) / t2d(period); |
||
419 | server_res[n_servers].min_u = server_res[n_servers].max_u = server_res[n_servers].tot_u = u; |
||
420 | |||
421 | //get statistics for the utilization of all the accepted contracts up to the current one |
||
422 | for (i=1;i<=n_servers;i++){ |
||
423 | |||
424 | terror = fsf_get_budget_and_period (server[i], &budget, &period); |
||
425 | if (terror) |
||
426 | { |
||
950 | trimarchi | 427 | fsf_printf("fsf_get_budget_and_period failed for server %d\n", n_servers); |
949 | trimarchi | 428 | ERROR(terror,"fsf_get_budget_and_period failed"); |
429 | } |
||
430 | if (period.tv_sec==0 && period.tv_nsec==0) { |
||
950 | trimarchi | 431 | fsf_printf("while processing server %d, the period gotten for server %d is cero!!\n", n_servers, i); |
949 | trimarchi | 432 | exit(-1); |
433 | } |
||
434 | u = t2d(budget) / t2d(period); |
||
435 | server_res[n_servers].tot_u += u; |
||
436 | if (u > server_res[n_servers].max_u) server_res[n_servers].max_u = u; |
||
437 | if (u < server_res[n_servers].min_u) server_res[n_servers].min_u = u; |
||
438 | } |
||
439 | |||
440 | //printf(" %d", n_servers); |
||
441 | |||
442 | } /* End of the while */ |
||
443 | |||
444 | //cancellation of contracts |
||
445 | for (i=n_servers-1; i>0;i--) { |
||
446 | start = put_time(NULL, "start server contract cancellation"); |
||
447 | terror=fsf_cancel_contract(server[i]); |
||
448 | end = put_time(NULL, " end server contract cancellation"); |
||
449 | if (terror) |
||
450 | { |
||
950 | trimarchi | 451 | fsf_printf("Cancel_Contract failed for server %d\n", i); |
949 | trimarchi | 452 | ERROR(terror,"fsf_cancel_contract failed"); |
453 | } |
||
454 | |||
455 | decr_timespec(&end, &start); |
||
456 | server_res[i].cancellation = end; |
||
457 | } |
||
458 | |||
950 | trimarchi | 459 | fsf_printf("\n"); |
460 | fsf_printf("The number of accepted servers was: %d \n", n_servers); |
||
461 | fsf_printf("==================================\n\n"); |
||
949 | trimarchi | 462 | |
950 | trimarchi | 463 | fsf_printf("server negotiation renegotiation qualityChange cancellation max_utilizati min_utilizati total_utilization\n\n"); |
949 | trimarchi | 464 | |
465 | for (i=0;i<n_servers;i++){ |
||
950 | trimarchi | 466 | fsf_printf(" %2d ", i+1); |
467 | fsf_printf(" %13.9f ", t2d(server_res[i].negotiation)); |
||
468 | fsf_printf(" %13.9f ", t2d(server_res[i].renegotiation)); |
||
469 | fsf_printf(" %13.9f ", t2d(server_res[i].change_q_and_i)); |
||
470 | fsf_printf(" %13.9f ", t2d(server_res[i].cancellation)); |
||
471 | fsf_printf(" %13.9f ", server_res[i].max_u); |
||
472 | fsf_printf(" %13.9f ", server_res[i].min_u); |
||
473 | fsf_printf(" %13.9f ", server_res[i].tot_u); |
||
474 | fsf_printf("\n"); |
||
949 | trimarchi | 475 | } |
476 | |||
477 | STANDARD_CONSOLE_INIT; //marte1.26i+ |
||
478 | |||
950 | trimarchi | 479 | fsf_printf("\n"); |
480 | fsf_printf("The number of accepted servers was: %d \n", n_servers); |
||
481 | fsf_printf("==================================\n\n"); |
||
949 | trimarchi | 482 | |
950 | trimarchi | 483 | fsf_printf("server negotiation renegotiation qualityChange cancellation max_utilizati min_utilizati total_utilization\n\n"); |
949 | trimarchi | 484 | |
485 | for (i=0;i<n_servers;i++){ |
||
950 | trimarchi | 486 | fsf_printf(" %2d ", i+1); |
487 | fsf_printf(" %13.9f ", t2d(server_res[i].negotiation)); |
||
488 | fsf_printf(" %13.9f ", t2d(server_res[i].renegotiation)); |
||
489 | fsf_printf(" %13.9f ", t2d(server_res[i].change_q_and_i)); |
||
490 | fsf_printf(" %13.9f ", t2d(server_res[i].cancellation)); |
||
491 | fsf_printf(" %13.9f ", server_res[i].max_u); |
||
492 | fsf_printf(" %13.9f ", server_res[i].min_u); |
||
493 | fsf_printf(" %13.9f ", server_res[i].tot_u); |
||
494 | fsf_printf("\n"); |
||
949 | trimarchi | 495 | } |
496 | |||
950 | trimarchi | 497 | fsf_printf("\nThe end.\n"); |
949 | trimarchi | 498 | |
499 | //.... |
||
500 | exit(-1); |
||
501 | return 0; |
||
502 | } /* End of main */ |