1 // -----------------------------------------------------------------------
2 // Copyright (C) 2006 - 2009 FRESCOR consortium partners:
4 // Universidad de Cantabria, SPAIN
5 // University of York, UK
6 // Scuola Superiore Sant'Anna, ITALY
7 // Kaiserslautern University, GERMANY
8 // Univ. Politécnica Valencia, SPAIN
9 // Czech Technical University in Prague, CZECH REPUBLIC
11 // Thales Communication S.A. FRANCE
12 // Visual Tools S.A. SPAIN
13 // Rapita Systems Ltd UK
16 // See http://www.frescor.org for a link to partners' websites
18 // FRESCOR project (FP6/2005/IST/5-034026) is funded
19 // in part by the European Union Sixth Framework Programme
20 // The European Union is not liable of any use that may be
24 // based on previous work (FSF) done in the FIRST project
26 // Copyright (C) 2005 Mälardalen University, SWEDEN
27 // Scuola Superiore S.Anna, ITALY
28 // Universidad de Cantabria, SPAIN
29 // University of York, UK
31 // FSF API web pages: http://marte.unican.es/fsf/docs
32 // http://shark.sssup.it/contrib/first/docs/
34 // This file is part of FRSH (FRescor ScHeduler)
36 // FRSH is free software; you can redistribute it and/or modify it
37 // under terms of the GNU General Public License as published by the
38 // Free Software Foundation; either version 2, or (at your option) any
39 // later version. FRSH is distributed in the hope that it will be
40 // useful, but WITHOUT ANY WARRANTY; without even the implied warranty
41 // of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
42 // General Public License for more details. You should have received a
43 // copy of the GNU General Public License along with FRSH; see file
44 // COPYING. If not, write to the Free Software Foundation, 675 Mass Ave,
45 // Cambridge, MA 02139, USA.
47 // As a special exception, including FRSH header files in a file,
48 // instantiating FRSH generics or templates, or linking other files
49 // with FRSH objects to produce an executable application, does not
50 // by itself cause the resulting executable application to be covered
51 // by the GNU General Public License. This exception does not
52 // however invalidate any other reasons why the executable file might be
53 // covered by the GNU Public License.
54 // -----------------------------------------------------------------------
56 //==============================================
57 // ******** ******* ******** ** **
58 // **///// /**////** **////// /** /**
59 // ** /** /** /** /** /**
60 // ******* /******* /********* /**********
61 // **//// /**///** ////////** /**//////**
62 // ** /** //** /** /** /**
63 // ** /** //** ******** /** /**
64 // // // // //////// // //
66 // FRSH(FRescor ScHeduler), pronounced "fresh"
67 //==============================================
79 #include <sys/types.h>
81 #include "frsh_core_types.h"
82 #include "frsh_spare_capacity.h"
88 * @defgroup core Core module
90 * This module includes the basic functions and services that are
91 * provided by any FRSH implementation. This module includes basic type
92 * definitions, and functions to
94 * - create a contract and initialize it
95 * - set/get the basic parameters of a contract
96 * - negotiate a service contract, obtaining a vres id
97 * - create and bind threads to vres
98 * - create/destroy a synchronization object
99 * - manage bounded workloads
104 //////////////////////////////////////////////////////////////////////
105 // INITIALIZATION SERVICES
106 //////////////////////////////////////////////////////////////////////
109 * @defgroup initialization Initialization services
112 * These functions need to be called before doing any FRSH operation
113 * (including contract initialization).
122 * We cannot call any frsh functions before frsh_init. After calling
123 * frsh_init, the main will be executing in the background. Then, it
124 * can do the negotiations and create new threads if needed. The
125 * second time this function is called it fails.
127 * @return 0 if no error. \n
128 * FRSH_ERR_SYSTEM_ALREADY_INITIALIZED : if the function has already
129 * been called before\n
131 * It may also return any of the errors that may be returned by the
132 * underlying operating system primitives required to perform the
133 * FRSH system start up
141 * Reverts the efect of frsh_init().
148 /////////////////////////////////////////////////////////////
149 // CONTRACT PARAMETERS
150 /////////////////////////////////////////////////////////////
152 * @defgroup contract Contract Creation and Initialization.
155 * These functions are used to create and initialize a contract, and
156 * set its parameters.
163 * frsh_contract_init()
165 * The operation receives a pointer to a contract object
166 * and initializes it, setting it to the default values.
168 * The default values are:
171 * - ressource_type => FRSH_CRT_PROCESSOR
172 * - contract_label => ""
173 * - budget_min => {0,0};
174 * - period_max => {0,0};
175 * - budget_max => {0,0};
176 * - period_min => {0,0};
177 * - workload => FRSH_WT_INDETERMINATE
178 * - d_equals_t => true
179 * - contract_type => FRSH_CT_REGULAR;
180 * - deadline => {0,0};
181 * - budget_overrun_signal => 0; (signal number)
182 * - budget_overrun_siginfo => {0, NULL};
183 * - deadline_miss_signal => 0; (signal number)
184 * - deadline_miss_siginfo => {0, NULL};
186 * - granularity => DEFAULT_GRANULARITY;
187 * - utilization_set; => size = 0
188 * - quality => DEFAULT_QUALITY; (range 0..100)
189 * - importance => DEFAULT_IMPORTANCE; (range 1..5)
190 * - preemption_level => 0; (range 1..2**32-1)
191 * - critical_sections; => size = 0
193 * - sched_policy => DEFAULT_SCHED_POLICY (FRSH_NONE)
195 * @param contract the pointer to the contract variable.
197 * @return 0 if no error \n
198 * FRSH_ERR_BAD_ARGUMENT : contract is NULL
201 int frsh_contract_init(frsh_contract_t *contract);
205 * frsh_contract_destroy()
207 * The operation deallocates all memory which might be allocated for
210 * @param contract the pointer to the contract variable.
212 void frsh_contract_destroy(frsh_contract_t *contract);
216 * frsh_contract_set_basic_params()
218 * The operation updates the specified contract parameters object by
219 * setting its budget, period, workload and type to the specified
220 * input parameters. (Note: the workload is a basic parameter because
221 * bounded tasks are triggered by the scheduler (see the
222 * frsh_timed_wait() and frsh_synchobj_wait* operations), while
223 * indeterminate tasks are not; therefore, their programming model is
226 * @param contract the pointer to the contract object
227 * @param[in] budget_min the minimum budget for the contract
228 * @param[in] period_max the maximum period for the contract
229 * @param[in] workload the kind of workload (can be FRSH_WT_BOUNDED,
230 * FRSH_WT_INDETERMINATE or FRSH_OVERHEAD)
231 * @param[in] contract_type can be FRSH_CT_REGULAR,
232 * FRSH_CT_BACKGROUND, FRSH_CT_DUMMY.
234 * @return 0 if no error \n
235 * FRSH_ERR_BAD_ARGUMENT : if any of the pointers is NULL
236 * or if only one of the time values is 0, and also if the
237 * workload or the contract type values are unknown in the
240 int frsh_contract_set_basic_params
241 (frsh_contract_t *contract,
242 const frsh_rel_time_t *budget_min,
243 const frsh_rel_time_t *period_max,
244 const frsh_workload_t workload,
245 const frsh_contract_type_t contract_type);
248 * frsh_contract_get_basic_params()
250 * This operation obtains from the specified contract object its
251 * budget, period, and workload, and copies them to the places pointed
252 * to by the corresponding output parameters.
254 * @param[in] contract the pointer to the contract object
255 * @param[out] budget_min pointer to preallocated space
256 * @param[out] period_max pointer to preallocated space
257 * @param[out] workload pointer to preallocated space
258 * @param[out] contract_type pointer to preallocated space
260 * @return 0 if no error \n
261 * FRSH_ERR_BAD_ARGUMENT : if one of the contract or
265 int frsh_contract_get_basic_params
266 (const frsh_contract_t *contract,
267 frsh_rel_time_t *budget_min,
268 frsh_rel_time_t *period_max,
269 frsh_workload_t *workload,
270 frsh_contract_type_t *contract_type);
273 * frsh_contract_set_resource_and_label()
275 * Specify resource_id and type, and the contract label. Otherwise
276 * default values will apply. If the contract label is too long it is truncated
278 * @return 0 if no error \n
279 * FRSH_ERR_BAD_ARGUMENT : if the contract pointer is NULL.
281 int frsh_contract_set_resource_and_label
282 (frsh_contract_t *contract,
283 const frsh_resource_type_t resource_type,
284 const frsh_resource_id_t resource_id,
285 const char *contract_label);
289 * frsh_contract_get_resource_and_label()
291 * Obtain the resource_id and type, and the contract label.
293 * @return 0 if no error \n
294 * FRSH_ERR_BAD_ARGUMENT : if the contract or the contract_label
297 int frsh_contract_get_resource_and_label
298 (const frsh_contract_t *contract,
299 frsh_resource_type_t *resource_type,
300 frsh_resource_id_t *resource_id,
301 char *contract_label);
305 * frsh_contract_set_timing_reqs()
307 * The operation updates the specified contract object, specifying
308 * additional time-related requirements.
310 * @param contract The pointer to the contract object
312 * @param [in] d_equals_t It is a boolean value, set to true (1) if
313 * we want to specify a deadline different from
314 * the period for the contract.
315 * @param [in] deadline If the previous parameter is set to true,
316 * this parameter is ignored (the contract value
317 * will be NULL_DEADLINE internally). Otherwise, it
318 * contains the desired deadline value.
320 * @return 0 if successful\n
321 * FRSH_ERR_BAD_ARGUMENT : if contract is NULL \b or \n
322 * (d_equals_t is true and deadline is not FRSH_NULL_DEADLINE) \b or \n
323 * (budget_overrun_signal is not a valid signal) \b or \n
324 * (deadline_miss_signal is not a valid signal) \b or \n
325 * (d_equals_t is false but (deadline is FRSH_NULL_DEADLINE or its value
326 * is grater than the contract's maximum period))
329 int frsh_contract_set_timing_reqs
330 (frsh_contract_t *contract,
331 const bool d_equals_t,
332 const frsh_rel_time_t *deadline);
335 * frsh_contract_get_timing_reqs()
337 * The operation obtains the corresponding input parameters from the
338 * specified contract object. If d_equals_t is true, the deadline will
339 * be set to FRSH_NULL_DEADLINE.
341 * @return 0 if no error \n
342 * FRSH_ERR_BAD_ARGUMENT : if contract is NULL
345 int frsh_contract_get_timing_reqs
346 (const frsh_contract_t *contract,
348 frsh_rel_time_t *deadline);
353 //////////////////////////////////////////////////////////////////
354 // SYNCHRONIZATION OBJECTS
355 //////////////////////////////////////////////////////////////////
357 * @defgroup synch Synchronization objects
360 * Synchronisation objects provide an alternative to timers for
361 * bounded-workload vres to signal the end of their current job and
362 * return their remaining budget to FRSH.
364 * Instead of asking to be reactivated based on an absolute time, they
365 * queue themselves in a synchronisation object and will wait there
366 * until another vres (bounded-workload or indeterminate-workload)
367 * wakes them up with a signal call the earliest at the beginning of
370 * Indeterminate-workload vres cannot queue themselves here because
371 * they don't have any budget to return. However they can signal on
372 * the objects to activate a waiting workload vres.
374 * For classical signal/wait synchronisation paradigms the application
375 * must use whatever mechanism the underlying OS provides.
377 * In the future we may add a broadcast operation that would signal a
378 * group of synchronization objects. We have not included a broadcast
379 * service in this version because it can be easily created by the
380 * user by signalling individual synchronization objects inside a
383 * Notice that for synchronization objects there is no naming service
384 * like in shared objects because tasks that use synchronization are
385 * not developed independently, as they are closely coupled.
392 * frsh_synchobj_create()
394 * This operation creates and initializes a synchronization object
395 * variable managed by the scheduler, and returns a handle to it in
396 * the variable pointed to by synch_handle.
398 * @param[out] synch_handle pointer to the variable that will contain
399 * the handle to the newly created synchronization object
401 * @return 0 if the operation is succesful
402 * FRSH_ERR_TOO_MANY_SYNCH_OBJS if the number of synchronization
403 * objects in the system has already exceeded the maximum
405 * FRSH_ERR_TOO_MANY_SYNCH_OBJS : if the number of synchronization
406 * objects in the system has already exceeded the maximum\n
408 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
409 * scheduled under FRSH\n
411 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
414 int frsh_synchobj_create
415 (frsh_synchobj_handle_t *synch_handle);
419 * frsh_synchobj_destroy()
421 * This operation destroys the synchronization object (created by a
422 * previous call to frsh_synchobj_create) that is referenced by the
423 * synch_handle variable. After calling this operation, the
424 * synch_handle variable can not be used until it is initialized again
425 * by a call to frsh_synchobj_create.
427 * @param synch_handle the handle to the synchronization object
430 * @return 0 if no error \n
431 * FRSH_ERR_BAD_ARGUMENT : if synch_handle is 0\n
432 * FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE if the handle is not valid\n
433 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
434 * scheduled under FRSH \n
435 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
438 * @sa frsh_synchobj_create
440 int frsh_synchobj_destroy
441 (const frsh_synchobj_handle_t synchobj_handle);
444 * frsh_synchobj_wait()
446 * This operation is invoked by threads associated with bounded
447 * workload vres to indicate that a job has been completed (and
448 * that the scheduler may reassign the unused capacity of the current
449 * job to other vres).
451 * As a difference with frsh_timed_wait(), here the vres
452 * specifies to be awakened by the arrival of a signal operation
453 * instead of at a precise point of time.
455 * This function can also be called to schedule the first job of a
456 * recently created vres and make it start when a signal operation
457 * has been sent from another thread.
459 * The vres' budget will be made zero for the remainder of the vres'
460 * period, and FRSH will not replenish it until an event has been
461 * notified to the synchronisation object by another vres.
463 * It can happen that the synchronisation object has notification
464 * events queued from the past, in this case one of the events is
465 * dequeued immediately and the vres won't have to wait for another
468 * At the time of reception of a notification event (wether in the
469 * future or in the past), all pending budget replenishments (if any)
470 * are made effective. Once the vres has a positive budget and the
471 * scheduler schedules the calling thread again, the call returns and
472 * the vres continues executing.
474 * If the synchronisation object is destroyed while the vres was
475 * waiting on it, the vres will be awaken and the function will
476 * return with a code FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE
478 * Except for those parameters equal to NULL pointers, the system
479 * reports the current period and budget for the current job, it informs
480 * if the deadline of the previous job was missed or not, and whether the
481 * budget of the previous job was overrun or not.
483 * In a system with hierarchical scheduling, since this call makes the
484 * budget of the current period zero, the other threads in the same
485 * vres are not run. As mentioned above, only when the call finishes
486 * the budget may be replenished.
488 * @param synch_handle Synchronisation object upon which the vres
490 * @param next_budget[out] Upon return of this function, the variable
491 * pointed by this function will be equal to
492 * the current vres budget. If this parameter is
493 * set to NULL, no action is taken
494 * @param next_period[out] The vres period upon return (ignored if NULL).
495 * @param was_deadline_missed Upon return whether the deadline was
496 * missed in the previous period.
497 * @param was_budget_overran
500 * @return 0 if success \n
501 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
503 * FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
505 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled
507 * FRSH_ERR_NOT_BOUND : if the calling thread does not have a valid
508 * vres bound to it \n
509 * FRSH_ERR_BAD_ARGUMENT : if synch_handle is 0 \n
510 * FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE if the synch_handle is not
511 * valid or was destroyed while the vres was waiting on it. \n
512 * FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload of the vres
513 * is not FRSH_BOUNDED
516 int frsh_synchobj_wait
517 (const frsh_synchobj_handle_t synch_handle,
518 frsh_rel_time_t *next_budget,
519 frsh_rel_time_t *next_period,
520 bool *was_deadline_missed,
521 bool *was_budget_overran);
525 * frsh_synchobj_wait_with_timeout()
527 * This call is the same as frsh_synchobj_wait() but with an extra
528 * absolute timeout. The timed_out argument, indicates whether the
529 * function returned because of the expiration of the timeout or not.
531 * @return 0 if no error \n
532 * FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE if the synch_handle is not
534 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
536 * FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
538 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled
540 * FRSH_ERR_NOT_BOUND : if the calling thread does not have a valid
541 * vres bound to it \n
542 * FRSH_ERR_BAD_ARGUMENT : if the synch_handle given is not valid or the
543 * abs_timeout argument is NULL or its value is in the past\n
544 * FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload of the vres
545 * is not FRSH_BOUNDED
548 int frsh_synchobj_wait_with_timeout
549 (const frsh_synchobj_handle_t synch_handle,
550 const frsh_abs_time_t *abs_timeout,
552 frsh_rel_time_t *next_budget,
553 frsh_rel_time_t *next_period,
554 bool *was_deadline_missed,
555 bool *was_budget_overran);
558 * frsh_synchobj_signal()
560 * This function sends a notification event to the synchronization object
561 * specified as parameter. If there is at least one vres waiting on
562 * the synchronization object, it is awaken. If more than one vres
563 * are waiting, just one of them is awaken. However, which one is
564 * awaken is implementation dependent. If no vres is waiting on the
565 * synchronization object, the notification event is queued.
567 * @param [in] synch_handle the handle of the synchronization object to
570 * @return 0 if no error \n
571 * FRSH_ERR_BAD_ARGUMENT : if synch_handle is 0 \n
572 * FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE if the handle is not valid \n
573 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
574 * scheduled under FRSH \n
575 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
577 * FRSH_ERR_TOO_MANY_EVENTS_IN_SYNCH_OBJ : if the number of events stored
578 * in the synchronization object reaches the maximum defined in the
579 * configuration parameter header file
581 * @sa frsh_synchobj_wait, frsh_synchobj_wait_with_timeout
583 int frsh_synchobj_signal
584 (const frsh_synchobj_handle_t synch_handle);
589 * This operation is invoked by threads associated with bounded
590 * workload vres to indicate that a job has been completed (and
591 * that the scheduler may reassign the unused capacity of the current
592 * job to other vres). It is also invoked when the first job of
593 * such threads has to be scheduled.
595 * As an effect, the system will make the current vres's budget zero
596 * for the remainder of the vres's period, and will not replenish
597 * the budget until the specified absolute time. At that time, all
598 * pending budget replenishments (if any) are made effective. Once the
599 * vres has a positive budget and the scheduler schedules the
600 * calling thread again, the call returns and at that time, except for
601 * those parameters equal to NULL pointers, the system reports the
602 * current period and budget for the current job, whether the deadline
603 * of the previous job was missed or not, and whether the budget of
604 * the previous job was overrun or not.
606 * In a system with hierarchical scheduling, since this call makes the
607 * budget zero, the other threads in the same vres are not run. As
608 * mentioned abobe, only when the call finishes the budget may be
611 * @param [in] abs_time absolute time at which the budget will be
614 * @param [out] next_budget upon return of this function, the variable
615 * pointed by this function will be equal to
616 * the current vres budget. If this parameter is
617 * set to NULL, no action is taken.
619 * @param [out] next_period upon return of this function, the variable
620 * pointed by this function will be equal to
621 * the current vres period. If this parameter is
622 * set to NULL, no action is taken.
624 * @param [out] was_deadline_missed upon return of this function, the
625 * variable pointed by this function will be
626 * equal to true if the previous vres deadline
627 * was missed, to false otherwise. If this
628 * parameter is set to NULL, no action is
631 * @param [out] was_budget_overrun upon return of this function, the
632 * variable pointed by this function will be
633 * equal to true if the previous vres budget was
634 * overrun, to false otherwise. If this
635 * parameter is set to NULL, no action is
638 * @return 0 if the operation is successful \n
639 * FRSH_ERR_TIME_SPEC_IN_THE_PAST if the absolute time specification
641 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong
643 * FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
645 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling
646 * thread is not scheduled under FRSH \n
647 * FRSH_ERR_NOT_BOUND : if the calling thread does not have a valid
648 * vres bound to it \n
649 * FRSH_ERR_BAD_ARGUMENT : if abs_time is NULL \n
650 * FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload of the vres
651 * is not FRSH_BOUNDED
654 * @sa frsh_synchobj_wait, frsh_synchobj_wait_with_timeout
657 (const frsh_abs_time_t *abs_time,
658 frsh_rel_time_t *next_budget,
659 frsh_rel_time_t *next_period,
660 bool *was_deadline_missed,
661 bool *was_budget_overran);
666 * frsh_vresperiod_wait()
668 * Suspend the calling thread until the start of the specified virtual
669 * resource period of a vres_id, for a synchronized workload.
671 * Virtual resource periods are numbered. The number of the current
672 * period can be obtained through the frsh_vres_get_period_number()
675 int frsh_vresperiod_wait(unsigned long period_num,
676 frsh_rel_time_t *next_budget,
677 frsh_rel_time_t *next_period,
678 bool *was_deadline_missed,
679 bool *was_budget_overran);
683 * frsh_vres_get_period()
685 * Return the current period number, for a virtual resource of
686 * synchronized workload.
688 int frsh_vres_get_period_number
689 (const frsh_vres_id_t vres,
697 ///////////////////////////////////////////////////////////////////
698 // CONTRACT NEGOCIATION OPERATIONS
699 ///////////////////////////////////////////////////////////////////
702 * @defgroup negotiate Negotiate contract functions
705 * The following functions are used to negotiate contracts and thus
706 * creating vres which are the execution image of a contract.
707 * Besides, these functions allow to assign and unassign threads to
710 * In the case of more than one thread per vres please refer to the
711 * hierarchical module.
719 * frsh_contract_negotiate()
721 * The operation negotiates a contract and if accepted it will return
722 * a vres_id. It will also check that the given contract_label is unique
725 * If the on-line admission test is enabled, it determines whether the
726 * contract can be admitted or not based on the current contracts
727 * established in the system. Then it creates the vres and
728 * recalculates all necessary parameters for the contracts already
729 * present in the system.
731 * This is a potentially blocking operation, it returns when the
732 * system has either rejected the contract, or admitted it and made it
733 * effective. No thread is bound to the newly created vres, which
734 * will be idle until a thread is bound to it via frsh_thread_bind()
735 * or frsh_thread_create_and_bind().
737 * This operation can only be executed by threads that are already
738 * bound to an active vres and therefore are being scheduled by the
741 * @return 0 if successful \n
742 * FRSH_ERR_CONTRACT_REJECTED: The contract is not accepted.\n
743 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
745 * FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
747 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled
748 * under FRSH scheduler \n
749 * FRSH_ERR_BAD_ARGUMENT : if the contract or vres arguments are NULL \n
750 * FRSH_ERR_TOO_MANY_VRES : if there is no space for more vres
751 * (the maximum number of them is already reached) \n
752 * FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS : contract_label is not unique.
755 int frsh_contract_negotiate
756 (const frsh_contract_t *contract,
757 frsh_vres_id_t *vres);
760 * frsh_thread_create_and_bind()
762 * This operation creates a thread and binds it to an existing vres.
764 * This is the preferred way to add threads to the application because
765 * we make sure that the thread won't become unbound.
767 * The vres must not have any thread binded to it. If you want to
768 * bind more than one thread to the vres you must use the
769 * hierarchical module.
771 * The frsh_thread_attr_t parameter is overwritten as necessary to
772 * introduce the adequate scheduling policy and priority, according
773 * to the preemption level given in the contract and the
774 * frsh_priority_map() function defined by the user.
776 * @param[in] vres_id vres with which the thread will be bound.
777 * @param[out] thread frsh_thread_id returned by the system.
778 * @param attr pthread_attr taken and maybe corrected
779 * by the system. Ignored if NULL
780 * @param[in] thread_code Thread function (void func(void *) )
781 * that will constitute the main of the
783 * @param[in] arg Argument for data to be passed at the
784 * thread. Set to NUL if you don't want
785 * to do anything like this.
787 * @return 0 if successful \n
788 * FRSH_ERR_BAD_ARGUMENT : if the contract or vres arguments are
790 * FRSH_ERR_CONTRACT_REJECTED : if the contract is rejected. \n
792 * It may also return all the errors that may be returned by the
793 * fosa_thread_create() function call
796 int frsh_thread_create_and_bind
797 (const frsh_vres_id_t vres,
798 frsh_thread_id_t *thread,
799 frsh_thread_attr_t *attr,
800 frsh_thread_code_t thread_code,
805 * frsh_thread_create_in_background()
807 * This function creates a "background contract" that does not need to
808 * be negotiated, creates a threads and binds to the new vres.
810 * This method is suggested as a way to initate components and
811 * plugins. The event that triggers the component activation should
812 * arrive to an application thread that could use this function to
813 * create a thread used in its initialisation.
815 * The attribute parameter is overwritten as necessary to introduce
816 * the adequate scheduling policy and priority.
818 * @param[in] thread_code Function to be executed by the new
820 * @param[in] thread_arg General pointer that will be passed to
821 * the new thread as initialisation data.
822 * @param attr Pthread attribute with thread params
823 * @param[in] contract_label Contract label for the new vres.
824 * @param[out] thread_id Id of the new thread.
825 * @param[out] vres_id vres_id of the new vres.
827 * @return 0 if successful \n
828 * FRSH_ERR_BAD_ARGUMENT : Any problems with the argument \n
829 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is
830 * not scheduled under FRSH \n
831 * FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS : contract_label is not unique \n
832 * FRSH_ERR_TOO_MANY_VRES : if there is no space for more vres
833 * (the maximum number of them is already reached)
836 int frsh_thread_create_in_background
837 (frsh_thread_code_t thread_code,
838 const void *thread_arg,
839 const char *contract_label,
840 frsh_thread_attr_t *attr,
841 frsh_thread_id_t *thread_id,
842 frsh_vres_id_t *vres_id);
847 * frsh_thread_join_in_background()
849 * This function is aimed for external threads to join FRSH in the
850 * least disturbing possible mode.
852 * Upon calling this function by a thread which has been created
853 * natively in the OS, it joins the framework and gets inmediately
854 * bound to an on-the-fly generated background contract.
856 * In order to gain a higher priority then it can renegotiate a
857 * contract for its vres with the needed parameters.
859 * @param[in] resource_id: Resource (CPU) in which the vres will
862 * @param[in] resource_type: Resource type (should be CPU) for the
865 * @param[in] label: Label to be added to the contract.
867 * @param[out] vres_id: Resulting vres_id from the on-the-fly
868 * generated background contract.
870 * @return 0 if successful\n
871 * FRSH_ERR_NOT_CONTRACTED_VRES if the thread is already
874 int frsh_thread_join_in_background(frsh_resource_id_t resource_id,
875 frsh_resource_type_t resource_type,
877 frsh_vres_id_t *vres_id);
884 * This operation associates a thread with a vres, which means that
885 * it starts consuming the vres's budget and is executed according
886 * to the contract established for that vres. If the thread is
887 * already bound to another vres, it is effectively unbound from it
888 * and bound to the specified one.
890 * It fails if the vres's policy is different than FRSH_NONE, or if
891 * there is already a thread bound to this vres. In order to bind
892 * more than one vres to the same thread you must use the
893 * hierarchical module.
895 * Implementation dependent issue: In order to allow the usage of
896 * application defined schedulers, the given thread must not have the
897 * scheduling policy SCHED_APP and at the same time be attached to an
898 * application scheduler different than the frsh scheduler.
900 * @return 0 if successful \n
901 * FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
903 * FRSH_ERR_UNKNOWN_APPSCHEDULED_THREAD : if the thread is attached to
904 * an application defined scheduler different than the frsh
906 * FRSH_ERR_BAD_ARGUMENT : if the vres value does not complain with the
907 * expected format or valid range or the given thread does not
909 * FRSH_ERR_NOT_CONTRACTED_VRES : if the referenced vres is not
911 * FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload
912 * of the vres is FRSH_OVERHEAD \n
913 * FRSH_ERR_ALREADY_BOUND : if the given vres has a thread already
918 (const frsh_vres_id_t vres,
919 const frsh_thread_id_t thread);
923 * frsh_thread_unbind()
925 * This operation unbinds a thread from a vres. Since threads with
926 * no vres associated are not allowed to execute, they remain in a
927 * dormant state until they are either eliminated or bound again.
929 * If the thread is inside a critical section the effects of this call
930 * are deferred until the critical section is ended
932 * Implementation dependent issue: in the implementation with an
933 * application scheduler, the thread is still attached to the frsh
934 * scheduler, but suspended.
936 * @return 0 if successful \n
937 * FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
939 * FRSH_ERR_BAD_ARGUMENT : if the given thread does not exist \n
940 * FRSH_ERR_NOT_SCHEDULED_THREAD : if the given thread is not scheduled
942 * FRSH_ERR_UNKNOWN_APPSCHEDULED_THREAD : if the thread is attached to
943 * an application defined scheduler different than the frsh
945 * FRSH_ERR_NOT_BOUND : if the given thread does not have a valid
948 int frsh_thread_unbind(const frsh_thread_id_t thread);
951 * frsh_vres_set_notification()
953 * This function setups notification signals for CPU vres. It is
954 * necessary to call this function before bounding the thread to the
957 * @param [in] budget_overrun_signal contains the number of the signal
958 * that must be raised if the budget of the vres is
959 * overrun by the thread.
960 * If the value of this parameter is FRSH_NULL_SIGNAL, no signal will
962 * @param [in] budget_overrun_siginfo contains the value that will be
963 * passed to the signal "catcher" when the signal is raised.
964 * This parameters is not used if the budget_overrun_signal
965 * parameter is set to FRSH_NULL_SIGNAL.
966 * @param [in] deadline_miss_signal contains the number of the
967 * signal that must be raised if the deadline of the
968 * vres is missed. If the value of this parameter is
969 * FRSH_NULL_SIGNAL, no signal is raised.
970 * @param [in] deadline_miss_siginfo contains the value that will be
971 * passed to the signal "catcher" when the signal is
972 * raised. This parameter is not used if the
973 * deadline_signal parameter is set to NULL_SIGNAL
975 int frsh_vres_set_notification(
977 const frsh_signal_t budget_overrun_signal,
978 const frsh_signal_info_t budget_overrun_siginfo,
979 const frsh_signal_t deadline_miss_signal,
980 const frsh_signal_info_t deadline_miss_siginfo);
983 * frsh_thread_get_vres_id()
985 * This operation stores the Id of the vres associated with the
986 * specified thread in the variable pointed to by vres. It returns
987 * an error if the thread does not exist, it is not under the control
988 * of the scheduling framework, or is not bound.
990 * @return 0 if no error \n
991 * FRSH_ERR_NOT_SCHEDULED_THREAD : if the given thread is not scheduled
993 * FRSH_ERR_NOT_BOUND : if the given thread does not have a valid
994 * vres bound to it \n
995 * FRSH_ERR_BAD_ARGUMENT : if the given thread does not exist or the
996 * vres argument is NULL
999 int frsh_thread_get_vres_id(const frsh_thread_id_t thread,
1000 frsh_vres_id_t *vres_id);
1003 * frsh_vres_get_priority()
1005 * This operation stores the priority currently associated
1006 * with the specified vres in the variable pointed to by
1007 * priority. It returns an error if the vres_id is not recognised.
1009 * @return 0 if no error \n
1010 * FRSH_ERR_BAD_ARGUMENT : if the contract argument is NULL or the value
1011 * of the vres argument is not in range \n
1012 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1013 * scheduled under FRSH \n
1014 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1016 * FRSH_ERR_NOT_CONTRACTED_VRES: if the vres of the calling thread
1017 * has been cancelled or it is not valid
1020 int frsh_vres_get_priority
1021 (frsh_vres_id_t vres_id,
1025 * frsh_vres_get_contract()
1027 * This operation stores the contract parameters currently associated
1028 * with the specified vres in the variable pointed to by
1029 * contract. It returns an error if the vres_id is not recognised.
1031 * @return 0 if no error \n
1032 * FRSH_ERR_BAD_ARGUMENT : if the contract argument is NULL or the value
1033 * of the vres argument is not in range \n
1034 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1035 * scheduled under FRSH \n
1036 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1038 * FRSH_ERR_NOT_CONTRACTED_VRES: if the vres of the calling thread
1039 * has been cancelled or it is not valid
1042 int frsh_vres_get_contract
1043 (const frsh_vres_id_t vres,
1044 frsh_contract_t *contract);
1047 * frsh_resource_get_vres_from_label()
1049 * This operation retrieves the vres_id whose contract_label
1050 * corresponds to the parameter in the resource_id and resource_type
1053 * The contract label must refer to a contract negotiated
1054 * in the same processing node in which the call is being
1055 * made. Otherwise an error is returned.
1057 * @return 0 if no error \n
1058 * FRSH_ERR_BAD_ARGUMENT : if the contract argument is NULL or the
1059 * contract_label is NULL \n
1060 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1061 * scheduled under FRSH \n
1062 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1064 * FRSH_ERR_CONTRACT_LABEL_UNKNOWN: if the contract_label is not known
1066 int frsh_resource_get_vres_from_label
1067 (const char *contract_label,
1068 const frsh_resource_type_t resource_type,
1069 const frsh_resource_id_t resource_id,
1070 frsh_vres_id_t *vres);
1075 * frsh_contract_cancel()
1077 * The operation eliminates the specified vres
1078 * and recalculates all necessary parameters for the contracts
1079 * remaining in the system. This is a potentially blocking operation;
1080 * it returns when the system has made the changes effective.
1082 * Note that the thread is not eliminated. We leave the application
1083 * the option to either freeze it for a later use or bind it to
1086 * @return 0 if successful \n
1087 * FRSH_ERR_BAD_ARGUMENT : if the value of vres is not in range \n
1088 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1089 * scheduled under FRSH \n
1090 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1092 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1093 * has been cancelled or it is not valid
1096 int frsh_contract_cancel (const frsh_vres_id_t vres);
1100 * frsh_contract_renegotiate_sync()
1102 * The operation renegotiates a contract for an existing vres. If
1103 * the on-line admission test is enabled it determines whether the
1104 * contract can be admitted or not based on the current contracts
1105 * established in the system. If it cannot be admitted, the old
1106 * contract remains in effect and an error is returned. If it can be
1107 * admitted, it recalculates all necessary parameters for the
1108 * contracts already present in the system and returns zero. This is a
1109 * potentially blocking operation; it returns when the system has
1110 * either rejected the new contract, or admitted it and made it
1113 * @return 0 if successful \n
1114 * FRSH_ERR_BAD_ARGUMENT : if the new_contract argument is NULL or the
1115 * value of the vres argument is not in range \n
1116 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1117 * scheduled under FRSH \n
1118 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1120 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1121 * has been cancelled or it is not valid \n
1122 * FRSH_ERR_CONTRACT_REJECTED : if the renegotiation fails
1125 int frsh_contract_renegotiate_sync
1126 (const frsh_contract_t *new_contract,
1127 const frsh_vres_id_t vres);
1131 * frsh_contract_renegotiate_async()
1133 * The operation enqueues a renegotiate operation for an existing
1134 * vres, and returns immediately. The renegotiate operation is
1135 * performed asynchronously, as soon as it is practical; meanwhile the
1136 * system operation will continue normally. When the renegotiation is
1137 * made, if the on-line admission test is enabled it determines
1138 * whether the contract can be admitted or not based on the current
1139 * contracts established in the system. If it cannot be admitted, the
1140 * old contract remains in effect. If it can be admitted, it
1141 * recalculates all necessary parameters for the contracts already
1142 * present in the system.
1144 * When the operation is completed, notification is made to the
1145 * caller, if requested, via a signal. The status of the operation (in
1146 * progress, admitted, rejected) can be checked with the
1147 * frsh_vres_get_renegotiation_status() operation. The argument
1148 * sig_notify can be FRSH_NULL_SIGNAL (no notification), or any FRSH
1149 * signal value and in this case signal_info is to be sent with the signal.
1151 * @param[in] new_contract New contract parameters for the new
1152 * situation if approved.
1153 * @param[in] vres vres_id on which to do the renegotiation.
1154 * @param[in] signal_to_notify Signal number to use to notify vres of
1155 * the negotiation result. If
1156 * FRSH_NULL_SIGNAL, no signal will be raised.
1157 * @param[in] signal_info: Associated info that will come with the
1158 * signal. This parameter will be ignored
1159 * if signal_to_notify == FRSH_NULL_SIGNAL.
1161 * @return 0 if no error \n
1162 * FRSH_ERR_BAD_ARGUMENT : if the new_contract argument is NULL, the
1163 * value of the vres argument is not in range or sig_notify is
1164 * neither NULL nor a valid POSIX signal \n
1165 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1166 * scheduled under FRSH \n
1167 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1169 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1170 * has been cancelled or it is not valid
1173 int frsh_contract_renegotiate_async
1174 (const frsh_contract_t *new_contract,
1175 const frsh_vres_id_t vres,
1176 const frsh_signal_t signal_to_notify,
1177 const frsh_signal_info_t signal_info);
1181 * frsh_vres_get_renegotiation_status()
1183 * The operation reports on the status of the last renegotiation
1184 * operation enqueued for the specified vres. It is callable even
1185 * after notification of the completion of such operation, if
1188 * If the vres is not and has not been involved in any of the
1189 * frsh_contract_renegotiate_async() or frsh_group_change_mode_async()
1190 * operations, the status returned is FRSH_RS_NOT_REQUESTED
1192 * @return 0 if no error \n
1193 * FRSH_ERR_BAD_ARGUMENT : if the renegotiation_status argument is
1194 * NULL or the value of the vres argument is not in range \n
1195 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1196 * scheduled under FRSH \n
1197 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1199 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1200 * has been cancelled or it is not valid
1203 int frsh_vres_get_renegotiation_status
1204 (const frsh_vres_id_t vres,
1205 frsh_renegotiation_status_t *renegotiation_status);
1209 ////////////////////////////////////////////////////////////////////////
1210 // CHANGE OF MODE: GROUPS OF CONTRACTS
1211 ////////////////////////////////////////////////////////////////////////
1213 * @defgroup groupofcontracts Group of contracts
1216 * The following functions are used to negotiate atomically more than
1217 * one contract. This allows to build complex applications by
1218 * splitting them in individual contracts that are negotiated
1219 * simultaneously and atomically.
1225 * frsh_group_change_mode_sync()
1227 * This function performs a set of negotiation operations which can
1228 * include: adding new contracts (neg), modifying existing vres (reneg)
1229 * or cancelling existing vres (cancel).
1231 * If one of the group operations has a NULL value, unless it causes an
1232 * inconsistency the system will suppose that no operation of that
1233 * type (neg, reneg or cancel) should be done.
1235 * The virtual resources resulting from negotiations of new contracts are
1236 * returned in the parameter 'new_vres' which must be provided by the user.
1238 * If the on-line admission test is enabled, FRSH analizes the
1239 * schedulability of the context that would result in the new
1240 * contract situation with removed, changed and added contracts.
1242 * A successful return code will mean that all contracts have been
1243 * accepted and all required operations (creation, cancellation or
1244 * update of vres) have been carried out to reach the new running
1247 * If any of the contracts is not accepted a corresponding error shall be
1248 * returned and no changes will be made to the previously running context.
1250 * This call is a synchronous, potentially blocking operation. It
1251 * returns when the system has rejected the contracts or accepted
1252 * and made them effective.
1254 * @param[in] contracts_to_neg List of new contracts to negotiate
1255 * @param[in] contracts_to_reneg List of contracts to renegotiate
1256 * @param[in] vres_to_reneg List of vres to renegotiate
1257 * @param[in] vres_to_cancel List of vres to cancel
1258 * @param[out] new_vres List of vres of new contracts.
1260 * @return 0 if no error \n
1261 * FRSH_ERR_BAD_ARGUMENT Invalid pointer or group identifier. \n
1262 * FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS contract_label not unique. \n
1263 * FRSH_ERR_NOT_CONTRACTED_VRES: One of the provided vres_ids
1264 * is not recognised. \n
1265 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD The calling thread
1266 * is not scheduled under FRSH. \n
1267 * FRSH_ERR_INVALID_SCHEDULER_REPLY: The scheduler is wrong or
1269 * FRSH_ERR_INTERNAL_ERROR: Erroneous binding or malfunction of
1270 * FRSH main scheduler. \n
1271 * FRSH_ERR_REJECTED_CONTRACT: The negotiation of one of the
1272 * proposed contracts has failed.
1274 int frsh_group_change_mode_sync
1275 (const frsh_contracts_group_t *contracts_to_neg,
1276 const frsh_contracts_group_t *contracts_to_reneg,
1277 const frsh_vres_group_t *vres_to_reneg,
1278 const frsh_vres_group_t *vres_to_cancel,
1279 frsh_vres_group_t *new_vres);
1282 * frsh_group_change_mode_async()
1284 * This is an asynchronous (non-blocking) version of the previous function,
1285 * frsh_group_change_mode_sync() and thus, it returns inmediately.
1287 * The status of the change of mode and the identifiers for new virtual
1288 * resources must be requested with the function 'frsh_group_get_status'
1289 * by using the return parameter 'group'.
1291 * As in the asynchronous renegotiations, when the operation is completed,
1292 * the user is notified with a signal so he can check the final result with
1293 * 'frsh_group_get_status'. In case that FRSH_NULL_SIGNAL is used, no
1294 * signal will be sent to the user.
1296 * @param[in] contracts_to_neg List of new contracts to negotiate
1297 * @param[in] contracts_to_reneg List of contracts to renegotiate
1298 * @param[in] vres_to_reneg List of vres to renegotiate
1299 * @param[in] vres_to_cancel List of vres to cancel
1300 * @param[in] signal Signal number to notify completion of
1301 * the change of mode. If FRSH_NULL_SIGNAL,
1302 * no signal will be raised.
1303 * @param[in] signal_info Data associated to the signal
1304 * @param[out] group The group identifier to get the status
1306 * @return 0 if no error \n
1307 * FRSH_ERR_BAD_ARGUMENT Invalid pointer, signal or group identifier. \n
1308 * FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS contract_label not unique. \n
1309 * FRSH_ERR_NOT_CONTRACTED_VRES: One of the provided vres_ids
1310 * is not recognised. \n
1311 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD The calling thread
1312 * is not scheduled under FRSH. \n
1313 * FRSH_ERR_INVALID_SCHEDULER_REPLY: The scheduler is wrong or
1315 * FRSH_ERR_INTERNAL_ERROR: Erroneous binding or malfunction of
1316 * FRSH main scheduler.
1318 int frsh_group_change_mode_async
1319 (const frsh_contracts_group_t *contracts_to_neg,
1320 const frsh_contracts_group_t *contracts_to_reneg,
1321 const frsh_vres_group_t *vres_to_reneg,
1322 const frsh_vres_group_t *vres_to_cancel,
1323 const frsh_signal_t signal,
1324 const frsh_signal_info_t signal_info,
1325 frsh_group_id_t *group);
1328 * frsh_group_get_status()
1330 * This function is similar to 'frsh_vres_get_renegotiation_status' but it
1331 * is intented for group negotiations (changes of mode).
1333 * The operation reports on the status of the last negotiation
1334 * operation enqueued for the specified group identifier.
1336 * The status value can be one of the following values:
1338 * - FRSH_RS_IN_PROGRESS: the change of mode is in progress
1339 * - FRSH_RS_REJECTED: the change of mode was not accepted
1340 * - FRSH_RS_ADMITTED: the change of mode was accepted
1341 * - FRSH_RS_NOT_REQUESTED: no change of mode has been requested yet
1343 * When status returns 'FRSH_RS_ADMITTED', the array 'new_vres' contains
1344 * the values for the new virtual resources (if there was any).
1346 * This function frees the group identifier when status returns something
1347 * different than FRSH_RS_IN_PROGRESS so further calls to this function may
1348 * return inconsistent values.
1350 * @param[in] group The group identifier
1351 * @param[out] status The status of the change of mode
1352 * @param[out] new_vres List of vres for the negotiation of new contracts.
1354 * @return 0 if no error \n
1355 * FRSH_ERR_BAD_ARGUMENT Invalid pointer, signal or group identifier. \n
1356 * FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS contract_label not unique. \n
1357 * FRSH_ERR_NOT_CONTRACTED_VRES: One of the provided vres_ids
1358 * is not recognised. \n
1359 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD The calling thread
1360 * is not scheduled under FRSH. \n
1361 * FRSH_ERR_INVALID_SCHEDULER_REPLY: The scheduler is wrong or
1363 * FRSH_ERR_INTERNAL_ERROR: Erroneous binding or malfunction of
1364 * FRSH main scheduler.
1366 int frsh_group_get_status(const frsh_group_id_t group,
1367 frsh_renegotiation_status_t *status,
1368 frsh_vres_group_t *new_vres);
1374 ////////////////////////////////////////////////////
1375 // OBTAINING INFORMATION FROM THE SCHEDULER
1376 ////////////////////////////////////////////////////
1379 * @defgroup getschedinfo Obtaining information from the scheduler
1383 * The following functions are used to obtain available budget and
1384 * resource usage in the system. They can be used to adapt the
1385 * execution of threads according to the load of the system.
1392 * frsh_config_is_admission_test_enabled()
1394 * Returns true if the system is
1395 * configured with the on-line admission test enabled, or false
1396 * otherwise. This situation can only be changed at compile time.
1398 bool frsh_config_is_admission_test_enabled();
1401 * frsh_vres_get_usage()
1403 * This function stores the current execution time spent by the
1404 * threads bound to the specified vres in the variable pointed to by
1407 * @return 0 if successful \n
1408 * FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range or
1409 * cpu_time is NULL \n
1410 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1411 * scheduled under FRSH \n
1412 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1414 * FRSH_ERR_NOT_CONTRACTED_VRESR : if the vres of the calling thread
1415 * has been cancelled or it is not valid
1418 int frsh_vres_get_usage
1419 (const frsh_vres_id_t vres,
1420 frsh_rel_time_t *spent);
1424 * frsh_vres_get_job_usage()
1426 * Get the execution time of the current job of the specified virtual
1427 * resource for a bounded or synchronized workload.
1429 int frsh_vres_get_job_usage
1430 (const frsh_vres_id_t vres,
1431 frsh_rel_time_t *spent);
1435 * frsh_vres_get_remaining_budget()
1437 * This function stores in the variable pointed to by budget the
1438 * remaining execution-time budget associated with the specified
1441 * @return 0 if successful \n
1442 * FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range or
1444 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1445 * scheduled under FRSH \n
1446 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1448 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1449 * has been cancelled or it is not valid
1452 int frsh_vres_get_remaining_budget
1453 (const frsh_vres_id_t vres,
1454 frsh_rel_time_t *budget);
1458 * frsh_vres_get_budget_and_period()
1460 * This function stores in the variables
1461 * pointed to by budget and period, the execution-time budget and the
1462 * period respectively associated with the specified vres. If any of
1463 * these pointers is NULL, the corresponding information is not stored.
1465 * @return 0 if successful \n
1466 * FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range,
1467 * or budget and period are both NULL \n
1468 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1469 * scheduled under FRSH \n
1470 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1472 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1473 * has been cancelled or it is not valid
1476 int frsh_vres_get_budget_and_period
1477 (const frsh_vres_id_t vres,
1478 frsh_rel_time_t *budget,
1479 frsh_rel_time_t *period);
1483 /////////////////////////////////////////////////////////////////////
1484 // SERVICE THREAD TUNING
1485 /////////////////////////////////////////////////////////////////////
1487 * @defgroup servthtuning Service thread tuning
1491 * The following functions are used to obtain available budget and
1492 * resource usage in the system. They can be used to adapt the
1493 * execution of threads to the load of the system.
1499 * frsh_service_thread_set_data()
1501 * This function allows the application to change the period and
1502 * budget of the service thread that makes the
1503 * negotiations. Increasing the utilization of this thread makes the
1504 * negotiations faster, but introduces additional load in the system
1505 * that may decrease the bandwidth available for the vres. For this
1506 * call, the system will make a schedulability analysis to determine
1507 * if the new situation is acceptable or not. This is reported back in
1508 * the variable pointed to by accepted. If the new service thread data
1509 * is accepted, the system will reassign budgets and periods to the
1510 * vres according to the new bandwidth available, in the same way
1511 * as it does for a regular contract negotiation.
1513 * When its budget is exhausted, the service thread may run in the
1516 * The service thread starts with a default budget and period that are
1519 * Implementation dependency: in the fixed priority implementtaion of
1520 * frsh, the default priority is lower than the priority of any vres,
1521 * but higher than the background. According to the
1522 * implementation-dependent module the priority is adjustable by means
1523 * of a function that changes its preemption level
1525 * @return 0 if successful \n
1526 * FRSH_ERR_BAD_ARGUMENT : if any of the pointer arguments is NULL or
1527 * the budget value is greater than the period value \n
1528 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1529 * scheduled under FRSH \n
1530 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1532 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1533 * has been cancelled or it is not valid
1536 int frsh_service_thread_set_data (const frsh_rel_time_t *budget,
1537 const frsh_rel_time_t *period,
1541 * frsh_service_thread_get_data()
1543 * this function returns in the variables pointed by budget and
1544 * period, respectively, the current budget and period of the service
1547 * @return 0 if successful \n
1548 * FRSH_ERR_BAD_ARGUMENT : if any of the pointer arguments is NULL \n
1549 * FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1550 * scheduled under FRSH \n
1551 * FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1553 * FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1554 * has been cancelled or it is not valid
1557 int frsh_service_thread_get_data
1558 (frsh_rel_time_t *budget,
1559 frsh_rel_time_t *period);
1565 ////////////////////////////////////////////////////////////////////////
1566 // BACKGROUND MANAGEMENT
1567 ////////////////////////////////////////////////////////////////////////
1569 //A round-robin background scheduling policy is available for those
1570 //threads that do not have real-time requirements. Because some of
1571 //these threads may require sharing information with other threads run
1572 //by regular vres. Special background contracts may be created for
1573 //specifying the synchronization requirements.
1575 //The way of specifying a background contract is by setting
1576 //contract_type to FRSH_CT_BACKGROUND. Negotiation may fail if the contract uses
1577 //shared_objects. If the contract has no shared_objects the returned
1578 //vres id represents the background and may be used to bind more
1579 //than one thread. If the contract has shared objects a vres is
1580 //created to keep track of them, but the associated threads are
1581 //executed in the background, together with the other background
1585 ////////////////////////////////////////////////////////////////////////
1587 ////////////////////////////////////////////////////////////////////////
1590 * Returns resource id of local CPU.
1592 * The ID is determined from environment variable FRSH_CPU_ID or, if
1593 * that is not defined, the compile time default (defined in
1594 * config.target/omk).
1596 frsh_resource_id_t frsh_get_local_cpu_id(void);
1600 #endif // _FRSH_CORE_H_