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