Subversion Repositories shark

Rev

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