Subversion Repositories shark

Rev

Rev 858 | Rev 875 | 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
 
125
int fsf_schedule_next_timed_job
126
  (const struct timespec *at_absolute_time,
127
   struct timespec       *next_budget,
128
   struct timespec       *next_period,
129
   bool                  *was_deadline_missed,
130
   bool                  *was_budget_overran)
131
{
132
 
661 giacomo 133
  TIME T,Q,D;
221 giacomo 134
  int budget, local_scheduler_level, scheduler_id;
135
 
241 giacomo 136
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level, exec_shadow);
137
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, exec_shadow);
221 giacomo 138
 
226 giacomo 139
  if (proc_table[exec_shadow].task_level != local_scheduler_level) return 0;
140
 
221 giacomo 141
  switch (scheduler_id) {
868 trimarchi 142
    case FSF_POSIX:
221 giacomo 143
      budget = POSIXSTAR_getbudget(local_scheduler_level, exec_shadow);
144
      break;
868 trimarchi 145
    case FSF_EDF:
221 giacomo 146
      budget = EDFSTAR_getbudget(local_scheduler_level, exec_shadow);
147
      break;
868 trimarchi 148
    case FSF_NONE:
858 trimarchi 149
      budget = NONESTAR_getbudget(local_scheduler_level, exec_shadow);
150
      break;
868 trimarchi 151
    case FSF_RM:
858 trimarchi 152
      budget = RMSTAR_getbudget(local_scheduler_level, exec_shadow);
153
      break;
154
 
221 giacomo 155
    default:
156
      budget = -1;
157
      break;
158
  }
159
 
160
  if (budget == -1) return FSF_ERR_INVALID_SERVER;
161
 
162
  if (next_budget != NULL && next_period != NULL) {
163
 
661 giacomo 164
    SERVER_getbudgetinfo(fsf_server_level, &Q, &T, &D, budget);
221 giacomo 165
 
166
    #ifdef FSF_DEBUG
167
      kern_printf("(budget %d Q=%d T=%d)",budget,(int)Q,(int)T);
168
    #endif
169
 
170
    next_budget->tv_sec = Q / 1000000;
171
    next_budget->tv_nsec = (Q % 1000000) * 1000;
172
    next_period->tv_sec = T / 1000000;
173
    next_period->tv_nsec = (T % 1000000) * 1000;
174
 
175
  }
176
 
224 giacomo 177
  if (was_deadline_missed != NULL)
178
    *was_deadline_missed = false;
221 giacomo 179
  if (was_budget_overran != NULL)
224 giacomo 180
    *was_budget_overran = false;
221 giacomo 181
 
182
  if (at_absolute_time != NULL)
799 giacomo 183
    kern_event_post(at_absolute_time, (void (*)(void *))task_activate, (void *)(exec_shadow));
221 giacomo 184
 
185
  #ifdef FSF_DEBUG
186
    if (at_absolute_time != NULL)
187
      kern_printf("(Next act s%d:us%d)",(int)at_absolute_time->tv_sec,(int)at_absolute_time->tv_nsec/1000);
188
    else
189
      kern_printf("(End Cycle %d)",exec_shadow);
190
  #endif
191
 
798 giacomo 192
  task_endcycle();
221 giacomo 193
 
194
  return 0;
195
 
196
}
197
 
198
int
199
fsf_schedule_next_event_triggered_job
868 trimarchi 200
  (fsf_synch_obj_handle_t *synch_handle,
221 giacomo 201
   struct timespec           *next_budget,
202
   struct timespec           *next_period,
203
   bool                      *was_deadline_missed,
204
   bool                      *was_budget_overran)
205
{
206
 
661 giacomo 207
  TIME T,Q,D;
868 trimarchi 208
  int index,oldindex;
221 giacomo 209
  int budget, local_scheduler_level, scheduler_id;
210
 
241 giacomo 211
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level, exec_shadow);
212
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, exec_shadow);
226 giacomo 213
 
214
  if (proc_table[exec_shadow].task_level != local_scheduler_level) return 0;
215
 
221 giacomo 216
  switch (scheduler_id) {
868 trimarchi 217
    case FSF_POSIX:
221 giacomo 218
      budget = POSIXSTAR_getbudget(local_scheduler_level, exec_shadow);
219
      break;
868 trimarchi 220
    case FSF_EDF:
221 giacomo 221
      budget = EDFSTAR_getbudget(local_scheduler_level, exec_shadow);
222
      break;
868 trimarchi 223
    case FSF_RM:
221 giacomo 224
    default:
225
      budget = -1;
226
      break;
227
  }
228
 
229
  if (budget == -1) return FSF_ERR_INVALID_SERVER;
230
 
231
  if (next_budget != NULL && next_period != NULL) {
232
 
661 giacomo 233
    SERVER_getbudgetinfo(fsf_server_level, &Q, &T, &D, budget);
221 giacomo 234
 
235
    #ifdef FSF_DEBUG
236
      kern_printf("(budget %d Q=%d T=%d)",budget,(int)Q,(int)T);
237
    #endif
238
 
239
    next_budget->tv_sec = Q / 1000000;
240
    next_budget->tv_nsec = (Q % 1000000) * 1000;
241
    next_period->tv_sec = T / 1000000;
242
    next_period->tv_nsec = (T % 1000000) * 1000;
243
 
244
  }
245
 
225 giacomo 246
  if (was_deadline_missed != NULL)
247
    *was_deadline_missed = false;
221 giacomo 248
  if (was_budget_overran != NULL)
225 giacomo 249
    *was_budget_overran = false;
868 trimarchi 250
 
251
  index=hash_fun(*synch_handle);
252
 
253
  if (htable[index].id!=*synch_handle) {
254
    oldindex=index;
255
    index = (index + 1) % MAX_HASH_ENTRY;
256
    // find 
257
    while (htable[index].id != *synch_handle && index!=oldindex) index=(index+1) % MAX_HASH_ENTRY;
258
    if (index==oldindex) return FSF_ERR_INVALID_SYNCH_OBJ_HANDLE;
259
  }
221 giacomo 260
 
868 trimarchi 261
  if (htable[index].events > 0) {
221 giacomo 262
    task_activate(exec_shadow);
868 trimarchi 263
    htable[index].events--;
221 giacomo 264
  } else
868 trimarchi 265
    iq_insertlast(exec_shadow,&(htable[index].threads));
221 giacomo 266
 
267
  #ifdef FSF_DEBUG
268
    kern_printf("(Synch_Handle Events %d)",synch_handle->events);
269
  #endif
270
 
798 giacomo 271
  task_endcycle();
221 giacomo 272
 
273
  return 0;
274
 
275
}