Subversion Repositories shark

Rev

Rev 996 | 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_configuration_parameters.h"
15
#include "fsf_core.h"
241 giacomo 16
#include "fsf_server.h"
221 giacomo 17
 
1009 trimarchi 18
#include "fedfstar.h"
868 trimarchi 19
#include "posixstar.h"
20
#include "edfstar.h"
21
#include "nonestar.h"
22
#include "rmstar.h"
23
 
241 giacomo 24
extern int fsf_server_level;
221 giacomo 25
 
868 trimarchi 26
struct hash_entry {
27
  IQUEUE             threads;
28
  int                events;
29
  FSF_SYNCH_OBJ_HANDLE_T_OPAQUE id;
30
};
31
 
32
#define MAX_HASH_ENTRY FSF_MAX_N_SYNCH_OBJECTS 
33
struct  hash_entry htable[MAX_HASH_ENTRY];
34
 
35
void FSF_init_synch_obj_layer() {
36
   int i;
37
   for (i=0; i<MAX_HASH_ENTRY; i++)
38
        htable[i].id=-1;
39
}
40
 
41
/*----------------------------------------------------------------------*/
42
/* hash_fun() : address hash table                                      */
43
/*----------------------------------------------------------------------*/
936 trimarchi 44
static int hash_fun(FSF_SYNCH_OBJ_HANDLE_T_OPAQUE *id)
868 trimarchi 45
{
936 trimarchi 46
    return ((int)id % MAX_HASH_ENTRY);
868 trimarchi 47
}
48
 
221 giacomo 49
//#define FSF_DEBUG
50
 
51
int
936 trimarchi 52
fsf_create_synch_obj(fsf_synch_obj_handle_t *synch_handle)
221 giacomo 53
{
868 trimarchi 54
  int index,oldindex;
945 trimarchi 55
  SYS_FLAGS f;
56
  f=kern_fsave();
57
 
58
  index=hash_fun(synch_handle);
221 giacomo 59
 
945 trimarchi 60
  if (index<0 || index>=MAX_HASH_ENTRY)  {
61
    kern_frestore(f);
62
    return FSF_ERR_INVALID_SYNCH_OBJ_HANDLE;
63
  }
941 trimarchi 64
 
65
  if (htable[index].id==1) {
868 trimarchi 66
    oldindex=index;
67
    index = (index + 1) % MAX_HASH_ENTRY;
68
    // find 
941 trimarchi 69
    while (htable[index].id == 1 && index!=oldindex) index=(index+1) % MAX_HASH_ENTRY;
945 trimarchi 70
    if (index==oldindex) {
71
      kern_frestore(f);
72
      return FSF_ERR_TOO_MANY_SYNCH_OBJS;
73
    }  
868 trimarchi 74
  }
75
  //if (!synch_handle) return FSF_ERR_INVALID_SYNCH_OBJECT_HANDLE;
221 giacomo 76
 
868 trimarchi 77
  iq_init(&(htable[index].threads), NULL, 0);  
78
  htable[index].events = 0;
936 trimarchi 79
  htable[index].id = 1;
945 trimarchi 80
 
81
  kern_frestore(f);
82
 
936 trimarchi 83
  *synch_handle=index;
221 giacomo 84
 
85
  return 0;
86
 
87
}
88
 
89
int
936 trimarchi 90
fsf_signal_synch_obj(fsf_synch_obj_handle_t synch_handle)
221 giacomo 91
{
92
 
93
  PID p;
936 trimarchi 94
  int index=synch_handle;
934 trimarchi 95
  fsf_server_id_t server;
96
  SYS_FLAGS f;
97
  f=kern_fsave();
945 trimarchi 98
 
99
  if (synch_handle<0 || synch_handle>=MAX_HASH_ENTRY)  {
100
    kern_frestore(f);
101
    return FSF_ERR_INVALID_SYNCH_OBJ_HANDLE;
102
  }
103
 
936 trimarchi 104
  if (htable[index].id==-1) {
105
    kern_frestore(f);
106
    return  FSF_ERR_INVALID_SYNCH_OBJ_HANDLE;
868 trimarchi 107
  }
936 trimarchi 108
 
868 trimarchi 109
  //if (!synch_handle) return FSF_ERR_INVALID_SYNCH_OBJECT_HANDLE;
221 giacomo 110
 
934 trimarchi 111
  if ((p = iq_getfirst(&(htable[index].threads))) != NIL) {
112
    fsf_get_server(p, &server);
113
    fsf_settask_preemptive(&server, p);
221 giacomo 114
    task_activate(p);
934 trimarchi 115
  }
221 giacomo 116
  else
868 trimarchi 117
    htable[index].events++;
221 giacomo 118
 
934 trimarchi 119
  kern_frestore(f);
221 giacomo 120
  return 0;
121
 
122
}
123
 
124
int
936 trimarchi 125
fsf_destroy_synch_obj(fsf_synch_obj_handle_t synch_handle)
221 giacomo 126
{
936 trimarchi 127
  int index=synch_handle;
128
  SYS_FLAGS f;
129
  f=kern_fsave();
945 trimarchi 130
 
131
  if (synch_handle<0 || synch_handle>=MAX_HASH_ENTRY) {
132
    kern_frestore(f);
133
    return FSF_ERR_INVALID_SYNCH_OBJ_HANDLE;
134
  }
135
 
936 trimarchi 136
  if (htable[index].id==-1) {
137
    kern_frestore(f);
138
    return FSF_ERR_INVALID_SYNCH_OBJ_HANDLE;
868 trimarchi 139
  }
964 trimarchi 140
  htable[index].id=-1;
868 trimarchi 141
  //if (!synch_handle) return FSF_ERR_INVALID_SYNCH_OBJECT_HANDLE;
142
 
143
  while (iq_getfirst(&(htable[index].threads)) != NIL);  
144
  htable[index].events = 0;
945 trimarchi 145
  kern_frestore(f);
868 trimarchi 146
 
221 giacomo 147
  return 0;
148
 
149
}
150
 
933 trimarchi 151
int restart_task(PID p) {
152
  fsf_server_id_t server;
153
 
154
  fsf_get_server(p, &server);
155
  fsf_settask_preemptive(&server, p);
156
  return task_activate(p);
157
}
158
 
932 trimarchi 159
int fsf_schedule_timed_job
221 giacomo 160
  (const struct timespec *at_absolute_time,
161
   struct timespec       *next_budget,
162
   struct timespec       *next_period,
163
   bool                  *was_deadline_missed,
164
   bool                  *was_budget_overran)
165
{
661 giacomo 166
  TIME T,Q,D;
221 giacomo 167
  int budget, local_scheduler_level, scheduler_id;
933 trimarchi 168
  SYS_FLAGS f;
169
  fsf_server_id_t server;
221 giacomo 170
 
996 trimarchi 171
  if (!at_absolute_time && (at_absolute_time->tv_sec < 0 || at_absolute_time->tv_nsec > 1000000000))
940 trimarchi 172
     return FSF_ERR_BAD_ARGUMENT;
173
 
933 trimarchi 174
  f=kern_fsave();
175
 
241 giacomo 176
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level, exec_shadow);
177
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, exec_shadow);
221 giacomo 178
 
226 giacomo 179
  if (proc_table[exec_shadow].task_level != local_scheduler_level) return 0;
180
 
221 giacomo 181
  switch (scheduler_id) {
954 trimarchi 182
    case FSF_RR:
221 giacomo 183
      budget = POSIXSTAR_getbudget(local_scheduler_level, exec_shadow);
184
      break;
868 trimarchi 185
    case FSF_EDF:
221 giacomo 186
      budget = EDFSTAR_getbudget(local_scheduler_level, exec_shadow);
187
      break;
868 trimarchi 188
    case FSF_NONE:
858 trimarchi 189
      budget = NONESTAR_getbudget(local_scheduler_level, exec_shadow);
190
      break;
954 trimarchi 191
    case FSF_FP:
858 trimarchi 192
      budget = RMSTAR_getbudget(local_scheduler_level, exec_shadow);
193
      break;
1009 trimarchi 194
  case FSF_FEDF:
195
      budget = FEDFSTAR_getbudget(local_scheduler_level, exec_shadow);
196
      break;
858 trimarchi 197
 
221 giacomo 198
    default:
199
      budget = -1;
200
      break;
201
  }
202
 
933 trimarchi 203
  if (budget == -1) {
204
    kern_frestore(f);
205
    return FSF_ERR_BAD_ARGUMENT;
206
  }
221 giacomo 207
 
208
  if (next_budget != NULL && next_period != NULL) {
209
 
661 giacomo 210
    SERVER_getbudgetinfo(fsf_server_level, &Q, &T, &D, budget);
221 giacomo 211
 
212
    #ifdef FSF_DEBUG
213
      kern_printf("(budget %d Q=%d T=%d)",budget,(int)Q,(int)T);
214
    #endif
215
 
216
    next_budget->tv_sec = Q / 1000000;
217
    next_budget->tv_nsec = (Q % 1000000) * 1000;
218
    next_period->tv_sec = T / 1000000;
219
    next_period->tv_nsec = (T % 1000000) * 1000;
220
 
221
  }
222
 
224 giacomo 223
  if (was_deadline_missed != NULL)
224
    *was_deadline_missed = false;
221 giacomo 225
  if (was_budget_overran != NULL)
224 giacomo 226
    *was_budget_overran = false;
221 giacomo 227
 
933 trimarchi 228
  if (at_absolute_time != NULL) {    
229
    fsf_get_server(exec_shadow, &server);
230
    fsf_settask_nopreemptive(&server, exec_shadow);
231
    kern_event_post(at_absolute_time, (void (*)(void *))restart_task, (void *)(exec_shadow));
232
  }
221 giacomo 233
 
1009 trimarchi 234
#ifdef FSF_DEBUG
221 giacomo 235
    if (at_absolute_time != NULL)
236
      kern_printf("(Next act s%d:us%d)",(int)at_absolute_time->tv_sec,(int)at_absolute_time->tv_nsec/1000);
237
    else
238
      kern_printf("(End Cycle %d)",exec_shadow);
1009 trimarchi 239
#endif
221 giacomo 240
 
933 trimarchi 241
  kern_frestore(f);
798 giacomo 242
  task_endcycle();
940 trimarchi 243
 
221 giacomo 244
 
940 trimarchi 245
 
221 giacomo 246
  return 0;
247
 
248
}
249
 
932 trimarchi 250
int fsf_schedule_triggered_job
251
  (fsf_synch_obj_handle_t  synch_handle,
252
   struct timespec         *next_budget,
253
   struct timespec         *next_period,
254
   bool                    *was_deadline_missed,
255
   bool                    *was_budget_overran)
221 giacomo 256
{
257
 
661 giacomo 258
  TIME T,Q,D;
936 trimarchi 259
  int index=synch_handle;
221 giacomo 260
  int budget, local_scheduler_level, scheduler_id;
934 trimarchi 261
  fsf_server_id_t server;
933 trimarchi 262
  SYS_FLAGS f;
221 giacomo 263
 
933 trimarchi 264
  f=kern_fsave();
265
 
241 giacomo 266
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level, exec_shadow);
267
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, exec_shadow);
226 giacomo 268
 
933 trimarchi 269
  if (proc_table[exec_shadow].task_level != local_scheduler_level) {
270
    kern_frestore(f);
936 trimarchi 271
      return FSF_ERR_BAD_ARGUMENT;
933 trimarchi 272
  }
226 giacomo 273
 
221 giacomo 274
  switch (scheduler_id) {
954 trimarchi 275
    case FSF_RR:
221 giacomo 276
      budget = POSIXSTAR_getbudget(local_scheduler_level, exec_shadow);
277
      break;
868 trimarchi 278
    case FSF_EDF:
221 giacomo 279
      budget = EDFSTAR_getbudget(local_scheduler_level, exec_shadow);
280
      break;
954 trimarchi 281
    case FSF_FP:
933 trimarchi 282
      budget = RMSTAR_getbudget(local_scheduler_level, exec_shadow);
936 trimarchi 283
   case FSF_NONE:
284
      budget = NONESTAR_getbudget(local_scheduler_level, exec_shadow);
285
      break;
221 giacomo 286
    default:
287
      budget = -1;
288
      break;
289
  }
290
 
933 trimarchi 291
  if (budget == -1) {
292
    kern_frestore(f);
293
    return FSF_ERR_BAD_ARGUMENT;
221 giacomo 294
 
933 trimarchi 295
  }
296
 
221 giacomo 297
  if (next_budget != NULL && next_period != NULL) {
298
 
661 giacomo 299
    SERVER_getbudgetinfo(fsf_server_level, &Q, &T, &D, budget);
221 giacomo 300
 
301
    #ifdef FSF_DEBUG
302
      kern_printf("(budget %d Q=%d T=%d)",budget,(int)Q,(int)T);
303
    #endif
304
 
305
    next_budget->tv_sec = Q / 1000000;
306
    next_budget->tv_nsec = (Q % 1000000) * 1000;
307
    next_period->tv_sec = T / 1000000;
308
    next_period->tv_nsec = (T % 1000000) * 1000;
309
 
310
  }
311
 
225 giacomo 312
  if (was_deadline_missed != NULL)
313
    *was_deadline_missed = false;
221 giacomo 314
  if (was_budget_overran != NULL)
225 giacomo 315
    *was_budget_overran = false;
868 trimarchi 316
 
936 trimarchi 317
  if (htable[index].id==-1) {
318
    kern_frestore(f);
319
    return FSF_ERR_INVALID_SYNCH_OBJ_HANDLE;
320
  }
868 trimarchi 321
 
936 trimarchi 322
  if (htable[index].events > 0) {
323
    task_activate(exec_shadow);
324
    htable[index].events--;
325
  } else {
326
    fsf_get_server(exec_shadow, &server);
327
    fsf_settask_nopreemptive(&server, exec_shadow);
328
    iq_insertlast(exec_shadow,&(htable[index].threads));
868 trimarchi 329
  }
221 giacomo 330
 
936 trimarchi 331
  #ifdef FSF_DEBUG
332
    kern_printf("(Synch_Handle Events %d)",synch_handle->events);
333
  #endif
334
 
335
  kern_frestore(f);
336
 
337
  task_endcycle();
338
  return 0;
339
 
340
}
341
 
342
 int fsf_timed_schedule_triggered_job(fsf_synch_obj_handle_t     synch_handle,
343
                                      const struct timespec *   abs_timeout,
344
                                      bool *    timed_out,
345
                                      struct timespec *         next_budget,
346
                                      struct timespec *         next_period,
347
                                      bool *    was_deadline_missed,
348
                                      bool *    was_budget_overran) {
349
 TIME T,Q,D;
350
  int index=synch_handle;
351
  int budget, local_scheduler_level, scheduler_id;
352
  fsf_server_id_t server;
940 trimarchi 353
 
936 trimarchi 354
  SYS_FLAGS f;
355
 
996 trimarchi 356
  if (!abs_timeout && (abs_timeout->tv_sec < 0 || abs_timeout->tv_nsec > 1000000000))
940 trimarchi 357
     return FSF_ERR_BAD_ARGUMENT;
358
 
936 trimarchi 359
  f=kern_fsave();
360
 
361
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level, exec_shadow);
362
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, exec_shadow);
363
 
364
  if (proc_table[exec_shadow].task_level != local_scheduler_level) {
365
    kern_frestore(f);
366
    return 0;
367
  }
368
 
369
  switch (scheduler_id) {
954 trimarchi 370
    case FSF_RR:
936 trimarchi 371
      budget = POSIXSTAR_getbudget(local_scheduler_level, exec_shadow);
372
      break;
373
    case FSF_EDF:
374
      budget = EDFSTAR_getbudget(local_scheduler_level, exec_shadow);
375
      break;
954 trimarchi 376
    case FSF_FP:
936 trimarchi 377
      budget = RMSTAR_getbudget(local_scheduler_level, exec_shadow);
378
    default:
379
      budget = -1;
380
      break;
381
  }
382
 
383
  if (budget == -1) {
384
    kern_frestore(f);
385
    return FSF_ERR_BAD_ARGUMENT;
386
 
387
  }
388
 
389
  if (next_budget != NULL && next_period != NULL) {
390
 
391
    SERVER_getbudgetinfo(fsf_server_level, &Q, &T, &D, budget);
392
 
393
    #ifdef FSF_DEBUG
394
      kern_printf("(budget %d Q=%d T=%d)",budget,(int)Q,(int)T);
395
    #endif
396
 
397
    next_budget->tv_sec = Q / 1000000;
398
    next_budget->tv_nsec = (Q % 1000000) * 1000;
399
    next_period->tv_sec = T / 1000000;
400
    next_period->tv_nsec = (T % 1000000) * 1000;
401
 
402
  }
403
 
404
  if (was_deadline_missed != NULL)
405
    *was_deadline_missed = false;
406
  if (was_budget_overran != NULL)
407
    *was_budget_overran = false;
408
 
409
 
410
  if (htable[index].id==-1) {
411
    kern_frestore(f);
412
    return FSF_ERR_INVALID_SYNCH_OBJ_HANDLE;
413
  }
414
 
415
 
868 trimarchi 416
  if (htable[index].events > 0) {
221 giacomo 417
    task_activate(exec_shadow);
868 trimarchi 418
    htable[index].events--;
934 trimarchi 419
  } else {
420
    fsf_get_server(exec_shadow, &server);
421
    fsf_settask_nopreemptive(&server, exec_shadow);
868 trimarchi 422
    iq_insertlast(exec_shadow,&(htable[index].threads));
936 trimarchi 423
    //kern_event_post(ats_timeout, (void (*)(void *))restart_task, (void *)(exec_shadow));
934 trimarchi 424
  }
221 giacomo 425
 
426
  #ifdef FSF_DEBUG
427
    kern_printf("(Synch_Handle Events %d)",synch_handle->events);
428
  #endif
429
 
933 trimarchi 430
  kern_frestore(f);
431
 
798 giacomo 432
  task_endcycle();
221 giacomo 433
  return 0;
434
 
936 trimarchi 435
};