Subversion Repositories shark

Rev

Rev 932 | Rev 934 | 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;
221 giacomo 79
 
868 trimarchi 80
  index=hash_fun(*synch_handle);  
81
 
82
  if (htable[index].id!=*synch_handle) {
83
    oldindex=index;
84
    index = (index + 1) % MAX_HASH_ENTRY;
85
    // find 
86
    while (htable[index].id != *synch_handle && index!=oldindex) index=(index+1) % MAX_HASH_ENTRY;
87
    if (index==oldindex) return FSF_ERR_INVALID_SYNCH_OBJ_HANDLE;
88
  }
89
 
90
  //if (!synch_handle) return FSF_ERR_INVALID_SYNCH_OBJECT_HANDLE;
221 giacomo 91
 
868 trimarchi 92
  if ((p = iq_getfirst(&(htable[index].threads))) != NIL)
221 giacomo 93
    task_activate(p);
94
  else
868 trimarchi 95
    htable[index].events++;
221 giacomo 96
 
97
  return 0;
98
 
99
}
100
 
101
int
868 trimarchi 102
fsf_destroy_synchobject(fsf_synch_obj_handle_t *synch_handle)
221 giacomo 103
{
868 trimarchi 104
  int index, oldindex;
221 giacomo 105
 
868 trimarchi 106
  index=hash_fun(*synch_handle);  
221 giacomo 107
 
868 trimarchi 108
  if (htable[index].id!=*synch_handle) {
109
    oldindex=index;
110
    index = (index + 1) % MAX_HASH_ENTRY;
111
    // find 
112
    while (htable[index].id != *synch_handle && index!=oldindex) index=(index+1) % MAX_HASH_ENTRY;
113
    if (index==oldindex) return FSF_ERR_INVALID_SYNCH_OBJ_HANDLE;
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
  int budget, local_scheduler_level, scheduler_id;
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
 
933 trimarchi 146
  f=kern_fsave();
147
 
241 giacomo 148
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level, exec_shadow);
149
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, exec_shadow);
221 giacomo 150
 
226 giacomo 151
  if (proc_table[exec_shadow].task_level != local_scheduler_level) return 0;
152
 
221 giacomo 153
  switch (scheduler_id) {
868 trimarchi 154
    case FSF_POSIX:
221 giacomo 155
      budget = POSIXSTAR_getbudget(local_scheduler_level, exec_shadow);
156
      break;
868 trimarchi 157
    case FSF_EDF:
221 giacomo 158
      budget = EDFSTAR_getbudget(local_scheduler_level, exec_shadow);
159
      break;
868 trimarchi 160
    case FSF_NONE:
858 trimarchi 161
      budget = NONESTAR_getbudget(local_scheduler_level, exec_shadow);
162
      break;
868 trimarchi 163
    case FSF_RM:
858 trimarchi 164
      budget = RMSTAR_getbudget(local_scheduler_level, exec_shadow);
165
      break;
166
 
221 giacomo 167
    default:
168
      budget = -1;
169
      break;
170
  }
171
 
933 trimarchi 172
  if (budget == -1) {
173
    kern_frestore(f);
174
    return FSF_ERR_BAD_ARGUMENT;
175
  }
221 giacomo 176
 
177
  if (next_budget != NULL && next_period != NULL) {
178
 
661 giacomo 179
    SERVER_getbudgetinfo(fsf_server_level, &Q, &T, &D, budget);
221 giacomo 180
 
181
    #ifdef FSF_DEBUG
182
      kern_printf("(budget %d Q=%d T=%d)",budget,(int)Q,(int)T);
183
    #endif
184
 
185
    next_budget->tv_sec = Q / 1000000;
186
    next_budget->tv_nsec = (Q % 1000000) * 1000;
187
    next_period->tv_sec = T / 1000000;
188
    next_period->tv_nsec = (T % 1000000) * 1000;
189
 
190
  }
191
 
224 giacomo 192
  if (was_deadline_missed != NULL)
193
    *was_deadline_missed = false;
221 giacomo 194
  if (was_budget_overran != NULL)
224 giacomo 195
    *was_budget_overran = false;
221 giacomo 196
 
933 trimarchi 197
  if (at_absolute_time != NULL) {    
198
    fsf_get_server(exec_shadow, &server);
199
    fsf_settask_nopreemptive(&server, exec_shadow);
200
    kern_event_post(at_absolute_time, (void (*)(void *))restart_task, (void *)(exec_shadow));
201
  }
221 giacomo 202
 
203
  #ifdef FSF_DEBUG
204
    if (at_absolute_time != NULL)
205
      kern_printf("(Next act s%d:us%d)",(int)at_absolute_time->tv_sec,(int)at_absolute_time->tv_nsec/1000);
206
    else
207
      kern_printf("(End Cycle %d)",exec_shadow);
208
  #endif
209
 
933 trimarchi 210
  kern_frestore(f);
798 giacomo 211
  task_endcycle();
221 giacomo 212
 
213
  return 0;
214
 
215
}
216
 
932 trimarchi 217
int fsf_schedule_triggered_job
218
  (fsf_synch_obj_handle_t  synch_handle,
219
   struct timespec         *next_budget,
220
   struct timespec         *next_period,
221
   bool                    *was_deadline_missed,
222
   bool                    *was_budget_overran)
221 giacomo 223
{
224
 
661 giacomo 225
  TIME T,Q,D;
868 trimarchi 226
  int index,oldindex;
221 giacomo 227
  int budget, local_scheduler_level, scheduler_id;
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);
237
    return 0;
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);
221 giacomo 249
    default:
250
      budget = -1;
251
      break;
252
  }
253
 
933 trimarchi 254
  if (budget == -1) {
255
    kern_frestore(f);
256
    return FSF_ERR_BAD_ARGUMENT;
221 giacomo 257
 
933 trimarchi 258
  }
259
 
221 giacomo 260
  if (next_budget != NULL && next_period != NULL) {
261
 
661 giacomo 262
    SERVER_getbudgetinfo(fsf_server_level, &Q, &T, &D, budget);
221 giacomo 263
 
264
    #ifdef FSF_DEBUG
265
      kern_printf("(budget %d Q=%d T=%d)",budget,(int)Q,(int)T);
266
    #endif
267
 
268
    next_budget->tv_sec = Q / 1000000;
269
    next_budget->tv_nsec = (Q % 1000000) * 1000;
270
    next_period->tv_sec = T / 1000000;
271
    next_period->tv_nsec = (T % 1000000) * 1000;
272
 
273
  }
274
 
225 giacomo 275
  if (was_deadline_missed != NULL)
276
    *was_deadline_missed = false;
221 giacomo 277
  if (was_budget_overran != NULL)
225 giacomo 278
    *was_budget_overran = false;
868 trimarchi 279
 
932 trimarchi 280
  index=hash_fun(synch_handle);
868 trimarchi 281
 
932 trimarchi 282
  if (htable[index].id!=synch_handle) {
868 trimarchi 283
    oldindex=index;
284
    index = (index + 1) % MAX_HASH_ENTRY;
285
    // find 
932 trimarchi 286
    while (htable[index].id != synch_handle && index!=oldindex) index=(index+1) % MAX_HASH_ENTRY;
933 trimarchi 287
    if (index==oldindex) {
288
      kern_frestore(f);
289
      return FSF_ERR_INVALID_SYNCH_OBJ_HANDLE;
290
    }
868 trimarchi 291
  }
221 giacomo 292
 
868 trimarchi 293
  if (htable[index].events > 0) {
221 giacomo 294
    task_activate(exec_shadow);
868 trimarchi 295
    htable[index].events--;
221 giacomo 296
  } else
868 trimarchi 297
    iq_insertlast(exec_shadow,&(htable[index].threads));
221 giacomo 298
 
299
  #ifdef FSF_DEBUG
300
    kern_printf("(Synch_Handle Events %d)",synch_handle->events);
301
  #endif
302
 
933 trimarchi 303
  kern_frestore(f);
304
 
798 giacomo 305
  task_endcycle();
221 giacomo 306
  return 0;
307
 
308
}