Subversion Repositories shark

Rev

Rev 221 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
221 giacomo 1
//====================================================================================
2
//       FFFFFFIII   RRRRR      SSTTTTTTT
3
//      FF         IIR   RR    SS
4
//     FF           IR        SS
5
//    FFFFFF         RRRR    SSSSST      
6
//   FF       FI       RRR  SS
7
//  FF         II     RRR  SS
8
// FF           IIIIIR    RS 
9
//       
10
// Basic FSF(FIRST Scheduling Framework) contract management
11
// S.Ha.R.K. Implementation
12
//=====================================================================
13
 
14
#include <time.h>
15
#include <sys/boolean.h>
16
#include <sys/types.h>
17
 
18
#include "fsf_configuration_parameters.h"
19
#include "fsf_opaque_types.h"
20
 
224 giacomo 21
#include "posix.h"
22
#include "cbsstar.h"
23
#include "edfstar.h"
24
#include "posixstar.h"
25
 
221 giacomo 26
#ifndef _FSF_CONTRACT_H_
27
#define _FSF_CONTRACT_H_
28
 
224 giacomo 29
/* S.Ha.R.K. Init */
30
int FSF_register_module(int posix_level, int cbsstar_level);
31
 
221 giacomo 32
//////////////////////////////////////////////////////////////////
33
//                     BASIC TYPES AND CONSTANTS
34
//////////////////////////////////////////////////////////////////
35
 
36
typedef enum {FSF_BOUNDED, FSF_INDETERMINATE} fsf_workload_t;
37
 
38
typedef enum {FSF_CONTINUOUS, FSF_DISCRETE} fsf_granularity_t;
39
 
40
typedef struct {
41
  struct timespec    budget;    // Execution time
42
  struct timespec    period;    // Period
43
} fsf_utilization_value_t;
44
 
45
typedef struct {
46
  int                         size; // = 0
47
  fsf_utilization_value_t     unit[FSF_MAX_N_UTILIZATION_VALUES];
48
} fsf_utilization_set_t;
49
 
50
typedef unsigned long         fsf_preemption_level_t; // range 1..2**32-1
51
 
52
typedef struct {
53
  struct timespec          wcet;      // Execution time
54
  fsf_preemption_level_t   plevel;    // Preemption_Level, range 1..2**32-1
55
} fsf_critical_section_data_t;
56
 
57
typedef struct {
58
  int                          size; // = 0
59
  fsf_critical_section_data_t  section[FSF_MAX_N_CRITICAL_SECTIONS];
60
} fsf_critical_sections_t;
61
 
62
typedef int fsf_scheduler_id_t;
63
 
64
#define FSF_SCHEDULER_POSIX             0
65
#define FSF_SCHEDULER_EDF               1
66
#define FSF_SCHEDULER_RM                2
67
 
68
// Constants for assigning default values
69
#define FSF_DEFAULT_WORKLOAD            FSF_INDETERMINATE
70
#define FSF_DEFAULT_GRANULARITY         FSF_CONTINUOUS
71
#define FSF_DEFAULT_QUALITY             0
72
#define FSF_DEFAULT_IMPORTANCE          1
73
#define FSF_DEFAULT_D_EQUALS_T          false
74
#define FSF_DEFAULT_DEADLINE            {0,0}
75
#define FSF_DEFAULT_SCHEDULER           FSF_SCHEDULER_POSIX
76
 
77
// Constants for omitting the assignment of values to specific arguments
78
// in calls to initialization functions
79
#define FSF_NULL_CRITICAL_SECTIONS      (fsf_critical_sections_t *)NULL
80
#define FSF_NULL_UTILIZATION_SET        (fsf_utilization_set_t *)NULL
81
#define FSF_NULL_DEADLINE               (struct timespec *)NULL
82
#define FSF_NULL_SIGNAL                 0
83
 
84
 
85
// Error codes
86
#define FSF_ERR_NOT_INITIALIZED                 2003001
87
#define FSF_ERR_TOO_MANY_TASKS                  2003002
88
#define FSF_ERR_ALREADY_INITIALIZED             2003003
89
#define FSF_ERR_BAD_ARGUMENT                    2003004
90
#define FSF_ERR_INVALID_SYNCH_OBJECT_HANDLE     2003005
91
#define FSF_ERR_NO_RENEGOTIATION_REQUESTED      2003006
92
#define FSF_ERR_CONTRACT_REJECTED               2003007
93
#define FSF_ERR_TOO_MANY_SERVERS                2003008
94
#define FSF_ERR_BIND_THREAD                     2003009
95
#define FSF_ERR_UNBIND_THREAD                   2003010
96
#define FSF_ERR_CREATE_THREAD                   2003011
97
#define FSF_ERR_SERVER_USED                     2003012
98
#define FSF_ERR_INVALID_SERVER                  2003013
99
#define FSF_ERR_CREATE_SERVER                   2003014
100
 
101
//////////////////////////////////////////////////////////////
102
//                       CONTRACT PARAMETERS
103
//////////////////////////////////////////////////////////////
104
 
105
// Contract parameters type; it is an opaque type
106
typedef FSF_CONTRACT_PARAMETERS_T_OPAQUE fsf_contract_parameters_t;
107
 
108
int
109
fsf_initialize_contract(fsf_contract_parameters_t *contract);
110
 
111
//Description: The operation receives a pointer to a contract parameters
112
//object and initializes it, setting it to the default values.
113
//  budget_min                  => {0,0};                              
114
//  period_max                  => {0,0};                              
115
//  budget_max                  => {0,0};                              
116
//  period_min                  => {0,0};                              
117
//  workload                    => DEFAULT_WORKLOAD;                   
118
 
119
//  d_equals_t                  => DEFAULT_D_EQUALS_T; (false or true)
120
//  deadline                    => DEFAULT_DEADLINE;                     
121
//  budget_overrun_sig_notify   => 0;                  (signal number)
122
//  budget_overrun_sig_value    => {0, NULL};
123
//  deadline_miss_sig_notify    => 0;                  (signal number)
124
//  deadline_miss_sig_value     => {0, NULL};
125
//                                                         
126
//  granularity                 => DEFAULT_GRANULARITY;               
127
//  utilization_set;            => size = 0                         
128
//  quality                     => DEFAULT_QUALITY;     (range 0..100)
129
//  importance                  => DEFAULT_IMPORTANCE;    (range 1..5)
130
//                                                         
131
//  preemption_level            => 0;               (range 1..2**32-1)
132
//  critical_sections;          => size = 0                         
133
 
134
int
135
fsf_set_contract_basic_parameters
136
  (fsf_contract_parameters_t *contract,
137
   const struct timespec  *budget_min,
138
   const struct timespec  *period_max,
139
   const struct timespec  *budget_max,
140
   const struct timespec  *period_min,
141
   fsf_workload_t          workload);
142
 
143
//Description: The operation updates the specified contract parameters
144
//object by setting its budget, period, and workload to the specified
145
//input parameters. (Note: the workload is a basic parameter because
146
//bounded tasks are triggered by the scheduler (see the Timed Schedule
147
//Next Job operation, later), while indeterminate tasks are not;
148
//therefore, their programming model is quite different).
149
 
150
int
151
fsf_get_contract_basic_parameters
152
  (const fsf_contract_parameters_t *contract,
153
   struct timespec  *budget_min,
154
   struct timespec  *period_max,
155
   struct timespec  *budget_max,
156
   struct timespec  *period_min,
157
   fsf_workload_t   *workload);
158
 
159
//Description: This operation obtains from the specified contract parameters
160
//object its budget, period, and workload, and copies them to the places
161
//pointed to by the corresponding input parameters.
162
 
163
int
164
fsf_set_contract_timing_requirements
165
  (fsf_contract_parameters_t *contract,
166
   bool                   d_equals_t,
167
   const struct timespec *deadline,
168
   int                    budget_overrun_sig_notify,
169
   union sigval           budget_overrun_sig_value,
170
   int                    deadline_miss_sig_notify,
171
   union sigval           deadline_miss_sig_value);
172
 
173
//Description: The operation updates the specified contract parameters
174
//object. d_equals_t is used as a boolean, deadline must be
175
//NULL_DEADLINE if d_equals_t is true, budget_overrun_sig_notify or
176
//deadline_miss_sig_notify may be NULL_SIGNAL (no notification) or any
177
//posix signal. budget_overrun_sig_value and deadline_miss_sig_value
178
//are the values to be delivered with the signal.
179
 
180
int
181
fsf_get_contract_timing_requirements
182
  (const fsf_contract_parameters_t *contract,
183
   bool                            *d_equals_t,
184
   struct timespec                 *deadline,
185
   int                             *budget_overrun_sig_notify,
186
   union sigval                    *budget_overrun_sig_value,
187
   int                             *deadline_miss_sig_notify,
188
   union sigval                    *deadline_miss_sig_value);
189
 
190
//Description: The operation obtains the corresponding input
191
//parameters from the specified contract parameters object. If
192
//d_equals_t is true, the deadline will not be updated.
193
 
194
int  
195
fsf_set_contract_reclamation_parameters
196
  (fsf_contract_parameters_t *contract,
197
   fsf_granularity_t            granularity,
198
   const fsf_utilization_set_t *utilization_set,
199
   int                          quality,
200
   int                          importance);
201
 
202
//Description: The operation updates the specified contract parameters
203
//object by setting its granularity, utilization set, quality, and
204
//importance to the specified input parameters.
205
 
206
int  
207
fsf_get_contract_reclamation_parameters
208
  (const fsf_contract_parameters_t *contract,
209
   fsf_granularity_t               *granularity,
210
   fsf_utilization_set_t           *utilization_set,
211
   int                             *quality,
212
   int                             *importance);
213
 
214
//Description: The operation obtains from the specified contract parameters
215
//object its granularity, utilization set, quality, and importance. Then
216
//copies them to the places pointed to by the specified input parameters.
217
//Only the utilization_values of the utilization_set that are in use, are
218
//copied (according to its size field). 
219
 
220
int
221
fsf_set_contract_synchronization_parameters
222
  (fsf_contract_parameters_t     *contract,
223
   fsf_preemption_level_t         preemption_level,
224
   const fsf_critical_sections_t *critical_sections);
225
 
226
//Description: The operation updates the specified contract parameters
227
//object by setting its preemption level and critical sections to the
228
//specified input parameters.
229
 
230
int
231
fsf_get_contract_synchronization_parameters
232
  (const fsf_contract_parameters_t *contract,
233
   fsf_preemption_level_t          *preemption_level,
234
   fsf_critical_sections_t         *critical_sections);
235
 
236
//Description: The operation obtains from the specified contract
237
//parameters object its preemption level and critical sections, and
238
//copies them to the places pointed to by the specified input
239
//parameters.  Only those critical_section_data records that are in use
240
//in the critical_sections structure are copied (according to its size
241
//field).
242
 
243
int
244
fsf_set_local_scheduler_parameter
245
  (fsf_contract_parameters_t *contract,
246
   fsf_scheduler_id_t local_scheduler_id);
247
 
248
int
249
fsf_get_local_scheduler_parameter
250
  (const fsf_contract_parameters_t *contract,
251
   fsf_scheduler_id_t *local_scheduler_id);
252
 
253
//////////////////////////////////////////////////////////////
254
//                 SYNCHRONIZATION OBJECTS
255
//////////////////////////////////////////////////////////////
256
 
257
//An abstract synchronization object is defined by the application.
258
//This object can be used by an application to wait for an event to
259
//arrive by invoking the Event Triggered Schedule Next Job operation.
260
//It can also be used to signal the event either causing a waiting
261
//server to wake up, or the event to be queued if no server is waiting
262
//for it.  It is defined by the following opaque type and has the
263
//following operations:
264
 
265
typedef FSF_SYNCH_OBJECT_HANDLE_T_OPAQUE fsf_synch_object_handle_t;
266
 
267
int
268
fsf_create_synchobject(fsf_synch_object_handle_t *synch_handle);
269
 
270
//Description: This operation creates and initializes a
271
//synchronization object variable managed by the scheduler, and
272
//returns a handle to it in the variable pointed to by synch_handle.
273
 
274
int
275
fsf_signal_synchobject(fsf_synch_object_handle_t *synch_handle);
276
 
277
//Description: If one or more servers are waiting upon the specified
278
//synchronization object one of them is awakened; if not, the event is
279
//queued at the synchronization object.
280
 
281
int
282
fsf_destroy_synchobject(fsf_synch_object_handle_t *synch_handle);
283
 
284
//This operation destroys the synchronization object (created by a
285
//previous call to fsf_create_synchobject) that is referenced by the
286
//synch_handle variable. After calling this operation, the
287
//synch_handle variable can not be used until it is initialized again
288
//by a call to fsf_create_synchobject.
289
 
290
 
291
///////////////////////////////////////////////////////////////
292
//                 CONTRACT NEGOCIATION OPERATIONS
293
///////////////////////////////////////////////////////////////
294
 
295
// Server Id type, that identifies a server created to manage a 
296
// given contract
297
 
298
typedef int      fsf_server_id_t;
299
 
300
// The following type references a function that may become 
301
// a thread's code
302
 
303
typedef void * (*fsf_thread_code_t) (void *);
304
 
305
// Negotiate contract functions: The following functions are used to
306
// create servers for a contract parameters specification and also to
307
// assign one or more threads to a server (Note: the current
308
// implementation only supports one thread per server; this limitation
309
// will be removed in the next phase of the project)
310
 
311
// The first time that any of these operations is called, it creates
312
// all the internal management structures that are necessary for the
313
// FIRST Scheduling Framework to operate properly.
314
 
315
int
316
fsf_negotiate_contract
317
  (const fsf_contract_parameters_t *contract,
318
   fsf_server_id_t      *server);
319
 
320
//Description: The operation negotiates a contract for a new
321
//server. If the on-line admission test is enabled it determines
322
//whether the contract can be admitted or not based on the current
323
//contracts established in the system. Then it creates the server and
324
//recalculates all necessary parameters for the contracts already
325
//present in the system. This is a potentially blocking operation; it
326
//returns when the system has either rejected the contract, or
327
//admitted it and made it effective. It returns zero and places the
328
//server identification number in the location pointed to by the
329
//server input parameter if accepted, or an error if rejected.  No
330
//thread is bound to the newly created server, which will be idle
331
//until a thread is bound to it. This operation can only be executed
332
//by threads that are already bound to an active server and therefore
333
//are being scheduled by the fsf scheduler.
334
 
335
int
336
fsf_negotiate_contract_for_new_thread
337
  (const fsf_contract_parameters_t *contract,
338
   fsf_server_id_t      *server,
339
   pthread_t            *thread,
340
   pthread_attr_t       *attr,
341
   fsf_thread_code_t     thread_code,
342
   void                 *arg,
343
   void                 *rt_arg);
344
 
345
//Description: This operation negotiates a contract for a new server,
346
//creates a thread and binds it to the server. If the contract is
347
//accepted, the operation creates a thread with the arguments thread,
348
//attr, thread_code and arg as they are defined for the
349
//pthread_create() POSIX function call, and attaches it to the fsf
350
//scheduler. Then, it binds the created thread to the new server. It
351
//returns zero and puts the server identification number in the
352
//location pointed to by the server input parameter. The attr
353
//parameter is overwritten as necessary to introduce the adequate
354
//scheduling policy and priority, according to the preemption level
355
//given in the contract and the fsf_priority_map() function defined by
356
//the user. If the contract is rejected, the thread is not created and
357
//the corresponding error is returned.
358
 
359
int
360
fsf_negotiate_contract_for_myself
361
  (const fsf_contract_parameters_t *contract,
362
   fsf_server_id_t      *server,
363
   void                 *rt_arg);
364
 
365
//Description: This operation negotiates a contract for a new 
366
//server, and binds the calling thread to it. If the contract is 
367
//accepted it returns zero and copies the server identification 
368
//number in the location pointed to by the server input parameter.
369
//If it is rejected, an error is returned.
370
 
371
//Implementation dependent issue: In order to allow the usage of
372
//application defined schedulers, the calling thread must not have the
373
//SCHED_APP scheduling policy and at the same time be attached to an
374
//application scheduler different than the fsf scheduler; in such case,
375
//an error is returned. After a successful call the calling thread
376
//will have the SCHED_APP scheduling policy and will be attached to
377
//the fsf scheduler.
378
 
379
int
380
fsf_bind_thread_to_server
381
  (fsf_server_id_t server,
382
   pthread_t       thread,
383
   void            *rt_arg);
384
 
385
//Description: This operation associates a thread with a server, which
386
//means that it starts consuming the server's budget and is executed
387
//according to the contract established for that server. If the thread
388
//is already bound to another server, it is effectively unbound from
389
//it and bound to the specified one.  
390
 
391
//Implementation dependent issue: In order to allow the usage of
392
//application defined schedulers, the given thread must not have the
393
//scheduling policy SCHED_APP and at the same time be attached to an
394
//application scheduler different than the fsf scheduler.
395
 
396
//FIRST project development issue: In this phase of the project, only
397
//one thread is allowed to be bound to a server, sharing a server by
398
//multiple threads is planned to be allowed in the next phase of
399
//the project.
400
 
401
int
402
fsf_unbind_thread_from_server (pthread_t thread);
403
 
404
//Description: This operation unbinds a thread from a server.
405
//Since threads with no server associated are not allow to execute, 
406
//they remain in a dormant state until they are either eliminated or 
407
//bound again.
408
 
409
//Implementation dependent issue: in the implementation with an
410
//application scheduler, the thread is still attached to the fsf
411
//scheduler, but suspended.
412
 
413
int
414
fsf_get_server
415
  (fsf_server_id_t *server,
416
   pthread_t       thread);
417
 
418
//Description: This operation returns the server associated with a
419
//thread. It returns an error if the thread does not exist, it is not 
420
//under the control of the scheduling framework, or is not bound.
421
 
422
int
423
fsf_cancel_contract (fsf_server_id_t *server);
424
 
425
//Description: The operation eliminates the specified server and
426
//recalculates all necessary parameters for the contracts remaining in 
427
//the system. This is a potentially blocking operation; it returns when 
428
//the system has made the changes effective.
429
 
430
int
431
fsf_renegotiate_contract
432
  (const fsf_contract_parameters_t *new_contract,
433
   fsf_server_id_t server);
434
 
435
//Description: The operation renegotiates a contract for an existing
436
//server. If the on-line admission test is enabled it determines
437
//whether the contract can be admitted or not based on the current
438
//contracts established in the system. If it cannot be admitted, the
439
//old contract remains in effect and an error is returned. If it can
440
//be admitted, it recalculates all necessary parameters for the
441
//contracts already present in the system anr returns zero. This is a
442
//potentially blocking operation; it returns when the system has
443
//either rejected the new contract, or admitted it and made it
444
//effective.
445
 
446
int
447
fsf_request_contract_renegotiation
448
  (const fsf_contract_parameters_t *new_contract,
449
   fsf_server_id_t                  server,
450
   int                              sig_notify,
451
   union sigval                     sig_value);
452
 
453
//Description: The operation enqueues a renegotiate operation for an
454
//existing server, and returns immediately. The renegotiate operation
455
//is performed asynchronously, as soon as it is practical; meanwhile
456
//the system operation will continue normally. When the renegotiation
457
//is made, if the on-line admission test is enabled it determines
458
//whether the contract can be admitted or not based on the current
459
//contracts established in the system. If it cannot be admitted, the
460
//old contract remains in effect. If it can be admitted, it
461
//recalculates all necessary parameters for the contracts already
462
//present in the system. When the operation is completed, notification
463
//is made to the caller, if requested, via a signal. The status of the
464
//operation (in progress, admitted, rejected) can be checked with the
465
//get_renegotiation_status operation.  The argument sig_notify can be
466
//NULL_SIGNAL (no notification), or any posix signal; and in this case
467
//sig_value is to be sent with the signal.
468
 
469
typedef enum {FSF_IN_PROGRESS,
470
              FSF_REJECTED,
471
              FSF_ADMITTED} fsf_renegotiation_status_t;
472
 
473
int
474
fsf_get_renegotiation_status
475
  (fsf_server_id_t server,
476
   fsf_renegotiation_status_t *renegotiation_status);
477
 
478
//Description: The operation reports on the status of the last
479
//renegotiation operation enqueued for the specified server. It is 
480
//callable even after notification of the completion of such operation,
481
//if requested.
482
 
483
int
484
fsf_request_change_quality_and_importance
485
  (fsf_server_id_t server,
486
   int new_importance,
487
   int new_quality);
488
 
489
//Description: The operation enqueues a request to change the quality and 
490
//importance parameters of the specified server, and returns immediately.
491
//The change operation is performed as soon as it is practical;
492
//meanwhile the system operation will continue normally.
493
 
494
 
495
////////////////////////////////////////////////////////////
496
//                  SCHEDULING BOUNDED WORKLOADS
497
////////////////////////////////////////////////////////////
498
 
499
int
500
fsf_schedule_next_timed_job
501
  (const struct timespec *at_absolute_time,
502
   struct timespec       *next_budget,
503
   struct timespec       *next_period,
504
   bool                  *was_deadline_missed,
505
   bool                  *was_budget_overran);
506
 
507
//Description: This operation is invoked by threads associated with
508
//bounded workload servers to indicate that a job has been completed
509
//(and that the scheduler may reassign the unused capacity of the
510
//current job to other servers), and also when the first job require
511
//to be scheduled. The system will activate the job at the specified 
512
//absolute time, and will then use the scheduling rules to determine 
513
//when the job can run, at which time the call returns. Upon return, 
514
//the system reports the current period and budget for the current
515
//job, whether the deadline of the previous job was missed or not, 
516
//and whether the budget of the previous job was overrun or not.
517
 
518
 
519
int
520
fsf_schedule_next_event_triggered_job
521
  (fsf_synch_object_handle_t *synch_handle,
522
   struct timespec           *next_budget,
523
   struct timespec           *next_period,
524
   bool                      *was_deadline_missed,
525
   bool                      *was_budget_overran);
526
 
527
//Description: This operation is invoked by threads associated with
528
//bounded workload servers to indicate that a job has been completed
529
//(and that the scheduler may reassign the unused capacity of the
530
//current job to other servers), and also when the first job require
531
//to be scheduled. If the specified synchronization object has events 
532
//queued, one of them is dequeued; otherwise the server will wait upon 
533
//the specified synchronization object until it is signalled. Then, the 
534
//system will use the scheduling rules to determine when the job can run 
535
//and the call will return at that time. Upon return, the system reports
536
//the current period and budget for the current job, whether the deadline
537
//of the previous job was missed or not, and whether the budget of the
538
//previous job was overrun or not.
539
 
540
 
541
//////////////////////////////////////////////////////////////
542
//           OBTAINING INFORMATION FROM THE SCHEDULER
543
//////////////////////////////////////////////////////////////
544
 
545
int
546
fsf_get_available_capacity (fsf_server_id_t server, float *capacity);
547
 
548
//Description: This operation returns the current spare capacity (in 
549
//percentage of processor or network utilization), currently assigned 
550
//to the importance level of the specified server.
551
 
552
int
553
fsf_get_total_quality (fsf_server_id_t server, int *total_quality);
554
 
555
//Description: This operation returns the sum of the quality parameters 
556
//for all servers in the system of importance level equal to that of 
557
//the specified server.
558
 
559
int
560
fsf_is_admission_test_enabled();
561
 
562
//Description: Returns true if the system is configured with the 
563
//on-line admission test enabled, or false otherwise.
564
 
565
 
566
#endif // _FSF_CONTRACT_H_