Subversion Repositories shark

Rev

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