Subversion Repositories shark

Rev

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