Subversion Repositories shark

Rev

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