Rev 964 | Rev 1063 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
221 | giacomo | 1 | //===================================================================== |
2 | // FFFFFFIII RRRRR SSTTTTTTT |
||
3 | // FF IIR RR SS |
||
4 | // FF IR SS |
||
5 | // FFFFFF RRRR SSSSST |
||
6 | // FF FI RRR SS |
||
7 | // FF II RRR SS |
||
8 | // FF IIIIIR RS |
||
9 | // |
||
10 | // Basic FSF(FIRST Scheduling Framework) contract management |
||
11 | // S.Ha.R.K. Implementation |
||
12 | //===================================================================== |
||
13 | |||
908 | trimarchi | 14 | #include "fsf.h" |
808 | trimarchi | 15 | #include "fsf_server.h" |
16 | #include <kernel/descr.h> |
||
17 | #include <kernel/func.h> |
||
18 | #include <pistar.h> |
||
989 | trimarchi | 19 | #include <ll/i386/string.h> |
221 | giacomo | 20 | |
989 | trimarchi | 21 | #define MAX_SHARED_NAME 15 |
22 | |||
808 | trimarchi | 23 | struct hash_entry { |
24 | mutex_t mx; |
||
989 | trimarchi | 25 | char shared_obj_name[MAX_SHARED_NAME]; |
868 | trimarchi | 26 | FSF_SHARED_OBJ_HANDLE_T_OPAQUE id; |
808 | trimarchi | 27 | }; |
28 | |||
29 | |||
868 | trimarchi | 30 | #define MAX_HASH_ENTRY FSF_MAX_N_SHARED_OBJECTS |
808 | trimarchi | 31 | struct hash_entry htable[MAX_HASH_ENTRY]; |
32 | |||
33 | |||
34 | /*----------------------------------------------------------------------*/ |
||
35 | /* hash_fun() : address hash table */ |
||
36 | /*----------------------------------------------------------------------*/ |
||
868 | trimarchi | 37 | static int hash_fun(fsf_shared_obj_id_t id) |
808 | trimarchi | 38 | { |
39 | return (*id % MAX_HASH_ENTRY); |
||
40 | } |
||
41 | |||
811 | trimarchi | 42 | void fsf_register_shared_object(void) { |
43 | int i=0; |
||
44 | // Init Hash table |
||
45 | //kern_printf("(IT SO)\n"); |
||
46 | for (i=0; i<MAX_HASH_ENTRY; i++) { |
||
47 | htable[i].id=-1; |
||
808 | trimarchi | 48 | |
811 | trimarchi | 49 | } |
50 | |||
51 | } |
||
881 | trimarchi | 52 | int fsf_init() { |
811 | trimarchi | 53 | |
881 | trimarchi | 54 | FSF_start_service_task(); |
941 | trimarchi | 55 | FSF_init_synch_obj_layer(); |
964 | trimarchi | 56 | return 0; |
881 | trimarchi | 57 | } |
58 | |||
59 | |||
221 | giacomo | 60 | int fsf_initialize_contract |
61 | (fsf_contract_parameters_t *contract) |
||
62 | { |
||
63 | struct timespec default_deadline = FSF_DEFAULT_DEADLINE; |
||
64 | |||
65 | /* Check */ |
||
868 | trimarchi | 66 | if (!contract) return FSF_ERR_BAD_ARGUMENT; |
221 | giacomo | 67 | |
68 | /* Set to default value */ |
||
69 | NULL_TIMESPEC(&contract->budget_min); |
||
70 | NULL_TIMESPEC(&contract->budget_max); |
||
71 | NULL_TIMESPEC(&contract->period_min); |
||
72 | NULL_TIMESPEC(&contract->period_max); |
||
73 | |||
74 | contract->workload = FSF_DEFAULT_WORKLOAD; |
||
75 | |||
868 | trimarchi | 76 | contract->policy = FSF_DEFAULT_SCHED_POLICY; |
221 | giacomo | 77 | |
78 | contract->d_equals_t = FSF_DEFAULT_D_EQUALS_T; |
||
79 | |||
80 | TIMESPEC_ASSIGN(&contract->deadline,&default_deadline); |
||
81 | |||
82 | contract->budget_overrun_sig_notify = 0; |
||
83 | memset(&contract->budget_overrun_sig_value,0,sizeof(union sigval)); |
||
84 | |||
85 | contract->deadline_miss_sig_notify = 0; |
||
86 | memset(&contract->deadline_miss_sig_value,0,sizeof(union sigval)); |
||
87 | |||
88 | contract->granularity = FSF_DEFAULT_GRANULARITY; |
||
89 | contract->utilization_set.size = 0; |
||
90 | contract->quality = FSF_DEFAULT_QUALITY; |
||
91 | contract->importance = FSF_DEFAULT_IMPORTANCE; |
||
92 | |||
93 | contract->preemption_level = 0; |
||
94 | contract->critical_sections.size = 0; |
||
95 | |||
96 | return 0; |
||
97 | |||
98 | } |
||
99 | |||
100 | int fsf_set_contract_basic_parameters |
||
101 | (fsf_contract_parameters_t *contract, |
||
102 | const struct timespec *budget_min, |
||
868 | trimarchi | 103 | const struct timespec *period_max, |
221 | giacomo | 104 | fsf_workload_t workload) |
105 | { |
||
106 | |||
868 | trimarchi | 107 | if (!contract) return FSF_ERR_BAD_ARGUMENT; |
221 | giacomo | 108 | |
940 | trimarchi | 109 | if (budget_min->tv_sec < 0 || budget_min->tv_nsec > 1000000000) |
110 | return FSF_ERR_BAD_ARGUMENT; |
||
111 | |||
112 | if (period_max->tv_sec < 0 || period_max->tv_nsec > 1000000000) |
||
113 | return FSF_ERR_BAD_ARGUMENT; |
||
114 | |||
874 | trimarchi | 115 | if (budget_min && (budget_min->tv_sec!=0 || budget_min->tv_nsec!=0)) { |
868 | trimarchi | 116 | TIMESPEC_ASSIGN(&contract->budget_min,budget_min); |
117 | TIMESPEC_ASSIGN(&contract->budget_max,budget_min); |
||
874 | trimarchi | 118 | } else return FSF_ERR_BAD_ARGUMENT; |
119 | |||
120 | if (period_max && (period_max->tv_sec!=0 || period_max->tv_nsec!=0)) { |
||
868 | trimarchi | 121 | TIMESPEC_ASSIGN(&contract->period_max,period_max); |
122 | TIMESPEC_ASSIGN(&contract->period_min,period_max); |
||
874 | trimarchi | 123 | } else return FSF_ERR_BAD_ARGUMENT; |
124 | |||
125 | switch(workload) { |
||
126 | case FSF_INDETERMINATE: |
||
127 | case FSF_BOUNDED: |
||
128 | case FSF_OVERHEAD: |
||
129 | contract->workload = workload; |
||
130 | break; |
||
131 | default: return FSF_ERR_BAD_ARGUMENT; |
||
868 | trimarchi | 132 | } |
221 | giacomo | 133 | |
874 | trimarchi | 134 | |
221 | giacomo | 135 | return 0; |
136 | |||
137 | } |
||
138 | |||
139 | int fsf_get_contract_basic_parameters |
||
140 | (const fsf_contract_parameters_t *contract, |
||
141 | struct timespec *budget_min, |
||
142 | struct timespec *period_max, |
||
143 | fsf_workload_t *workload) |
||
144 | { |
||
145 | |||
874 | trimarchi | 146 | if (!contract) return FSF_ERR_BAD_ARGUMENT; |
221 | giacomo | 147 | |
148 | TIMESPEC_ASSIGN(budget_min,&contract->budget_min); |
||
868 | trimarchi | 149 | TIMESPEC_ASSIGN(period_max,&contract->period_max); |
221 | giacomo | 150 | |
151 | *workload = contract->workload; |
||
152 | |||
153 | return 0; |
||
154 | |||
155 | } |
||
156 | |||
157 | int fsf_set_contract_timing_requirements |
||
158 | (fsf_contract_parameters_t *contract, |
||
159 | bool d_equals_t, |
||
160 | const struct timespec *deadline, |
||
161 | int budget_overrun_sig_notify, |
||
162 | union sigval budget_overrun_sig_value, |
||
163 | int deadline_miss_sig_notify, |
||
164 | union sigval deadline_miss_sig_value) |
||
165 | { |
||
166 | |||
868 | trimarchi | 167 | if (!contract) return FSF_ERR_BAD_ARGUMENT; |
908 | trimarchi | 168 | if ((d_equals_t==true && deadline != FSF_NULL_DEADLINE) || |
169 | (d_equals_t==false && deadline == FSF_NULL_DEADLINE)) |
||
874 | trimarchi | 170 | return FSF_ERR_BAD_ARGUMENT; |
908 | trimarchi | 171 | if (deadline != FSF_NULL_DEADLINE && TIMESPEC_A_GT_B(deadline, &contract->period_max)) |
874 | trimarchi | 172 | return FSF_ERR_BAD_ARGUMENT; |
221 | giacomo | 173 | |
174 | contract->d_equals_t = d_equals_t; |
||
175 | |||
176 | if (deadline) TIMESPEC_ASSIGN(&contract->deadline,deadline); |
||
177 | |||
178 | contract->budget_overrun_sig_notify = budget_overrun_sig_notify; |
||
179 | contract->budget_overrun_sig_value = budget_overrun_sig_value; |
||
180 | contract->deadline_miss_sig_notify = deadline_miss_sig_notify; |
||
181 | contract->deadline_miss_sig_value = deadline_miss_sig_value; |
||
182 | |||
183 | return 0; |
||
184 | |||
185 | } |
||
186 | |||
187 | int fsf_get_contract_timing_requirements |
||
188 | (const fsf_contract_parameters_t *contract, |
||
189 | bool *d_equals_t, |
||
190 | struct timespec *deadline, |
||
191 | int *budget_overrun_sig_notify, |
||
192 | union sigval *budget_overrun_sig_value, |
||
193 | int *deadline_miss_sig_notify, |
||
194 | union sigval *deadline_miss_sig_value) |
||
195 | { |
||
196 | |||
868 | trimarchi | 197 | if (!contract) return FSF_ERR_BAD_ARGUMENT; |
221 | giacomo | 198 | |
199 | *d_equals_t = contract->d_equals_t; |
||
200 | |||
201 | TIMESPEC_ASSIGN(deadline,&contract->deadline); |
||
202 | |||
203 | *budget_overrun_sig_notify = contract->budget_overrun_sig_notify; |
||
204 | *budget_overrun_sig_value = contract->budget_overrun_sig_value; |
||
205 | *deadline_miss_sig_notify = contract->deadline_miss_sig_notify; |
||
206 | *deadline_miss_sig_value = contract->deadline_miss_sig_value; |
||
207 | |||
208 | return 0; |
||
209 | |||
210 | } |
||
211 | |||
868 | trimarchi | 212 | int |
213 | fsf_set_contract_reclamation_parameters |
||
214 | (fsf_contract_parameters_t *contract, |
||
215 | const struct timespec *budget_max, |
||
216 | const struct timespec *period_min, |
||
221 | giacomo | 217 | fsf_granularity_t granularity, |
868 | trimarchi | 218 | const fsf_utilization_set_t *utilization_set, |
221 | giacomo | 219 | int quality, |
220 | int importance) |
||
221 | { |
||
222 | |||
868 | trimarchi | 223 | if (!contract) return FSF_ERR_BAD_ARGUMENT; |
221 | giacomo | 224 | |
940 | trimarchi | 225 | if (budget_max->tv_sec < 0 || budget_max->tv_nsec > 1000000000) |
226 | return FSF_ERR_BAD_ARGUMENT; |
||
227 | |||
228 | if (period_min->tv_sec < 0 || period_min->tv_nsec > 1000000000) |
||
229 | return FSF_ERR_BAD_ARGUMENT; |
||
230 | |||
221 | giacomo | 231 | contract->granularity = granularity; |
232 | |||
233 | if (utilization_set) memcpy(&contract->utilization_set,utilization_set,sizeof(fsf_utilization_set_t)); |
||
868 | trimarchi | 234 | |
235 | if (budget_max) TIMESPEC_ASSIGN(&contract->budget_max,budget_max); |
||
236 | if (period_min) TIMESPEC_ASSIGN(&contract->period_min,period_min); |
||
237 | |||
221 | giacomo | 238 | contract->quality = quality; |
239 | contract->importance = importance; |
||
240 | |||
241 | return 0; |
||
242 | |||
243 | } |
||
244 | |||
245 | int fsf_get_contract_reclamation_parameters |
||
246 | (const fsf_contract_parameters_t *contract, |
||
868 | trimarchi | 247 | struct timespec *budget_max, |
248 | struct timespec *period_min, |
||
221 | giacomo | 249 | fsf_granularity_t *granularity, |
250 | fsf_utilization_set_t *utilization_set, |
||
251 | int *quality, |
||
252 | int *importance) |
||
253 | { |
||
254 | |||
868 | trimarchi | 255 | if (!contract) return FSF_ERR_BAD_ARGUMENT; |
221 | giacomo | 256 | |
257 | *granularity = contract->granularity; |
||
964 | trimarchi | 258 | if (utilization_set) |
259 | memcpy(utilization_set,&contract->utilization_set,sizeof(fsf_utilization_set_t)); |
||
868 | trimarchi | 260 | |
261 | TIMESPEC_ASSIGN(budget_max,&contract->budget_max); |
||
262 | TIMESPEC_ASSIGN(period_min,&contract->period_min); |
||
221 | giacomo | 263 | |
264 | *quality = contract->quality; |
||
265 | *importance = contract->importance; |
||
266 | |||
267 | return 0; |
||
268 | |||
269 | } |
||
270 | |||
271 | int fsf_set_contract_synchronization_parameters |
||
272 | (fsf_contract_parameters_t *contract, |
||
273 | const fsf_critical_sections_t *critical_sections) |
||
274 | { |
||
275 | |||
868 | trimarchi | 276 | if (!contract) return FSF_ERR_BAD_ARGUMENT; |
221 | giacomo | 277 | |
278 | if (critical_sections) memcpy(&contract->critical_sections,critical_sections,sizeof(fsf_critical_sections_t)); |
||
279 | |||
280 | return 0; |
||
281 | |||
282 | } |
||
283 | |||
284 | int |
||
285 | fsf_get_contract_synchronization_parameters |
||
286 | (const fsf_contract_parameters_t *contract, |
||
287 | fsf_critical_sections_t *critical_sections) |
||
288 | { |
||
289 | |||
868 | trimarchi | 290 | if (!contract) return FSF_ERR_BAD_ARGUMENT; |
964 | trimarchi | 291 | if (critical_sections) |
292 | memcpy(critical_sections,&contract->critical_sections,sizeof(fsf_critical_sections_t)); |
||
868 | trimarchi | 293 | |
221 | giacomo | 294 | return 0; |
295 | |||
296 | } |
||
297 | |||
868 | trimarchi | 298 | int |
299 | fsf_set_contract_scheduling_policy |
||
221 | giacomo | 300 | (fsf_contract_parameters_t *contract, |
868 | trimarchi | 301 | fsf_sched_policy_t sched_policy) |
221 | giacomo | 302 | { |
303 | |||
868 | trimarchi | 304 | if (!contract) return FSF_ERR_BAD_ARGUMENT; |
221 | giacomo | 305 | |
868 | trimarchi | 306 | contract->policy = sched_policy; |
221 | giacomo | 307 | |
308 | return 0; |
||
309 | |||
310 | } |
||
311 | |||
312 | int |
||
868 | trimarchi | 313 | fsf_get_contract_scheduling_policy |
221 | giacomo | 314 | (const fsf_contract_parameters_t *contract, |
868 | trimarchi | 315 | fsf_sched_policy_t *sched_policy) |
221 | giacomo | 316 | { |
317 | |||
868 | trimarchi | 318 | if (!contract) return FSF_ERR_BAD_ARGUMENT; |
221 | giacomo | 319 | |
868 | trimarchi | 320 | *sched_policy = contract->policy; |
221 | giacomo | 321 | |
322 | return 0; |
||
323 | |||
324 | } |
||
325 | |||
868 | trimarchi | 326 | /* OLD VERSION |
808 | trimarchi | 327 | // mutex lock function |
221 | giacomo | 328 | |
808 | trimarchi | 329 | int fsf_lock_object(fsf_shared_operation_t *op) { |
330 | int index, oldindex; |
||
811 | trimarchi | 331 | |
332 | index=hash_fun(&(op->obj_id)); |
||
333 | //kern_printf("index %d, htableid %d, obj_op_id %d", index, htable[index].id,op->obj_id); |
||
221 | giacomo | 334 | |
808 | trimarchi | 335 | if (htable[index].id!=op->obj_id) { |
336 | oldindex=index; |
||
337 | index = (index + 1) % MAX_HASH_ENTRY; |
||
338 | // find |
||
811 | trimarchi | 339 | while (htable[index].id != op->obj_id && index!=oldindex) index=(index+1) % MAX_HASH_ENTRY; |
808 | trimarchi | 340 | if (index==oldindex) return -1; |
341 | } |
||
811 | trimarchi | 342 | //kern_printf("(SO LK)"); |
808 | trimarchi | 343 | // we need a special implementation for mutex_lock ... additional parameter |
829 | giacomo | 344 | return PISTAR_lock(FSF_get_shared_object_level(), &htable[index].mx,TIMESPEC2USEC(&op->wcet)); |
808 | trimarchi | 345 | |
346 | } |
||
347 | |||
348 | int fsf_unlock_object(fsf_shared_operation_t *op) { |
||
349 | |||
350 | int index, oldindex; |
||
351 | |||
352 | index=hash_fun(&op->obj_id); |
||
353 | |||
354 | if (htable[index].id!=op->obj_id) { |
||
355 | oldindex=index; |
||
356 | index = (index + 1) % MAX_HASH_ENTRY; |
||
357 | // find |
||
811 | trimarchi | 358 | while (htable[index].id != op->obj_id && index!=oldindex) index=(index+1) % MAX_HASH_ENTRY; |
808 | trimarchi | 359 | if (index==oldindex) return -1; |
360 | } |
||
811 | trimarchi | 361 | //kern_printf("UNLOCK index %d", index); |
362 | |||
808 | trimarchi | 363 | return mutex_unlock(&htable[index].mx); |
364 | |||
365 | |||
366 | |||
367 | } |
||
368 | |||
868 | trimarchi | 369 | */ |
370 | |||
989 | trimarchi | 371 | |
372 | int fsf_get_shared_object_handle |
||
373 | (fsf_shared_obj_id_t obj_id, |
||
374 | fsf_shared_obj_handle_t *obj_handle) { |
||
375 | int index; |
||
376 | int oldindex; |
||
377 | SYS_FLAGS f; |
||
378 | |||
379 | f=kern_fsave(); |
||
380 | |||
381 | index=hash_fun(obj_id); |
||
382 | |||
383 | if (strcmp(htable[index].shared_obj_name,obj_id) == 0) { |
||
384 | kern_frestore(f); |
||
385 | return index; |
||
386 | } |
||
387 | |||
388 | if (htable[index].id!=0) { |
||
389 | oldindex=index; |
||
390 | index = (index + 1) % MAX_HASH_ENTRY; |
||
391 | // collision detection |
||
392 | while (htable[index].id !=0 && index!=oldindex) { |
||
393 | if (strcmp(htable[index].shared_obj_name,obj_id) == 0) { |
||
394 | kern_frestore(f); |
||
395 | return index; |
||
396 | } |
||
397 | index=(index+1) % MAX_HASH_ENTRY; |
||
398 | } |
||
399 | |||
400 | // table is full |
||
401 | if (index==oldindex) { |
||
402 | kern_frestore(f); |
||
403 | return -1; |
||
404 | } |
||
405 | } |
||
406 | |||
407 | kern_frestore(f); |
||
408 | return -1; |
||
409 | |||
410 | } |
||
411 | |||
412 | |||
413 | |||
868 | trimarchi | 414 | int fsf_init_shared_object |
415 | (fsf_shared_obj_id_t id, |
||
416 | fsf_shared_obj_handle_t *obj, |
||
417 | pthread_mutex_t *mutex) { |
||
808 | trimarchi | 418 | int index; |
419 | int oldindex; |
||
420 | PISTAR_mutexattr_t a; |
||
811 | trimarchi | 421 | SYS_FLAGS f; |
808 | trimarchi | 422 | |
423 | PISTAR_mutexattr_default(a); |
||
811 | trimarchi | 424 | //kern_printf("(SI SO)\n"); |
425 | f=kern_fsave(); |
||
829 | giacomo | 426 | |
868 | trimarchi | 427 | index=hash_fun(id); |
811 | trimarchi | 428 | //kern_printf("Index %d Hash %d", index, htable[index].id); |
829 | giacomo | 429 | |
989 | trimarchi | 430 | if (strcmp(htable[index].shared_obj_name,id) == 0) { |
829 | giacomo | 431 | kern_frestore(f); |
432 | return -1; |
||
433 | } |
||
434 | |||
989 | trimarchi | 435 | if (htable[index].id!=0) { |
808 | trimarchi | 436 | oldindex=index; |
437 | index = (index + 1) % MAX_HASH_ENTRY; |
||
438 | // collision detection |
||
989 | trimarchi | 439 | while (htable[index].id !=0 && index!=oldindex) index=(index+1) % MAX_HASH_ENTRY; |
808 | trimarchi | 440 | // table is full |
825 | trimarchi | 441 | if (index==oldindex) { |
442 | kern_frestore(f); |
||
829 | giacomo | 443 | return -1; |
825 | trimarchi | 444 | } |
808 | trimarchi | 445 | } |
829 | giacomo | 446 | |
868 | trimarchi | 447 | //obj->size=0; |
829 | giacomo | 448 | |
808 | trimarchi | 449 | mutex_init(&(htable[index]).mx, &a); |
868 | trimarchi | 450 | mutex=&(htable[index]).mx; |
989 | trimarchi | 451 | strncpy(htable[index].shared_obj_name, id,MAX_SHARED_NAME); |
452 | *obj=index; |
||
811 | trimarchi | 453 | kern_frestore(f); |
829 | giacomo | 454 | |
455 | return 0; |
||
456 | |||
811 | trimarchi | 457 | //kern_printf("(EI SO)\n"); |
808 | trimarchi | 458 | } |
459 | |||
868 | trimarchi | 460 | /* OLD VERSION |
808 | trimarchi | 461 | // Declare an operation |
462 | // This function is used to declare that a shared object has |
||
463 | // a synchronized operation on it. |
||
464 | // It checks if another operation with the same id has already been |
||
465 | // declared; if so, return false (-1). |
||
466 | // The obj_id field of the operation is set equal to the shared object id. |
||
467 | // the structure op is copied in the first free element in the array |
||
468 | // shared_op pof the structure obj. If there are no more free element, |
||
469 | // returns -1. |
||
470 | // Returns 0 if the operation has been completed, -1 otherwise. |
||
471 | |||
472 | int fsf_declare_shared_object_operation(fsf_shared_object_t *obj, |
||
473 | fsf_shared_operation_t *op) { |
||
474 | int i; |
||
825 | trimarchi | 475 | SYS_FLAGS f; |
476 | |||
477 | f=kern_fsave(); |
||
478 | |||
808 | trimarchi | 479 | for (i=0; i<obj->size; i++) { |
480 | // fail if the operation already declared |
||
825 | trimarchi | 481 | if (op->op_id==obj->shared_op[i].op_id) { |
482 | kern_frestore(f); |
||
808 | trimarchi | 483 | return -1; |
825 | trimarchi | 484 | } |
808 | trimarchi | 485 | } |
486 | |||
487 | // fail if the object is full |
||
825 | trimarchi | 488 | if (obj->size>(FSF_MAX_SHARED_OPERATION-1)) { |
489 | kern_frestore(f); |
||
808 | trimarchi | 490 | return -1; |
825 | trimarchi | 491 | } |
829 | giacomo | 492 | |
823 | trimarchi | 493 | //kern_printf("(DO SO)"); |
808 | trimarchi | 494 | obj->size++; |
829 | giacomo | 495 | obj->shared_op[i].op_id = op->op_id; |
496 | TIMESPEC_ASSIGN(&obj->shared_op[i].wcet,&op->wcet); |
||
497 | obj->shared_op[i].obj_id = obj->obj_id; |
||
498 | op->obj_id = obj->obj_id; |
||
499 | |||
825 | trimarchi | 500 | kern_frestore(f); |
829 | giacomo | 501 | |
808 | trimarchi | 502 | return 0; |
503 | |||
504 | |||
505 | } |
||
868 | trimarchi | 506 | */ |
808 | trimarchi | 507 | |
868 | trimarchi | 508 | /* OLD VERSION |
808 | trimarchi | 509 | int fsf_set_contract_synchronization_parameters( |
510 | fsf_contract_parameters_t *contract, |
||
511 | const fsf_shared_operation_t *shared_ops, |
||
512 | size_t op_num) |
||
513 | { |
||
514 | if (shared_ops && op_num < FSF_MAX_SHARED_OPERATION) |
||
515 | memcpy(&contract->shared_operations,shared_ops,op_num); |
||
516 | else return -1; |
||
517 | |||
518 | return 0; |
||
519 | } |
||
868 | trimarchi | 520 | */ |
954 | trimarchi | 521 | |
522 | // MARTE IMPLEMENTATION SPECIFIC MODULE |
||
523 | |||
524 | // The operations defined in this module are of optional use. They |
||
525 | // only work in the fixed priority implementation, and they may be |
||
526 | // used to enhance the behavior of the applications running under the |
||
527 | // fsf scheduler. |
||
528 | |||
529 | //// The definition of this type is in fsf_basic_types.h |
||
530 | // |
||
531 | //typedef unsigned long fsf_preemption_level_t; |
||
532 | // // range 1..2**32-1 |
||
533 | |||
534 | |||
535 | //fsf_set_contract_preemption_level: The operation updates the |
||
536 | //specified contract parameters object by setting its preemption level |
||
537 | //to the specified input parameter. |
||
538 | |||
539 | int |
||
540 | fsf_set_contract_preemption_level |
||
541 | (fsf_contract_parameters_t *contract, |
||
542 | fsf_preemption_level_t preemption_level) { |
||
543 | return 0; |
||
544 | } |
||
545 | |||
546 | |||
547 | //fsf_get_contract_preemption_level: The operation obtains from the |
||
548 | //specified contract parameters object its preemption level and copies |
||
549 | //it to the place pointed to by the specified input parameter. |
||
550 | |||
551 | int |
||
552 | fsf_get_contract_preemption_level |
||
553 | (const fsf_contract_parameters_t *contract, |
||
554 | fsf_preemption_level_t *preemption_level) { |
||
555 | return 0; |
||
556 | } |
||
557 | |||
558 | |||
559 | |||
560 | //fsf_set_service_thread_preemption_level: this function sets the |
||
561 | //preemption level of the service thread to the specified value. The |
||
562 | //initial preemption level is a configurable parameter |
||
563 | |||
564 | int |
||
565 | fsf_set_service_thread_preemption_level |
||
566 | (fsf_preemption_level_t preemption_level) { |
||
567 | return 0; |
||
568 | } |
||
569 | |||
570 | |||
571 | //fsf_get_service_thread_preemption_level: this function stores the |
||
572 | //current preemption level of the service thread in the variable |
||
573 | //pointed to by preemption_level |
||
574 | |||
575 | int |
||
576 | fsf_get_service_thread_preemption_level |
||
577 | (fsf_preemption_level_t *preemption_level) { |
||
578 | return 0; |
||
579 | } |
||
580 | |||
581 | |||
582 | |||
583 | //fsf_thread_exit: There is a limitation in the current version of the |
||
584 | //MaRTE implementation that causes the information of a terminated |
||
585 | //thread to continue to be stored in the fsf scheduler, and the thread |
||
586 | //to continue to be counted in the number of threads. The |
||
587 | //fsf_thread_exit operation allows the implementation to delete the |
||
588 | //thread's information, and then terminate the thread. Therefore, it |
||
589 | //is recommended to use this function to terminate a thread under fsf. |
||
590 | |||
591 | //This operation shall terminate the calling thread, make the value |
||
592 | //value_ptr available to any successful join with the terminating |
||
593 | //thread, and unbind the thread from its associated server. After |
||
594 | //cleaning up the thread management data, it is unbound and the |
||
595 | //scheduling policy is changed to fixed priority before the posix |
||
596 | //pthread_exit() function is called. |
||
597 | |||
598 | void |
||
599 | fsf_thread_exit (void *value_ptr) { |
||
600 | return; |
||
601 | } |
||
602 | |||
603 | |||
604 | |||
605 | //fsf_set_shared_obj_preemption_level: The operation updates the |
||
606 | //specified shared object by setting its preemption level |
||
607 | //to the specified input parameter. |
||
608 | //OBSERVATION: if this value is changed being any contract that |
||
609 | //uses the resource already accepted, the system's behavior and |
||
610 | //particularly the acceptance tests correctness are not garantee |
||
611 | //and probably wrong. |
||
612 | |||
613 | int |
||
614 | fsf_set_shared_obj_preemption_level |
||
615 | (fsf_shared_obj_handle_t obj_handle, |
||
616 | fsf_preemption_level_t preemption_level) { |
||
617 | return 0; |
||
618 | } |
||
619 | |||
620 | |||
621 | |||
622 | //fsf_get_shared_obj_preemption_level: The operation obtains from the |
||
623 | //specified shared object its preemption level and copies |
||
624 | //it to the place pointed to by the specified input parameter. |
||
625 | |||
626 | int |
||
627 | fsf_get_shared_obj_preemption_level |
||
628 | (fsf_shared_obj_handle_t obj_handle, |
||
629 | fsf_preemption_level_t *preemption_level) { |
||
630 | return 0; |
||
631 | } |