Subversion Repositories shark

Rev

Rev 1009 | Details | Compare with Previous | Last modification | View Log | RSS feed

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