Subversion Repositories shark

Rev

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