Subversion Repositories shark

Rev

Rev 897 | Rev 940 | Go to most recent revision | 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
 
908 trimarchi 14
#include "fsf.h"
808 trimarchi 15
#include "fsf_server.h"
16
#include <kernel/descr.h>
17
#include <kernel/func.h>
18
#include <pistar.h>
221 giacomo 19
 
808 trimarchi 20
struct hash_entry {
21
  mutex_t mx;
868 trimarchi 22
  FSF_SHARED_OBJ_HANDLE_T_OPAQUE id;
808 trimarchi 23
};
24
 
25
 
868 trimarchi 26
#define MAX_HASH_ENTRY FSF_MAX_N_SHARED_OBJECTS 
808 trimarchi 27
struct  hash_entry htable[MAX_HASH_ENTRY];
28
 
29
 
30
/*----------------------------------------------------------------------*/
31
/* hash_fun() : address hash table                                      */
32
/*----------------------------------------------------------------------*/
868 trimarchi 33
static int hash_fun(fsf_shared_obj_id_t id)
808 trimarchi 34
{
35
    return (*id % MAX_HASH_ENTRY);
36
}
37
 
811 trimarchi 38
void fsf_register_shared_object(void) {
39
int i=0;
40
// Init Hash table
41
//kern_printf("(IT SO)\n");
42
for (i=0; i<MAX_HASH_ENTRY; i++) {
43
  htable[i].id=-1;
808 trimarchi 44
 
811 trimarchi 45
}
46
 
47
}
881 trimarchi 48
int fsf_init() {
811 trimarchi 49
 
881 trimarchi 50
  FSF_start_service_task();
811 trimarchi 51
 
881 trimarchi 52
}
53
 
54
 
221 giacomo 55
int fsf_initialize_contract
56
  (fsf_contract_parameters_t *contract)
57
{
58
  struct timespec default_deadline = FSF_DEFAULT_DEADLINE;
59
 
60
  /* Check */
868 trimarchi 61
  if (!contract) return  FSF_ERR_BAD_ARGUMENT;
221 giacomo 62
 
63
  /* Set to default value */
64
  NULL_TIMESPEC(&contract->budget_min);
65
  NULL_TIMESPEC(&contract->budget_max);
66
  NULL_TIMESPEC(&contract->period_min);
67
  NULL_TIMESPEC(&contract->period_max);
68
 
69
  contract->workload = FSF_DEFAULT_WORKLOAD;
70
 
868 trimarchi 71
  contract->policy = FSF_DEFAULT_SCHED_POLICY;
221 giacomo 72
 
73
  contract->d_equals_t = FSF_DEFAULT_D_EQUALS_T;
74
 
75
  TIMESPEC_ASSIGN(&contract->deadline,&default_deadline);
76
 
77
  contract->budget_overrun_sig_notify = 0;
78
  memset(&contract->budget_overrun_sig_value,0,sizeof(union sigval));
79
 
80
  contract->deadline_miss_sig_notify = 0;
81
  memset(&contract->deadline_miss_sig_value,0,sizeof(union sigval));
82
 
83
  contract->granularity = FSF_DEFAULT_GRANULARITY;
84
  contract->utilization_set.size = 0;
85
  contract->quality = FSF_DEFAULT_QUALITY;
86
  contract->importance = FSF_DEFAULT_IMPORTANCE;
87
 
88
  contract->preemption_level = 0;
89
  contract->critical_sections.size = 0;
90
 
91
  return 0;
92
 
93
}
94
 
95
int fsf_set_contract_basic_parameters
96
  (fsf_contract_parameters_t *contract,
97
   const struct timespec  *budget_min,
868 trimarchi 98
   const struct timespec  *period_max,  
221 giacomo 99
   fsf_workload_t          workload)
100
{
101
 
868 trimarchi 102
  if (!contract) return  FSF_ERR_BAD_ARGUMENT;
221 giacomo 103
 
874 trimarchi 104
  if (budget_min && (budget_min->tv_sec!=0 || budget_min->tv_nsec!=0)) {
868 trimarchi 105
     TIMESPEC_ASSIGN(&contract->budget_min,budget_min);
106
     TIMESPEC_ASSIGN(&contract->budget_max,budget_min);
874 trimarchi 107
  } else return FSF_ERR_BAD_ARGUMENT;
108
 
109
  if (period_max && (period_max->tv_sec!=0 || period_max->tv_nsec!=0)) {
868 trimarchi 110
     TIMESPEC_ASSIGN(&contract->period_max,period_max);
111
     TIMESPEC_ASSIGN(&contract->period_min,period_max);
874 trimarchi 112
  } else return FSF_ERR_BAD_ARGUMENT;
113
 
114
  switch(workload) {
115
     case FSF_INDETERMINATE:
116
     case FSF_BOUNDED:
117
     case FSF_OVERHEAD:
118
        contract->workload = workload;
119
        break;
120
     default: return FSF_ERR_BAD_ARGUMENT;
868 trimarchi 121
  }
221 giacomo 122
 
874 trimarchi 123
 
221 giacomo 124
  return 0;
125
 
126
}
127
 
128
int fsf_get_contract_basic_parameters
129
  (const fsf_contract_parameters_t *contract,
130
   struct timespec  *budget_min,
131
   struct timespec  *period_max,
132
   fsf_workload_t   *workload)
133
{
134
 
874 trimarchi 135
  if (!contract) return FSF_ERR_BAD_ARGUMENT;
221 giacomo 136
 
137
  TIMESPEC_ASSIGN(budget_min,&contract->budget_min);
868 trimarchi 138
  TIMESPEC_ASSIGN(period_max,&contract->period_max);
221 giacomo 139
 
140
  *workload = contract->workload;
141
 
142
  return 0;
143
 
144
}
145
 
146
int fsf_set_contract_timing_requirements
147
  (fsf_contract_parameters_t *contract,
148
   bool                   d_equals_t,
149
   const struct timespec *deadline,
150
   int                    budget_overrun_sig_notify,
151
   union sigval           budget_overrun_sig_value,
152
   int                    deadline_miss_sig_notify,
153
   union sigval           deadline_miss_sig_value)
154
{
155
 
868 trimarchi 156
  if (!contract) return FSF_ERR_BAD_ARGUMENT;
908 trimarchi 157
  if ((d_equals_t==true && deadline != FSF_NULL_DEADLINE) ||
158
      (d_equals_t==false && deadline == FSF_NULL_DEADLINE))
874 trimarchi 159
     return FSF_ERR_BAD_ARGUMENT;
908 trimarchi 160
  if (deadline != FSF_NULL_DEADLINE && TIMESPEC_A_GT_B(deadline, &contract->period_max))
874 trimarchi 161
     return FSF_ERR_BAD_ARGUMENT;
221 giacomo 162
 
163
  contract->d_equals_t = d_equals_t;
164
 
165
  if (deadline) TIMESPEC_ASSIGN(&contract->deadline,deadline);
166
 
167
  contract->budget_overrun_sig_notify = budget_overrun_sig_notify;
168
  contract->budget_overrun_sig_value = budget_overrun_sig_value;
169
  contract->deadline_miss_sig_notify = deadline_miss_sig_notify;
170
  contract->deadline_miss_sig_value = deadline_miss_sig_value;
171
 
172
  return 0;
173
 
174
}
175
 
176
int fsf_get_contract_timing_requirements
177
  (const fsf_contract_parameters_t *contract,
178
   bool                            *d_equals_t,
179
   struct timespec                 *deadline,
180
   int                             *budget_overrun_sig_notify,
181
   union sigval                    *budget_overrun_sig_value,
182
   int                             *deadline_miss_sig_notify,
183
   union sigval                    *deadline_miss_sig_value)
184
{
185
 
868 trimarchi 186
  if (!contract) return  FSF_ERR_BAD_ARGUMENT;
221 giacomo 187
 
188
  *d_equals_t = contract->d_equals_t;
189
 
190
  TIMESPEC_ASSIGN(deadline,&contract->deadline);
191
 
192
  *budget_overrun_sig_notify = contract->budget_overrun_sig_notify;
193
  *budget_overrun_sig_value = contract->budget_overrun_sig_value;
194
  *deadline_miss_sig_notify = contract->deadline_miss_sig_notify;
195
  *deadline_miss_sig_value = contract->deadline_miss_sig_value;
196
 
197
  return 0;
198
 
199
}
200
 
868 trimarchi 201
int
202
fsf_set_contract_reclamation_parameters
203
  (fsf_contract_parameters_t   *contract,
204
   const struct timespec       *budget_max,
205
   const struct timespec       *period_min,
221 giacomo 206
   fsf_granularity_t            granularity,
868 trimarchi 207
   const fsf_utilization_set_t *utilization_set,
221 giacomo 208
   int                          quality,
209
   int                          importance)
210
{
211
 
868 trimarchi 212
  if (!contract) return  FSF_ERR_BAD_ARGUMENT;
221 giacomo 213
 
214
  contract->granularity = granularity;
215
 
216
  if (utilization_set) memcpy(&contract->utilization_set,utilization_set,sizeof(fsf_utilization_set_t));
868 trimarchi 217
 
218
  if (budget_max) TIMESPEC_ASSIGN(&contract->budget_max,budget_max);
219
  if (period_min) TIMESPEC_ASSIGN(&contract->period_min,period_min);
220
 
221 giacomo 221
  contract->quality = quality;
222
  contract->importance = importance;
223
 
224
  return 0;
225
 
226
}
227
 
228
int fsf_get_contract_reclamation_parameters
229
  (const fsf_contract_parameters_t *contract,
868 trimarchi 230
   struct timespec                 *budget_max,
231
   struct timespec                 *period_min,
221 giacomo 232
   fsf_granularity_t               *granularity,
233
   fsf_utilization_set_t           *utilization_set,
234
   int                             *quality,
235
   int                             *importance)
236
{
237
 
868 trimarchi 238
  if (!contract) return FSF_ERR_BAD_ARGUMENT;
221 giacomo 239
 
240
  *granularity = contract->granularity;
241
 
242
  memcpy(utilization_set,&contract->utilization_set,sizeof(fsf_utilization_set_t));
868 trimarchi 243
 
244
  TIMESPEC_ASSIGN(budget_max,&contract->budget_max);
245
  TIMESPEC_ASSIGN(period_min,&contract->period_min);
221 giacomo 246
 
247
  *quality = contract->quality;
248
  *importance = contract->importance;
249
 
250
  return 0;
251
 
252
}
253
 
254
int fsf_set_contract_synchronization_parameters
255
  (fsf_contract_parameters_t     *contract,
256
   const fsf_critical_sections_t *critical_sections)
257
{
258
 
868 trimarchi 259
  if (!contract) return FSF_ERR_BAD_ARGUMENT;
221 giacomo 260
 
261
  if (critical_sections) memcpy(&contract->critical_sections,critical_sections,sizeof(fsf_critical_sections_t));
262
 
263
  return 0;
264
 
265
}
266
 
267
int
268
fsf_get_contract_synchronization_parameters
269
  (const fsf_contract_parameters_t *contract,
270
   fsf_critical_sections_t         *critical_sections)
271
{
272
 
868 trimarchi 273
  if (!contract) return FSF_ERR_BAD_ARGUMENT;
274
 
221 giacomo 275
  memcpy(critical_sections,&contract->critical_sections,sizeof(fsf_critical_sections_t));
276
 
277
  return 0;
278
 
279
}
280
 
868 trimarchi 281
int
282
fsf_set_contract_scheduling_policy
221 giacomo 283
  (fsf_contract_parameters_t *contract,
868 trimarchi 284
   fsf_sched_policy_t         sched_policy)
221 giacomo 285
{
286
 
868 trimarchi 287
  if (!contract) return  FSF_ERR_BAD_ARGUMENT;
221 giacomo 288
 
868 trimarchi 289
  contract->policy = sched_policy;
221 giacomo 290
 
291
  return 0;
292
 
293
}
294
 
295
int
868 trimarchi 296
fsf_get_contract_scheduling_policy
221 giacomo 297
  (const fsf_contract_parameters_t *contract,
868 trimarchi 298
   fsf_sched_policy_t              *sched_policy)
221 giacomo 299
{
300
 
868 trimarchi 301
  if (!contract) return FSF_ERR_BAD_ARGUMENT;
221 giacomo 302
 
868 trimarchi 303
  *sched_policy = contract->policy;
221 giacomo 304
 
305
  return 0;
306
 
307
}
308
 
868 trimarchi 309
/* OLD VERSION
808 trimarchi 310
// mutex lock function
221 giacomo 311
 
808 trimarchi 312
int fsf_lock_object(fsf_shared_operation_t *op) {
313
  int index, oldindex;
811 trimarchi 314
 
315
  index=hash_fun(&(op->obj_id));  
316
  //kern_printf("index %d, htableid %d, obj_op_id %d", index, htable[index].id,op->obj_id);
221 giacomo 317
 
808 trimarchi 318
  if (htable[index].id!=op->obj_id) {
319
    oldindex=index;
320
    index = (index + 1) % MAX_HASH_ENTRY;
321
    // find
811 trimarchi 322
    while (htable[index].id != op->obj_id && index!=oldindex) index=(index+1) % MAX_HASH_ENTRY;
808 trimarchi 323
    if (index==oldindex) return -1;
324
  }
811 trimarchi 325
  //kern_printf("(SO LK)");
808 trimarchi 326
  // we need a special implementation for mutex_lock ... additional parameter
829 giacomo 327
  return PISTAR_lock(FSF_get_shared_object_level(), &htable[index].mx,TIMESPEC2USEC(&op->wcet));
808 trimarchi 328
 
329
}
330
 
331
int fsf_unlock_object(fsf_shared_operation_t *op) {
332
 
333
  int index, oldindex;
334
 
335
  index=hash_fun(&op->obj_id);  
336
 
337
  if (htable[index].id!=op->obj_id) {
338
    oldindex=index;
339
    index = (index + 1) % MAX_HASH_ENTRY;
340
    // find
811 trimarchi 341
    while (htable[index].id != op->obj_id && index!=oldindex) index=(index+1) % MAX_HASH_ENTRY;
808 trimarchi 342
    if (index==oldindex) return -1;
343
  }
811 trimarchi 344
  //kern_printf("UNLOCK index %d", index);
345
 
808 trimarchi 346
  return mutex_unlock(&htable[index].mx);
347
 
348
 
349
 
350
}
351
 
868 trimarchi 352
*/
353
 
354
int fsf_init_shared_object
355
   (fsf_shared_obj_id_t      id,
356
    fsf_shared_obj_handle_t *obj,
357
    pthread_mutex_t         *mutex) {
808 trimarchi 358
  int index;
359
  int oldindex;
360
  PISTAR_mutexattr_t a;
811 trimarchi 361
  SYS_FLAGS f;
808 trimarchi 362
 
363
  PISTAR_mutexattr_default(a);
811 trimarchi 364
  //kern_printf("(SI SO)\n");
365
  f=kern_fsave();
829 giacomo 366
 
868 trimarchi 367
  index=hash_fun(id);
811 trimarchi 368
  //kern_printf("Index %d Hash %d", index, htable[index].id);
829 giacomo 369
 
868 trimarchi 370
  if (htable[index].id == index) {
829 giacomo 371
        kern_frestore(f);
372
        return -1;
373
  }
374
 
808 trimarchi 375
  if (htable[index].id>=0) {
376
    oldindex=index;
377
    index = (index + 1) % MAX_HASH_ENTRY;
378
    // collision detection
811 trimarchi 379
    while (htable[index].id >=0 && index!=oldindex) index=(index+1) % MAX_HASH_ENTRY;
808 trimarchi 380
    // table is full
825 trimarchi 381
    if (index==oldindex) {
382
        kern_frestore(f);
829 giacomo 383
        return -1;
825 trimarchi 384
    }
808 trimarchi 385
  }
829 giacomo 386
 
868 trimarchi 387
  //obj->size=0;
829 giacomo 388
 
808 trimarchi 389
  mutex_init(&(htable[index]).mx, &a);
868 trimarchi 390
  mutex=&(htable[index]).mx;
391
  htable[index].id=index;
392
  *obj=*id;
811 trimarchi 393
  kern_frestore(f);
829 giacomo 394
 
395
  return 0;
396
 
811 trimarchi 397
  //kern_printf("(EI SO)\n");
808 trimarchi 398
}
399
 
868 trimarchi 400
/* OLD VERSION
808 trimarchi 401
// Declare an operation
402
// This function is used to declare that a shared object has
403
//    a synchronized operation on it.
404
// It checks if another operation with the same id has already been
405
//    declared; if so, return false (-1).
406
// The obj_id field of the operation is set equal to the shared object id.
407
// the structure op is copied in the first free element in the array
408
//    shared_op pof the structure obj. If there are no more free element,
409
//    returns -1.
410
// Returns 0 if the operation has been completed, -1 otherwise.
411
 
412
int fsf_declare_shared_object_operation(fsf_shared_object_t *obj,
413
                                        fsf_shared_operation_t *op) {
414
  int i;
825 trimarchi 415
  SYS_FLAGS f;
416
 
417
  f=kern_fsave();
418
 
808 trimarchi 419
  for (i=0; i<obj->size; i++) {
420
    // fail if the operation already declared
825 trimarchi 421
    if (op->op_id==obj->shared_op[i].op_id) {
422
      kern_frestore(f);
808 trimarchi 423
      return -1;    
825 trimarchi 424
    }
808 trimarchi 425
  }
426
 
427
  // fail if the object is full
825 trimarchi 428
  if (obj->size>(FSF_MAX_SHARED_OPERATION-1)) {
429
    kern_frestore(f);
808 trimarchi 430
    return -1;  
825 trimarchi 431
  }
829 giacomo 432
 
823 trimarchi 433
  //kern_printf("(DO SO)");
808 trimarchi 434
  obj->size++;
829 giacomo 435
  obj->shared_op[i].op_id = op->op_id;
436
  TIMESPEC_ASSIGN(&obj->shared_op[i].wcet,&op->wcet);
437
  obj->shared_op[i].obj_id = obj->obj_id;
438
  op->obj_id = obj->obj_id;
439
 
825 trimarchi 440
  kern_frestore(f);  
829 giacomo 441
 
808 trimarchi 442
  return 0;
443
 
444
 
445
}
868 trimarchi 446
*/
808 trimarchi 447
 
868 trimarchi 448
/* OLD VERSION
808 trimarchi 449
int fsf_set_contract_synchronization_parameters(
450
    fsf_contract_parameters_t *contract,
451
    const fsf_shared_operation_t *shared_ops,
452
    size_t op_num)
453
{
454
  if (shared_ops && op_num < FSF_MAX_SHARED_OPERATION)
455
    memcpy(&contract->shared_operations,shared_ops,op_num);
456
  else return -1;
457
 
458
  return 0;
459
}
868 trimarchi 460
*/