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