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