Subversion Repositories shark

Rev

Rev 933 | Rev 936 | 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
/*----------------------------------------------------------------------*/
43
static int hash_fun(FSF_SYNCH_OBJ_HANDLE_T_OPAQUE id)
44
{
45
    return (id % MAX_HASH_ENTRY);
46
}
47
 
221 giacomo 48
//#define FSF_DEBUG
49
 
50
int
868 trimarchi 51
fsf_create_synchobject(fsf_synch_obj_handle_t *synch_handle)
221 giacomo 52
{
868 trimarchi 53
  int index,oldindex;
221 giacomo 54
 
868 trimarchi 55
  index=hash_fun(*synch_handle);
56
 
57
  if (htable[index].id!=*synch_handle) {
58
    oldindex=index;
59
    index = (index + 1) % MAX_HASH_ENTRY;
60
    // find 
61
    while (htable[index].id != *synch_handle && index!=oldindex) index=(index+1) % MAX_HASH_ENTRY;
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;
221 giacomo 68
 
69
  return 0;
70
 
71
}
72
 
73
int
868 trimarchi 74
fsf_signal_synchobject(fsf_synch_obj_handle_t *synch_handle)
221 giacomo 75
{
76
 
77
  PID p;
868 trimarchi 78
  int index, oldindex;
934 trimarchi 79
  fsf_server_id_t server;
80
  SYS_FLAGS f;
81
  f=kern_fsave();
221 giacomo 82
 
868 trimarchi 83
  index=hash_fun(*synch_handle);  
84
 
85
  if (htable[index].id!=*synch_handle) {
86
    oldindex=index;
87
    index = (index + 1) % MAX_HASH_ENTRY;
88
    // find 
89
    while (htable[index].id != *synch_handle && index!=oldindex) index=(index+1) % MAX_HASH_ENTRY;
934 trimarchi 90
    if (index==oldindex) {
91
      kern_frestore(f);
92
      return FSF_ERR_INVALID_SYNCH_OBJ_HANDLE;
93
    }
868 trimarchi 94
  }
95
 
96
  //if (!synch_handle) return FSF_ERR_INVALID_SYNCH_OBJECT_HANDLE;
221 giacomo 97
 
934 trimarchi 98
  if ((p = iq_getfirst(&(htable[index].threads))) != NIL) {
99
    fsf_get_server(p, &server);
100
    fsf_settask_preemptive(&server, p);
221 giacomo 101
    task_activate(p);
934 trimarchi 102
  }
221 giacomo 103
  else
868 trimarchi 104
    htable[index].events++;
221 giacomo 105
 
934 trimarchi 106
  kern_frestore(f);
221 giacomo 107
  return 0;
108
 
109
}
110
 
111
int
868 trimarchi 112
fsf_destroy_synchobject(fsf_synch_obj_handle_t *synch_handle)
221 giacomo 113
{
868 trimarchi 114
  int index, oldindex;
221 giacomo 115
 
868 trimarchi 116
  index=hash_fun(*synch_handle);  
221 giacomo 117
 
868 trimarchi 118
  if (htable[index].id!=*synch_handle) {
119
    oldindex=index;
120
    index = (index + 1) % MAX_HASH_ENTRY;
121
    // find 
122
    while (htable[index].id != *synch_handle && index!=oldindex) index=(index+1) % MAX_HASH_ENTRY;
123
    if (index==oldindex) return FSF_ERR_INVALID_SYNCH_OBJ_HANDLE;
124
  }
221 giacomo 125
 
868 trimarchi 126
  //if (!synch_handle) return FSF_ERR_INVALID_SYNCH_OBJECT_HANDLE;
127
 
128
  while (iq_getfirst(&(htable[index].threads)) != NIL);  
129
  htable[index].events = 0;
130
 
221 giacomo 131
  return 0;
132
 
133
}
134
 
933 trimarchi 135
int restart_task(PID p) {
136
  fsf_server_id_t server;
137
 
138
  fsf_get_server(p, &server);
139
  fsf_settask_preemptive(&server, p);
140
  return task_activate(p);
141
}
142
 
932 trimarchi 143
int fsf_schedule_timed_job
221 giacomo 144
  (const struct timespec *at_absolute_time,
145
   struct timespec       *next_budget,
146
   struct timespec       *next_period,
147
   bool                  *was_deadline_missed,
148
   bool                  *was_budget_overran)
149
{
661 giacomo 150
  TIME T,Q,D;
221 giacomo 151
  int budget, local_scheduler_level, scheduler_id;
933 trimarchi 152
  SYS_FLAGS f;
153
  fsf_server_id_t server;
221 giacomo 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();
221 giacomo 221
 
222
  return 0;
223
 
224
}
225
 
932 trimarchi 226
int fsf_schedule_triggered_job
227
  (fsf_synch_obj_handle_t  synch_handle,
228
   struct timespec         *next_budget,
229
   struct timespec         *next_period,
230
   bool                    *was_deadline_missed,
231
   bool                    *was_budget_overran)
221 giacomo 232
{
233
 
661 giacomo 234
  TIME T,Q,D;
868 trimarchi 235
  int index,oldindex;
221 giacomo 236
  int budget, local_scheduler_level, scheduler_id;
934 trimarchi 237
  fsf_server_id_t server;
933 trimarchi 238
  SYS_FLAGS f;
221 giacomo 239
 
933 trimarchi 240
  f=kern_fsave();
241
 
241 giacomo 242
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level, exec_shadow);
243
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, exec_shadow);
226 giacomo 244
 
933 trimarchi 245
  if (proc_table[exec_shadow].task_level != local_scheduler_level) {
246
    kern_frestore(f);
247
    return 0;
248
  }
226 giacomo 249
 
221 giacomo 250
  switch (scheduler_id) {
868 trimarchi 251
    case FSF_POSIX:
221 giacomo 252
      budget = POSIXSTAR_getbudget(local_scheduler_level, exec_shadow);
253
      break;
868 trimarchi 254
    case FSF_EDF:
221 giacomo 255
      budget = EDFSTAR_getbudget(local_scheduler_level, exec_shadow);
256
      break;
868 trimarchi 257
    case FSF_RM:
933 trimarchi 258
      budget = RMSTAR_getbudget(local_scheduler_level, exec_shadow);
221 giacomo 259
    default:
260
      budget = -1;
261
      break;
262
  }
263
 
933 trimarchi 264
  if (budget == -1) {
265
    kern_frestore(f);
266
    return FSF_ERR_BAD_ARGUMENT;
221 giacomo 267
 
933 trimarchi 268
  }
269
 
221 giacomo 270
  if (next_budget != NULL && next_period != NULL) {
271
 
661 giacomo 272
    SERVER_getbudgetinfo(fsf_server_level, &Q, &T, &D, budget);
221 giacomo 273
 
274
    #ifdef FSF_DEBUG
275
      kern_printf("(budget %d Q=%d T=%d)",budget,(int)Q,(int)T);
276
    #endif
277
 
278
    next_budget->tv_sec = Q / 1000000;
279
    next_budget->tv_nsec = (Q % 1000000) * 1000;
280
    next_period->tv_sec = T / 1000000;
281
    next_period->tv_nsec = (T % 1000000) * 1000;
282
 
283
  }
284
 
225 giacomo 285
  if (was_deadline_missed != NULL)
286
    *was_deadline_missed = false;
221 giacomo 287
  if (was_budget_overran != NULL)
225 giacomo 288
    *was_budget_overran = false;
868 trimarchi 289
 
932 trimarchi 290
  index=hash_fun(synch_handle);
868 trimarchi 291
 
932 trimarchi 292
  if (htable[index].id!=synch_handle) {
868 trimarchi 293
    oldindex=index;
294
    index = (index + 1) % MAX_HASH_ENTRY;
295
    // find 
932 trimarchi 296
    while (htable[index].id != synch_handle && index!=oldindex) index=(index+1) % MAX_HASH_ENTRY;
933 trimarchi 297
    if (index==oldindex) {
298
      kern_frestore(f);
299
      return FSF_ERR_INVALID_SYNCH_OBJ_HANDLE;
300
    }
868 trimarchi 301
  }
221 giacomo 302
 
868 trimarchi 303
  if (htable[index].events > 0) {
221 giacomo 304
    task_activate(exec_shadow);
868 trimarchi 305
    htable[index].events--;
934 trimarchi 306
  } else {
307
    fsf_get_server(exec_shadow, &server);
308
    fsf_settask_nopreemptive(&server, exec_shadow);
868 trimarchi 309
    iq_insertlast(exec_shadow,&(htable[index].threads));
934 trimarchi 310
  }
221 giacomo 311
 
312
  #ifdef FSF_DEBUG
313
    kern_printf("(Synch_Handle Events %d)",synch_handle->events);
314
  #endif
315
 
933 trimarchi 316
  kern_frestore(f);
317
 
798 giacomo 318
  task_endcycle();
221 giacomo 319
  return 0;
320
 
321
}