Subversion Repositories shark

Rev

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