]> rtime.felk.cvut.cz Git - frescor/frsh-include.git/blob - frsh_core.h
Update transaction API
[frescor/frsh-include.git] / frsh_core.h
1 // -----------------------------------------------------------------------
2 //  Copyright (C) 2006 - 2009 FRESCOR consortium partners:
3 //
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
10 //    ENEA                                   SWEDEN
11 //    Thales Communication S.A.              FRANCE
12 //    Visual Tools S.A.                      SPAIN
13 //    Rapita Systems Ltd                     UK
14 //    Evidence                               ITALY
15 //
16 //    See http://www.frescor.org for a link to partners' websites
17 //
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
21 //        made of this code.
22 //
23 //
24 //  based on previous work (FSF) done in the FIRST project
25 //
26 //   Copyright (C) 2005  Mälardalen University, SWEDEN
27 //                       Scuola Superiore S.Anna, ITALY
28 //                       Universidad de Cantabria, SPAIN
29 //                       University of York, UK
30 //
31 //   FSF API web pages: http://marte.unican.es/fsf/docs
32 //                      http://shark.sssup.it/contrib/first/docs/
33 //
34 //   This file is part of FRSH (FRescor ScHeduler)
35 //
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.
46 //
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 // -----------------------------------------------------------------------
55
56 //==============================================
57 //  ******** *******    ********  **      **
58 //  **///// /**////**  **//////  /**     /**
59 //  **      /**   /** /**        /**     /**
60 //  ******* /*******  /********* /**********
61 //  **////  /**///**  ////////** /**//////**
62 //  **      /**  //**        /** /**     /**
63 //  **      /**   //** ********  /**     /**
64 //  //       //     // ////////   //      //
65 //
66 // FRSH(FRescor ScHeduler), pronounced "fresh"
67 //==============================================
68
69 #ifndef _FRSH_CORE_H_
70 #define _FRSH_CORE_H_
71
72
73 /**
74  * @file frsh_core.h
75  **/
76
77
78 #include <time.h>
79 #include <sys/types.h>
80
81 #include "frsh_core_types.h"
82 #include "frsh_spare_capacity.h"
83
84
85 FRSH_CPP_BEGIN_DECLS
86
87 /**
88  * @defgroup core Core module
89  *
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
93  *
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
100  *
101  **/
102
103
104 //////////////////////////////////////////////////////////////////////
105 //           INITIALIZATION SERVICES
106 //////////////////////////////////////////////////////////////////////
107
108 /**
109  * @defgroup initialization Initialization services
110  * @ingroup core
111  *
112  * These functions need to be called before doing any FRSH operation
113  * (including contract initialization).
114  *
115  * @{
116  **/
117
118
119 /**
120  * frsh_init()
121  *
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.
126  *
127  * @return 0 if no error. \n
128  *  FRSH_ERR_SYSTEM_ALREADY_INITIALIZED : if the function has already
129  *                                        been called before\n
130  *  .
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
134  *
135  **/
136 int frsh_init();
137
138 /**
139  * frsh_destroy()
140  *
141  * Reverts the efect of frsh_init().
142  */
143 void frsh_destroy();
144
145 /*@}*/
146
147
148 /////////////////////////////////////////////////////////////
149 //                       CONTRACT PARAMETERS
150 /////////////////////////////////////////////////////////////
151 /**
152  * @defgroup contract Contract Creation and Initialization.
153  * @ingroup core
154  *
155  * These functions are used to create and initialize a contract, and
156  * set its parameters.
157  *
158  * @{
159  **/
160
161
162 /**
163  * frsh_contract_init()
164  *
165  * The operation receives a pointer to a contract object
166  * and initializes it, setting it to the default values.
167  *
168  * The default values are:
169  *
170  * - resource_id               => 0
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};
185  *
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
192  *
193  * - sched_policy              => DEFAULT_SCHED_POLICY (FRSH_NONE)
194  *
195  * @param     contract the pointer to the contract variable.
196  *
197  * @return 0 if no error \n
198  *     FRSH_ERR_BAD_ARGUMENT :  contract is NULL
199  *
200  **/
201 int frsh_contract_init(frsh_contract_t *contract);
202
203
204 /**
205  * frsh_contract_destroy()
206  *
207  * The operation deallocates all memory which might be allocated for
208  * the contract.
209  *
210  * @param contract the pointer to the contract variable.
211  **/
212 void frsh_contract_destroy(frsh_contract_t *contract);
213
214
215 /**
216  * frsh_contract_set_basic_params()
217  *
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
224  * quite different).
225  *
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.
233  *
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
238  *    enumerations.
239  **/
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);
246
247 /**
248  * frsh_contract_get_basic_params()
249  *
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.
253  *
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
259  *
260  * @return   0 if no error \n
261  *       FRSH_ERR_BAD_ARGUMENT :  if one of the contract or
262  *                                    pointers is NULL.
263  *
264  **/
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);
271
272 /**
273  * frsh_contract_set_resource_and_label()
274  *
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
277  *
278  * @return   0 if no error \n
279  *       FRSH_ERR_BAD_ARGUMENT :  if the contract pointer is NULL.
280  **/
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);
286
287
288 /**
289  * frsh_contract_get_resource_and_label()
290  *
291  * Obtain the resource_id and type, and the contract label.
292  *
293  * @return   0 if no error \n
294  *       FRSH_ERR_BAD_ARGUMENT :  if the contract or the contract_label
295  *                                 pointer is NULL.
296  **/
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);
302
303
304 /**
305  * frsh_contract_set_timing_reqs()
306  *
307  * The operation updates the specified contract object, specifying
308  * additional time-related requirements.
309  *
310  * @param  contract The pointer to the contract object
311  *
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.
319  *
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))
327  *
328  **/
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);
333
334 /**
335  * frsh_contract_get_timing_reqs()
336  *
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.
340  *
341  * @return 0 if no error \n
342  *   FRSH_ERR_BAD_ARGUMENT :  if contract is NULL
343  *
344  **/
345 int frsh_contract_get_timing_reqs
346   (const frsh_contract_t *contract,
347    bool                    *d_equals_t,
348    frsh_rel_time_t         *deadline);
349
350
351 /*@}*/
352
353 //////////////////////////////////////////////////////////////////
354 //                 SYNCHRONIZATION OBJECTS
355 //////////////////////////////////////////////////////////////////
356 /**
357  * @defgroup synch  Synchronization objects
358  * @ingroup core
359  *
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.
363  *
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
368  * the next period.
369  *
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.
373  *
374  * For classical signal/wait synchronisation paradigms the application
375  * must use whatever mechanism the underlying OS provides.
376  *
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
381  * loop.
382  *
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.
386  *
387  * @{
388  **/
389
390
391 /**
392  * frsh_synchobj_create()
393  *
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.
397  *
398  * @param[out]  synch_handle pointer to the variable that will contain
399  *                  the handle to the newly created synchronization object
400  *
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
404  *
405  *   FRSH_ERR_TOO_MANY_SYNCH_OBJS : if the number of synchronization
406  *      objects in the system has already exceeded the maximum\n
407  *   .
408  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
409  *      scheduled under FRSH\n
410  *   .
411  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
412  *
413  **/
414 int frsh_synchobj_create
415     (frsh_synchobj_handle_t *synch_handle);
416
417
418 /**
419  * frsh_synchobj_destroy()
420  *
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.
426  *
427  * @param synch_handle the handle to the synchronization object
428  *            to be destroyed
429  *
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
436  *                            running
437  *
438  * @sa frsh_synchobj_create
439  **/
440 int frsh_synchobj_destroy
441     (const frsh_synchobj_handle_t synchobj_handle);
442
443 /**
444  * frsh_synchobj_wait()
445  *
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).
450  *
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.
454  *
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.
458  *
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.
462  *
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
466  * one.
467  *
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.
473  *
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
477  *
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.
482  *
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.
487  *
488  * @param synch_handle   Synchronisation object upon which the vres
489  *                       will be waiting.
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
498  *
499  *
500  * @return 0 if success \n
501  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
502  *               running \n
503  *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
504  *     main scheduler \n
505  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled
506  *     under FRSH \n
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
514  *
515  **/
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);
522
523
524 /**
525  * frsh_synchobj_wait_with_timeout()
526  *
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.
530  *
531  * @return 0 if no error \n
532  *   FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE if the synch_handle is not
533  *        valid \n
534  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
535  *        running \n
536  *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
537  *     main scheduler \n
538  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled
539  *     under FRSH \n
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
546  *
547  **/
548 int frsh_synchobj_wait_with_timeout
549   (const frsh_synchobj_handle_t  synch_handle,
550    const frsh_abs_time_t         *abs_timeout,
551    bool                          *timed_out,
552    frsh_rel_time_t               *next_budget,
553    frsh_rel_time_t               *next_period,
554    bool                          *was_deadline_missed,
555    bool                          *was_budget_overran);
556
557 /**
558  * frsh_synchobj_signal()
559  *
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.
566  *
567  * @param [in] synch_handle the handle of the synchronization object to
568  *                 notify.
569  *
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
576  *            running \n
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
580  *
581  * @sa frsh_synchobj_wait, frsh_synchobj_wait_with_timeout
582  **/
583 int frsh_synchobj_signal
584     (const frsh_synchobj_handle_t synch_handle);
585
586 /**
587  * frsh_timed_wait()
588  *
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.
594  *
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.
605  *
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
609  * replenished.
610  *
611  * @param [in] abs_time     absolute time at which the budget will be
612  *                          replenished
613  *
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.
618  *
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.
623  *
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
629  *                          taken.
630  *
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
636  *                          taken.
637  *
638  * @return  0 if the operation is successful \n
639  *   FRSH_ERR_TIME_SPEC_IN_THE_PAST if the absolute time specification
640  *            is in the past. \n
641  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong
642  *             or not running \n
643  *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
644  *                                    main scheduler \n
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
652  *
653  *
654  * @sa frsh_synchobj_wait, frsh_synchobj_wait_with_timeout
655  **/
656 int frsh_timed_wait
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);
662
663
664
665 /**
666  * frsh_vresperiod_wait()
667  *
668  * Suspend the calling thread until the start of the specified virtual
669  * resource period of a vres_id, for a synchronized workload.
670  *
671  * Virtual resource periods are numbered. The number of the current
672  * period can be obtained through the frsh_vres_get_period_number()
673  * operation.
674  **/
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);
680
681
682 /**
683  * frsh_vres_get_period()
684  *
685  * Return the current period number, for a virtual resource of
686  * synchronized workload.
687  **/
688 int frsh_vres_get_period_number
689    (const frsh_vres_id_t vres,
690     long *period_num);
691
692
693
694
695 /*@}*/
696
697 ///////////////////////////////////////////////////////////////////
698 //                 CONTRACT NEGOCIATION OPERATIONS
699 ///////////////////////////////////////////////////////////////////
700
701 /**
702  * @defgroup negotiate Negotiate contract functions
703  * @ingroup core
704  *
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
708  * vres.
709  *
710  * In the case of more than one thread per vres please refer to the
711  * hierarchical module.
712  *
713  * @{
714  **/
715
716
717
718 /**
719  * frsh_contract_negotiate()
720  *
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
723  * within the node.
724  *
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.
730  *
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().
736  *
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
739  * frsh scheduler.
740  *
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
744  *                running \n
745  *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
746  *     main scheduler \n
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.
753  *
754  **/
755 int frsh_contract_negotiate
756   (const frsh_contract_t *contract,
757    frsh_vres_id_t        *vres);
758
759 /**
760  * frsh_thread_create_and_bind()
761  *
762  * This operation creates a thread and binds it to an existing vres.
763  *
764  * This is the preferred way to add threads to the application because
765  * we make sure that the thread won't become unbound.
766  *
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.
770  *
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.
775  *
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
782  *                                thread.
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.
786  *
787  * @return  0 if successful \n
788  *   FRSH_ERR_BAD_ARGUMENT : if the contract or vres arguments are
789  *               NULL \n
790  *   FRSH_ERR_CONTRACT_REJECTED : if the contract is rejected. \n
791  *   .
792  *   It may also return all the errors that may be returned by the
793  *     fosa_thread_create() function call
794  *
795  **/
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,
801    void                 *arg);
802
803
804 /**
805  * frsh_thread_create_in_background()
806  *
807  * This function creates a "background contract" that does not need to
808  * be negotiated, creates a threads and binds to the new vres.
809  *
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.
814  *
815  * The attribute parameter is overwritten as necessary to introduce
816  * the adequate scheduling policy and priority.
817  *
818  * @param[in]  thread_code   Function to be executed by the new
819  *                           thread.
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.
826  *
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)
834  *
835  **/
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);
843
844
845
846 /**
847  * frsh_thread_join_in_background()
848  *
849  * This function is aimed for external threads to join FRSH in the
850  * least disturbing possible mode.
851  *
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.
855  *
856  * In order to gain a higher priority then it can renegotiate a
857  * contract for its vres with the needed parameters.
858  *
859  * @param[in] resource_id:   Resource (CPU) in which the vres will
860  *                           be associated.
861  *
862  * @param[in] resource_type: Resource type (should be CPU) for the
863  *                           contract.
864  *
865  * @param[in] label:         Label to be added to the contract.
866  *
867  * @param[out] vres_id:      Resulting vres_id from the on-the-fly
868  *                           generated background contract.
869  *
870  * @return  0 if successful\n
871  *          FRSH_ERR_NOT_CONTRACTED_VRES if the thread is already
872  *          bound to a vres.
873  **/
874 int frsh_thread_join_in_background(frsh_resource_id_t resource_id,
875                                    frsh_resource_type_t resource_type,
876                                    const char *label,
877                                    frsh_vres_id_t *vres_id);
878
879
880
881 /**
882  * frsh_thread_bind()
883  *
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.
889  *
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.
894  *
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.
899  *
900  * @return 0 if successful \n
901  *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
902  *     main scheduler \n
903  *   FRSH_ERR_UNKNOWN_APPSCHEDULED_THREAD : if the thread is attached to
904  *     an application defined scheduler different than the frsh
905  *     scheduler \n
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
908  *     exist \n
909  *   FRSH_ERR_NOT_CONTRACTED_VRES : if the referenced vres is not
910  *      valid \n
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
914  *     bound
915  *
916  **/
917 int frsh_thread_bind
918   (const frsh_vres_id_t   vres,
919    const frsh_thread_id_t thread);
920
921
922 /**
923  * frsh_thread_unbind()
924  *
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.
928  *
929  * If the thread is inside a critical section the effects of this call
930  * are deferred until the critical section is ended
931  *
932  * Implementation dependent issue: in the implementation with an
933  * application scheduler, the thread is still attached to the frsh
934  * scheduler, but suspended.
935  *
936  * @return 0 if successful \n
937  *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
938  *     main scheduler \n
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
941  *     under FRSH \n
942  *   FRSH_ERR_UNKNOWN_APPSCHEDULED_THREAD : if the thread is attached to
943  *     an application defined scheduler different than the frsh
944  *     scheduler \n
945  *   FRSH_ERR_NOT_BOUND : if the given thread does not have a valid
946  *     vres bound to it
947  **/
948 int frsh_thread_unbind(const frsh_thread_id_t thread);
949
950 /**
951  * frsh_vres_set_notification()
952  *
953  * This function setups notification signals for CPU vres. It is
954  * necessary to call this function before bounding the thread to the
955  * vres.
956  * 
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
961  *                be raised.
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
974  **/
975 int frsh_vres_set_notification(
976         frsh_vres_id_t vres,
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);
981
982 /**
983  * frsh_thread_get_vres_id()
984  *
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.
989  *
990  * @return 0 if no error \n
991  *   FRSH_ERR_NOT_SCHEDULED_THREAD : if the given thread is not scheduled
992  *     under FRSH \n
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
997  *
998  **/
999 int frsh_thread_get_vres_id(const frsh_thread_id_t       thread,
1000                     frsh_vres_id_t *vres_id);
1001
1002 /**
1003  * frsh_vres_get_priority()
1004  *
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.
1008  *
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
1015  *        running \n
1016  *   FRSH_ERR_NOT_CONTRACTED_VRES: if the vres of the calling thread
1017  *     has been cancelled or it is not valid
1018  *
1019  **/
1020 int frsh_vres_get_priority
1021      (frsh_vres_id_t            vres_id,
1022       int *priority);
1023
1024 /**
1025  * frsh_vres_get_contract()
1026  *
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.
1030  *
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
1037  *        running \n
1038  *   FRSH_ERR_NOT_CONTRACTED_VRES: if the vres of the calling thread
1039  *     has been cancelled or it is not valid
1040  *
1041  **/
1042 int frsh_vres_get_contract
1043   (const frsh_vres_id_t vres,
1044     frsh_contract_t *contract);
1045
1046 /**
1047  * frsh_resource_get_vres_from_label()
1048  *
1049  * This operation retrieves the vres_id whose contract_label
1050  * corresponds to the parameter in the resource_id and resource_type
1051  * specified.
1052  *
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.
1056  *
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
1063  *     running \n
1064  *   FRSH_ERR_CONTRACT_LABEL_UNKNOWN: if the contract_label is not known
1065  **/
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);
1071
1072
1073
1074 /**
1075  * frsh_contract_cancel()
1076  *
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.
1081  *
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
1084  * another vres.
1085  *
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
1091  *     running \n
1092  *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1093  *     has been cancelled or it is not valid
1094  *
1095  **/
1096 int frsh_contract_cancel (const frsh_vres_id_t vres);
1097
1098
1099 /**
1100  * frsh_contract_renegotiate_sync()
1101  *
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
1111  * effective.
1112  *
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
1119  *     running \n
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
1123  *
1124  **/
1125 int frsh_contract_renegotiate_sync
1126   (const frsh_contract_t *new_contract,
1127    const frsh_vres_id_t vres);
1128
1129
1130 /**
1131  * frsh_contract_renegotiate_async()
1132  *
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.
1143  *
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.
1150  *
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.
1160  *
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
1168  *     running \n
1169  *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1170  *     has been cancelled or it is not valid
1171  *
1172  **/
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);
1178
1179
1180 /**
1181  * frsh_vres_get_renegotiation_status()
1182  *
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
1186  * requested.
1187  *
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
1191  *
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
1198  *     running \n
1199  *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1200  *     has been cancelled or it is not valid
1201  *
1202  **/
1203 int frsh_vres_get_renegotiation_status
1204   (const frsh_vres_id_t vres,
1205    frsh_renegotiation_status_t *renegotiation_status);
1206
1207 /*@}*/
1208
1209 ////////////////////////////////////////////////////////////////////////
1210 //           CHANGE OF MODE: GROUPS OF CONTRACTS
1211 ////////////////////////////////////////////////////////////////////////
1212 /**
1213  * @defgroup groupofcontracts Group of contracts
1214  * @ingroup core
1215  *
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.
1220  *
1221  * @{
1222  **/
1223
1224 /**
1225  * frsh_group_change_mode_sync()
1226  *
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).
1230  *
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.
1234  *
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.
1237  *
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.
1241  *
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
1245  * context.
1246  *
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.
1249  *
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.
1253  *
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.
1259  *
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
1268  *       not running. \n
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.
1273  **/
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);
1280
1281 /**
1282  * frsh_group_change_mode_async()
1283  *
1284  * This is an asynchronous (non-blocking) version of the previous function,
1285  * frsh_group_change_mode_sync() and thus, it returns inmediately.
1286  *
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'.
1290  *
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.
1295  *
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
1305  *
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
1314  *       not running. \n
1315  *    FRSH_ERR_INTERNAL_ERROR:  Erroneous binding or malfunction of
1316  *       FRSH main scheduler.
1317  **/
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);
1326
1327 /**
1328  * frsh_group_get_status()
1329  *
1330  * This function is similar to 'frsh_vres_get_renegotiation_status' but it
1331  * is intented for group negotiations (changes of mode).
1332  *
1333  * The operation reports on the status of the last negotiation
1334  * operation enqueued for the specified group identifier.
1335  *
1336  * The status value can be one of the following values:
1337  *
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
1342  *
1343  * When status returns 'FRSH_RS_ADMITTED', the array 'new_vres' contains
1344  * the values for the new virtual resources (if there was any).
1345  *
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.
1349  *
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.
1353  *
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
1362  *       not running. \n
1363  *    FRSH_ERR_INTERNAL_ERROR:  Erroneous binding or malfunction of
1364  *       FRSH main scheduler.
1365  **/
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);
1369
1370
1371 /*@}*/
1372
1373
1374 ////////////////////////////////////////////////////
1375 //           OBTAINING INFORMATION FROM THE SCHEDULER
1376 ////////////////////////////////////////////////////
1377
1378 /**
1379  * @defgroup getschedinfo Obtaining information from the scheduler
1380  *
1381  * @ingroup core
1382  *
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.
1386  *
1387  * @{
1388  **/
1389
1390
1391 /**
1392  * frsh_config_is_admission_test_enabled()
1393  *
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.
1397  **/
1398 bool frsh_config_is_admission_test_enabled();
1399
1400 /**
1401  * frsh_vres_get_usage()
1402  *
1403  * This function stores the current execution time spent by the
1404  * threads bound to the specified vres in the variable pointed to by
1405  * cpu_time.
1406  *
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
1413  *     running \n
1414  *   FRSH_ERR_NOT_CONTRACTED_VRESR : if the vres of the calling thread
1415  *     has been cancelled or it is not valid
1416  *
1417  **/
1418 int frsh_vres_get_usage
1419    (const frsh_vres_id_t vres,
1420     frsh_rel_time_t *spent);
1421
1422
1423 /**
1424  * frsh_vres_get_job_usage()
1425  *
1426  * Get the execution time of the current job of the specified virtual
1427  * resource for a bounded or synchronized workload.
1428  **/
1429 int frsh_vres_get_job_usage
1430     (const frsh_vres_id_t vres,
1431      frsh_rel_time_t *spent);
1432
1433
1434 /**
1435  * frsh_vres_get_remaining_budget()
1436  *
1437  * This function stores in the variable pointed to by budget the
1438  * remaining execution-time budget associated with the specified
1439  * vres.
1440  *
1441  *  @return 0 if successful \n
1442  *   FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range or
1443  *     budget is NULL \n
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
1447  *     running \n
1448  *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1449  *     has been cancelled or it is not valid
1450  *
1451  **/
1452 int frsh_vres_get_remaining_budget
1453    (const frsh_vres_id_t vres,
1454     frsh_rel_time_t *budget);
1455
1456
1457 /**
1458  * frsh_vres_get_budget_and_period()
1459  *
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.
1464  *
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
1471  *     running \n
1472  *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1473  *     has been cancelled or it is not valid
1474  *
1475  **/
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);
1480
1481 /*@}*/
1482
1483 /////////////////////////////////////////////////////////////////////
1484 //           SERVICE THREAD TUNING
1485 /////////////////////////////////////////////////////////////////////
1486 /**
1487  * @defgroup servthtuning Service thread tuning
1488  *
1489  * @ingroup core
1490  *
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.
1494  *
1495  * @{
1496  **/
1497
1498 /**
1499  * frsh_service_thread_set_data()
1500  *
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.
1512  *
1513  * When its budget is exhausted, the service thread may run in the
1514  * background
1515  *
1516  * The service thread starts with a default budget and period that are
1517  * configurable
1518  *
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
1524  *
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
1531  *     running \n
1532  *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1533  *     has been cancelled or it is not valid
1534  *
1535  **/
1536 int frsh_service_thread_set_data (const frsh_rel_time_t *budget,
1537                                   const frsh_rel_time_t *period,
1538                                   bool                  *accepted);
1539
1540 /**
1541  * frsh_service_thread_get_data()
1542  *
1543  * this function returns in the variables pointed by budget and
1544  * period, respectively, the current budget and period of the service
1545  * thread.
1546  *
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
1552  *     running \n
1553  *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1554  *     has been cancelled or it is not valid
1555  *
1556  **/
1557 int frsh_service_thread_get_data
1558    (frsh_rel_time_t *budget,
1559     frsh_rel_time_t *period);
1560
1561
1562 /*@}*/
1563
1564
1565 ////////////////////////////////////////////////////////////////////////
1566 //           BACKGROUND MANAGEMENT
1567 ////////////////////////////////////////////////////////////////////////
1568
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.
1574
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
1582 //threads
1583
1584
1585 ////////////////////////////////////////////////////////////////////////
1586 //           OTHER
1587 ////////////////////////////////////////////////////////////////////////
1588
1589 /**
1590  * Returns resource id of local CPU.
1591  *
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).
1595  */
1596 frsh_resource_id_t frsh_get_local_cpu_id(void);
1597
1598 FRSH_CPP_END_DECLS
1599
1600 #endif // _FRSH_CORE_H_