Subversion Repositories shark

Rev

Rev 889 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
881 trimarchi 1
//fsf_core.h
2
//=================================================================
3
//       FFFFFFIII   RRRRR      SSTTTTTTT
4
//      FF         IIR   RR    SS
5
//     FF           IR        SS
6
//    FFFFFF         RRRR    SSSSST
7
//   FF       FI       RRR  SS
8
//  FF         II     RRR  SS
9
// FF           IIIIIR    RS
10
//
11
// Basic FSF(FIRST Scheduling Framework) contract management
12
//================================================================
13
 
14
#include <time.h>
15
#include <pthread.h>
16
#include <sys/types.h>
17
#include <stdbool.h>  
18
 
19
#include "fsf_configuration_parameters.h"
20
#include "fsf_opaque_types.h"
21
#include "fsf_basic_types.h"
22
 
23
#ifndef _FSF_CORE_H_
24
#define _FSF_CORE_H_
25
 
26
 
27
//////////////////////////////////////////////////////////////////////
28
//           INITIALIZATION SERVICES 
29
//////////////////////////////////////////////////////////////////////
30
 
31
/**
32
    \ingroup coremodule
33
 
34
    \defgroup core_init Initialization and utilities
35
 
36
    @{
37
*/
38
 
39
/**
40
   We cannot call any fsf functions before fsf_init. After calling
41
   fsf_init, the main will be executing in the background. Then, it
42
   can do the negotiations, create the threads and, if needed,
43
   activate them via some user-specified synchronization mechanism. It
44
   may also create a contract for itself. The second time this
45
   function is called it fails.
46
 
47
   @retval 0 if the system is initialized
48
   @retval FSF_ERR_SYSTEM_ALREADY_INITIALIZED if the function has already
49
           been called before
50
 
51
   @retval others It may also return any of the errors that may be
52
         returned by the underlying operating system primitives
53
         required to perform the FSF system start up
54
*/
55
int fsf_init();
56
 
57
/**
58
   This function converts an error code to an error message that is
59
   stored in the buffer starting at the location pointed to by
60
   message. The size of this buffer is specified by the size
61
   argument. If the error message is longer than size-1, it is
62
   truncated to that length. Regardless of whether the message is
63
   truncated or not, a final zero character that marks the end of the
64
   string is stored in the buffer.  The function fails if the error
65
   code passed does not correspond to any of the fsf error codes.
66
 
67
   @retval FSF_ERR_BAD_ARGUMENT  error is not a valid value
68
*/
69
int fsf_strerror (int error, char *message, size_t size);
70
 
71
/* @} */
72
 
73
/////////////////////////////////////////////////////////////
74
//                       CONTRACT PARAMETERS
75
/////////////////////////////////////////////////////////////
76
 
77
/**
78
   \ingroup coremodule
79
   \defgroup core_contract Contract Creation and Initialization.
80
 
81
   These functions are used to create and initialize a contract, and
82
   set its parameters.
83
 */
84
/*@{*/
85
/**
86
    Contract parameters type; it is an opaque type (i.e. the internal
87
    structure of this data type is implementation dependent). The user
88
    can access and modify the parameters of a contract only with the
89
    proper functions, and should never access the data directly.
90
*/
91
typedef FSF_CONTRACT_PARAMETERS_T_OPAQUE fsf_contract_parameters_t;
92
 
93
/**
94
    The operation receives a pointer to a contract parameters object
95
    and initializes it, setting it to the default values.
96
    The default values are:
97
    - budget min and max are set to 0;
98
    - period min and max are set to 0;
99
    - the workload is unbounded (FSF_INDETERMINATE);
100
    - the server deadline is equal to the period;
101
    - the budget and deadline overrun are not notified;
102
    - the granularity is set to "continuous";
103
    - the quality and importance are set to the default values;
104
    - the scheduling policy is FSF_NONE.
105
 
106
    @param     contract the pointer to the contract variable.
107
    @retval   FSF_ERR_BAD_ARGUMENT   contract is NULL
108
*/
109
int fsf_initialize_contract (fsf_contract_parameters_t *contract);
110
 
111
//  budget_min                => {0,0};
112
//  period_max                => {0,0};
113
//  budget_max                => {0,0};
114
//  period_min                => {0,0};
115
//  workload                  => DEFAULT_WORKLOAD;
116
 
117
//  d_equals_t                => DEFAULT_D_EQUALS_T; (false or true)
118
//  deadline                  => DEFAULT_DEADLINE;
119
//  budget_overrun_sig_notify => 0;  (signal number)
120
//  budget_overrun_sig_value  => {0, NULL};
121
//  deadline_miss_sig_notify  => 0;  (signal number)
122
//  deadline_miss_sig_value   => {0, NULL};
123
//
124
//  granularity               => DEFAULT_GRANULARITY;
125
//  utilization_set;          => size = 0
126
//  quality                   => DEFAULT_QUALITY;    (range 0..100)
127
//  importance                => DEFAULT_IMPORTANCE; (range 1..5)
128
//
129
//  preemption_level          => 0; (range 1..2**32-1)
130
//  critical_sections;        => size = 0
131
 
132
//  sched_policy              => DEFAULT_SCHED_POLICY
133
//                              (FSF_NONE)
134
 
135
 
136
/**
137
   The operation updates the specified contract parameters object by
138
   setting its budget, period, and workload to the specified input
139
   parameters. (Note: the workload is a basic parameter because
140
   bounded tasks are triggered by the scheduler (see the
141
   fsf_schedule_timed_job() operation), while indeterminate tasks are
142
   not; therefore, their programming model is quite different).
143
 
144
   @param contract          the pointer to the contract object
145
   @param [in] budget_min   the minimum budget for the contract
146
   @param [in] period_max   the maximum period for the contract
147
   @param [in] workload     the kind of workload (can be FSF_BOUNDED or
148
                            FSF_INDETERMINATE)
149
 
150
   @retval 0 if the operation is succesful
151
   @retval FSF_ERR_BAD_ARGUMENT if any of the pointers is NULL
152
       or if only one of the timespec values is 0, and also if the workload
153
       is not a proper value (FSF_INDETERMINATE or FSF_BOUNDED)
154
*/
155
int
156
fsf_set_contract_basic_parameters
157
  (fsf_contract_parameters_t *contract,
158
   const struct timespec     *budget_min,
159
   const struct timespec     *period_max,
160
   fsf_workload_t            workload);
161
 
162
/**
163
   This operation obtains from the specified contract parameters
164
   object its budget, period, and workload, and copies them to the
165
   places pointed to by the corresponding input parameters.
166
 
167
   @param [in] contract   the pointer to the contract object
168
   @param[out] budget_min pointer to the variable that will contain
169
   the minimum budget
170
   @param[out] period_max pointer to the variable that will contain the
171
   max_period
172
   @param[out] workload pointer to the variable that will contain the
173
   workload type
174
 
175
   @retval  FSF_ERR_BAD_ARGUMENT :  if contract is NULL
176
*/
177
int
178
fsf_get_contract_basic_parameters
179
  (const fsf_contract_parameters_t *contract,
180
   struct timespec  *budget_min,
181
   struct timespec  *period_max,
182
   fsf_workload_t   *workload);
183
 
184
 
185
/**
186
   The operation updates the specified contract parameters
187
   object, specifying the additional parameters requirements of
188
   a contract.
189
 
190
   @param  contract The pointer to the contract object
191
 
192
   @param [in] d_equals_t It is a boolean value, set to true (1) if the
193
                 we want to specify a deadline different from the period
194
                 for the contract.
195
   @param [in] deadline If the previous parameter is set to true,
196
                 this parameter should be set to NULL_DEADLINE. Otherwise,
197
                 it contains the desired deadline value.
198
                 (PEPPE: should be return with error otherwise?)
199
   @param [in] budget_overrun_sig_notify contains the number of posix signal
200
                 that must be raised if the budget of the server is overrun.
201
                 If the value of this parameter is NULL_SIGNAL, no signal will
202
                 be raised.
203
   @param [in] budget_overrun_sig_value contains the value that will be
204
                 passed to the signal "catcher" when the signal is raised.
205
                 This parameters is not used if the budget_overrun_sig_notify
206
                 parameters is set to NULL_SIGNAL.
207
   @param [in] deadline_miss_sig_notify contains the number of posix
208
                 signal that must be raised if the deadline of the server
209
                 is missed. If the value of this parameter is NULL_SIGNAL,
210
                 no signal is raised.
211
   @param [in] deadline_miss_sig_value contains the value that will be
212
                 passed to the signal "catcher" when the signal is raised.
213
                 This parameters is not used if the budget_overrun_sig_notify
214
                 parameters is set to NULL_SIGNAL
215
 
216
   @retval 0    if the operation is succesful
217
   @retval FSF_BAD_ARGUMENT if contract is NULL or  
218
       (d_equals_t is true and  deadline is not FSF_NULL_DEADLINE) or
219
       (budget_overrun_sig_notify is not a valid signal)  or
220
       (deadline_miss_sig_notify is not a valid signal)  or
221
       (d_equals_t is false but (deadline is FSF_NULL_DEADLINE or its value
222
                                 is grater than the contract´s maximum period))
223
 
224
   @see sigexplanation
225
*/
226
int
227
fsf_set_contract_timing_requirements
228
  (fsf_contract_parameters_t *contract,
229
   bool                   d_equals_t,
230
   const struct timespec *deadline,
231
   int                    budget_overrun_sig_notify,
232
   union sigval           budget_overrun_sig_value,
233
   int                    deadline_miss_sig_notify,
234
   union sigval           deadline_miss_sig_value);
235
 
236
/**
237
   The operation obtains the corresponding input parameters from the
238
   specified contract parameters object. If d_equals_t is true, the
239
   deadline will not be updated.
240
 
241
   @retval FSF_ERR_BAD_ARGUMENT if contract is NULL
242
 
243
   @see fsf_set_contract_timing_requirements
244
*/
245
int
246
fsf_get_contract_timing_requirements
247
  (const fsf_contract_parameters_t *contract,
248
   bool                    *d_equals_t,
249
   struct timespec         *deadline,
250
   int                     *budget_overrun_sig_notify,
251
   union sigval            *budget_overrun_sig_value,
252
   int                     *deadline_miss_sig_notify,
253
   union sigval            *deadline_miss_sig_value);
254
 
255
/*@}*/
256
 
257
//////////////////////////////////////////////////////////////////
258
//                 SYNCHRONIZATION OBJECTS
259
//////////////////////////////////////////////////////////////////
260
 
261
 
262
/**
263
   \ingroup coremodule
264
 
265
   \defgroup core_synch  Synchronization objects
266
 
267
   These objects are used to synchronize threads belonging to bounded
268
   workload servers.
269
 
270
   In the future we may add a broadcast operation that would signal a
271
   group of synchronization objects. We have not included a broadcast
272
   service in this version because it can be easily created by the
273
   user by signalling individual synchronization objects inside a
274
   loop.
275
 
276
   Notice that for synchronization objects there is no naming service
277
   like in shared objects because tasks that use synchronization are
278
   not developed independently, as they are closely coupled.
279
 
280
*/
281
/*@{*/
282
/**
283
   An abstract synchronization object is defined by the application.
284
   This object can be used by an application to wait for an event to
285
   arrive by invoking the fsf_schedule_triggered_job() operation.  It
286
   can also be used to signal the event either causing a waiting
287
   server to wake up, or the event to be queued if no server is
288
   waiting for it.
289
*/
290
typedef FSF_SYNCH_OBJ_HANDLE_T_OPAQUE fsf_synch_obj_handle_t;
291
 
292
 
293
/**
294
   This operation creates and initializes a synchronization object
295
   variable managed by the scheduler, and returns a handle to it in
296
   the variable pointed to by synch_handle.
297
 
298
   @param[out]  pointer to the variable that will contain the handle to the
299
                newly created synchronization object
300
 
301
   @retval  0 if the operation is succesful
302
   @retval  FSF_ERR_BAD_ARGUMENT   if synch_handle is 0
303
   @retval  FSF_ERR_TOO_MANY_SYNCH_OBJS  if the number of synchronization
304
             objects in the system has already exceeded the maximum
305
   @retval FSF_ERR_NOT_SCHEDULED_CALLING_THREAD  if the calling thread is not
306
            scheduled under the FSF
307
   @retval  FSF_ERR_INVALID_SCHEDULER_REPLY  the scheduler is wrong
308
             or not running
309
*/
310
int
311
fsf_create_synch_obj
312
    (fsf_synch_obj_handle_t *synch_handle);
313
 
314
/**
315
 
316
   This function sends a notification to the synchronization object
317
   specified as parameter. If there is at least one server waiting on
318
   the synchronization object, the corresponding thread is unblocked,
319
   and the server rules for budget recharging apply.
320
 
321
   If more than one server is waiting, just one of them is woken.
322
   However, which one is woken is implementation dependent.
323
 
324
   If no thread is waiting on the synchronization object, the
325
   notification is queued.
326
 
327
   @param [in] synch_handle the handle of the synchronization object to
328
                  notify.
329
 
330
   @retval 0 if the operation is completed succesfully
331
   @retval FSF_ERR_BAD_ARGUMENT   if synch_handle is 0
332
   @retval FSF_ERR_INVALID_SYNCH_OBJ_HANDLE if the handle is not valid
333
   @retval FSF_ERR_NOT_SCHEDULED_CALLING_THREAD  if the calling thread
334
              is not scheduled under the FSF
335
   @retval FSF_ERR_INVALID_SCHEDULER_REPLY  the scheduler is wrong or
336
              not running
337
   @retval FSF_ERR_TOO_MANY_EVENTS_IN_SYNCH_OBJ  if the number of
338
              events stored in the synchronization object reaches the
339
              maximum defined in the configuration parameter header file
340
 
341
   @see fsf_schedule_triggered_job, fsf_timed_schedule_triggered_job
342
*/
343
int
344
fsf_signal_synch_obj
345
    (fsf_synch_obj_handle_t synch_handle);
346
 
347
/**
348
   This operation destroys the synchronization object (created by a
349
   previous call to fsf_create_synch_obj) that is referenced by the
350
   synch_handle variable. After calling this operation, the
351
   synch_handle variable can not be used until it is initialized again
352
   by a call to fsf_create_synch_obj.
353
 
354
   @param synch_handle the handle to the synchronization object
355
             to be destroyed
356
 
357
   @retval 0 if the operation is succesful
358
   @retval FSF_ERR_INVALID_SYNCH_OBJ_HANDLE is the handle is not valid
359
   @retval FSF_ERR_BAD_ARGUMENT   if synch_handle is 0
360
   @retval FSF_ERR_INVALID_SYNCH_OBJ_HANDLE if the handle is not valid
361
   @retval FSF_ERR_NOT_SCHEDULED_CALLING_THREAD if the calling thread is not
362
       scheduled under the FSF
363
   @retval FSF_ERR_INVALID_SCHEDULER_REPLY  the scheduler is wrong or
364
       not running
365
 
366
   @see fsf_create_synch_obj
367
*/
368
int
369
fsf_destroy_synch_obj
370
    (fsf_synch_obj_handle_t synch_handle);
371
 
372
 
373
////////////////////////////////////////////////////
374
//           SCHEDULING BOUNDED WORKLOADS
375
////////////////////////////////////////////////////
376
 
377
/**
378
   This operation is invoked by threads associated with bounded
379
   workload servers to indicate that a job has been completed (and
380
   that the scheduler may reassign the unused capacity of the current
381
   job to other servers). It is also invoked when the first job of
382
   such threads has to be scheduled.  (PEPPE: I have a question, what
383
   happens to the budget? if I do not get it wrong, the replenishment
384
   time is set to abs_time and the bandwidth of the server up to time
385
   abs_time can be reassigned. Is it true? what is the exact
386
   relationship between this abs_time and the server period? What if
387
   the user specifies an abs_time less than the end of the current
388
   server period??)
389
 
390
   As an effect, the system will make the current server's budget zero
391
   for the remainder of the server's period, and will not replenish
392
   the budget until the specified absolute time.  At that time, all
393
   pending budget replenishments (if any) are made effective. Once the
394
   server has a positive budget and the scheduler schedules the
395
   calling thread again, the call returns and at that time, except for
396
   those parameters equal to NULL pointers, the system reports the
397
   current period and budget for the current job, whether the deadline
398
   of the previous job was missed or not, and whether the budget of
399
   the previous job was overrun or not.
400
 
401
   In a system with hierarchical scheduling, since this call makes the
402
   budget zero, the other threads in the same server are not run. As
403
   mentioned abobe, only when the call finishes the budget may be
404
   replenished.
405
 
406
   @param [in] abs_time     absolute time at which the budget will be
407
                            replenished
408
 
409
   @param [out] next_budget upon return of this function, the variable
410
                            pointed by this function will be equal to
411
                            the current server budget. If this parameter is
412
                            set to NULL, no action is taken.
413
 
414
   @param [out] next_period upon return of this function, the variable
415
                            pointed by this function will be equal to
416
                            the current server period. If this parameter is
417
                            set to NULL, no action is taken.
418
 
419
   @param [out] was_deadline_missed upon return of this function, the
420
                            variable pointed by this function will be
421
                            equal to true if the previous server deadline
422
                            was missed, to false otherwise. If this
423
                            parameter is set to NULL, no action is
424
                            taken.
425
 
426
   @param [out] was_budget_overrun upon return of this function, the
427
                            variable pointed by this function will be
428
                            equal to true if the previous server budget was
429
                            overrun, to false otherwise. If this
430
                            parameter is set to NULL, no action is
431
                            taken.
432
 
433
   @retval 0 if the operation is succesful
434
   @retval FSF_ERR_INVALID_SCHEDULER_REPLY  the scheduler is wrong or
435
              not running
436
   @retval FSF_ERR_INTERNAL_ERROR  erroneous binding or malfunction of the FSF
437
       main scheduler
438
   @retval FSF_ERR_NOT_SCHEDULED_CALLING_THREAD if the calling thread is
439
       not scheduled under the FSF
440
   @retval FSF_ERR_UNBOUND if the calling thread does not have a valid
441
       server bound to it
442
   @retval FSF_ERR_BAD_ARGUMENT   if the workload of the server is not
443
       FSF_BOUNDED
444
 
445
   @sa fsf_schedule_triggered_job, fsf_timed_schedule_triggered_job
446
*/
447
int
448
fsf_schedule_timed_job
449
  (const struct timespec *abs_time,
450
   struct timespec       *next_budget,
451
   struct timespec       *next_period,
452
   bool                  *was_deadline_missed,
453
   bool                  *was_budget_overran);
454
 
455
/**
456
   This operation is invoked by threads associated with bounded
457
   workload servers to indicate that a job has been completed (and
458
   that the scheduler may reassign the unused capacity of the current
459
   job to other servers). It is also invoked when the first job of
460
   such threads has to be scheduled. If the specified synchronization
461
   object has events queued, one of them is dequeued; otherwise the
462
   server will wait upon the specified synchronization object, the
463
   server's budget will be made zero for the remainder of the server's
464
   period, and the implementation will not replenish the budget until
465
   the specified synchronization object is signalled.
466
 
467
   At that time, all pending budget replenishments (if any) are made
468
   effective. Once the server has a positive budget and the scheduler
469
   schedules the calling thread again, the call returns and at that
470
   time, except for those parameters equal to NULL pointers, the
471
   system reports the current period and budget for the current job,
472
   whether the deadline of the previous job was missed or not, and
473
   whether the budget of the previous job was overrun or not.
474
 
475
   In a system with hierarchical scheduling, since this call makes the
476
   budget zero, the other threads in the same server are not run. As
477
   mentioned above, only when the call finishes the budget may be
478
   replenished.
479
 
480
   @param [in]  synch_handle   handle of the synchronization object
481
 
482
   @param [out] next_budget    upon return of this function, the variable
483
                               pointed by this function will be equal
484
                               to the current server budget. If this
485
                               parameter is set to NULL, no action is
486
                               taken.
487
   @param [out] next_period    upon return of this function, the variable
488
                               pointed by this function will be equal to
489
                               the current server period. If this parameter is
490
                               set to NULL, no action is taken.
491
 
492
   @param [out] was_deadline_missed upon return of this function, the
493
                            variable pointed by this function will be
494
                            equal to true if the previous server deadline
495
                            was missed, to false otherwise. If this
496
                            parameter is set to NULL, no action is
497
                            taken.
498
 
499
   @param [out] was_budget_overrun upon return of this function, the
500
                            variable pointed by this function will be
501
                            equal to true if the previous server budget was
502
                            overrun, to false otherwise. If this
503
                            parameter is set to NULL, no action is
504
                            taken.
505
 
506
   @retval 0 if the operation is succesful
507
   @retval  FSF_ERR_INVALID_SYNCH_OBJ_HANDLE if the handle is not valid
508
   @retval  FSF_ERR_INVALID_SCHEDULER_REPLY  the scheduler is wrong or not
509
            running
510
   @retval  FSF_ERR_INTERNAL_ERROR  erroneous binding or malfunction of
511
            the FSF main scheduler
512
   @retval  FSF_ERR_NOT_SCHEDULED_CALLING_THREAD if the calling thread
513
            is not scheduled under the FSF
514
   @retval  FSF_ERR_UNBOUND if the calling thread does not have
515
            a valid server bound to it
516
   @retval  FSF_ERR_BAD_ARGUMENT if the workload of the server is not
517
            FSF_BOUNDED or the synch_handle given is not valid
518
 
519
   @sa fsf_schedule_triggered_job, fsf_schedule_timed_job
520
 
521
*/
522
int
523
fsf_schedule_triggered_job
524
  (fsf_synch_obj_handle_t  synch_handle,
525
   struct timespec         *next_budget,
526
   struct timespec         *next_period,
527
   bool                    *was_deadline_missed,
528
   bool                    *was_budget_overran);
529
 
530
 
531
/**
532
   This call is the same as fsf_schedule_triggered_job, but with an
533
   absolute timeout. The timed_out argument, indicates whether the
534
   function returned because of a timeout or not
535
 
536
   @retval FSF_ERR_INVALID_SCHEDULER_REPLY the scheduler is wrong or
537
       not running
538
   @retval FSF_ERR_INTERNAL_ERROR  erroneous binding or malfunction
539
       of the FSF main scheduler
540
   @retval FSF_ERR_NOT_SCHEDULED_CALLING_THREAD if the calling thread is
541
       not scheduled under the FSF
542
   @retval FSF_ERR_UNBOUND  if the calling thread does not have a valid
543
       server bound to it
544
   @retval FSF_ERR_BAD_ARGUMENT   if the workload of the server is not
545
       FSF_BOUNDED, the synch_handle given is not valid or the abs_timeout
546
       argument is NULL or its value is in the past
547
 
548
   @see fsf_schedule_triggered_job
549
*/
550
int
551
fsf_timed_schedule_triggered_job
552
  (fsf_synch_obj_handle_t  synch_handle,
553
   const struct timespec   *abs_timeout,
554
   bool                    *timed_out,
555
   struct timespec         *next_budget,
556
   struct timespec         *next_period,
557
   bool                    *was_deadline_missed,
558
   bool                    *was_budget_overran);
559
 
560
/*@}*/
561
 
562
///////////////////////////////////////////////////////////////////
563
//                 CONTRACT NEGOCIATION OPERATIONS
564
///////////////////////////////////////////////////////////////////
565
 
566
/**
567
   \ingroup coremodule
568
 
569
   \defgroup core_negotiate Negotiate contract functions
570
 
571
   The following functions are used to create servers for a contract
572
   parameters specification and also to assign one or more threads to
573
   a server (Note: the current implementation only supports one thread
574
   per server; this limitation will be removed in the next phase of
575
   the project)
576
*/
577
/*@{*/
578
 
579
/**
580
    Server Id type, that identifies a server created to manage a given
581
    contract
582
*/
583
typedef int      fsf_server_id_t;             // => 0
584
 
585
/**
586
    The type references a function that may become a thread's
587
    code
588
*/
589
typedef void * (*fsf_thread_code_t) (void *);
590
 
591
/**
592
   The operation negotiates a contract for a new server. If the
593
   on-line admission test is enabled it determines whether the
594
   contract can be admitted or not based on the current contracts
595
   established in the system. Then it creates the server and
596
   recalculates all necessary parameters for the contracts already
597
   present in the system.
598
 
599
   This is a potentially blocking operation; it returns when the
600
   system has either rejected the contract, or admitted it and made it
601
   effective. It returns zero and places the server identification
602
   number in the location pointed to by the server input parameter if
603
   accepted, or an error if rejected.  No thread is bound to the newly
604
   created server, which will be idle until a thread is bound to
605
   it. This operation can only be executed by threads that are already
606
   bound to an active server and therefore are being scheduled by the
607
   fsf scheduler.
608
 
609
   @param [in] contract pointer to the contract
610
   @param [out] server server id
611
 
612
   @retval 0 if the call is succesful
613
   @retval FSF_ERR_INVALID_SCHEDULER_REPLY  the scheduler is wrong or not
614
                                            running
615
   @retval FSF_ERR_INTERNAL_ERROR  erroneous binding or malfunction of the FSF
616
                                   main scheduler
617
   @retval FSF_ERR_NOT_SCHEDULED_CALLING_THREAD  
618
                                   if the calling thread is not scheduled
619
                                   under the FSF
620
   @retval FSF_ERR_BAD_ARGUMENT    if the contract or server arguments
621
                                   are NULL
622
*/
623
int
624
fsf_negotiate_contract
625
  (const fsf_contract_parameters_t *contract,
626
   fsf_server_id_t      *server);
627
 
628
/**
629
   This operation negotiates a contract for a new server, creates a
630
   thread and binds it to the server. If the contract is accepted, the
631
   operation creates a thread with the arguments thread, attr,
632
   thread_code and arg as they are defined for the pthread_create()
633
   POSIX function call, and attaches it to the fsf scheduler. Then, it
634
   binds the created thread to the new server. It returns zero and
635
   puts the server identification number in the location pointed to by
636
   the server input parameter.
637
 
638
   The attr parameter is overwritten as necessary to introduce the
639
   adequate scheduling attributes, according to the information given
640
   in the contract.
641
 
642
   The server is created with the FSF_NONE scheduling policy, which
643
   means no hierarchical scheduling, and only one thread per server,
644
   except for the case of background tasks (see below)
645
 
646
   If the contract is rejected, the thread is not created and the
647
   corresponding error is returned.
648
 
649
   @param [in] contract pointer to the contract
650
   @param [out] server server id
651
   @param [out] thread thread id
652
   @param [in] attr threads attributes
653
   @param [in] thread_code  pointer to the function that implements
654
               the thread
655
   @param [in] arg  arguments for the thread
656
 
657
   @retval  FSF_ERR_BAD_ARGUMENT  if the contract or server arguments are NULL
658
   @retval  FSF_ERR_CONTRACT_REJECTED  if the contract is rejected
659
 
660
   @retval  others it may also return all the errors that may be returned
661
            by the pthread_create()POSIX function call
662
 
663
*/
664
int
665
fsf_negotiate_contract_for_new_thread
666
  (const fsf_contract_parameters_t *contract,
667
   fsf_server_id_t      *server,
668
   pthread_t            *thread,
669
   pthread_attr_t       *attr,
670
   fsf_thread_code_t     thread_code,
671
   void                 *arg);
672
 
673
/**
674
   This operation negotiates a contract for a new server, and binds
675
   the calling thread to it. If the contract is accepted it returns
676
   zero and copies the server identification number in the location
677
   pointed to by the server input parameter.  If it is rejected, an
678
   error is returned.
679
 
680
   The server is created with the FSF_NONE scheduling policy, which
681
   means no hierarchical scheduling, and only one thread per server,
682
   except for the case of background tasks (see below)
683
 
684
   Implementation dependent issue: In order to allow the usage of
685
   application defined schedulers, the calling thread must not have
686
   the SCHED_APP scheduling policy and at the same time be attached to
687
   an application scheduler different than the fsf scheduler; in such
688
   case, an error is returned. After a successful call the calling
689
   thread will have the SCHED_APP scheduling policy and will be
690
   attached to the fsf scheduler.
691
 
692
   @param [in] contract pointer to the contract
693
   @param [out] server id
694
 
695
   @retval 0 if the contract negotation is succesful
696
   @retval  FSF_ERR_UNKNOWN_APPSCHEDULED_THREAD  if the thread is attached to
697
       an application defined scheduler different than the fsf scheduler
698
   @retval FSF_ERR_BAD_ARGUMENT  if the contract or server arguments
699
       are NULL
700
   @retval FSF_ERR_CONTRACT_REJECTED  if the contract is rejected.
701
*/
702
int
703
fsf_negotiate_contract_for_myself
704
  (const fsf_contract_parameters_t *contract,
705
   fsf_server_id_t      *server);
706
 
707
 
708
/**
709
   This operation associates a thread with a server, which means that
710
   it starts consuming the server's budget and is executed according
711
   to the contract established for that server. If the thread is
712
   already bound to another server, and error is returned.
713
 
714
   It fails if the server's policy is different than FSF_NONE, or if
715
   there is already a thread bound to this server
716
 
717
   Implementation dependent issue: In order to allow the usage of
718
   application defined schedulers, the given thread must not have the
719
   scheduling policy SCHED_APP and at the same time be attached to an
720
   application scheduler different than the fsf scheduler.
721
 
722
   @param [in] server id
723
   @param [in] thread id
724
 
725
   @retval FSF_ERR_INTERNAL_ERROR  erroneous binding or malfunction
726
       of the FSF main scheduler
727
   @retval FSF_ERR_UNKNOWN_APPSCHEDULED_THREAD if the thread is attached to
728
       an application defined scheduler different than the fsf scheduler
729
   @retval FSF_ERR_BAD_ARGUMENT if the server value does not complain with the
730
       expected format or valid range or the given thread does not exist
731
   @retval FSF_ERR_NOT_CONTRACTED_SERVER if the referenced server
732
       is not valid
733
   @retval FSF_ERR_ALREADY_BOUND if the thread is already bound to
734
       another server.
735
 
736
*/
737
int
738
fsf_bind_thread_to_server
739
  (fsf_server_id_t server,
740
   pthread_t       thread);
741
 
742
 
743
/**
744
   This operation unbinds a thread from a server.  Since threads with
745
   no server associated are not allow to execute, they remain in a
746
   dormant state until they are either eliminated or bound again.
747
 
748
   If the thread is inside a critical section the effects of this call
749
   are deferred until the critical section is ended
750
 
751
   Implementation dependent issue: in the implementation with an
752
   application scheduler, the thread is still attached to the fsf
753
   scheduler, but suspended.
754
 
755
   @param [in] thread thread id
756
 
757
   @retval 0 if the operation is succesful
758
   @retval FSF_ERR_INTERNAL_ERROR  erroneous binding or malfunction of the FSF
759
       main scheduler
760
   @retval FSF_ERR_BAD_ARGUMENT  if the given thread does not exist
761
   @retval FSF_ERR_NOT_SCHEDULED_THREAD  if the given thread is not scheduled
762
       under the FSF
763
   @retval FSF_ERR_UNKNOWN_APPSCHEDULED_THREAD if the thread is attached to
764
       an application defined scheduler different than the fsf scheduler
765
   @retval FSF_ERR_NOT_BOUND if the given thread does not have a valid
766
       server bound to it
767
*/
768
int
769
fsf_unbind_thread_from_server (pthread_t thread);
770
 
771
/**
772
   This operation stores the Id of the server associated with the
773
   specified thread in the variable pointed to by server. It returns
774
   an error if the thread does not exist, it is not under the control
775
   of the scheduling framework, or is not bound.
776
 
777
   @param [in] thread thread id
778
   @param [out] server server
779
 
780
   @retval 0 if the operation is succesful
781
   @retrun FSF_ERR_NOT_SCHEDULED_THREAD if the given thread is not scheduled
782
       under the FSF
783
   @retrun FSF_ERR_UNBOUND if the given thread does not have a valid
784
       server bound to it
785
   @retrun FSF_ERR_BAD_ARGUMENT if the given thread does not exist or the
786
       server argument is NULL
787
*/
788
int
789
fsf_get_server
790
  (pthread_t       thread,
791
   fsf_server_id_t *server);
792
 
793
/**
794
   This operation stores the contract parameters currently associated
795
   with the specified server in the variable pointed to by
796
   contract. It returns an error if the server id is incorrect.
797
 
798
   @param [in] server server id
799
   @param [out] contract pointer to the contract structure
800
 
801
   @retval 0 if the operation is succesful
802
   @retval FSF_ERR_BAD_ARGUMENT  if the contract argument is
803
         NULL or the value of the server argument is not in range
804
   @retval FSF_ERR_NOT_SCHEDULED_CALLING_THREAD if the calling thread is not
805
       scheduled under the FSF
806
   @retval FSF_ERR_INVALID_SCHEDULER_REPLY  the scheduler is wrong or
807
       not running
808
   @retval FSF_ERR_NOT_CONTRACTED_SERVER if the server of the calling thread
809
       has been cancelled or it is not valid
810
*/
811
int
812
fsf_get_contract
813
   (fsf_server_id_t server,
814
    fsf_contract_parameters_t *contract);
815
 
816
/**
817
   The operation eliminates the specified server
818
   and recalculates all necessary parameters for the contracts
819
   remaining in the system. This is a potentially blocking operation;
820
   it returns when the system has made the changes effective.
821
 
822
   @param [in] server server id
823
 
824
   @retval 0 if the operation is succesful
825
   @retval FSF_ERR_BAD_ARGUMENT   if the value of server is not in range
826
   @retval FSF_ERR_NOT_SCHEDULED_CALLING_THREAD  if the calling thread is not
827
           scheduled under the FSF
828
   @retval FSF_ERR_INVALID_SCHEDULER_REPLY  the scheduler is wrong or not
829
           running
830
   @retval FSF_ERR_NOT_CONTRACTED_SERVER  if the server of the calling thread
831
           has been cancelled or it is not valid
832
*/
833
int
834
fsf_cancel_contract (fsf_server_id_t server);
835
 
836
 
837
/**
838
   The operation renegotiates a contract for an existing server. If
839
   the on-line admission test is enabled it determines whether the
840
   contract can be admitted or not based on the current contracts
841
   established in the system. If it cannot be admitted, the old
842
   contract remains in effect and an error is returned. If it can be
843
   admitted, it recalculates all necessary parameters for the
844
   contracts already present in the system anr returns zero. This is a
845
   potentially blocking operation; it returns when the system has
846
   either rejected the new contract, or admitted it and made it
847
   effective.
848
 
849
   @param [in]  new_contract a pointer to the new contract
850
   @param [in]  server server id
851
 
852
   @retval 0 if the operation is succesful
853
   @retval FSF_ERR_BAD_ARGUMENT  if the new_contract argument is NULL or the  
854
       value of the server argument is not in range
855
   @retval FSF_ERR_NOT_SCHEDULED_CALLING_THREAD if the calling thread is not
856
       scheduled under the FSF
857
   @retval FSF_ERR_INVALID_SCHEDULER_REPLY the scheduler is wrong or not
858
       running
859
   @retval FSF_ERR_NOT_CONTRACTED_SERVER if the server of the calling thread
860
       has been cancelled or it is not valid
861
*/
862
int
863
fsf_renegotiate_contract
864
  (const fsf_contract_parameters_t *new_contract,
865
   fsf_server_id_t server);
866
 
867
/**
868
   The operation enqueues a renegotiate operation for an existing
869
   server, and returns immediately. The renegotiate operation is
870
   performed asynchronously and the calling thread may continue
871
   executing normally. Of course, wheter the operation is performed
872
   immediately or not depends on the relative priority of the service
873
   thread and the calling thread, on the scheduler used, etc.
874
 
875
   When the renegotiation is completed, if the on-line admission test
876
   is enabled it determines whether the contract can be admitted or
877
   not based on the current contracts established in the system. If it
878
   cannot be admitted, the old contract remains in effect. If it can
879
   be admitted, it recalculates all necessary parameters for the
880
   contracts already present in the system. When the operation is
881
   completed, notification is made to the caller, if requested, via a
882
   signal. The status of the operation (in progress, admitted,
883
   rejected) can be checked with the get_renegotiation_status
884
   operation.  The argument sig_notify can be NULL_SIGNAL (no
885
   notification), or any POSIX signal; and in this case sig_value is
886
   to be sent with the signal.
887
 
888
   @param [in] new_contract pointer to the new contract to be negotiated
889
   @param [in] server  server id
890
   @param [in] sig_notify NULL (no signal) or any POSIX signal
891
   @param [in] sign_value a sigval structure that contains values to be
892
               passed to the signal handler. Valid only if sig_notify
893
               is different from NULL.
894
 
895
   @retval 0 if the call is succesful
896
   @retval FSF_ERR_BAD_ARGUMENT  if the new_contract argument is NULL, the  
897
       value of the server argument is not in range or sig_notify is
898
       neither NULL nor a valid POSIX signal
899
   @retval FSF_ERR_NOT_SCHEDULED_CALLING_THREAD if the calling thread is not
900
       scheduled under the FSF
901
   @retval FSF_ERR_INVALID_SCHEDULER_REPLY the scheduler is wrong or not
902
       running
903
   @retval FSF_ERR_NOT_CONTRACTED_SERVER if the server of the calling thread
904
       has been cancelled or it is not valid
905
 
906
*/
907
int
908
fsf_request_contract_renegotiation
909
  (const fsf_contract_parameters_t *new_contract,
910
   fsf_server_id_t                  server,
911
   int                              sig_notify,
912
   union sigval                     sig_value);
913
 
914
/**
915
   Possible values returned by fsf_get_renegotiation_status
916
*/
917
typedef enum {FSF_IN_PROGRESS,
918
              FSF_REJECTED,
919
              FSF_ADMITTED}
920
    fsf_renegotiation_status_t;
921
 
922
/**
923
   The operation reports on the status of the last renegotiation
924
   operation enqueued for the specified server. It is callable even
925
   after notification of the completion of such operation, if
926
   requested.
927
 
928
   @param [in] server server id
929
   @param [out] renegotiation_status the status of the renegotiation;
930
 
931
   @retval 0 if succesful completion;
932
   @retval FSF_ERR_BAD_ARGUMENT  if the renegotiation_status argument is
933
       NULL or the value of the server argument is not in range
934
   @retval FSF_ERR_NOT_SCHEDULED_CALLING_THREAD if the calling thread is not
935
       scheduled under the FSF
936
   @retval FSF_ERR_INVALID_SCHEDULER_REPLY the scheduler is wrong or not
937
       running
938
   @retval FSF_ERR_NOT_CONTRACTED_SERVER if the server of the calling thread
939
       has been cancelled or it is not valid
940
*/
941
int
942
fsf_get_renegotiation_status
943
  (fsf_server_id_t server,
944
   fsf_renegotiation_status_t *renegotiation_status);
945
 
946
 
947
//Data types
948
 
949
/// List of contracts to negotiate
950
typedef struct {
951
  int  size;
952
  fsf_contract_parameters_t*  contracts[FSF_MAX_N_SERVERS];
953
} fsf_contracts_group_t;
954
 
955
/// List of servers to cancel
956
typedef  struct {
957
  int             size;
958
  fsf_server_id_t servers[FSF_MAX_N_SERVERS];
959
} fsf_servers_group_t;
960
 
961
 
962
/**
963
   This operation analizes the schedulability of the context that
964
   results from negitiating the contracts specified in the
965
   contracts_up list and cacelling the contracts referenced by the
966
   servers_down list. If the overall negotiation is successful, a new
967
   server will be created for each of the elements of the contracts_up
968
   group, the servers in servers_down will be cancelled, the list of
969
   new server ids will be returned in the variable pointed to by
970
   servers_up, and the variable pointed to by accepted will be made
971
   true. Otherwise, this variable will be made false, and no other
972
   effect will take place. The function returns the corresponding
973
   error code if any of the contracts is not correct or any of the
974
   server is is not valid.
975
 
976
   @param [in] contracts_up list of contracts to negotiate
977
   @param [in] contracts_down list of contracts to be canceled
978
   @param [out] servers_up list of server ids that have been created, they are
979
      given in the same order as the contract_up list of contracts;
980
   @param [out] accepted if the operation is succesful;
981
 
982
   @retval 0 if succesful completion;
983
   @retval FSF_ERR_INVALID_SCHEDULER_REPLY the scheduler is wrong or
984
           not running
985
   @retval FSF_ERR_INTERNAL_ERROR erroneous binding or malfunction of the FSF
986
       main scheduler
987
   @retval FSF_ERR_NOT_SCHEDULED_CALLING_THREAD if the calling thread is
988
           not scheduled under the FSF
989
   @retval FSF_ERR_BAD_ARGUMENT if any of the servers_up or accepted arguments
990
       is NULL, if the contracts_up and servers_down arguments are both NULL,
991
       or any of them has erroneous size or its elements are NULL or not in the
992
       valid range respectively
993
*/
994
int
995
fsf_negotiate_group
996
   (const fsf_contracts_group_t *contracts_up,
997
    const fsf_servers_group_t   *severs_down,
998
    fsf_servers_group_t         *severs_up,
999
    bool                        *accepted);
1000
 
1001
 
1002
/*@}*/
1003
 
1004
 
1005
////////////////////////////////////////////////////
1006
//           OBTAINING INFORMATION FROM THE SCHEDULER
1007
////////////////////////////////////////////////////
1008
 
1009
 
1010
/**
1011
   \ingroup coremodule
1012
 
1013
   \defgroup core_sched_info Obtaining information from the scheduler.
1014
 
1015
   This group of function is used to get informations from the
1016
   scheduler, like execution time of a task, remaining budget of a
1017
   server, etc.
1018
 
1019
   @{
1020
 */
1021
 
1022
/**
1023
   Returns true if the system is configured with the on-line admission
1024
   test enabled, or false otherwise.
1025
*/
1026
bool
1027
fsf_is_admission_test_enabled();
1028
 
1029
/**
1030
   This function stores the current execution time spent by the
1031
   threads bound to the specified server in the variable pointed to by
1032
   cpu_time.
1033
 
1034
   @param [in] server server id
1035
   @param [out] cpu_time pointer to a timespec structure that will contain
1036
         the cpu time consumed by the threads that are bound to the
1037
         specific server, since its creation.
1038
 
1039
   @retval 0 if succesful completion
1040
   @retval FSF_ERR_BAD_ARGUMENT if the value of the server argument is
1041
       not in range or cpu_time is NULL
1042
   @retval FSF_ERR_NOT_SCHEDULED_CALLING_THREAD if the calling thread is not
1043
       scheduled under the FSF
1044
   @retval FSF_ERR_INVALID_SCHEDULER_REPLY the scheduler is wrong or
1045
       not running
1046
   @retval FSF_ERR_NOT_CONTRACTED_SERVER if the server of the calling thread
1047
       has been cancelled or it is not valid
1048
*/
1049
int
1050
fsf_get_cpu_time
1051
   (fsf_server_id_t server,
1052
    struct timespec *cpu_time);
1053
 
1054
/**
1055
   This function stores in the variable pointed to by budget the
1056
   remaining execution-time budget associated with the specified
1057
   server.
1058
 
1059
   @param [in] server server id
1060
   @param [out] budget pointer to a timespec structure that will
1061
     contain the remaining budget
1062
 
1063
   @retval 0 if succesful completion
1064
   @retval FSF_ERR_BAD_ARGUMENT if the value of the server argument is
1065
       not in range or budget is NULL
1066
   @retval FSF_ERR_NOT_SCHEDULED_CALLING_THREAD if the calling thread is not
1067
       scheduled under the FSF
1068
   @retval FSF_ERR_INVALID_SCHEDULER_REPLY the scheduler is wrong or
1069
       not running
1070
   @retval FSF_ERR_NOT_CONTRACTED_SERVER if the server of the calling thread
1071
       has been cancelled or it is not valid
1072
*/
1073
int
1074
fsf_get_remaining_budget
1075
   (fsf_server_id_t server,
1076
    struct timespec *budget);
1077
 
1078
 
1079
/**
1080
   This function stores in the variables pointed to by budget and
1081
   period, the execution-time budget and the period respectively
1082
   associated with the specified server. If any of these pointers is
1083
   NULL, the corresponding information is not stored.
1084
 
1085
   @param [in] server server id
1086
   @param [out] budget budget available for the current server instance
1087
   @param [out] period period available for the current server instance
1088
 
1089
   @retval 0 if succesful completion
1090
   @retval FSF_ERR_BAD_ARGUMENT if the value of the server argument is
1091
       not in range, budget is NULL or period is NULL
1092
   @retval FSF_ERR_NOT_SCHEDULED_CALLING_THREAD if the calling thread is not
1093
       scheduled under the FSF
1094
   @retval FSF_ERR_INVALID_SCHEDULER_REPLY the scheduler is wrong or not
1095
     running
1096
   @retval FSF_ERR_NOT_CONTRACTED_SERVER if the server of the calling thread
1097
       has been cancelled or it is not valid
1098
*/
1099
int
1100
fsf_get_budget_and_period
1101
   (fsf_server_id_t server,
1102
    struct timespec *budget,
1103
    struct timespec *period);
1104
 
1105
/* @} */
1106
 
1107
/////////////////////////////////////////////////////////////////////
1108
//           SERVICE THREAD TUNING
1109
/////////////////////////////////////////////////////////////////////
1110
 
1111
/**
1112
   \ingroup coremodule
1113
 
1114
   \defgroup core_service_thread Service Thread
1115
 
1116
   These functions are to the initialization and tuning of the service
1117
   thread.
1118
 
1119
   @todo specify that the default budget and periods are in the
1120
   configuration file.
1121
 
1122
   Implementation dependency: in the fixed priority implementation of
1123
   fsf, the default priority is lower than the priority of any server,
1124
   but higher than the background. According to the
1125
   implementation-dependent module the priority is adjustable by means
1126
   of a function that changes its preemption level.
1127
 
1128
   @{
1129
 */
1130
 
1131
 
1132
/**
1133
   This function allows the application to change the period and
1134
   budget of the service thread that makes the
1135
   negotiations. Increasing the utilization of this thread makes the
1136
   negotiations faster, but introduces additional load in the system
1137
   that may decrease the bandwidth available for the servers. For this
1138
   call, the system will make a schedulability analysis to determine
1139
   if the new situation is acceptable or not. This is reported back in
1140
   the variable pointed to by accepted. If the new service thread data
1141
   is accepted, the system will reassign budgets and periods to the
1142
   servers according to the new bandwidth available, in the same way
1143
   as it does for a regular contract negotiation.
1144
 
1145
   When its budget is exhausted, the service thread may run in the
1146
   background.
1147
 
1148
   The service thread starts with a default budget and period that are
1149
   configurable.
1150
 
1151
   @param [in] budget budget for the service thread
1152
   @param [in] period for the service thread
1153
   @param [out] accepted true is the change has been accepted
1154
 
1155
 
1156
   @retval 0 is the operation is succesful
1157
   @retval FSF_ERR_BAD_ARGUMENT if any of the pointer arguments is NULL or
1158
       the budget value is greater than the period value
1159
   @retval FSF_ERR_NOT_SCHEDULED_CALLING_THREAD if the calling thread is not
1160
       scheduled under the FSF
1161
   @retval FSF_ERR_INVALID_SCHEDULER_REPLY the scheduler is wrong or
1162
       not running
1163
   @retval FSF_ERR_NOT_CONTRACTED_SERVER if the server of the calling thread
1164
       has been cancelled or it is not valid
1165
*/
1166
int
1167
fsf_set_service_thread_data
1168
   (const struct timespec *budget,
1169
    const struct timespec *period,
1170
    bool                  *accepted);
1171
 
1172
/**
1173
   this function returns in the variables pointed by budget and
1174
   period, respectively, the current budget and period of the service
1175
   thread.
1176
 
1177
   @param [out] budget   current budget of the service thread
1178
   @param [out] period   current period of the service thread
1179
 
1180
   @retval FSF_ERR_BAD_ARGUMENT if any of the pointer arguments is NULL
1181
   @retval FSF_ERR_NOT_SCHEDULED_CALLING_THREAD if the calling thread is not
1182
       scheduled under the FSF
1183
   @retval FSF_ERR_INVALID_SCHEDULER_REPLY the scheduler is wrong
1184
       or not running
1185
   @retval FSF_ERR_NOT_CONTRACTED_SERVER if the server of the calling thread
1186
       has been cancelled or it is not valid
1187
*/
1188
int
1189
fsf_get_service_thread_data
1190
   (struct timespec *budget,
1191
    struct timespec *period);
1192
 
1193
/* @} */
1194
 
1195
////////////////////////////////////////////////////////////////////////
1196
//           BACKGROUND MANAGEMENT
1197
////////////////////////////////////////////////////////////////////////
1198
 
1199
/**
1200
 
1201
   A round-robin background scheduling policy is available for those
1202
   threads that do not have real-time requirements. Because some of
1203
   these threads may require sharing information with other threads
1204
   run by regular servers, special background contracts may be created
1205
   for specifying the synchronization requirements.
1206
 
1207
   The way of specifying a background contract is by setting
1208
   budget_min = period_max = 0. Negotiation may fail if the contract
1209
   uses shared_objects. If the contract has no shared_objects the
1210
   returned server id represents the background and may be used to
1211
   bind more than one thread. If the contract has shared objects a
1212
   server is created to keep track of them, but the associated threads
1213
   are executed in the background, together with the other background
1214
   threads
1215
 
1216
   @todo [PEPPE: this will be put in the general description of the core
1217
   module]
1218
*/
1219
 
1220
 
1221
#endif // _FSF_CORE_H_