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