Subversion Repositories shark

Rev

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