Subversion Repositories shark

Rev

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