]> rtime.felk.cvut.cz Git - frescor/frsh-include.git/blob - frsh_core.h
cpu id and network id
[frescor/frsh-include.git] / frsh_core.h
1 // -----------------------------------------------------------------------
2 //  Copyright (C) 2006 - 2007 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 API
35 //
36 //  FRSH API is free software; you can  redistribute it and/or  modify
37 //  it under the terms of  the GNU General Public License as published by
38 //  the Free Software Foundation;  either  version 2, or (at  your option)
39 //  any later version.
40 //
41 //  FRSH API  is distributed  in  the hope  that  it  will  be useful,  but
42 //  WITHOUT  ANY  WARRANTY;     without  even the   implied   warranty  of
43 //  MERCHANTABILITY  or  FITNESS FOR  A  PARTICULAR PURPOSE. See  the  GNU
44 //  General Public License for more details.
45 //
46 //  You should have  received a  copy of  the  GNU  General Public License
47 //  distributed  with  FRSH API;  see file COPYING.   If not,  write to the
48 //  Free Software  Foundation,  59 Temple Place  -  Suite 330,  Boston, MA
49 //  02111-1307, USA.
50 //
51 //  As a special exception, if you include this header file into source
52 //  files to be compiled, this header file does not by itself cause
53 //  the resulting executable to be covered by the GNU General Public
54 //  License.  This exception does not however invalidate any other
55 //  reasons why the executable file might be covered by the GNU General
56 //  Public License.
57 // -----------------------------------------------------------------------
58
59 //==============================================
60 //  ******** *******    ********  **      **
61 //  **///// /**////**  **//////  /**     /**
62 //  **      /**   /** /**        /**     /**
63 //  ******* /*******  /********* /**********
64 //  **////  /**///**  ////////** /**//////**
65 //  **      /**  //**        /** /**     /**
66 //  **      /**   //** ********  /**     /**
67 //  //       //     // ////////   //      //
68 //
69 // FRSH(FRescor ScHeduler), pronounced "fresh"
70 //==============================================
71
72 #ifndef _FRSH_CORE_H_
73 #define _FRSH_CORE_H_
74
75
76 /**
77  * @file frsh_core.h
78  **/
79
80
81 #include <time.h>
82 #include <sys/types.h>
83
84 #include "frsh_core_types.h"
85 #include "frsh_spare_capacity.h"
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
140
141 /////////////////////////////////////////////////////////////
142 //                       CONTRACT PARAMETERS
143 /////////////////////////////////////////////////////////////
144 /**
145  * @defgroup contract Contract Creation and Initialization.
146  * @ingroup core
147  *
148  * These functions are used to create and initialize a contract, and
149  * set its parameters.
150  *
151  * @{
152  **/
153
154
155
156 /**
157  * frsh_contract_init()
158  *
159  * The operation receives a pointer to a contract object
160  * and initializes it, setting it to the default values.
161  *
162  * The default values are:
163  *
164  * - resource_id               => 0
165  * - ressource_type            => FRSH_CRT_PROCESSOR
166  * - contract_label               => ""
167  * - budget_min                => {0,0};
168  * - period_max                => {0,0};
169  * - budget_max                => {0,0};
170  * - period_min                => {0,0};
171  * - workload                  => FRSH_INDETERMINATE
172  * - d_equals_t                => true
173  * - contract_type             => FRSH_CT_REGULAR;
174  * - deadline                  => {0,0};
175  * - budget_overrun_sig_notify => 0;  (signal number)
176  * - budget_overrun_sig_value  => {0, NULL};
177  * - deadline_miss_sig_notify  => 0;  (signal number)
178  * - deadline_miss_sig_value   => {0, NULL};
179  *
180  * - granularity               => DEFAULT_GRANULARITY;
181  * - utilization_set;          => size = 0
182  * - quality                   => DEFAULT_QUALITY;    (range 0..100)
183  * - importance                => DEFAULT_IMPORTANCE; (range 1..5)
184  * - preemption_level          => 0; (range 1..2**32-1)
185  * - critical_sections;        => size = 0
186  *
187  * - sched_policy              => DEFAULT_SCHED_POLICY (FRSH_NONE)
188  *
189  * @param     contract the pointer to the contract variable.
190  *
191  * @return 0 if no error \n
192  *     FRSH_ERR_BAD_ARGUMENT :  contract is NULL
193  *
194  **/
195 int frsh_contract_init(frsh_contract_t *contract);
196
197
198 /**
199  * frsh_contract_set_basic_params()
200  *
201  * The operation updates the specified contract parameters object by
202  * setting its budget, period, workload and type to the specified
203  * input parameters. (Note: the workload is a basic parameter because
204  * bounded tasks are triggered by the scheduler (see the
205  * frsh_timed_wait() and frsh_synchobj_wait* operations), while
206  * indeterminate tasks are not; therefore, their programming model is
207  * quite different).
208  *
209  * @param contract     the pointer to the contract object
210  * @param[in] budget_min   the minimum budget for the contract
211  * @param[in] period_max   the maximum period for the contract
212  * @param[in] workload     the kind of workload (can be FRSH_BOUNDED,
213  *                            FRSH_INDETERMINATE or FRSH_OVERHEAD)
214  * @param[in] contract_type can be FRSH_CT_REGULAR,
215  *                                 FRSH_CT_BACKGROUND, FRSH_CT_DUMMY.
216  *
217  * @return 0 if no error \n
218  *    FRSH_ERR_BAD_ARGUMENT :  if any of the pointers is NULL
219  *    or if only one of the timespec values is 0, and also if the
220  *    workload or the contract type values are unknown in the
221  *    enumerations.
222  **/
223 int frsh_contract_set_basic_params
224   (frsh_contract_t *contract,
225    const struct timespec      *budget_min,
226    const struct timespec      *period_max,
227    const frsh_workload_t      workload,
228    const frsh_contract_type_t contract_type);
229
230 /**
231  * frsh_contract_get_basic_params()
232  *
233  * This operation obtains from the specified contract object its
234  * budget, period, and workload, and copies them to the places pointed
235  * to by the corresponding output parameters.
236  *
237  * @param[in] contract   the pointer to the contract object
238  * @param[out] budget_min pointer to preallocated space
239  * @param[out] period_max pointer to preallocated space
240  * @param[out] workload pointer to preallocated space
241  * @param[out] contract_type pointer to preallocated space
242  *
243  * @return   0 if no error \n
244  *       FRSH_ERR_BAD_ARGUMENT :  if one of the contract or
245  *                                    pointers is NULL.
246  *
247  **/
248 int frsh_contract_get_basic_params
249   (const frsh_contract_t *contract,
250    struct timespec  *budget_min,
251    struct timespec  *period_max,
252    frsh_workload_t   *workload,
253    frsh_contract_type_t *contract_type);
254
255 /**
256  * frsh_contract_set_resource_and_label()
257  *
258  * Specify resource_id and type, and the contract label. Otherwise
259  * default values will apply. If the contract label is too long it is truncated
260  *
261  * @return   0 if no error \n
262  *       FRSH_ERR_BAD_ARGUMENT :  if the contract pointer is NULL.
263  **/
264
265 int frsh_contract_set_resource_and_label
266   (frsh_contract_t *contract,
267    const frsh_resource_type_t resource_type,
268    const frsh_resource_id_t resource_id,
269    const char *contract_label);
270
271
272 /**
273  * frsh_contract_get_resource_and_label()
274  *
275  * Obtain the resource_id and type, and the contract label.
276  *
277  * @return   0 if no error \n
278  *       FRSH_ERR_BAD_ARGUMENT :  if the contract or the contract_label
279                                   pointer is NULL.
280  **/
281 int frsh_contract_get_resource_and_label
282   (const frsh_contract_t *contract,
283    frsh_resource_type_t *resource_type,
284    frsh_resource_id_t *resource_id,
285    char *contract_label);
286
287
288 /**
289  * frsh_contract_set_timing_reqs()
290  *
291  * The operation updates the specified contract object, specifying
292  * additional time-related requirements.
293  *
294  * @param  contract The pointer to the contract object
295  *
296  * @param [in] d_equals_t It is a boolean value, set to true (1) if
297  *                        we want to specify a deadline different from
298  *                        the period  for the contract.
299  * @param [in] deadline  If the previous parameter is set to true,
300  *                       this parameter is ignored (the contract value
301  *                       will be NULL_DEADLINE internally). Otherwise, it
302  *                       contains the desired deadline value.
303  * @param [in] budget_overrun_sig_notify contains the number of the signal
304  *                that must be raised if the budget of the vres is overrun.
305  *                If the value of this parameter is FRSH_NULL_SIGNAL, no signal will
306  *                be raised.
307  * @param [in] budget_overrun_sig_value contains the value that will be
308  *               passed to the signal "catcher" when the signal is raised.
309  *               This parameters is not used if the budget_overrun_sig_notify
310  *               parameter is set to FRSH_NULL_SIGNAL.
311  * @param [in] deadline_miss_sig_notify contains the number of the
312  *               signal that must be raised if the deadline of the
313  *               vres is missed. If the value of this parameter is
314  *               FRSH_NULL_SIGNAL, no signal is raised.
315  * @param [in] deadline_miss_sig_value contains the value that will be
316  *                passed to the signal "catcher" when the signal is
317  *                raised.  This parameter is not used if the
318  *                deadline_sig_notify parameter is set to NULL_SIGNAL
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_sig_notify is not a valid signal)  \b or \n
324  *      (deadline_miss_sig_notify 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 struct timespec        *deadline,
333    const frsh_signal_t          budget_overrun_signal,
334    const frsh_signal_info_t     budget_overrun_siginfo,
335    const frsh_signal_t          deadline_miss_signal,
336    const frsh_signal_info_t     deadline_miss_siginfo);
337
338 /**
339  * frsh_contract_get_timing_reqs()
340  *
341  * The operation obtains the corresponding input parameters from the
342  * specified contract object. If d_equals_t is true, the deadline will
343  * be set to FRSH_NULL_DEADLINE.
344  *
345  * @return 0 if no error \n
346  *   FRSH_ERR_BAD_ARGUMENT :  if contract is NULL
347  *
348  **/
349 int frsh_contract_get_timing_reqs
350   (const frsh_contract_t *contract,
351    bool                    *d_equals_t,
352    struct timespec         *deadline,
353    frsh_signal_t           *budget_overrun_signal,
354    frsh_signal_info_t      *budget_overrun_siginfo,
355    frsh_signal_t           *deadline_miss_signal,
356    frsh_signal_info_t      *deadline_miss_siginfo);
357
358
359 /*@}*/
360
361 //////////////////////////////////////////////////////////////////
362 //                 SYNCHRONIZATION OBJECTS
363 //////////////////////////////////////////////////////////////////
364 /**
365  * @defgroup synch  Synchronization objects
366  * @ingroup core
367  *
368  * Synchronisation objects provide an alternative to timers for
369  * bounded-workload vres to signal the end of their current job and
370  * return their remaining budget to FRSH.
371  *
372  * Instead of asking to be reactivated based on an absolute time, they
373  * queue themselves in a synchronisation object and will wait there
374  * until another vres (bounded-workload or indeterminate-workload)
375  * wakes them up with a signal call the earliest at the beginning of
376  * the next period.
377  *
378  * Indeterminate-workload vres cannot queue themselves here because
379  * they don't have any budget to return.  However they can signal on
380  * the objects to activate a waiting workload vres.
381  *
382  * For classical signal/wait synchronisation paradigms the application
383  * must use whatever mechanism the underlying OS provides.
384  *
385  * In the future we may add a broadcast operation that would signal a
386  * group of synchronization objects. We have not included a broadcast
387  * service in this version because it can be easily created by the
388  * user by signalling individual synchronization objects inside a
389  * loop.
390  *
391  * Notice that for synchronization objects there is no naming service
392  * like in shared objects because tasks that use synchronization are
393  * not developed independently, as they are closely coupled.
394  *
395  * @{
396  **/
397
398
399 /**
400  * frsh_synchobj_create()
401  *
402  * This operation creates and initializes a synchronization object
403  * variable managed by the scheduler, and returns a handle to it in
404  * the variable pointed to by synch_handle.
405  *
406  * @param[out]  pointer to the variable that will contain the handle to the
407  *              newly created synchronization object
408  *
409  * @return 0 if no error \n
410  *   FRSH_ERR_BAD_ARGUMENT :  if synch_handle is 0\n
411  *   .
412  *   FRSH_ERR_TOO_MANY_SYNCH_OBJS : if the number of synchronization
413  *      objects in the system has already exceeded the maximum\n
414  *   .
415  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
416  *      scheduled under FRSH\n
417  *   .
418  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not running
419  *
420  **/
421 int frsh_synchobj_create
422     (frsh_synchobj_handle_t *synch_handle);
423
424
425 /**
426  * frsh_synchobj_destroy()
427  *
428  * This operation destroys the synchronization object (created by a
429  * previous call to frsh_create_synch_obj) that is referenced by the
430  * synch_handle variable. After calling this operation, the
431  * synch_handle variable can not be used until it is initialized again
432  * by a call to frsh_create_synch_obj.
433  *
434  * @param synch_handle the handle to the synchronization object
435  *            to be destroyed
436  *
437  * @return 0 if no error \n
438  *   FRSH_ERR_BAD_ARGUMENT :  if synch_handle is 0\n
439  *   FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE if the handle is not valid\n
440  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
441  *                            scheduled under FRSH \n
442  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
443  *                            running
444  *
445  * @sa frsh_synchobj_create
446  **/
447 int frsh_synchobj_destroy
448     (const frsh_synchobj_handle_t synchobj_handle);
449
450 /**
451  * frsh_synchobj_wait()
452  *
453  * This operation is invoked by threads associated with bounded
454  * workload vres to indicate that a job has been completed (and
455  * that the scheduler may reassign the unused capacity of the current
456  * job to other vres).
457  *
458  * As a difference with frsh_timed_wait(), here the vres
459  * specifies to be awakened by the arrival of a signal operation
460  * instead of at a precise point of time.
461  *
462  * This function can also be called to schedule the first job of a
463  * recently created vres and make it start when a signal operation
464  * has been sent from another thread.
465  *
466  * The vres' budget will be made zero for the remainder of the vres'
467  * period, and FRSH will not replenish it until an event has been
468  * notified to the synchronisation object by another vres.
469  *
470  * It can happen that the synchronisation object has notification
471  * events queued from the past, in this case one of the events is
472  * dequeued immediately and the vres won't have to wait for another
473  * one.
474  *
475  * At the time of reception of a notification event (wether in the
476  * future or in the past), all pending budget replenishments (if any)
477  * are made effective. Once the vres has a positive budget and the
478  * scheduler schedules the calling thread again, the call returns and
479  * the vres continues executing.
480  *
481  * If the synchronisation object is destroyed while the vres was
482  * waiting on it, the vres will be awaken and the function will
483  * return with a code FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE
484  *
485  * Except for those parameters equal to NULL pointers, the system
486  * reports the current period and budget for the current job, it informs
487  * if the deadline of the previous job was missed or not, and whether the
488  * budget of the previous job was overrun or not.
489  *
490  * In a system with hierarchical scheduling, since this call makes the
491  * budget of the current period zero, the other threads in the same
492  * vres are not run. As mentioned above, only when the call finishes
493  * the budget may be replenished.
494  *
495  * @param synch_handle   Synchronisation object upon which the vres
496  *                       will be waiting.
497  * @param next_budget[out]  Upon return of this function, the variable
498  *                          pointed by this function will be equal to
499  *                                      the current vres budget. If this parameter is
500  *                                      set to NULL, no action is taken
501  * @param next_period[out]  The vres period upon return (ignored if NULL).
502  * @param was_deadline_missed Upon return whether the deadline was
503  *                           missed in the previous period.
504  * @param was_budget_overran
505  *
506  *
507  * @return 0 if success \n
508  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
509  *               running \n
510  *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
511  *     main scheduler \n
512  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled
513  *     under FRSH \n
514  *   FRSH_ERR_NOT_BOUND : if the calling thread does not have a valid
515  *            vres bound to it \n
516  *   FRSH_ERR_BAD_ARGUMENT : if synch_handle is 0 \n
517  *   FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE if the synch_handle is not
518  *          valid or was destroyed while the vres was waiting on it. \n
519  *   FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload of the vres
520  *     is not FRSH_BOUNDED
521  *
522  **/
523 int frsh_synchobj_wait
524   (const frsh_synchobj_handle_t  synch_handle,
525    struct timespec               *next_budget,
526    struct timespec               *next_period,
527    bool                          *was_deadline_missed,
528    bool                          *was_budget_overran);
529
530
531 /**
532  * frsh_synchobj_wait_with_timeout()
533  *
534 g * This call is the same as frsh_synchobj_wait() but with an extra
535  * absolute timeout. The timed_out argument, indicates whether the
536  * function returned because of the expiration of the timeout or not.
537  *
538  * @return 0 if no error \n
539  *   FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE if the synch_handle is not
540  *        valid \n
541  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
542  *        running \n
543  *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
544  *     main scheduler \n
545  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled
546  *     under FRSH \n
547  *   FRSH_ERR_NOT_BOUND : if the calling thread does not have a valid
548  *     vres bound to it \n
549  *   FRSH_ERR_BAD_ARGUMENT :  if the synch_handle given is not valid or the
550  *     abs_timeout argument is NULL or its value is in the past\n
551  *   FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload of the vres
552  *     is not FRSH_BOUNDED
553  *
554  **/
555 int frsh_synchobj_wait_with_timeout
556   (const frsh_synchobj_handle_t  synch_handle,
557    const struct timespec         *abs_timeout,
558    bool                          *timed_out,
559    struct timespec               *next_budget,
560    struct timespec               *next_period,
561    bool                          *was_deadline_missed,
562    bool                          *was_budget_overran);
563
564 /**
565  * frsh_synchobj_signal()
566  *
567  * This function sends a notification event to the synchronization object
568  * specified as parameter. If there is at least one vres waiting on
569  * the synchronization object, it is awaken. If more than one vres
570  * are waiting, just one of them is awaken. However, which one is
571  * awaken is implementation dependent. If no vres is waiting on the
572  * synchronization object, the notification event is queued.
573  *
574  * @param [in] synch_handle the handle of the synchronization object to
575  *                 notify.
576  *
577  * @return 0 if no error \n
578  *    FRSH_ERR_BAD_ARGUMENT :  if synch_handle is 0 \n
579  *    FRSH_ERR_INVALID_SYNCH_OBJ_HANDLE if the handle is not valid \n
580  *    FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
581  *            scheduled under FRSH \n
582  *    FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
583  *            running \n
584  *    FRSH_ERR_TOO_MANY_EVENTS_IN_SYNCH_OBJ : if the number of events stored
585  *            in the synchronization object reaches the maximum defined in the
586  *            configuration parameter header file
587  *
588  * @sa frsh_synchobj_wait, frsh_synchobj_wait_with_timeout
589  **/
590 int frsh_synchobj_signal
591     (const frsh_synchobj_handle_t synch_handle);
592
593 /**
594  * frsh_timed_wait()
595  *
596  * This operation is invoked by threads associated with bounded
597  * workload vres to indicate that a job has been completed (and
598  * that the scheduler may reassign the unused capacity of the current
599  * job to other vres). It is also invoked when the first job of
600  * such threads has to be scheduled.
601  *
602  * As an effect, the system will make the current vres's budget zero
603  * for the remainder of the vres's period, and will not replenish
604  * the budget until the specified absolute time.  At that time, all
605  * pending budget replenishments (if any) are made effective. Once the
606  * vres has a positive budget and the scheduler schedules the
607  * calling thread again, the call returns and at that time, except for
608  * those parameters equal to NULL pointers, the system reports the
609  * current period and budget for the current job, whether the deadline
610  * of the previous job was missed or not, and whether the budget of
611  * the previous job was overrun or not.
612  *
613  * In a system with hierarchical scheduling, since this call makes the
614  * budget zero, the other threads in the same vres are not run. As
615  * mentioned abobe, only when the call finishes the budget may be
616  * replenished.
617  *
618  *  * @param [in] abs_time     absolute time at which the budget will be
619  *                          replenished
620  *
621  * @param [out] next_budget upon return of this function, the variable
622  *                          pointed by this function will be equal to
623  *                          the current vres budget. If this parameter is
624  *                          set to NULL, no action is taken.
625  *
626  * @param [out] next_period upon return of this function, the variable
627  *                          pointed by this function will be equal to
628  *                          the current vres period. If this parameter is
629  *                          set to NULL, no action is taken.
630  *
631  * @param [out] was_deadline_missed upon return of this function, the
632  *                          variable pointed by this function will be
633  *                          equal to true if the previous vres deadline
634  *                          was missed, to false otherwise. If this
635  *                          parameter is set to NULL, no action is
636  *                          taken.
637  *
638  * @param [out] was_budget_overrun upon return of this function, the
639  *                          variable pointed by this function will be
640  *                          equal to true if the previous vres budget was
641  *                          overrun, to false otherwise. If this
642  *                          parameter is set to NULL, no action is
643  *                          taken.
644  *
645  * @return  0 if the operation is successful \n
646  *   FRSH_ERR_TIME_SPEC_IN_THE_PAST if the absolute time specification
647  *            is in the past. \n
648  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong
649  *             or not running \n
650  *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
651  *                                    main scheduler \n
652  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling
653  *                      thread is not scheduled under FRSH \n
654  *   FRSH_ERR_NOT_BOUND : if the calling thread does not have a valid
655  *     vres bound to it \n
656  *   FRSH_ERR_BAD_ARGUMENT :  if abs_time is NULL \n
657  *   FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload of the vres
658  *     is not FRSH_BOUNDED
659  *
660  *
661  * @sa frsh_synchobj_wait, frsh_synchobj_wait_with_timeout
662  **/
663 int frsh_timed_wait
664   (const struct timespec *abs_time,
665    struct timespec       *next_budget,
666    struct timespec       *next_period,
667    bool                  *was_deadline_missed,
668    bool                  *was_budget_overran);
669
670
671 /*@}*/
672
673 ///////////////////////////////////////////////////////////////////
674 //                 CONTRACT NEGOCIATION OPERATIONS
675 ///////////////////////////////////////////////////////////////////
676
677 /**
678  * @defgroup negotiate Negotiate contract functions
679  * @ingroup core
680  *
681  * The following functions are used to negotiate contracts and thus
682  * creating vres which are the execution image of a contract.
683  * Besides, these functions allow to assign and unassign threads to
684  * vres.
685  *
686  * In the case of more than one thread per vres please refer to the
687  * hierarchical module.
688  *
689  * @{
690  **/
691
692
693
694 /**
695  * frsh_contract_negotiate()
696  *
697  * The operation negotiates a contract and if accepted it will return
698  * a vres_id.  It will also check that the given contract_label is unique
699  * within the node.
700  *
701  * If the on-line admission test is enabled, it determines whether the
702  * contract can be admitted or not based on the current contracts
703  * established in the system. Then it creates the vres and
704  * recalculates all necessary parameters for the contracts already
705  * present in the system.
706  *
707  * This is a potentially blocking operation, it returns when the
708  * system has either rejected the contract, or admitted it and made it
709  * effective. No thread is bound to the newly created vres, which
710  * will be idle until a thread is bound to it via frsh_thread_bind()
711  * or frsh_thread_create_and_bind().
712  *
713  * This operation can only be executed by threads that are already
714  * bound to an active vres and therefore are being scheduled by the
715  * frsh scheduler.
716  *
717  * @return 0 if successful \n
718  *   FRSH_ERR_CONTRACT_REJECTED:  The contract is not accepted.\n
719  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
720  *                running \n
721  *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
722  *     main scheduler \n
723  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled
724  *     under FRSH scheduler \n
725  *   FRSH_ERR_BAD_ARGUMENT :  if the contract or vres arguments are NULL \n
726  *   FRSH_ERR_TOO_MANY_VRES : if there is no space for more vres
727  *     (the maximum number of them is already reached) \n
728  *   FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS : contract_label is not unique.
729  *
730  **/
731 int frsh_contract_negotiate
732   (const frsh_contract_t *contract,
733    frsh_vres_id_t        *vres);
734
735 /**
736  * frsh_thread_create_and_bind()
737  *
738  * This operation creates a thread and binds it to an existing vres.
739  *
740  * This is the preferred way to add threads to the application because
741  * we make sure that the thread won't become unbound.
742  *
743  * The vres must not have any thread binded to it.  If you want to
744  * bind more than one thread to the vres you must use the
745  * hierarchical module.
746  *
747  * The frsh_thread_attr_t parameter is overwritten as necessary to
748  * introduce the adequate scheduling policy and priority,  according
749  * to the preemption level given in the contract and the
750  * frsh_priority_map() function defined by the user.
751  *
752  * @param[in] vres_id       vres with which the thread will be bound.
753  * @param[out] thread         frsh_thread_id returned by the system.
754  * @param attr         pthread_attr taken and maybe corrected
755  *                                by the system.  Ignored if NULL
756  * @param[in] thread_code     Thread function (void func(void *) )
757  *                                that will constitute the main of the
758  *                                thread.
759  * @param[in] arg             Argument for data to be passed at the
760  *                            thread. Set to NUL if you don't want
761  *                            to do anything like this.
762  *
763  * @return  0 if successful \n
764  *   FRSH_ERR_BAD_ARGUMENT : if the contract or vres arguments are
765  *               NULL \n
766  *   FRSH_ERR_CONTRACT_REJECTED : if the contract is rejected. \n
767  *   .
768  *   It may also return all the errors that may be returned by the
769  *     fosa_thread_create() function call
770  *
771  **/
772 int frsh_thread_create_and_bind
773   (const frsh_vres_id_t vres,
774    frsh_thread_id_t     *thread,
775    frsh_thread_attr_t   *attr,
776    frsh_thread_code_t   thread_code,
777    void                 *arg);
778
779
780 /**
781  * frsh_thread_create_in_background()
782  *
783  * This function creates a "background contract" that does not need to
784  * be negotiated, creates a threads and binds to the new vres.
785  *
786  * This method is suggested as a way to initate components and
787  * plugins.  The event that triggers the component activation should
788  * arrive to an application thread that could use this function to
789  * create a thread used in its initialisation.
790  *
791  * The attribute parameter is overwritten as necessary to introduce
792  * the adequate scheduling policy and priority.
793  *
794  * @param[in]  thread_code   Function to be executed by the new
795  *                           thread.
796  * @param[in]  thread_arg    General pointer that will be passed to
797  *                           the new thread as initialisation data.
798  * @param attr               Pthread attribute with thread params
799  * @param[in]  contract_label   Contract label for the new vres.
800  * @param[out] thread_id     Id of the new thread.
801  * @param[out] vres_id       vres_id of the new vres.
802  *
803  * @return 0 if successful \n
804  *   FRSH_ERR_BAD_ARGUMENT : Any problems with the argument \n
805  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is
806  *               not scheduled under FRSH \n
807  *   FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS : contract_label is not unique \n
808  *   FRSH_ERR_TOO_MANY_VRES : if there is no space for more vres
809  *     (the maximum number of them is already reached)
810  *
811  **/
812 int frsh_thread_create_in_background
813     (frsh_thread_code_t thread_code,
814      const void *thread_arg,
815      const char *contract_label,
816      frsh_thread_attr_t *attr,
817      frsh_thread_id_t *thread_id,
818      frsh_vres_id_t *vres_id);
819
820
821 /**
822  * frsh_thread_bind()
823  *
824  * This operation associates a thread with a vres, which means that
825  * it starts consuming the vres's budget  and is executed according
826  * to the contract established for that vres. If the thread is
827  * already bound to another vres, it is effectively unbound from it
828  * and bound to the specified one.
829  *
830  * It fails if the vres's policy is different than FRSH_NONE, or if
831  * there is already a thread bound to this vres.  In order to bind
832  * more than one vres to the same thread you must use the
833  * hierarchical module.
834  *
835  * Implementation dependent issue: In order to allow the usage of
836  * application defined schedulers, the given thread must not have the
837  * scheduling policy SCHED_APP and at the same time be attached to an
838  * application scheduler different than the frsh scheduler.
839  *
840  * @return 0 if successful \n
841  *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
842  *     main scheduler \n
843  *   FRSH_ERR_UNKNOWN_APPSCHEDULED_THREAD : if the thread is attached to
844  *     an application defined scheduler different than the frsh
845  *     scheduler \n
846  *   FRSH_ERR_BAD_ARGUMENT : if the vres value does not complain with the
847  *     expected format or valid range or the given thread does not
848  *     exist \n
849  *   FRSH_ERR_NOT_CONTRACTED_VRES : if the referenced vres is not
850  *      valid \n
851  *   FRSH_ERR_VRES_WORKLOAD_NOT_COMPATIBLE: if the kind of workload
852  *     of the vres is FRSH_OVERHEAD \n
853  *   FRSH_ERR_ALREADY_BOUND : if the given vres has a thread already
854  *     bound
855  *
856  **/
857 int frsh_thread_bind
858   (const frsh_vres_id_t   vres,
859    const frsh_thread_id_t thread);
860
861
862 /**
863  * frsh_thread_unbind()
864  *
865  * This operation unbinds a thread from a vres.  Since threads with
866  * no vres associated are not allowed to execute, they remain in a
867  * dormant state until they are either eliminated or bound again.
868  *
869  * If the thread is inside a critical section the effects of this call
870  * are deferred until the critical section is ended
871  *
872  * Implementation dependent issue: in the implementation with an
873  * application scheduler, the thread is still attached to the frsh
874  * scheduler, but suspended.
875  *
876  * @return 0 if successful \n
877  *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
878  *     main scheduler \n
879  *   FRSH_ERR_BAD_ARGUMENT : if the given thread does not exist \n
880  *   FRSH_ERR_NOT_SCHEDULED_THREAD : if the given thread is not scheduled
881  *     under FRSH \n
882  *   FRSH_ERR_UNKNOWN_APPSCHEDULED_THREAD : if the thread is attached to
883  *     an application defined scheduler different than the frsh
884  *     scheduler \n
885  *   FRSH_ERR_NOT_BOUND : if the given thread does not have a valid
886  *     vres bound to it
887  **/
888 int frsh_thread_unbind(const frsh_thread_id_t thread);
889
890 /**
891  * frsh_thread_get_vres_id()
892  *
893  * This operation stores the Id of the vres associated with the
894  * specified thread in the variable pointed to by vres. It returns
895  * an error if the thread does not exist, it is not under the control
896  * of the scheduling framework, or is not bound.
897  *
898  * @return 0 if no error \n
899  *   FRSH_ERR_NOT_SCHEDULED_THREAD : if the given thread is not scheduled
900  *     under FRSH \n
901  *   FRSH_ERR_NOT_BOUND : if the given thread does not have a valid
902  *     vres bound to it \n
903  *   FRSH_ERR_BAD_ARGUMENT : if the given thread does not exist or the
904  *     vres argument is NULL
905  *
906  **/
907 int frsh_thread_get_vres_id(const frsh_thread_id_t       thread,
908                     frsh_vres_id_t *vres_id);
909
910 /**
911  * frsh_vres_get_contract()
912  *
913  * This operation stores the contract parameters currently associated
914  * with the specified vres in the variable pointed to by
915  * contract. It returns an error if the vres_id is not recognised.
916  *
917  * @return 0 if no error \n
918  *   FRSH_ERR_BAD_ARGUMENT :  if the contract argument is NULL or the value
919  *     of the vres argument is not in range \n
920  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
921  *     scheduled under FRSH \n
922  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
923  *        running \n
924  *   FRSH_ERR_NOT_CONTRACTED_VRES: if the vres of the calling thread
925  *     has been cancelled or it is not valid
926  *
927  **/
928 int frsh_vres_get_contract
929   (const frsh_vres_id_t vres,
930     frsh_contract_t *contract);
931
932 /**
933  * frsh_resource_get_vres_from_label()
934  *
935  * This operation retrieves the vres_id whose contract_label
936  * corresponds to the parameter in the resource_id and resource_type
937  * specified.
938  *
939  * The contract label must refer to a contract negotiated
940  * in the same processing node in which the call is being
941  * made. Otherwise an error is returned.
942  *
943  * @return 0 if no error \n
944  *   FRSH_ERR_BAD_ARGUMENT :  if the contract argument is NULL or the
945  *     contract_label is NULL \n
946  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
947  *     scheduled under FRSH \n
948  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
949  *     running \n
950  *   FRSH_ERR_CONTRACT_LABEL_UNKNOWN: if the contract_label is not known
951  **/
952 int frsh_resource_get_vres_from_label
953   (const char *contract_label,
954    const frsh_resource_type_t resource_type,
955    const frsh_resource_id_t resource_id,
956    frsh_vres_id_t *vres);
957
958
959
960 /**
961  * frsh_contract_cancel()
962  *
963  * The operation eliminates the specified vres
964  * and recalculates all necessary parameters for the contracts
965  * remaining in the system. This is a potentially blocking operation;
966  * it returns when the system has made the changes effective.
967  *
968  * Note that the thread is not eliminated.  We leave the application
969  * the option to either freeze it for a later use or bind it to
970  * another vres.
971  *
972  * @return 0 if successful \n
973  *   FRSH_ERR_BAD_ARGUMENT :  if the value of vres is not in range \n
974  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
975  *     scheduled under FRSH \n
976  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
977  *     running \n
978  *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
979  *     has been cancelled or it is not valid
980  *
981  **/
982 int frsh_contract_cancel (const frsh_vres_id_t vres);
983
984
985 /**
986  * frsh_contract_renegotiate_sync()
987  *
988  * The operation renegotiates a contract for an existing vres. If
989  * the on-line admission test is enabled it determines whether the
990  * contract can be admitted or not based on the current contracts
991  * established in the system. If it cannot be admitted, the old
992  * contract remains in effect and an error is returned. If it can be
993  * admitted, it recalculates all necessary parameters for the
994  * contracts already present in the system and returns zero. This is a
995  * potentially blocking operation; it returns when the system has
996  * either rejected the new contract, or admitted it and made it
997  * effective.
998  *
999  *  @return 0 if successful \n
1000  *   FRSH_ERR_BAD_ARGUMENT :  if the new_contract argument is NULL or the
1001  *     value of the vres argument is not in range \n
1002  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1003  *     scheduled under FRSH \n
1004  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1005  *     running \n
1006  *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1007  *     has been cancelled or it is not valid \n
1008  *   FRSH_ERR_REJECTED_CONTRACT : if the renegotiation fails
1009  *
1010  **/
1011 int frsh_contract_renegotiate_sync
1012   (const frsh_contract_t *new_contract,
1013    const frsh_vres_id_t vres);
1014
1015
1016 /**
1017  * frsh_contract_renegotiate_async()
1018  *
1019  * The operation enqueues a renegotiate operation for an existing
1020  * vres, and returns immediately. The renegotiate operation is
1021  * performed asynchronously, as soon as it is practical; meanwhile the
1022  * system operation will continue normally. When the renegotiation is
1023  * made, if the on-line admission test is enabled it determines
1024  * whether the contract can be admitted or not based on the current
1025  * contracts established in the system. If it cannot be admitted, the
1026  * old contract remains in effect. If it can be admitted, it
1027  * recalculates all necessary parameters for the contracts already
1028  * present in the system.
1029  *
1030  * When the operation is completed, notification is made to the
1031  * caller, if requested, via a signal. The status of the operation (in
1032  * progress, admitted, rejected) can be checked with the
1033  * frsh_vres_get_renegotiation_status() operation.  The argument
1034  * sig_notify can be FRSH_NULL_SIGNAL (no notification), or any FRSH
1035  * signal value and in this case signal_info is to be sent with the signal.
1036  *
1037  * @param[in] new_contract   New contract parameters for the new
1038  *                           situation if approved.
1039  * @param[in] vres           vres_id on which to do the renegotiation.
1040  * @param[in] signal_to_notify  Signal number to use to notify vres of
1041  *                           the negotiation result.  If
1042  *                           FRSH_NULL_SIGNAL,  no signal will be raised.
1043  * @param[in] signal_info:   Associated info that will come with the
1044  *                           signal.  This parameter will be ignored
1045  *                           if signal_to_notify == FRSH_NULL_SIGNAL.
1046  *
1047  * @return 0 if no error \n
1048  *   FRSH_ERR_BAD_ARGUMENT :  if the new_contract argument is NULL, the
1049  *     value of the vres argument is not in range or sig_notify is
1050  *     neither NULL nor a valid POSIX signal \n
1051  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1052  *     scheduled under FRSH \n
1053  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1054  *     running \n
1055  *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1056  *     has been cancelled or it is not valid
1057  *
1058  **/
1059 int frsh_contract_renegotiate_async
1060   (const frsh_contract_t *new_contract,
1061    const frsh_vres_id_t vres,
1062    const frsh_signal_t                     signal_to_notify,
1063    const frsh_signal_info_t                signal_info);
1064
1065
1066 /**
1067  * frsh_vres_get_renegotiation_status()
1068  *
1069  * The operation reports on the status of the last renegotiation
1070  * operation enqueued for the specified vres. It is callable even
1071  * after notification of the completion of such operation, if
1072  * requested.
1073  *
1074  * If the vres is not and has not been involved in any of the
1075  * frsh_contract_renegotiate_async() or frsh_group_change_mode_async()
1076  * operations, the status returned is FRSH_NOT_REQUESTED
1077  *
1078  * @return 0 if no error \n
1079  *   FRSH_ERR_BAD_ARGUMENT :  if the renegotiation_status argument is
1080  *     NULL or the value of the vres argument is not in range \n
1081  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1082  *     scheduled under FRSH \n
1083  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1084  *     running \n
1085  *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1086  *     has been cancelled or it is not valid
1087  *
1088  **/
1089 int frsh_vres_get_renegotiation_status
1090   (const frsh_vres_id_t vres,
1091    frsh_renegotiation_status_t *renegotiation_status);
1092
1093 /*@}*/
1094
1095 ////////////////////////////////////////////////////////////////////////
1096 //           CHANGE OF MODE: GROUPS OF CONTRACTS
1097 ////////////////////////////////////////////////////////////////////////
1098 /**
1099  * @defgroup groupofcontracts Group of contracts
1100  * @ingroup core
1101  *
1102  * The following functions are used to negotiate atomically more than
1103  * one contract.  This allows to build complex applications by
1104  * splitting them in individual contracts that are negotiated
1105  * simultaneously and atomically.
1106  *
1107  * @{
1108  **/
1109
1110 /**
1111  * frsh_group_negotiate()
1112  *
1113  * This function negotiates atomically a group of new contracts
1114  * while giving the possibility of cancellling others.
1115  *
1116  * If the on-line admission test is enabled, FRSH analizes the
1117  * schedulability of the context that results in the new contract
1118  * situation with removed and added contracts.
1119  *
1120  * If the overall negotiation is successful, all actions will be taken
1121  * inmediatly:  the creation of new vres for the contract_up list
1122  * and the cancellation of the designated ones.
1123  *
1124  * If for any reason one of the contracts is not accepted, a
1125  * corresponding error will be returned and no actions will be taken,
1126  * the previous context will be preserved.
1127  *
1128  * This call is a synchronous, potentially blocking operation.  It
1129  * returns when the system has rejected the contracts or accepted them
1130  * and made them effective.
1131  *
1132  * @param[in] contracts_up   List of new proposed contracts
1133  *
1134  * @param[in] vres_down   List of vres_id to be canceled
1135  *
1136  * @param[out] vres_up    vres_id assigned by the system to the
1137  *                           corresponding contracts_up.
1138  *
1139  * @return 0 if no error \n
1140  * .
1141  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1142  *      running \n
1143  *   FRSH_ERR_INTERNAL_ERROR : erroneous binding or malfunction of the FRSH
1144  *      main scheduler \n
1145  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not scheduled
1146  *      under FRSH \n
1147  *   FRSH_ERR_BAD_ARGUMENT :  if any of the vres_up or accepted arguments
1148  *     is NULL, if the contracts_up and vres_down arguments are both NULL,
1149  *     or any of them has erroneous size or its elements are NULL or not in the
1150  *      valid range respectively
1151  **/
1152 int frsh_group_negotiate
1153    (const frsh_contracts_group_t *contracts_up,
1154     const frsh_vres_group_t   *vres_down,
1155     frsh_vres_group_t         *vres_up);
1156
1157
1158
1159 /**
1160  * frsh_group_change_mode_sync()
1161  *
1162  * An extension of frsh_negotiate_group() by adding the possibility of
1163  * specifying also group contract renegotiation and removal.
1164  *
1165  * NOTE:  This function will be implemented in a second phase after
1166  *        having fully implemented frsh_group_negotiate() in order to
1167  *        better grasp possible issues that the problems it may raise.
1168  *
1169  *        This is a draft of the specification, it is yet subject to
1170  *        change.
1171  *
1172  * This operation performs a global (re)negotiation of a group of
1173  * contracts in an atomic way.  Contracts can be added, canceled or
1174  * renegotiated.  Note that any of the groups can be empty.
1175  *
1176  * If the on-line admission test is enabled, FRSH analizes the
1177  * schedulability of the context that would  result in the new
1178  * contract situation with removed, changed and added contracts.
1179  *
1180  * A successful return code will mean that all contracts have been
1181  * accepted  and all required operations (creation, cancellation or
1182  * update of vres) have been carried out to reach the new running
1183  * context.
1184  *
1185  * If for any reason one of the contracts is not accepted a
1186  * corresponding error shall be returned and no changes will be made
1187  * to the previously running context.
1188  *
1189  * This call is a synchronous, potentially blocking operation.  It
1190  * returns when the system has rejected the contracts or accepted them
1191  * and made them effective.  There is also an asynchronous
1192  * (non-blocking) version of this function below.
1193  *
1194  * @param[in]  contracts_new_vres  Contracts to be added.
1195  * @param[out] vres_id_new  vres_id's corresponding to the new
1196  *                                    contracts.
1197  * @param[in]  contracts_update_vres New contracts for vres to
1198  *                                    be updated.
1199  * @param[in]  vres_update  vres_id's corresponding to the
1200  *                              contracts that have to be updated.
1201  * @param[in]  vres_removed Vres_id's to be removed.
1202  *
1203  * @return 0 if no error \n
1204  *    FRSH_ERR_BAD_ARGUMENT Invalid pointer or vres_id ranges. \n
1205  *    FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS contract_label not unique. \n
1206  *    FRSH_ERR_NOT_CONTRACTED_VRES: One of the provided
1207  *                          vres_ids is not recognised. \n
1208  *    FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD The calling thread
1209  *                           is not scheduled under FRSH. \n
1210  *    FRSH_ERR_INVALID_SCHEDULER_REPLY: The scheduler is wrong
1211  *                           or not running. \n
1212  *    FRSH_ERR_INTERNAL_ERROR:  Erroneous binding or malfunction of
1213  *                           FRSH main scheduler. \n
1214  *    FRSH_ERR_REJECTED_CONTRACT:  The negotiation of one of the
1215  *                           proposed contracts has failed.
1216  *
1217  **/
1218 int frsh_group_change_mode_sync
1219     (const frsh_contracts_group_t *contracts_new_vres,
1220      frsh_vres_group_t *vres_id_new,
1221      const frsh_contracts_group_t *contracts_update_vres,
1222      const frsh_vres_group_t *vres_update,
1223      const frsh_vres_group_t *vres_removed);
1224
1225
1226 /**
1227  * frsh_group_change_mode_async()
1228  *
1229  * This operation enqueues a global renegotiation of a group of
1230  * contracts (with a possible addition of new vres) and returns
1231  * immediately.  The renegotiation is performed asynchronously as soon
1232  * as it is practical.
1233  *
1234  * NOTE:  This function will be implemented in a second phase after
1235  *        having fully implemented frsh_negotiate_group() in order to
1236  *        better grasp possible issues that the problem may raise.
1237  *
1238  *        This is a draft of the specification, it is yet subject to
1239  *        change.
1240  *
1241  * This is an asynchronous (non-blocking) version of
1242  * frsh_group_change_mode_sync().  Note however that there must
1243  * be at least one existing thread involved in the operation (to be
1244  * canceled or have its contract updated).  An operation of puring
1245  * adding a group of new contracts can only be done synchronously.
1246  *
1247  * The status of the operation (in progress, admitted or rejected) can
1248  * be queried via frsh_vres_get_renegotiation_status() invoked for any of
1249  * the vres involved in the renegotiation (updated or to be
1250  * removed).  As an option, a signal can be sent to the caller to
1251  * notify the end-result  of the operation.
1252  *
1253  * @param[in]  contracts_new_vres  Contracts for new vres to be
1254  *                                    added.
1255  * @param[in]  contract_labels Contract labels for the corresponding new
1256  *                          vres to be added.
1257  * @param[out] vres_id_new  vres_id's corresponding to the new
1258  *                                    contracts.
1259  * @param[in]  contracts_update_vres New contracts for vres to
1260  *                                    be updated.
1261  * @param[in]  vres_update  vres_id's corresponding to the
1262  *                              contracts that have to be updated.
1263  * @param[in]  vres_removed vres_id's to be removed.
1264  *
1265  * @param[in] sig_notify  Signal number where the coller expects to
1266  *                        receive the information.
1267  * @param[in] sig_value   Signal data associated with that signal.
1268  *
1269  * @return 0 if no error \n
1270  *    FRSH_ERR_BAD_ARGUMENT Invalid pointer or vres_id ranges.  Also
1271  *           when the request is for adding only new contracts. \n
1272  *    FRSH_ERR_CONTRACT_LABEL_ALREADY_EXISTS contract_label not unique. \n
1273  *    FRSH_ERR_NOT_CONTRACTED_VRES: One of the provided
1274  *                            vres_id's is not recognised. \n
1275  *    FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD The calling thread
1276  *                           is not scheduled under FRSH. \n
1277  *    FRSH_ERR_INVALID_SCHEDULER_REPLY: The scheduler is wrong
1278  *                           or not running. \n
1279  *    FRSH_ERR_INTERNAL_ERROR:  Erroneous binding or malfunction of
1280  *                           FRSH main scheduler. \n
1281  *    FRSH_ERR_REJECTED_CONTRACT:  The negotiation of one of the
1282  *                           proposed contracts has failed.
1283  **/
1284 int frsh_group_change_mode_async
1285     (const frsh_contracts_group_t *contracts_new_vres,
1286      frsh_vres_group_t *vres_id_new,
1287      const frsh_contracts_group_t *contracts_update_vres,
1288      const frsh_vres_group_t *vres_update,
1289      const frsh_vres_group_t *vres_removed,
1290      const frsh_signal_t         signal_notify,
1291      const frsh_signal_info_t    signal_info);
1292
1293 /*@}*/
1294
1295
1296
1297 ////////////////////////////////////////////////////
1298 //           OBTAINING INFORMATION FROM THE SCHEDULER
1299 ////////////////////////////////////////////////////
1300
1301 /**
1302  * @defgroup getschedinfo Obtaining information from the scheduler
1303  *
1304  * @ingroup core
1305  *
1306  * The following functions are used to obtain available budget and
1307  * resource usage in the system.  They can be used to adapt the
1308  * execution of threads according to the load of the system.
1309  *
1310  * @{
1311  **/
1312
1313
1314 /**
1315  * frsh_config_is_admission_test_enabled()
1316  *
1317  * Returns true if the system is
1318  * configured with the on-line admission test enabled, or false
1319  * otherwise.  This situation can only be changed at compile time.
1320  **/
1321 bool frsh_config_is_admission_test_enabled();
1322
1323 /**
1324  * frsh_vres_get_usage()
1325  *
1326  * This function stores the current execution time spent by the
1327  * threads bound to the specified vres in the variable pointed to by
1328  * cpu_time.
1329  *
1330  * @return 0 if successful \n
1331  *   FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range or
1332  *     cpu_time is NULL \n
1333  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1334  *     scheduled under FRSH \n
1335  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1336  *     running \n
1337  *   FRSH_ERR_NOT_CONTRACTED_VRESR : if the vres of the calling thread
1338  *     has been cancelled or it is not valid
1339  *
1340  **/
1341 int frsh_vres_get_usage
1342    (const frsh_vres_id_t vres,
1343     struct timespec *spent);
1344
1345 /**
1346  * frsh_vres_get_remaining_budget()
1347  *
1348  * This function stores in the variable pointed to by budget the
1349  * remaining execution-time budget associated with the specified
1350  * vres.
1351  *
1352  *  @return 0 if successful \n
1353  *   FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range or
1354  *     budget is NULL \n
1355  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1356  *     scheduled under FRSH \n
1357  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1358  *     running \n
1359  *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1360  *     has been cancelled or it is not valid
1361  *
1362  **/
1363 int frsh_vres_get_remaining_budget
1364    (const frsh_vres_id_t vres,
1365     struct timespec *budget);
1366
1367
1368 /**
1369  * frsh_vres_get_budget_and_period()
1370  *
1371  * This function stores in the variables
1372  * pointed to by budget and period, the execution-time budget and the
1373  * period respectively associated with the specified vres. If any of
1374  * these pointers is NULL, the corresponding information is not stored.
1375  *
1376  * @return 0 if successful \n
1377  *   FRSH_ERR_BAD_ARGUMENT : if the value of the vres argument is not in range,
1378  *     or budget and period are both NULL \n
1379  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1380  *     scheduled under FRSH \n
1381  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1382  *     running \n
1383  *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1384  *     has been cancelled or it is not valid
1385  *
1386  **/
1387 int frsh_vres_get_budget_and_period
1388    (const frsh_vres_id_t vres,
1389     struct timespec *budget,
1390     struct timespec *period);
1391
1392 /*@}*/
1393
1394 /////////////////////////////////////////////////////////////////////
1395 //           SERVICE THREAD TUNING
1396 /////////////////////////////////////////////////////////////////////
1397 /**
1398  * @defgroup servthtuning Service thread tuning
1399  *
1400  * @ingroup core
1401  *
1402  * The following functions are used to obtain available budget and
1403  * resource usage in the system.  They can be used to adapt the
1404  * execution of threads to the load of the system.
1405  *
1406  * @{
1407  **/
1408
1409 /**
1410  * frsh_service_thread_set_data()
1411  *
1412  * This function allows the application to change the period and
1413  * budget of the service thread that makes the
1414  * negotiations. Increasing the utilization of this thread makes the
1415  * negotiations faster, but introduces additional load in the system
1416  * that may decrease the bandwidth available for the vres. For this
1417  * call, the system will make a schedulability analysis to determine
1418  * if the new situation is acceptable or not. This is reported back in
1419  * the variable pointed to by accepted. If the new service thread data
1420  * is accepted, the system will reassign budgets and periods to the
1421  * vres according to the new bandwidth available, in the same way
1422  * as it does for a regular contract negotiation.
1423  *
1424  * When its budget is exhausted, the service thread may run in the
1425  * background
1426  *
1427  * The service thread starts with a default budget and period that are
1428  * configurable
1429  *
1430  * Implementation dependency: in the fixed priority implementtaion of
1431  * frsh, the default priority is lower than the priority of any vres,
1432  * but higher than the background. According to the
1433  * implementation-dependent module the priority is adjustable by means
1434  * of a function that changes its preemption level
1435  *
1436  * @return 0 if successful \n
1437  *   FRSH_ERR_BAD_ARGUMENT : if any of the pointer arguments is NULL or
1438  *     the budget value is greater than the period value \n
1439  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1440  *     scheduled under FRSH \n
1441  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1442  *     running \n
1443  *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1444  *     has been cancelled or it is not valid
1445  *
1446  **/
1447 int frsh_service_thread_set_data (const struct timespec *budget,
1448                                   const struct timespec *period,
1449                                   bool                  *accepted);
1450
1451 /**
1452  * frsh_service_thread_get_data()
1453  *
1454  * this function returns in the variables pointed by budget and
1455  * period, respectively, the current budget and period of the service
1456  * thread.
1457  *
1458  * @return 0 if successful \n
1459  *   FRSH_ERR_BAD_ARGUMENT : if any of the pointer arguments is NULL \n
1460  *   FRSH_ERR_NOT_SCHEDULED_CALLING_THREAD : if the calling thread is not
1461  *     scheduled under FRSH \n
1462  *   FRSH_ERR_INVALID_SCHEDULER_REPLY : the scheduler is wrong or not
1463  *     running \n
1464  *   FRSH_ERR_NOT_CONTRACTED_VRES : if the vres of the calling thread
1465  *     has been cancelled or it is not valid
1466  *
1467  **/
1468 int frsh_service_thread_get_data
1469    (struct timespec *budget,
1470     struct timespec *period);
1471
1472
1473 /*@}*/
1474
1475
1476 ////////////////////////////////////////////////////////////////////////
1477 //           BACKGROUND MANAGEMENT
1478 ////////////////////////////////////////////////////////////////////////
1479
1480 //A round-robin background scheduling policy is available for those
1481 //threads that do not have real-time requirements. Because some of
1482 //these threads may require sharing information with other threads run
1483 //by regular vres.  Special background contracts may be created for
1484 //specifying the synchronization requirements.
1485
1486 //The way of specifying a background contract is by setting
1487 //contract_type to FRSH_CT_BACKGROUND. Negotiation may fail if the contract uses
1488 //shared_objects. If the contract has no shared_objects the returned
1489 //vres id represents the background and may be used to bind more
1490 //than one thread. If the contract has shared objects a vres is
1491 //created to keep track of them, but the associated threads are
1492 //executed in the background, together with the other background
1493 //threads
1494
1495
1496
1497
1498
1499 #endif // _FRSH_CORE_H_