Subversion Repositories shark

Rev

Rev 875 | Rev 933 | 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
 
932 trimarchi 125
int fsf_schedule_timed_job
221 giacomo 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
 
875 trimarchi 160
  if (budget == -1) return FSF_ERR_BAD_ARGUMENT;
221 giacomo 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
 
932 trimarchi 198
int fsf_schedule_triggered_job
199
  (fsf_synch_obj_handle_t  synch_handle,
200
   struct timespec         *next_budget,
201
   struct timespec         *next_period,
202
   bool                    *was_deadline_missed,
203
   bool                    *was_budget_overran)
221 giacomo 204
{
205
 
661 giacomo 206
  TIME T,Q,D;
868 trimarchi 207
  int index,oldindex;
221 giacomo 208
  int budget, local_scheduler_level, scheduler_id;
209
 
241 giacomo 210
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level, exec_shadow);
211
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, exec_shadow);
226 giacomo 212
 
213
  if (proc_table[exec_shadow].task_level != local_scheduler_level) return 0;
214
 
221 giacomo 215
  switch (scheduler_id) {
868 trimarchi 216
    case FSF_POSIX:
221 giacomo 217
      budget = POSIXSTAR_getbudget(local_scheduler_level, exec_shadow);
218
      break;
868 trimarchi 219
    case FSF_EDF:
221 giacomo 220
      budget = EDFSTAR_getbudget(local_scheduler_level, exec_shadow);
221
      break;
868 trimarchi 222
    case FSF_RM:
221 giacomo 223
    default:
224
      budget = -1;
225
      break;
226
  }
227
 
875 trimarchi 228
  if (budget == -1) return  FSF_ERR_BAD_ARGUMENT;
221 giacomo 229
 
230
  if (next_budget != NULL && next_period != NULL) {
231
 
661 giacomo 232
    SERVER_getbudgetinfo(fsf_server_level, &Q, &T, &D, budget);
221 giacomo 233
 
234
    #ifdef FSF_DEBUG
235
      kern_printf("(budget %d Q=%d T=%d)",budget,(int)Q,(int)T);
236
    #endif
237
 
238
    next_budget->tv_sec = Q / 1000000;
239
    next_budget->tv_nsec = (Q % 1000000) * 1000;
240
    next_period->tv_sec = T / 1000000;
241
    next_period->tv_nsec = (T % 1000000) * 1000;
242
 
243
  }
244
 
225 giacomo 245
  if (was_deadline_missed != NULL)
246
    *was_deadline_missed = false;
221 giacomo 247
  if (was_budget_overran != NULL)
225 giacomo 248
    *was_budget_overran = false;
868 trimarchi 249
 
932 trimarchi 250
  index=hash_fun(synch_handle);
868 trimarchi 251
 
932 trimarchi 252
  if (htable[index].id!=synch_handle) {
868 trimarchi 253
    oldindex=index;
254
    index = (index + 1) % MAX_HASH_ENTRY;
255
    // find 
932 trimarchi 256
    while (htable[index].id != synch_handle && index!=oldindex) index=(index+1) % MAX_HASH_ENTRY;
868 trimarchi 257
    if (index==oldindex) return FSF_ERR_INVALID_SYNCH_OBJ_HANDLE;
258
  }
221 giacomo 259
 
868 trimarchi 260
  if (htable[index].events > 0) {
221 giacomo 261
    task_activate(exec_shadow);
868 trimarchi 262
    htable[index].events--;
221 giacomo 263
  } else
868 trimarchi 264
    iq_insertlast(exec_shadow,&(htable[index].threads));
221 giacomo 265
 
266
  #ifdef FSF_DEBUG
267
    kern_printf("(Synch_Handle Events %d)",synch_handle->events);
268
  #endif
269
 
798 giacomo 270
  task_endcycle();
221 giacomo 271
 
272
  return 0;
273
 
274
}