Subversion Repositories shark

Rev

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