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