Subversion Repositories shark

Rev

Rev 934 | Rev 940 | 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
 
933 trimarchi 145
  f=kern_fsave();
146
 
241 giacomo 147
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level, exec_shadow);
148
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, exec_shadow);
221 giacomo 149
 
226 giacomo 150
  if (proc_table[exec_shadow].task_level != local_scheduler_level) return 0;
151
 
221 giacomo 152
  switch (scheduler_id) {
868 trimarchi 153
    case FSF_POSIX:
221 giacomo 154
      budget = POSIXSTAR_getbudget(local_scheduler_level, exec_shadow);
155
      break;
868 trimarchi 156
    case FSF_EDF:
221 giacomo 157
      budget = EDFSTAR_getbudget(local_scheduler_level, exec_shadow);
158
      break;
868 trimarchi 159
    case FSF_NONE:
858 trimarchi 160
      budget = NONESTAR_getbudget(local_scheduler_level, exec_shadow);
161
      break;
868 trimarchi 162
    case FSF_RM:
858 trimarchi 163
      budget = RMSTAR_getbudget(local_scheduler_level, exec_shadow);
164
      break;
165
 
221 giacomo 166
    default:
167
      budget = -1;
168
      break;
169
  }
170
 
933 trimarchi 171
  if (budget == -1) {
172
    kern_frestore(f);
173
    return FSF_ERR_BAD_ARGUMENT;
174
  }
221 giacomo 175
 
176
  if (next_budget != NULL && next_period != NULL) {
177
 
661 giacomo 178
    SERVER_getbudgetinfo(fsf_server_level, &Q, &T, &D, budget);
221 giacomo 179
 
180
    #ifdef FSF_DEBUG
181
      kern_printf("(budget %d Q=%d T=%d)",budget,(int)Q,(int)T);
182
    #endif
183
 
184
    next_budget->tv_sec = Q / 1000000;
185
    next_budget->tv_nsec = (Q % 1000000) * 1000;
186
    next_period->tv_sec = T / 1000000;
187
    next_period->tv_nsec = (T % 1000000) * 1000;
188
 
189
  }
190
 
224 giacomo 191
  if (was_deadline_missed != NULL)
192
    *was_deadline_missed = false;
221 giacomo 193
  if (was_budget_overran != NULL)
224 giacomo 194
    *was_budget_overran = false;
221 giacomo 195
 
933 trimarchi 196
  if (at_absolute_time != NULL) {    
197
    fsf_get_server(exec_shadow, &server);
198
    fsf_settask_nopreemptive(&server, exec_shadow);
199
    kern_event_post(at_absolute_time, (void (*)(void *))restart_task, (void *)(exec_shadow));
200
  }
221 giacomo 201
 
202
  #ifdef FSF_DEBUG
203
    if (at_absolute_time != NULL)
204
      kern_printf("(Next act s%d:us%d)",(int)at_absolute_time->tv_sec,(int)at_absolute_time->tv_nsec/1000);
205
    else
206
      kern_printf("(End Cycle %d)",exec_shadow);
207
  #endif
208
 
933 trimarchi 209
  kern_frestore(f);
798 giacomo 210
  task_endcycle();
221 giacomo 211
 
212
  return 0;
213
 
214
}
215
 
932 trimarchi 216
int fsf_schedule_triggered_job
217
  (fsf_synch_obj_handle_t  synch_handle,
218
   struct timespec         *next_budget,
219
   struct timespec         *next_period,
220
   bool                    *was_deadline_missed,
221
   bool                    *was_budget_overran)
221 giacomo 222
{
223
 
661 giacomo 224
  TIME T,Q,D;
936 trimarchi 225
  int index=synch_handle;
221 giacomo 226
  int budget, local_scheduler_level, scheduler_id;
934 trimarchi 227
  fsf_server_id_t server;
933 trimarchi 228
  SYS_FLAGS f;
221 giacomo 229
 
933 trimarchi 230
  f=kern_fsave();
231
 
241 giacomo 232
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level, exec_shadow);
233
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, exec_shadow);
226 giacomo 234
 
933 trimarchi 235
  if (proc_table[exec_shadow].task_level != local_scheduler_level) {
236
    kern_frestore(f);
936 trimarchi 237
      return FSF_ERR_BAD_ARGUMENT;
933 trimarchi 238
  }
226 giacomo 239
 
221 giacomo 240
  switch (scheduler_id) {
868 trimarchi 241
    case FSF_POSIX:
221 giacomo 242
      budget = POSIXSTAR_getbudget(local_scheduler_level, exec_shadow);
243
      break;
868 trimarchi 244
    case FSF_EDF:
221 giacomo 245
      budget = EDFSTAR_getbudget(local_scheduler_level, exec_shadow);
246
      break;
868 trimarchi 247
    case FSF_RM:
933 trimarchi 248
      budget = RMSTAR_getbudget(local_scheduler_level, exec_shadow);
936 trimarchi 249
   case FSF_NONE:
250
      budget = NONESTAR_getbudget(local_scheduler_level, exec_shadow);
251
      break;
221 giacomo 252
    default:
253
      budget = -1;
254
      break;
255
  }
256
 
933 trimarchi 257
  if (budget == -1) {
258
    kern_frestore(f);
259
    return FSF_ERR_BAD_ARGUMENT;
221 giacomo 260
 
933 trimarchi 261
  }
262
 
221 giacomo 263
  if (next_budget != NULL && next_period != NULL) {
264
 
661 giacomo 265
    SERVER_getbudgetinfo(fsf_server_level, &Q, &T, &D, budget);
221 giacomo 266
 
267
    #ifdef FSF_DEBUG
268
      kern_printf("(budget %d Q=%d T=%d)",budget,(int)Q,(int)T);
269
    #endif
270
 
271
    next_budget->tv_sec = Q / 1000000;
272
    next_budget->tv_nsec = (Q % 1000000) * 1000;
273
    next_period->tv_sec = T / 1000000;
274
    next_period->tv_nsec = (T % 1000000) * 1000;
275
 
276
  }
277
 
225 giacomo 278
  if (was_deadline_missed != NULL)
279
    *was_deadline_missed = false;
221 giacomo 280
  if (was_budget_overran != NULL)
225 giacomo 281
    *was_budget_overran = false;
868 trimarchi 282
 
936 trimarchi 283
  if (htable[index].id==-1) {
284
    kern_frestore(f);
285
    return FSF_ERR_INVALID_SYNCH_OBJ_HANDLE;
286
  }
868 trimarchi 287
 
936 trimarchi 288
  if (htable[index].events > 0) {
289
    task_activate(exec_shadow);
290
    htable[index].events--;
291
  } else {
292
    fsf_get_server(exec_shadow, &server);
293
    fsf_settask_nopreemptive(&server, exec_shadow);
294
    iq_insertlast(exec_shadow,&(htable[index].threads));
868 trimarchi 295
  }
221 giacomo 296
 
936 trimarchi 297
  #ifdef FSF_DEBUG
298
    kern_printf("(Synch_Handle Events %d)",synch_handle->events);
299
  #endif
300
 
301
  kern_frestore(f);
302
 
303
  task_endcycle();
304
  return 0;
305
 
306
}
307
 
308
 int fsf_timed_schedule_triggered_job(fsf_synch_obj_handle_t     synch_handle,
309
                                      const struct timespec *   abs_timeout,
310
                                      bool *    timed_out,
311
                                      struct timespec *         next_budget,
312
                                      struct timespec *         next_period,
313
                                      bool *    was_deadline_missed,
314
                                      bool *    was_budget_overran) {
315
 TIME T,Q,D;
316
  int index=synch_handle;
317
  int budget, local_scheduler_level, scheduler_id;
318
  fsf_server_id_t server;
319
  int timed_out;
320
  SYS_FLAGS f;
321
 
322
  f=kern_fsave();
323
 
324
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level, exec_shadow);
325
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, exec_shadow);
326
 
327
  if (proc_table[exec_shadow].task_level != local_scheduler_level) {
328
    kern_frestore(f);
329
    return 0;
330
  }
331
 
332
  switch (scheduler_id) {
333
    case FSF_POSIX:
334
      budget = POSIXSTAR_getbudget(local_scheduler_level, exec_shadow);
335
      break;
336
    case FSF_EDF:
337
      budget = EDFSTAR_getbudget(local_scheduler_level, exec_shadow);
338
      break;
339
    case FSF_RM:
340
      budget = RMSTAR_getbudget(local_scheduler_level, exec_shadow);
341
    default:
342
      budget = -1;
343
      break;
344
  }
345
 
346
  if (budget == -1) {
347
    kern_frestore(f);
348
    return FSF_ERR_BAD_ARGUMENT;
349
 
350
  }
351
 
352
  if (next_budget != NULL && next_period != NULL) {
353
 
354
    SERVER_getbudgetinfo(fsf_server_level, &Q, &T, &D, budget);
355
 
356
    #ifdef FSF_DEBUG
357
      kern_printf("(budget %d Q=%d T=%d)",budget,(int)Q,(int)T);
358
    #endif
359
 
360
    next_budget->tv_sec = Q / 1000000;
361
    next_budget->tv_nsec = (Q % 1000000) * 1000;
362
    next_period->tv_sec = T / 1000000;
363
    next_period->tv_nsec = (T % 1000000) * 1000;
364
 
365
  }
366
 
367
  if (was_deadline_missed != NULL)
368
    *was_deadline_missed = false;
369
  if (was_budget_overran != NULL)
370
    *was_budget_overran = false;
371
 
372
 
373
  if (htable[index].id==-1) {
374
    kern_frestore(f);
375
    return FSF_ERR_INVALID_SYNCH_OBJ_HANDLE;
376
  }
377
 
378
 
868 trimarchi 379
  if (htable[index].events > 0) {
221 giacomo 380
    task_activate(exec_shadow);
868 trimarchi 381
    htable[index].events--;
934 trimarchi 382
  } else {
383
    fsf_get_server(exec_shadow, &server);
384
    fsf_settask_nopreemptive(&server, exec_shadow);
868 trimarchi 385
    iq_insertlast(exec_shadow,&(htable[index].threads));
936 trimarchi 386
    //kern_event_post(ats_timeout, (void (*)(void *))restart_task, (void *)(exec_shadow));
934 trimarchi 387
  }
221 giacomo 388
 
389
  #ifdef FSF_DEBUG
390
    kern_printf("(Synch_Handle Events %d)",synch_handle->events);
391
  #endif
392
 
933 trimarchi 393
  kern_frestore(f);
394
 
798 giacomo 395
  task_endcycle();
221 giacomo 396
  return 0;
397
 
936 trimarchi 398
};