Rev 929 | Rev 983 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
881 | trimarchi | 1 | //fsf_core.h |
2 | //================================================================= |
||
3 | // FFFFFFIII RRRRR SSTTTTTTT |
||
4 | // FF IIR RR SS |
||
5 | // FF IR SS |
||
6 | // FFFFFF RRRR SSSSST |
||
7 | // FF FI RRR SS |
||
8 | // FF II RRR SS |
||
9 | // FF IIIIIR RS |
||
10 | // |
||
11 | // Basic FSF(FIRST Scheduling Framework) contract management |
||
12 | //================================================================ |
||
13 | |||
974 | trimarchi | 14 | /** |
15 | \defgroup core Core module |
||
929 | lipari | 16 | |
974 | trimarchi | 17 | This module includes the basic functions and services that are |
18 | provided by any FSF implementation. This module includes basic type |
||
19 | definitions, and functions to |
||
20 | |||
21 | - create a contract and initialize it |
||
22 | - set/get the basci parameters of a contract |
||
23 | - negotiate a service contract, obtaining a server id |
||
24 | - create and bind threads to servers |
||
25 | - create/destroy a synchronization object |
||
26 | - manage bounded workloads |
||
27 | */ |
||
28 | /*@{*/ |
||
29 | |||
30 | /** |
||
31 | \file fsf_core.h |
||
32 | |||
33 | This file contains the types, definitions and function prototypes |
||
34 | for the core module of the First Scheduling Framework. |
||
35 | */ |
||
36 | |||
881 | trimarchi | 37 | #include <time.h> |
38 | #include <pthread.h> |
||
39 | #include <sys/types.h> |
||
974 | trimarchi | 40 | #include "stdbool.h" |
881 | trimarchi | 41 | |
42 | #include "fsf_configuration_parameters.h" |
||
43 | #include "fsf_opaque_types.h" |
||
44 | #include "fsf_basic_types.h" |
||
45 | |||
46 | #ifndef _FSF_CORE_H_ |
||
47 | #define _FSF_CORE_H_ |
||
48 | |||
49 | |||
974 | trimarchi | 50 | ///////////////////////////////////////////////////////////////// |
51 | // BASIC TYPES AND CONSTANTS are in fsf_basic_types.h |
||
52 | ///////////////////////////////////////////////////////////////// |
||
881 | trimarchi | 53 | |
54 | |||
928 | trimarchi | 55 | |
881 | trimarchi | 56 | /** |
57 | This function converts an error code to an error message that is |
||
58 | stored in the buffer starting at the location pointed to by |
||
59 | message. The size of this buffer is specified by the size |
||
60 | argument. If the error message is longer than size-1, it is |
||
61 | truncated to that length. Regardless of whether the message is |
||
62 | truncated or not, a final zero character that marks the end of the |
||
63 | string is stored in the buffer. The function fails if the error |
||
64 | code passed does not correspond to any of the fsf error codes. |
||
974 | trimarchi | 65 | [ERR@RETURNED: |
66 | FSF_ERR_BAD_ARGUMENT : error is not a valid value |
||
67 | ] |
||
881 | trimarchi | 68 | */ |
69 | int fsf_strerror (int error, char *message, size_t size); |
||
70 | |||
71 | ///////////////////////////////////////////////////////////// |
||
72 | // CONTRACT PARAMETERS |
||
73 | ///////////////////////////////////////////////////////////// |
||
74 | |||
75 | /** |
||
974 | trimarchi | 76 | \defgroup contract Contract Creation and Initialization. |
881 | trimarchi | 77 | |
78 | These functions are used to create and initialize a contract, and |
||
79 | set its parameters. |
||
80 | */ |
||
81 | /*@{*/ |
||
82 | /** |
||
83 | Contract parameters type; it is an opaque type (i.e. the internal |
||
84 | structure of this data type is implementation dependent). The user |
||
85 | can access and modify the parameters of a contract only with the |
||
86 | proper functions, and should never access the data directly. |
||
87 | */ |
||
88 | typedef FSF_CONTRACT_PARAMETERS_T_OPAQUE fsf_contract_parameters_t; |
||
89 | |||
90 | /** |
||
91 | The operation receives a pointer to a contract parameters object |
||
92 | and initializes it, setting it to the default values. |
||
93 | The default values are: |
||
974 | trimarchi | 94 | - budget min and max are set to 0 |
95 | - period min and max are set to 0 |
||
96 | - the workload is unbounded (FSF_INDETERMINATE) |
||
97 | - the server deadline is equal to the period |
||
98 | - the budget and deadline overrun are not notified |
||
99 | - the granularity is set to "continuous" |
||
100 | - the quality and importance are set to the default values |
||
101 | (PEPPE: implementation dependent??) |
||
102 | - the scheduling policy is FSF_NONE |
||
881 | trimarchi | 103 | |
104 | @param contract the pointer to the contract variable. |
||
974 | trimarchi | 105 | @returns (PEPPE: should not return anything! change to void??) |
106 | [ERR@RETURNED: |
||
107 | FSF_ERR_BAD_ARGUMENT : contract is NULL |
||
108 | ] |
||
881 | trimarchi | 109 | */ |
110 | int fsf_initialize_contract (fsf_contract_parameters_t *contract); |
||
111 | |||
112 | // budget_min => {0,0}; |
||
113 | // period_max => {0,0}; |
||
114 | // budget_max => {0,0}; |
||
115 | // period_min => {0,0}; |
||
116 | // workload => DEFAULT_WORKLOAD; |
||
117 | |||
118 | // d_equals_t => DEFAULT_D_EQUALS_T; (false or true) |
||
119 | // deadline => DEFAULT_DEADLINE; |
||
120 | // budget_overrun_sig_notify => 0; (signal number) |
||
121 | // budget_overrun_sig_value => {0, NULL}; |
||
122 | // deadline_miss_sig_notify => 0; (signal number) |
||
123 | // deadline_miss_sig_value => {0, NULL}; |
||
124 | // |
||
125 | // granularity => DEFAULT_GRANULARITY; |
||
126 | // utilization_set; => size = 0 |
||
127 | // quality => DEFAULT_QUALITY; (range 0..100) |
||
128 | // importance => DEFAULT_IMPORTANCE; (range 1..5) |
||
129 | // |
||
130 | // preemption_level => 0; (range 1..2**32-1) |
||
131 | // critical_sections; => size = 0 |
||
132 | |||
133 | // sched_policy => DEFAULT_SCHED_POLICY |
||
134 | // (FSF_NONE) |
||
135 | |||
136 | |||
137 | /** |
||
138 | The operation updates the specified contract parameters object by |
||
139 | setting its budget, period, and workload to the specified input |
||
140 | parameters. (Note: the workload is a basic parameter because |
||
141 | bounded tasks are triggered by the scheduler (see the |
||
142 | fsf_schedule_timed_job() operation), while indeterminate tasks are |
||
143 | not; therefore, their programming model is quite different). |
||
144 | |||
974 | trimarchi | 145 | @param contract the pointer to the contract object |
881 | trimarchi | 146 | @param [in] budget_min the minimum budget for the contract |
147 | @param [in] period_max the maximum period for the contract |
||
974 | trimarchi | 148 | @param [in] workload the kind of workload (can be FSF_BOUNDED, |
149 | FSF_INDETERMINATE or FSF_OVERHEAD) |
||
881 | trimarchi | 150 | |
974 | trimarchi | 151 | @returns 0 if the operation is succesful |
152 | @returns FSF_ERR_BAD_ARGUMENT if some of the arguments is not in |
||
153 | the expected range |
||
154 | [ERR@RETURNED: |
||
155 | FSF_ERR_BAD_ARGUMENT : if any of the pointers is NULL |
||
881 | trimarchi | 156 | or if only one of the timespec values is 0, and also if the workload |
974 | trimarchi | 157 | is not a proper value (FSF_INDETERMINATE, FSF_BOUNDED, or FSF_OVERHEAD) |
158 | ] |
||
881 | trimarchi | 159 | */ |
160 | int |
||
161 | fsf_set_contract_basic_parameters |
||
162 | (fsf_contract_parameters_t *contract, |
||
163 | const struct timespec *budget_min, |
||
164 | const struct timespec *period_max, |
||
165 | fsf_workload_t workload); |
||
166 | |||
974 | trimarchi | 167 | |
881 | trimarchi | 168 | /** |
169 | This operation obtains from the specified contract parameters |
||
170 | object its budget, period, and workload, and copies them to the |
||
171 | places pointed to by the corresponding input parameters. |
||
172 | |||
173 | @param [in] contract the pointer to the contract object |
||
174 | @param[out] budget_min pointer to the variable that will contain |
||
175 | the minimum budget |
||
176 | @param[out] period_max pointer to the variable that will contain the |
||
177 | max_period |
||
178 | @param[out] workload pointer to the variable that will contain the |
||
179 | workload type |
||
180 | |||
974 | trimarchi | 181 | @returns (PEPPE: this should return nothing!) |
182 | [ERR@RETURNED: |
||
183 | FSF_ERR_BAD_ARGUMENT : if contract is NULL |
||
184 | ] |
||
881 | trimarchi | 185 | */ |
186 | int |
||
187 | fsf_get_contract_basic_parameters |
||
188 | (const fsf_contract_parameters_t *contract, |
||
189 | struct timespec *budget_min, |
||
190 | struct timespec *period_max, |
||
191 | fsf_workload_t *workload); |
||
192 | |||
193 | |||
194 | /** |
||
195 | The operation updates the specified contract parameters |
||
196 | object, specifying the additional parameters requirements of |
||
197 | a contract. |
||
198 | |||
199 | @param contract The pointer to the contract object |
||
200 | |||
201 | @param [in] d_equals_t It is a boolean value, set to true (1) if the |
||
202 | we want to specify a deadline different from the period |
||
203 | for the contract. |
||
204 | @param [in] deadline If the previous parameter is set to true, |
||
205 | this parameter should be set to NULL_DEADLINE. Otherwise, |
||
206 | it contains the desired deadline value. |
||
207 | (PEPPE: should be return with error otherwise?) |
||
208 | @param [in] budget_overrun_sig_notify contains the number of posix signal |
||
209 | that must be raised if the budget of the server is overrun. |
||
210 | If the value of this parameter is NULL_SIGNAL, no signal will |
||
211 | be raised. |
||
212 | @param [in] budget_overrun_sig_value contains the value that will be |
||
213 | passed to the signal "catcher" when the signal is raised. |
||
214 | This parameters is not used if the budget_overrun_sig_notify |
||
215 | parameters is set to NULL_SIGNAL. |
||
216 | @param [in] deadline_miss_sig_notify contains the number of posix |
||
217 | signal that must be raised if the deadline of the server |
||
218 | is missed. If the value of this parameter is NULL_SIGNAL, |
||
219 | no signal is raised. |
||
220 | @param [in] deadline_miss_sig_value contains the value that will be |
||
221 | passed to the signal "catcher" when the signal is raised. |
||
222 | This parameters is not used if the budget_overrun_sig_notify |
||
223 | parameters is set to NULL_SIGNAL |
||
224 | |||
974 | trimarchi | 225 | @returns 0 if the operation is succesful |
226 | @returns FSF_BAD_ARGUMENT if some argument is out of range or not |
||
227 | admissible. |
||
228 | [ERR@RETURNED: |
||
229 | FSF_ERR_BAD_ARGUMENT : if contract is NULL or |
||
881 | trimarchi | 230 | (d_equals_t is true and deadline is not FSF_NULL_DEADLINE) or |
231 | (budget_overrun_sig_notify is not a valid signal) or |
||
232 | (deadline_miss_sig_notify is not a valid signal) or |
||
233 | (d_equals_t is false but (deadline is FSF_NULL_DEADLINE or its value |
||
974 | trimarchi | 234 | is grater than the contract´s maximum period))) |
235 | ] |
||
881 | trimarchi | 236 | |
237 | @see sigexplanation |
||
238 | */ |
||
239 | int |
||
240 | fsf_set_contract_timing_requirements |
||
241 | (fsf_contract_parameters_t *contract, |
||
242 | bool d_equals_t, |
||
243 | const struct timespec *deadline, |
||
244 | int budget_overrun_sig_notify, |
||
245 | union sigval budget_overrun_sig_value, |
||
246 | int deadline_miss_sig_notify, |
||
247 | union sigval deadline_miss_sig_value); |
||
248 | |||
249 | /** |
||
250 | The operation obtains the corresponding input parameters from the |
||
251 | specified contract parameters object. If d_equals_t is true, the |
||
252 | deadline will not be updated. |
||
253 | |||
974 | trimarchi | 254 | [ERR@RETURNED: |
255 | FSF_ERR_BAD_ARGUMENT : if contract is NULL |
||
256 | ] |
||
257 | |||
881 | trimarchi | 258 | */ |
259 | int |
||
260 | fsf_get_contract_timing_requirements |
||
261 | (const fsf_contract_parameters_t *contract, |
||
262 | bool *d_equals_t, |
||
263 | struct timespec *deadline, |
||
264 | int *budget_overrun_sig_notify, |
||
265 | union sigval *budget_overrun_sig_value, |
||
266 | int *deadline_miss_sig_notify, |
||
267 | union sigval *deadline_miss_sig_value); |
||
268 | |||
269 | /*@}*/ |
||
270 | |||
271 | ////////////////////////////////////////////////////////////////// |
||
272 | // SYNCHRONIZATION OBJECTS |
||
273 | ////////////////////////////////////////////////////////////////// |
||
274 | |||
275 | |||
276 | /** |
||
974 | trimarchi | 277 | \defgroup synch Synchronization objects |
881 | trimarchi | 278 | */ |
279 | /*@{*/ |
||
280 | /** |
||
281 | An abstract synchronization object is defined by the application. |
||
282 | This object can be used by an application to wait for an event to |
||
283 | arrive by invoking the fsf_schedule_triggered_job() operation. It |
||
284 | can also be used to signal the event either causing a waiting |
||
285 | server to wake up, or the event to be queued if no server is |
||
286 | waiting for it. |
||
287 | */ |
||
288 | typedef FSF_SYNCH_OBJ_HANDLE_T_OPAQUE fsf_synch_obj_handle_t; |
||
289 | |||
290 | |||
291 | /** |
||
292 | This operation creates and initializes a synchronization object |
||
293 | variable managed by the scheduler, and returns a handle to it in |
||
294 | the variable pointed to by synch_handle. |
||
295 | |||
974 | trimarchi | 296 | @param[out] pointer to the variable that will contain the handle to the |
297 | newly created synchronization object |
||
881 | trimarchi | 298 | |
974 | trimarchi | 299 | @returns 0 if the operation is succesful |
300 | @returns FSF_ERR_TOO_MANY_SYNCH_OBJS if the number of synchronization |
||
301 | objects in the system has already exceeded the maximum |
||
302 | [ERR@RETURNED: |
||
303 | FSF_ERR_BAD_ARGUMENT : if synch_handle is 0 |
||
304 | FSF_ERR_TOO_MANY_SYNCH_OBJS : if the number of synchronization |
||
305 | objects in the system has already exceeded the maximum |
||
306 | FSF_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not |
||
307 | scheduled under the FSF |
||
308 | FSF_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running |
||
309 | ] |
||
310 | |||
881 | trimarchi | 311 | */ |
312 | int |
||
313 | fsf_create_synch_obj |
||
314 | (fsf_synch_obj_handle_t *synch_handle); |
||
315 | |||
974 | trimarchi | 316 | |
928 | trimarchi | 317 | /** |
881 | trimarchi | 318 | This function sends a notification to the synchronization object |
974 | trimarchi | 319 | specified as parameter. If there is at least one thread waiting on |
320 | the synchronization object, it is awaken. If more than one thread |
||
321 | is waiting, just one of them is awaken. However, which one is |
||
322 | awaken is implementation dependent. If no thread is waiting on the |
||
323 | synchronization object, the notification is queued. |
||
881 | trimarchi | 324 | |
974 | trimarchi | 325 | [JULIO: all the ocurrrences of the word "thread" should be changed |
326 | by "server" in the paragraph above |
||
327 | ] |
||
881 | trimarchi | 328 | @param [in] synch_handle the handle of the synchronization object to |
329 | notify. |
||
330 | |||
974 | trimarchi | 331 | @returns 0 if the operation is completed succesfully |
332 | @returns FSF_ERR_INVALID_SYNCH_OBJ_HANDLE is the handle is not valid |
||
333 | [ERR@RETURNED: |
||
334 | FSF_ERR_BAD_ARGUMENT : if synch_handle is 0 |
||
335 | FSF_ERR_INVALID_SYNCH_OBJ_HANDLE if the handle is not valid |
||
336 | FSF_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not |
||
337 | scheduled under the FSF |
||
338 | FSF_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running |
||
339 | FSF_ERR_TOO_MANY_EVENTS_IN_SYNCH_OBJ : if the number of events stored |
||
340 | in the synchronization object reaches the maximum defined in the |
||
341 | configuration parameter header file |
||
342 | ] |
||
881 | trimarchi | 343 | |
974 | trimarchi | 344 | @sa fsf_schedule_triggered_job, fsf_timed_schedule_triggered_job |
881 | trimarchi | 345 | */ |
346 | int |
||
347 | fsf_signal_synch_obj |
||
348 | (fsf_synch_obj_handle_t synch_handle); |
||
349 | |||
350 | /** |
||
351 | This operation destroys the synchronization object (created by a |
||
352 | previous call to fsf_create_synch_obj) that is referenced by the |
||
353 | synch_handle variable. After calling this operation, the |
||
354 | synch_handle variable can not be used until it is initialized again |
||
355 | by a call to fsf_create_synch_obj. |
||
356 | |||
357 | @param synch_handle the handle to the synchronization object |
||
358 | to be destroyed |
||
359 | |||
974 | trimarchi | 360 | @returns 0 if the operation is succesful |
361 | @returns FSF_ERR_INVALID_SYNCH_OBJ_HANDLE is the handle is not valid |
||
362 | [ERR@RETURNED: |
||
363 | FSF_ERR_BAD_ARGUMENT : if synch_handle is 0 |
||
364 | FSF_ERR_INVALID_SYNCH_OBJ_HANDLE if the handle is not valid |
||
365 | FSF_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not |
||
881 | trimarchi | 366 | scheduled under the FSF |
974 | trimarchi | 367 | FSF_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running |
368 | ] |
||
881 | trimarchi | 369 | |
974 | trimarchi | 370 | @sa fsf_create_synch_obj |
881 | trimarchi | 371 | */ |
372 | int |
||
373 | fsf_destroy_synch_obj |
||
374 | (fsf_synch_obj_handle_t synch_handle); |
||
375 | |||
974 | trimarchi | 376 | // In the future we may add a broadcast operation that would signal a |
377 | // group of synchronization objects. We have not included a broadcast |
||
378 | // service in this version because it can be easily created by the |
||
379 | // user by signalling individual synchronization objects inside a |
||
380 | // loop. |
||
881 | trimarchi | 381 | |
974 | trimarchi | 382 | // Notice that for synchronization objects there is no naming service |
383 | // like in shared objects because tasks that use synchronization are |
||
384 | // not developed independently, as they are closely coupled. |
||
385 | |||
386 | |||
881 | trimarchi | 387 | //////////////////////////////////////////////////// |
388 | // SCHEDULING BOUNDED WORKLOADS |
||
389 | //////////////////////////////////////////////////// |
||
390 | |||
391 | /** |
||
392 | This operation is invoked by threads associated with bounded |
||
393 | workload servers to indicate that a job has been completed (and |
||
394 | that the scheduler may reassign the unused capacity of the current |
||
395 | job to other servers). It is also invoked when the first job of |
||
396 | such threads has to be scheduled. (PEPPE: I have a question, what |
||
397 | happens to the budget? if I do not get it wrong, the replenishment |
||
398 | time is set to abs_time and the bandwidth of the server up to time |
||
399 | abs_time can be reassigned. Is it true? what is the exact |
||
400 | relationship between this abs_time and the server period? What if |
||
401 | the user specifies an abs_time less than the end of the current |
||
402 | server period??) |
||
403 | |||
404 | As an effect, the system will make the current server's budget zero |
||
405 | for the remainder of the server's period, and will not replenish |
||
406 | the budget until the specified absolute time. At that time, all |
||
407 | pending budget replenishments (if any) are made effective. Once the |
||
408 | server has a positive budget and the scheduler schedules the |
||
409 | calling thread again, the call returns and at that time, except for |
||
410 | those parameters equal to NULL pointers, the system reports the |
||
411 | current period and budget for the current job, whether the deadline |
||
412 | of the previous job was missed or not, and whether the budget of |
||
413 | the previous job was overrun or not. |
||
414 | |||
415 | In a system with hierarchical scheduling, since this call makes the |
||
416 | budget zero, the other threads in the same server are not run. As |
||
417 | mentioned abobe, only when the call finishes the budget may be |
||
418 | replenished. |
||
419 | |||
420 | @param [in] abs_time absolute time at which the budget will be |
||
421 | replenished |
||
422 | |||
423 | @param [out] next_budget upon return of this function, the variable |
||
424 | pointed by this function will be equal to |
||
425 | the current server budget. If this parameter is |
||
426 | set to NULL, no action is taken. |
||
427 | |||
428 | @param [out] next_period upon return of this function, the variable |
||
429 | pointed by this function will be equal to |
||
430 | the current server period. If this parameter is |
||
431 | set to NULL, no action is taken. |
||
432 | |||
433 | @param [out] was_deadline_missed upon return of this function, the |
||
434 | variable pointed by this function will be |
||
435 | equal to true if the previous server deadline |
||
436 | was missed, to false otherwise. If this |
||
437 | parameter is set to NULL, no action is |
||
438 | taken. |
||
439 | |||
974 | trimarchi | 440 | @param [out] was_budget_overrun upon return of this function, the |
881 | trimarchi | 441 | variable pointed by this function will be |
442 | equal to true if the previous server budget was |
||
443 | overrun, to false otherwise. If this |
||
444 | parameter is set to NULL, no action is |
||
445 | taken. |
||
446 | |||
974 | trimarchi | 447 | @returns 0 if the operation is succesful |
448 | @returns FSF_ERR_TIME_SPEC_IN_THE_PAST if the absolute time specification |
||
449 | is in the past. |
||
450 | [ERR@RETURNED: |
||
451 | FSF_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running |
||
452 | FSF_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FSF |
||
881 | trimarchi | 453 | main scheduler |
974 | trimarchi | 454 | FSF_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled |
455 | under the FSF |
||
456 | FSF_ERR_NOT_BOUND_THREAD : if the calling thread does not have a valid |
||
881 | trimarchi | 457 | server bound to it |
974 | trimarchi | 458 | FSF_ERR_BAD_ARGUMENT : if abs_time is NULL |
459 | FSF_ERR_SERVER_WORKLOAD_NOT_COMPATIBLE: if the kind of workload of the server |
||
460 | is not FSF_BOUNDED |
||
461 | ] |
||
881 | trimarchi | 462 | |
463 | @sa fsf_schedule_triggered_job, fsf_timed_schedule_triggered_job |
||
974 | trimarchi | 464 | |
881 | trimarchi | 465 | */ |
466 | int |
||
467 | fsf_schedule_timed_job |
||
468 | (const struct timespec *abs_time, |
||
469 | struct timespec *next_budget, |
||
470 | struct timespec *next_period, |
||
471 | bool *was_deadline_missed, |
||
472 | bool *was_budget_overran); |
||
473 | |||
974 | trimarchi | 474 | |
881 | trimarchi | 475 | /** |
476 | This operation is invoked by threads associated with bounded |
||
477 | workload servers to indicate that a job has been completed (and |
||
478 | that the scheduler may reassign the unused capacity of the current |
||
479 | job to other servers). It is also invoked when the first job of |
||
480 | such threads has to be scheduled. If the specified synchronization |
||
481 | object has events queued, one of them is dequeued; otherwise the |
||
482 | server will wait upon the specified synchronization object, the |
||
483 | server's budget will be made zero for the remainder of the server's |
||
484 | period, and the implementation will not replenish the budget until |
||
974 | trimarchi | 485 | the specified synchronization object is signalled. At that time, |
486 | all pending budget replenishments (if any) are made effective. Once |
||
487 | the server has a positive budget and the scheduler schedules the |
||
488 | calling thread again, the call returns and at that time, except for |
||
489 | those parameters equal to NULL pointers, the system reports the |
||
490 | current period and budget for the current job, whether the deadline |
||
491 | of the previous job was missed or not, and whether the budget of |
||
492 | the previous job was overrun or not. |
||
881 | trimarchi | 493 | |
494 | In a system with hierarchical scheduling, since this call makes the |
||
495 | budget zero, the other threads in the same server are not run. As |
||
496 | mentioned above, only when the call finishes the budget may be |
||
497 | replenished. |
||
498 | |||
974 | trimarchi | 499 | [ERR@RETURNED: |
500 | FSF_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running |
||
501 | FSF_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FSF |
||
502 | main scheduler |
||
503 | FSF_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled |
||
504 | under the FSF |
||
505 | FSF_ERR_NOT_BOUND_THREAD : if the calling thread does not have a valid |
||
506 | server bound to it |
||
507 | FSF_ERR_BAD_ARGUMENT : if the synch_handle given is not valid |
||
508 | FSF_ERR_SERVER_WORKLOAD_NOT_COMPATIBLE: if the kind of workload of the server |
||
509 | is not FSF_BOUNDED |
||
510 | ] |
||
881 | trimarchi | 511 | |
512 | |||
513 | */ |
||
514 | int |
||
515 | fsf_schedule_triggered_job |
||
516 | (fsf_synch_obj_handle_t synch_handle, |
||
517 | struct timespec *next_budget, |
||
518 | struct timespec *next_period, |
||
519 | bool *was_deadline_missed, |
||
520 | bool *was_budget_overran); |
||
521 | |||
522 | |||
523 | /** |
||
524 | This call is the same as fsf_schedule_triggered_job, but with an |
||
525 | absolute timeout. The timed_out argument, indicates whether the |
||
526 | function returned because of a timeout or not |
||
527 | |||
974 | trimarchi | 528 | [ERR@RETURNED: |
529 | FSF_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running |
||
530 | FSF_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FSF |
||
531 | main scheduler |
||
532 | FSF_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled |
||
533 | under the FSF |
||
534 | FSF_ERR_NOT_BOUND_THREAD : if the calling thread does not have a valid |
||
881 | trimarchi | 535 | server bound to it |
974 | trimarchi | 536 | FSF_ERR_BAD_ARGUMENT : if the synch_handle given is not valid or the |
537 | abs_timeout argument is NULL or its value is in the past |
||
538 | FSF_ERR_SERVER_WORKLOAD_NOT_COMPATIBLE: if the kind of workload of the server |
||
539 | is not FSF_BOUNDED |
||
540 | ] |
||
881 | trimarchi | 541 | |
542 | */ |
||
543 | int |
||
544 | fsf_timed_schedule_triggered_job |
||
545 | (fsf_synch_obj_handle_t synch_handle, |
||
546 | const struct timespec *abs_timeout, |
||
547 | bool *timed_out, |
||
548 | struct timespec *next_budget, |
||
549 | struct timespec *next_period, |
||
550 | bool *was_deadline_missed, |
||
551 | bool *was_budget_overran); |
||
552 | |||
974 | trimarchi | 553 | |
554 | |||
555 | |||
881 | trimarchi | 556 | /*@}*/ |
557 | |||
558 | /////////////////////////////////////////////////////////////////// |
||
559 | // CONTRACT NEGOCIATION OPERATIONS |
||
560 | /////////////////////////////////////////////////////////////////// |
||
561 | |||
562 | /** |
||
974 | trimarchi | 563 | \defgroup negotiate Negotiate contract functions |
881 | trimarchi | 564 | |
565 | The following functions are used to create servers for a contract |
||
566 | parameters specification and also to assign one or more threads to |
||
974 | trimarchi | 567 | a server (Note: the current implementation only supports one thread |
568 | per server; this limitation will be removed in the next phase of |
||
569 | the project) |
||
881 | trimarchi | 570 | */ |
571 | /*@{*/ |
||
572 | |||
573 | /** |
||
574 | Server Id type, that identifies a server created to manage a given |
||
575 | contract |
||
576 | */ |
||
577 | typedef int fsf_server_id_t; // => 0 |
||
578 | |||
579 | /** |
||
580 | The type references a function that may become a thread's |
||
581 | code |
||
582 | */ |
||
583 | typedef void * (*fsf_thread_code_t) (void *); |
||
584 | |||
974 | trimarchi | 585 | |
881 | trimarchi | 586 | /** |
587 | The operation negotiates a contract for a new server. If the |
||
588 | on-line admission test is enabled it determines whether the |
||
589 | contract can be admitted or not based on the current contracts |
||
590 | established in the system. Then it creates the server and |
||
591 | recalculates all necessary parameters for the contracts already |
||
974 | trimarchi | 592 | present in the system. This is a potentially blocking operation; it |
593 | returns when the system has either rejected the contract, or |
||
594 | admitted it and made it effective. It returns zero and places the |
||
595 | server identification number in the location pointed to by the |
||
596 | server input parameter if accepted, or an error if rejected. No |
||
597 | thread is bound to the newly created server, which will be idle |
||
598 | until a thread is bound to it. This operation can only be executed |
||
599 | by threads that are already bound to an active server and therefore |
||
600 | are being scheduled by the fsf scheduler. |
||
881 | trimarchi | 601 | |
974 | trimarchi | 602 | [ERR@RETURNED: |
603 | FSF_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running |
||
604 | FSF_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FSF |
||
605 | main scheduler |
||
606 | FSF_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled |
||
607 | under the FSF |
||
608 | FSF_ERR_BAD_ARGUMENT : if the contract or server arguments are NULL |
||
609 | FSF_ERR_TOO_MANY_SERVERS : if there is no space for more servers |
||
610 | (the maximum number of them is already reached) |
||
611 | ] |
||
881 | trimarchi | 612 | |
613 | */ |
||
614 | int |
||
615 | fsf_negotiate_contract |
||
616 | (const fsf_contract_parameters_t *contract, |
||
617 | fsf_server_id_t *server); |
||
618 | |||
974 | trimarchi | 619 | |
881 | trimarchi | 620 | /** |
621 | This operation negotiates a contract for a new server, creates a |
||
622 | thread and binds it to the server. If the contract is accepted, the |
||
623 | operation creates a thread with the arguments thread, attr, |
||
624 | thread_code and arg as they are defined for the pthread_create() |
||
625 | POSIX function call, and attaches it to the fsf scheduler. Then, it |
||
626 | binds the created thread to the new server. It returns zero and |
||
627 | puts the server identification number in the location pointed to by |
||
974 | trimarchi | 628 | the server input parameter. The attr parameter is overwritten as |
629 | necessary to introduce the adequate scheduling policy and priority, |
||
630 | according to the preemption level given in the contract and the |
||
631 | fsf_priority_map() function defined by the user. If the contract is |
||
632 | rejected, the thread is not created and the corresponding error is |
||
633 | returned. |
||
881 | trimarchi | 634 | |
635 | The server is created with the FSF_NONE scheduling policy, which |
||
636 | means no hierarchical scheduling, and only one thread per server, |
||
637 | except for the case of background tasks (see below) |
||
638 | |||
974 | trimarchi | 639 | [ERR@RETURNED: |
640 | FSF_ERR_BAD_ARGUMENT : if the contract or server arguments are NULL |
||
641 | FSF_ERR_CONTRACT_REJECTED : if the contract is rejected. |
||
642 | FSF_ERR_SERVER_WORKLOAD_NOT_COMPATIBLE: if the kind of workload |
||
643 | in the contract is FSF_OVERHEAD |
||
881 | trimarchi | 644 | |
974 | trimarchi | 645 | It may also return all the errors that may be returned by the |
646 | pthread_create()POSIX function call |
||
647 | ] |
||
881 | trimarchi | 648 | |
649 | */ |
||
650 | int |
||
651 | fsf_negotiate_contract_for_new_thread |
||
652 | (const fsf_contract_parameters_t *contract, |
||
653 | fsf_server_id_t *server, |
||
654 | pthread_t *thread, |
||
655 | pthread_attr_t *attr, |
||
656 | fsf_thread_code_t thread_code, |
||
657 | void *arg); |
||
658 | |||
659 | /** |
||
660 | This operation negotiates a contract for a new server, and binds |
||
661 | the calling thread to it. If the contract is accepted it returns |
||
662 | zero and copies the server identification number in the location |
||
663 | pointed to by the server input parameter. If it is rejected, an |
||
664 | error is returned. |
||
665 | |||
666 | The server is created with the FSF_NONE scheduling policy, which |
||
667 | means no hierarchical scheduling, and only one thread per server, |
||
668 | except for the case of background tasks (see below) |
||
669 | |||
670 | Implementation dependent issue: In order to allow the usage of |
||
671 | application defined schedulers, the calling thread must not have |
||
672 | the SCHED_APP scheduling policy and at the same time be attached to |
||
673 | an application scheduler different than the fsf scheduler; in such |
||
674 | case, an error is returned. After a successful call the calling |
||
675 | thread will have the SCHED_APP scheduling policy and will be |
||
676 | attached to the fsf scheduler. |
||
677 | |||
974 | trimarchi | 678 | [ERR@RETURNED: |
679 | FSF_ERR_UNKNOWN_APPSCHEDULED_THREAD : if the thread is attached to |
||
881 | trimarchi | 680 | an application defined scheduler different than the fsf scheduler |
974 | trimarchi | 681 | FSF_ERR_BAD_ARGUMENT : if the contract or server arguments are NULL |
682 | FSF_ERR_CONTRACT_REJECTED : if the contract is rejected. |
||
683 | FSF_ERR_SERVER_WORKLOAD_NOT_COMPATIBLE: if the kind of workload |
||
684 | in the contract is FSF_OVERHEAD |
||
685 | ] |
||
686 | |||
881 | trimarchi | 687 | */ |
688 | int |
||
689 | fsf_negotiate_contract_for_myself |
||
690 | (const fsf_contract_parameters_t *contract, |
||
691 | fsf_server_id_t *server); |
||
692 | |||
693 | |||
694 | /** |
||
974 | trimarchi | 695 | fsf_bind_thread_to_server: This operation associates a thread with |
696 | a server, which means that it starts consuming the server's budget |
||
697 | and is executed according to the contract established for that |
||
698 | server. If the thread is already bound to another server, it is |
||
699 | effectively unbound from it and bound to the specified one. |
||
881 | trimarchi | 700 | |
701 | It fails if the server's policy is different than FSF_NONE, or if |
||
702 | there is already a thread bound to this server |
||
703 | |||
704 | Implementation dependent issue: In order to allow the usage of |
||
705 | application defined schedulers, the given thread must not have the |
||
706 | scheduling policy SCHED_APP and at the same time be attached to an |
||
707 | application scheduler different than the fsf scheduler. |
||
708 | |||
974 | trimarchi | 709 | [ERR@RETURNED: |
710 | FSF_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FSF |
||
711 | main scheduler |
||
712 | FSF_ERR_UNKNOWN_APPSCHEDULED_THREAD : if the thread is attached to |
||
881 | trimarchi | 713 | an application defined scheduler different than the fsf scheduler |
974 | trimarchi | 714 | FSF_ERR_BAD_ARGUMENT : if the server value does not complain with the |
881 | trimarchi | 715 | expected format or valid range or the given thread does not exist |
974 | trimarchi | 716 | FSF_ERR_NOT_CONTRACTED_SERVER : if the referenced server is not valid |
717 | FSF_ERR_SERVER_WORKLOAD_NOT_COMPATIBLE: if the kind of workload |
||
718 | of the server is FSF_OVERHEAD |
||
719 | FSF_ERR_ALREADY_BOUND : if the given server has a thread already bound |
||
720 | ] |
||
881 | trimarchi | 721 | |
722 | */ |
||
723 | int |
||
724 | fsf_bind_thread_to_server |
||
725 | (fsf_server_id_t server, |
||
726 | pthread_t thread); |
||
727 | |||
728 | |||
729 | /** |
||
730 | This operation unbinds a thread from a server. Since threads with |
||
731 | no server associated are not allow to execute, they remain in a |
||
732 | dormant state until they are either eliminated or bound again. |
||
733 | |||
734 | If the thread is inside a critical section the effects of this call |
||
735 | are deferred until the critical section is ended |
||
736 | |||
737 | Implementation dependent issue: in the implementation with an |
||
738 | application scheduler, the thread is still attached to the fsf |
||
739 | scheduler, but suspended. |
||
740 | |||
974 | trimarchi | 741 | [ERR@RETURNED: |
742 | FSF_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FSF |
||
881 | trimarchi | 743 | main scheduler |
974 | trimarchi | 744 | FSF_ERR_BAD_ARGUMENT : if the given thread does not exist |
745 | FSF_ERR_NOT_SCHEDULED_THREAD : if the given thread is not scheduled |
||
881 | trimarchi | 746 | under the FSF |
974 | trimarchi | 747 | FSF_ERR_UNKNOWN_APPSCHEDULED_THREAD : if the thread is attached to |
881 | trimarchi | 748 | an application defined scheduler different than the fsf scheduler |
974 | trimarchi | 749 | FSF_ERR_NOT_BOUND_THREAD : if the given thread does not have a valid |
881 | trimarchi | 750 | server bound to it |
974 | trimarchi | 751 | ] |
752 | |||
881 | trimarchi | 753 | */ |
754 | int |
||
755 | fsf_unbind_thread_from_server (pthread_t thread); |
||
756 | |||
757 | /** |
||
758 | This operation stores the Id of the server associated with the |
||
759 | specified thread in the variable pointed to by server. It returns |
||
760 | an error if the thread does not exist, it is not under the control |
||
761 | of the scheduling framework, or is not bound. |
||
762 | |||
974 | trimarchi | 763 | [ERR@RETURNED: |
764 | FSF_ERR_NOT_SCHEDULED_THREAD : if the given thread is not scheduled |
||
881 | trimarchi | 765 | under the FSF |
974 | trimarchi | 766 | FSF_ERR_NOT_BOUND_THREAD : if the given thread does not have a valid |
881 | trimarchi | 767 | server bound to it |
974 | trimarchi | 768 | FSF_ERR_BAD_ARGUMENT : if the given thread does not exist or the |
881 | trimarchi | 769 | server argument is NULL |
974 | trimarchi | 770 | ] |
771 | |||
881 | trimarchi | 772 | */ |
773 | int |
||
774 | fsf_get_server |
||
775 | (pthread_t thread, |
||
776 | fsf_server_id_t *server); |
||
777 | |||
778 | /** |
||
779 | This operation stores the contract parameters currently associated |
||
780 | with the specified server in the variable pointed to by |
||
781 | contract. It returns an error if the server id is incorrect. |
||
782 | |||
974 | trimarchi | 783 | [ERR@RETURNED: |
784 | FSF_ERR_BAD_ARGUMENT : if the contract argument is NULL or the value |
||
785 | of the server argument is not in range |
||
786 | FSF_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not |
||
881 | trimarchi | 787 | scheduled under the FSF |
974 | trimarchi | 788 | FSF_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running |
789 | FSF_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread |
||
881 | trimarchi | 790 | has been cancelled or it is not valid |
974 | trimarchi | 791 | ] |
792 | |||
881 | trimarchi | 793 | */ |
794 | int |
||
795 | fsf_get_contract |
||
796 | (fsf_server_id_t server, |
||
797 | fsf_contract_parameters_t *contract); |
||
798 | |||
799 | /** |
||
800 | The operation eliminates the specified server |
||
801 | and recalculates all necessary parameters for the contracts |
||
802 | remaining in the system. This is a potentially blocking operation; |
||
803 | it returns when the system has made the changes effective. |
||
804 | |||
974 | trimarchi | 805 | [ERR@RETURNED: |
806 | FSF_ERR_BAD_ARGUMENT : if the value of server is not in range |
||
807 | FSF_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not |
||
808 | scheduled under the FSF |
||
809 | FSF_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running |
||
810 | FSF_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread |
||
811 | has been cancelled or it is not valid |
||
812 | ] |
||
881 | trimarchi | 813 | |
814 | */ |
||
815 | int |
||
816 | fsf_cancel_contract (fsf_server_id_t server); |
||
817 | |||
818 | |||
819 | /** |
||
820 | The operation renegotiates a contract for an existing server. If |
||
821 | the on-line admission test is enabled it determines whether the |
||
822 | contract can be admitted or not based on the current contracts |
||
823 | established in the system. If it cannot be admitted, the old |
||
824 | contract remains in effect and an error is returned. If it can be |
||
825 | admitted, it recalculates all necessary parameters for the |
||
826 | contracts already present in the system anr returns zero. This is a |
||
827 | potentially blocking operation; it returns when the system has |
||
828 | either rejected the new contract, or admitted it and made it |
||
829 | effective. |
||
830 | |||
974 | trimarchi | 831 | [ERR@RETURNED: |
832 | FSF_ERR_BAD_ARGUMENT : if the new_contract argument is NULL or the |
||
881 | trimarchi | 833 | value of the server argument is not in range |
974 | trimarchi | 834 | FSF_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not |
881 | trimarchi | 835 | scheduled under the FSF |
974 | trimarchi | 836 | FSF_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running |
837 | FSF_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread |
||
881 | trimarchi | 838 | has been cancelled or it is not valid |
974 | trimarchi | 839 | ] |
840 | |||
881 | trimarchi | 841 | */ |
842 | int |
||
843 | fsf_renegotiate_contract |
||
844 | (const fsf_contract_parameters_t *new_contract, |
||
845 | fsf_server_id_t server); |
||
846 | |||
974 | trimarchi | 847 | |
881 | trimarchi | 848 | /** |
849 | The operation enqueues a renegotiate operation for an existing |
||
850 | server, and returns immediately. The renegotiate operation is |
||
974 | trimarchi | 851 | performed asynchronously, as soon as it is practical; meanwhile the |
852 | system operation will continue normally. When the renegotiation is |
||
853 | made, if the on-line admission test is enabled it determines |
||
854 | whether the contract can be admitted or not based on the current |
||
855 | contracts established in the system. If it cannot be admitted, the |
||
856 | old contract remains in effect. If it can be admitted, it |
||
857 | recalculates all necessary parameters for the contracts already |
||
858 | present in the system. When the operation is completed, |
||
859 | notification is made to the caller, if requested, via a signal. The |
||
860 | status of the operation (in progress, admitted, rejected) can be |
||
861 | checked with the get_renegotiation_status operation. The argument |
||
862 | sig_notify can be NULL_SIGNAL (no notification), or any posix |
||
863 | signal; and in this case sig_value is to be sent with the signal. |
||
881 | trimarchi | 864 | |
974 | trimarchi | 865 | [ERR@RETURNED: |
866 | FSF_ERR_BAD_ARGUMENT : if the new_contract argument is NULL, the |
||
881 | trimarchi | 867 | value of the server argument is not in range or sig_notify is |
868 | neither NULL nor a valid POSIX signal |
||
974 | trimarchi | 869 | FSF_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not |
881 | trimarchi | 870 | scheduled under the FSF |
974 | trimarchi | 871 | FSF_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running |
872 | FSF_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread |
||
881 | trimarchi | 873 | has been cancelled or it is not valid |
974 | trimarchi | 874 | ] |
881 | trimarchi | 875 | |
876 | */ |
||
877 | int |
||
878 | fsf_request_contract_renegotiation |
||
879 | (const fsf_contract_parameters_t *new_contract, |
||
880 | fsf_server_id_t server, |
||
881 | int sig_notify, |
||
882 | union sigval sig_value); |
||
883 | |||
884 | |||
885 | /** |
||
886 | The operation reports on the status of the last renegotiation |
||
887 | operation enqueued for the specified server. It is callable even |
||
888 | after notification of the completion of such operation, if |
||
974 | trimarchi | 889 | requested. If the fsf_request_contract_renegotiation operation has |
890 | not ever been called for the given server the status returned is |
||
891 | FSF_NOT_REQUESTED |
||
881 | trimarchi | 892 | |
974 | trimarchi | 893 | [ERR@RETURNED: |
894 | FSF_ERR_BAD_ARGUMENT : if the renegotiation_status argument is |
||
881 | trimarchi | 895 | NULL or the value of the server argument is not in range |
974 | trimarchi | 896 | FSF_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not |
881 | trimarchi | 897 | scheduled under the FSF |
974 | trimarchi | 898 | FSF_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running |
899 | FSF_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread |
||
881 | trimarchi | 900 | has been cancelled or it is not valid |
974 | trimarchi | 901 | ] |
902 | |||
881 | trimarchi | 903 | */ |
904 | int |
||
905 | fsf_get_renegotiation_status |
||
906 | (fsf_server_id_t server, |
||
907 | fsf_renegotiation_status_t *renegotiation_status); |
||
908 | |||
909 | /*@}*/ |
||
910 | |||
911 | |||
912 | //////////////////////////////////////////////////// |
||
913 | // OBTAINING INFORMATION FROM THE SCHEDULER |
||
914 | //////////////////////////////////////////////////// |
||
915 | |||
916 | |||
917 | /** |
||
974 | trimarchi | 918 | Returns true if the system is |
919 | configured with the on-line admission test enabled, or false |
||
920 | otherwise. |
||
881 | trimarchi | 921 | */ |
922 | bool |
||
923 | fsf_is_admission_test_enabled(); |
||
924 | |||
925 | /** |
||
926 | This function stores the current execution time spent by the |
||
927 | threads bound to the specified server in the variable pointed to by |
||
928 | cpu_time. |
||
929 | |||
974 | trimarchi | 930 | [ERR@RETURNED: |
931 | FSF_ERR_BAD_ARGUMENT : if the value of the server argument is not in range or |
||
932 | cpu_time is NULL |
||
933 | FSF_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not |
||
881 | trimarchi | 934 | scheduled under the FSF |
974 | trimarchi | 935 | FSF_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running |
936 | FSF_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread |
||
881 | trimarchi | 937 | has been cancelled or it is not valid |
974 | trimarchi | 938 | ] |
939 | |||
881 | trimarchi | 940 | */ |
941 | int |
||
942 | fsf_get_cpu_time |
||
943 | (fsf_server_id_t server, |
||
944 | struct timespec *cpu_time); |
||
945 | |||
946 | /** |
||
947 | This function stores in the variable pointed to by budget the |
||
948 | remaining execution-time budget associated with the specified |
||
974 | trimarchi | 949 | server |
881 | trimarchi | 950 | |
974 | trimarchi | 951 | [ERR@RETURNED: |
952 | FSF_ERR_BAD_ARGUMENT : if the value of the server argument is not in range or |
||
953 | budget is NULL |
||
954 | FSF_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not |
||
881 | trimarchi | 955 | scheduled under the FSF |
974 | trimarchi | 956 | FSF_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running |
957 | FSF_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread |
||
881 | trimarchi | 958 | has been cancelled or it is not valid |
974 | trimarchi | 959 | ] |
960 | |||
881 | trimarchi | 961 | */ |
962 | int |
||
963 | fsf_get_remaining_budget |
||
964 | (fsf_server_id_t server, |
||
965 | struct timespec *budget); |
||
966 | |||
967 | |||
968 | /** |
||
974 | trimarchi | 969 | This function stores in the variables |
970 | pointed to by budget and period, the execution-time budget and the |
||
971 | period respectively associated with the specified server. If any of |
||
972 | these pointers is NULL, the corresponding information is not stored. |
||
881 | trimarchi | 973 | |
974 | trimarchi | 974 | [ERR@RETURNED: |
975 | FSF_ERR_BAD_ARGUMENT : if the value of the server argument is not in range, |
||
976 | or budget and period are both NULL |
||
977 | FSF_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not |
||
881 | trimarchi | 978 | scheduled under the FSF |
974 | trimarchi | 979 | FSF_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running |
980 | FSF_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread |
||
881 | trimarchi | 981 | has been cancelled or it is not valid |
974 | trimarchi | 982 | ] |
983 | |||
881 | trimarchi | 984 | */ |
985 | int |
||
986 | fsf_get_budget_and_period |
||
987 | (fsf_server_id_t server, |
||
988 | struct timespec *budget, |
||
989 | struct timespec *period); |
||
990 | |||
991 | |||
974 | trimarchi | 992 | |
881 | trimarchi | 993 | ///////////////////////////////////////////////////////////////////// |
994 | // SERVICE THREAD TUNING |
||
995 | ///////////////////////////////////////////////////////////////////// |
||
996 | |||
997 | /** |
||
974 | trimarchi | 998 | This function allows the application to |
999 | change the period and budget of the service thread that makes the |
||
881 | trimarchi | 1000 | negotiations. Increasing the utilization of this thread makes the |
1001 | negotiations faster, but introduces additional load in the system |
||
1002 | that may decrease the bandwidth available for the servers. For this |
||
974 | trimarchi | 1003 | call, the system will make a schedulability analysis to determine if |
1004 | the new situation is acceptable or not. This is reported back in the |
||
1005 | variable pointed to by accepted. If the new service thread data is |
||
1006 | accepted, the system will reassign budgets and periods to the |
||
1007 | servers according to the new bandwidth available, in the same way as |
||
1008 | it does for a regular contract negotiation. |
||
881 | trimarchi | 1009 | |
1010 | When its budget is exhausted, the service thread may run in the |
||
974 | trimarchi | 1011 | background |
881 | trimarchi | 1012 | |
1013 | The service thread starts with a default budget and period that are |
||
974 | trimarchi | 1014 | configurable |
881 | trimarchi | 1015 | |
974 | trimarchi | 1016 | Implementation dependency: in the fixed priority implementtaion of |
1017 | fsf, the default priority is lower than the priority of any server, |
||
1018 | but higher than the background. According to the |
||
1019 | implementation-dependent module the priority is adjustable by means |
||
1020 | of a function that changes its preemption level |
||
881 | trimarchi | 1021 | |
974 | trimarchi | 1022 | [ERR@RETURNED: |
1023 | FSF_ERR_BAD_ARGUMENT : if any of the pointer arguments is NULL or |
||
881 | trimarchi | 1024 | the budget value is greater than the period value |
974 | trimarchi | 1025 | FSF_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not |
881 | trimarchi | 1026 | scheduled under the FSF |
974 | trimarchi | 1027 | FSF_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running |
1028 | FSF_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread |
||
881 | trimarchi | 1029 | has been cancelled or it is not valid |
974 | trimarchi | 1030 | ] |
1031 | |||
881 | trimarchi | 1032 | */ |
1033 | int |
||
1034 | fsf_set_service_thread_data |
||
1035 | (const struct timespec *budget, |
||
1036 | const struct timespec *period, |
||
1037 | bool *accepted); |
||
1038 | |||
1039 | /** |
||
1040 | this function returns in the variables pointed by budget and |
||
1041 | period, respectively, the current budget and period of the service |
||
1042 | thread. |
||
1043 | |||
974 | trimarchi | 1044 | [ERR@RETURNED: |
1045 | FSF_ERR_BAD_ARGUMENT : if any of the pointer arguments is NULL |
||
1046 | FSF_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not |
||
881 | trimarchi | 1047 | scheduled under the FSF |
974 | trimarchi | 1048 | FSF_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running |
1049 | FSF_ERR_NOT_CONTRACTED_SERVER : if the server of the calling thread |
||
881 | trimarchi | 1050 | has been cancelled or it is not valid |
974 | trimarchi | 1051 | ] |
1052 | |||
881 | trimarchi | 1053 | */ |
1054 | int |
||
1055 | fsf_get_service_thread_data |
||
1056 | (struct timespec *budget, |
||
1057 | struct timespec *period); |
||
1058 | |||
1059 | |||
1060 | //////////////////////////////////////////////////////////////////////// |
||
1061 | // BACKGROUND MANAGEMENT |
||
1062 | //////////////////////////////////////////////////////////////////////// |
||
1063 | |||
974 | trimarchi | 1064 | //A round-robin background scheduling policy is available for those |
1065 | //threads that do not have real-time requirements. Because some of |
||
1066 | //these threads may require sharing information with other threads run |
||
1067 | //by regular servers, special background contracts may be created for |
||
1068 | //specifying the synchronization requirements. |
||
1069 | |||
1070 | //The way of specifying a background contract is by setting budget_min |
||
1071 | //= period_max = 0. Negotiation may fail if the contract uses |
||
1072 | //shared_objects. If the contract has no shared_objects the returned |
||
1073 | //server id represents the background and may be used to bind more |
||
1074 | //than one thread. If the contract has shared objects a server is |
||
1075 | //created to keep track of them, but the associated threads are |
||
1076 | //executed in the background, together with the other background |
||
1077 | //threads |
||
1078 | |||
1079 | |||
1080 | //////////////////////////////////////////////////////////////////////// |
||
1081 | // CHANGE OF MODE: GROUPS OF CONTRACTS |
||
1082 | //////////////////////////////////////////////////////////////////////// |
||
1083 | |||
1084 | //Data types |
||
1085 | |||
1086 | //list of contracts to negotiate |
||
1087 | typedef struct { |
||
1088 | int size; |
||
1089 | fsf_contract_parameters_t* contracts[FSF_MAX_N_SERVERS]; |
||
1090 | } fsf_contracts_group_t; |
||
1091 | |||
1092 | //list of servers to cancel |
||
1093 | typedef struct { |
||
1094 | int size; |
||
1095 | fsf_server_id_t servers[FSF_MAX_N_SERVERS]; |
||
1096 | } fsf_servers_group_t; |
||
1097 | |||
1098 | |||
881 | trimarchi | 1099 | /** |
974 | trimarchi | 1100 | This operation analizes the schedulability of |
1101 | the context that results from negitiating the contracts specified in |
||
1102 | the contracts_up list and cacelling the contracts referenced by the |
||
1103 | servers_down list. If the overall negotiation is successful, a new |
||
1104 | server will be created for each of the elements of the contracts_up |
||
1105 | group, the servers in servers_down will be cancelled, the list of |
||
1106 | new server ids will be returned in the variable pointed to by |
||
1107 | servers_up, and the variable pointed to by accepted will be made |
||
1108 | true. Otherwise, this variable will be made false, and no other |
||
1109 | effect will take place. The function returns the corresponding error |
||
1110 | code if any of the contracts is not correct or any of the server ids |
||
1111 | is not valid. |
||
1112 | Observe that in order to be able to receive the returned arguments, |
||
1113 | the calling thread's server should not be in the servers_down list. |
||
881 | trimarchi | 1114 | |
974 | trimarchi | 1115 | [ERR@RETURNED: |
1116 | FSF_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running |
||
1117 | FSF_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FSF |
||
1118 | main scheduler |
||
1119 | FSF_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled |
||
1120 | under the FSF |
||
1121 | FSF_ERR_BAD_ARGUMENT : if any of the servers_up or accepted arguments |
||
1122 | is NULL, if the contracts_up and servers_down arguments are both NULL, |
||
1123 | or any of them has erroneous size or its elements are NULL or not in the |
||
1124 | valid range respectively |
||
1125 | ] |
||
881 | trimarchi | 1126 | |
974 | trimarchi | 1127 | */ |
1128 | int |
||
1129 | fsf_negotiate_group |
||
1130 | (const fsf_contracts_group_t *contracts_up, |
||
1131 | const fsf_servers_group_t *severs_down, |
||
1132 | fsf_servers_group_t *severs_up, |
||
1133 | bool *accepted); |
||
881 | trimarchi | 1134 | |
974 | trimarchi | 1135 | |
1136 | ////////////////////////////////////////////////////////////////////// |
||
1137 | // INITIALIZATION SERVICES |
||
1138 | ////////////////////////////////////////////////////////////////////// |
||
1139 | |||
1140 | |||
1141 | /** |
||
1142 | We cannot call any fsf functions before fsf_init. After calling |
||
1143 | fsf_init, the main will be executing in the background. Then, it |
||
1144 | can do the negotiations, create the threads and, if needed, |
||
1145 | activate them via some user-specified synchronization mechanism. It |
||
1146 | may also create a contract for itself. The second time this |
||
1147 | function is called it fails. |
||
1148 | |||
1149 | [ERR@RETURNED: |
||
1150 | FSF_ERR_SYSTEM_ALREADY_INITIALIZED : if the function has already |
||
1151 | been called before |
||
1152 | |||
1153 | It may also return any of the errors that may be returned by the |
||
1154 | underlying operating system primitives required to perform the |
||
1155 | FSF system start up |
||
1156 | ] |
||
1157 | |||
881 | trimarchi | 1158 | */ |
974 | trimarchi | 1159 | int fsf_init(); |
881 | trimarchi | 1160 | |
974 | trimarchi | 1161 | /*@}*/ |
881 | trimarchi | 1162 | |
974 | trimarchi | 1163 | |
881 | trimarchi | 1164 | #endif // _FSF_CORE_H_ |