Subversion Repositories shark

Rev

Rev 267 | Rev 298 | 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
 
14
#include "fsf_contract.h"
241 giacomo 15
#include "fsf_server.h"
221 giacomo 16
 
17
#include <pthread.h>
18
#include <stdlib.h>
19
 
224 giacomo 20
//#define FSF_DEBUG
221 giacomo 21
 
241 giacomo 22
int fsf_server_level;
221 giacomo 23
 
241 giacomo 24
int FSF_register_module(int server_level)
224 giacomo 25
{
26
 
27
  printk("FSF Module\n");
28
 
241 giacomo 29
  fsf_server_level = server_level;
224 giacomo 30
 
31
  return 0;
32
 
33
}
34
 
221 giacomo 35
/* Convert the contract specification to
36
 * budget parameters
37
 */
241 giacomo 38
int set_SERVER_budget_from_contract
221 giacomo 39
  (const fsf_contract_parameters_t *contract,
40
   int *budget)
41
{
42
 
43
  int local_scheduler_level = 0;
44
 
45
   switch (contract->local_scheduler_id) {
46
     case FSF_SCHEDULER_POSIX:
241 giacomo 47
       local_scheduler_level = POSIXSTAR_register_level(fsf_server_level,5000,32);
221 giacomo 48
       break;
49
     case FSF_SCHEDULER_EDF:
241 giacomo 50
       local_scheduler_level = EDFSTAR_register_level(fsf_server_level);
221 giacomo 51
       break;
52
     case FSF_SCHEDULER_RM:
241 giacomo 53
       local_scheduler_level = RMSTAR_register_level(fsf_server_level);
221 giacomo 54
       break;
55
   }    
56
 
241 giacomo 57
  *budget = SERVER_setbudget(fsf_server_level,
221 giacomo 58
                              TIMESPEC2USEC(&(contract->budget_min)),
59
                              TIMESPEC2USEC(&(contract->period_max)),
60
                              local_scheduler_level,contract->local_scheduler_id);
61
 
62
  return 0;
63
 
64
}
65
 
241 giacomo 66
int adjust_SERVER_budget_from_contract
221 giacomo 67
  (const fsf_contract_parameters_t *contract,
68
   int budget)
69
{
70
 
241 giacomo 71
  SERVER_adjust_budget(fsf_server_level,
72
                       TIMESPEC2USEC(&(contract->budget_min)),
73
                       TIMESPEC2USEC(&(contract->period_max)),
74
                       budget);
221 giacomo 75
 
76
  return 0;
77
 
78
}
79
 
80
/* Admission Test function */
81
int add_contract(const fsf_contract_parameters_t *contract)
82
{
83
 
84
  return 0;
85
 
86
}
87
 
88
int link_contract_to_server(const fsf_contract_parameters_t *contract,
89
                            fsf_server_id_t server)
90
{
91
 
92
  return 0;
93
 
94
}
95
 
96
int remove_contract(fsf_server_id_t server)
97
{
98
 
99
  return 0;
100
 
101
}
102
 
103
 
104
int fsf_negotiate_contract
105
  (const fsf_contract_parameters_t *contract,
106
   fsf_server_id_t                 *server)
107
{
108
 
109
  /* Check if contract is initialized */
110
  if (!contract) return FSF_ERR_NOT_INITIALIZED;
111
 
112
  /* Admission Test */
113
  if (FSF_ADMISSION_TEST_IS_ENABLED)
114
    if (add_contract(contract))
115
      return FSF_ERR_CONTRACT_REJECTED;
116
 
241 giacomo 117
  /* SERVER => BUDGET */    
118
  set_SERVER_budget_from_contract(contract,server);
221 giacomo 119
 
120
  #ifdef FSF_DEBUG
121
    kern_printf("(New Server %d)",*server);
122
  #endif
123
 
124
  if (*server >= 0)
125
    link_contract_to_server(contract,*server);
126
  else
127
    return FSF_ERR_CREATE_SERVER;
128
 
129
  return 0;
130
 
131
}
132
 
241 giacomo 133
int fsf_create_thread
134
  (fsf_server_id_t    server,
135
   pthread_t         *thread,
136
   pthread_attr_t    *attr,
137
   fsf_thread_code_t  thread_code,
138
   void              *arg,
139
   void              *local_scheduler_arg)
221 giacomo 140
{
141
 
241 giacomo 142
  NRT_TASK_MODEL nrt;
221 giacomo 143
  int local_scheduler_level,scheduler_id;
144
 
145
  #ifdef FSF_DEBUG 
267 giacomo 146
    kern_printf("(FSF:Insert thread = %d to Server = %d)",*thread,server);
221 giacomo 147
  #endif
148
 
149
  /* Check if server and thread exsist */
241 giacomo 150
  if (server == NIL)
151
    return FSF_ERR_INVALID_SERVER;
221 giacomo 152
 
241 giacomo 153
  local_scheduler_level = SERVER_get_local_scheduler_level_from_budget(fsf_server_level,server);
154
  scheduler_id = SERVER_get_local_scheduler_id_from_budget(fsf_server_level,server);
221 giacomo 155
 
156
  /* Check if thread is already bind */
157
  switch (scheduler_id) {
158
    case FSF_SCHEDULER_POSIX:
159
 
250 giacomo 160
      if (local_scheduler_arg == NULL) {
161
        nrt_task_default_model(nrt);
162
        nrt_task_def_save_arrivals(nrt);
163
        nrt_task_def_arg(nrt,arg);
164
        nrt_task_def_ctrl_jet(nrt);
165
        nrt_task_def_level(nrt,local_scheduler_level);
221 giacomo 166
 
250 giacomo 167
        *thread = task_create("POSIXSTAR", thread_code, &nrt, NULL);
168
      }
267 giacomo 169
      if (*thread == NIL) {
170
        #ifdef FSF_DEBUG
171
          kern_printf("(FSF:Error creating thread)");
172
        #endif
241 giacomo 173
        return FSF_ERR_CREATE_THREAD;
267 giacomo 174
      }
221 giacomo 175
 
241 giacomo 176
      POSIXSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
234 giacomo 177
 
241 giacomo 178
      task_activate(*thread);
221 giacomo 179
 
180
    break;
181
    case FSF_SCHEDULER_EDF:
182
 
250 giacomo 183
      hard_task_def_arg(*(HARD_TASK_MODEL *)(local_scheduler_arg),arg);
184
      hard_task_def_level(*(HARD_TASK_MODEL *)(local_scheduler_arg),local_scheduler_level);
185
 
186
      *thread = task_create("EDFSTAR", thread_code, local_scheduler_arg, NULL);
187
      if (*thread == NIL)
188
        return FSF_ERR_CREATE_THREAD;
189
 
190
      EDFSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
191
 
192
      task_activate(*thread);
193
 
221 giacomo 194
      break;
235 giacomo 195
 
221 giacomo 196
    case FSF_SCHEDULER_RM:
235 giacomo 197
 
273 giacomo 198
      hard_task_def_arg(*(HARD_TASK_MODEL *)(local_scheduler_arg),arg);
199
      hard_task_def_level(*(HARD_TASK_MODEL *)(local_scheduler_arg),local_scheduler_level);
200
 
201
      *thread = task_create("RMSTAR", thread_code, local_scheduler_arg, NULL);
202
      if (*thread == NIL)
203
        return FSF_ERR_CREATE_THREAD;
204
 
205
      RMSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
206
 
207
      task_activate(*thread);
208
 
209
      break;
221 giacomo 210
    default:
241 giacomo 211
      return FSF_ERR_INVALID_SERVER;
221 giacomo 212
      break;
213
  }
214
 
215
  return 0;
216
 
217
}
218
 
219
int fsf_get_server
220
  (fsf_server_id_t *server,
221
   pthread_t       thread)
222
{
223
  int local_scheduler_level, scheduler_id;
224
 
241 giacomo 225
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level,thread);
226
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, thread);
221 giacomo 227
 
228
  switch (scheduler_id) {
229
    case FSF_SCHEDULER_POSIX:  
230
      return POSIXSTAR_getbudget(local_scheduler_level,thread);
231
    case FSF_SCHEDULER_EDF:
235 giacomo 232
      return EDFSTAR_getbudget(local_scheduler_level,thread);
221 giacomo 233
    case FSF_SCHEDULER_RM:
235 giacomo 234
      return RMSTAR_getbudget(local_scheduler_level,thread);
235
    default:
221 giacomo 236
      return -1;
237
  }
238
 
239
  return -1;
240
 
241
}
242
 
243
int fsf_cancel_contract
244
  (fsf_server_id_t *server)
245
{
246
 
247
  int local_scheduler_level, scheduler_id;
248
 
249
  #ifdef FSF_DEBUG
250
    kern_printf("(Remove server %d)",*server);
251
  #endif
252
 
253
  /* Check server id */
254
  if (*server < 0)
255
    return FSF_ERR_INVALID_SERVER;
256
 
241 giacomo 257
  local_scheduler_level = SERVER_get_local_scheduler_level_from_budget(fsf_server_level,*server);
258
  scheduler_id = SERVER_get_local_scheduler_id_from_budget(fsf_server_level,*server);
221 giacomo 259
 
260
  switch (scheduler_id) {
261
    case FSF_SCHEDULER_POSIX:
262
 
263
      /* Check if some thread use the server */
264
      if(POSIXSTAR_budget_has_thread(local_scheduler_level,*server))
265
        return FSF_ERR_SERVER_USED;
266
 
267
      break;
268
    case FSF_SCHEDULER_EDF:
235 giacomo 269
      /* Check if some thread use the server */
270
      if(EDFSTAR_budget_has_thread(local_scheduler_level,*server))
271
        return FSF_ERR_SERVER_USED;
272
      break;
273
 
221 giacomo 274
    case FSF_SCHEDULER_RM:
235 giacomo 275
      /* Check if some thread use the server */
276
      if(RMSTAR_budget_has_thread(local_scheduler_level,*server))
277
        return FSF_ERR_SERVER_USED;
278
 
221 giacomo 279
      break;
280
  }
281
 
241 giacomo 282
  SERVER_removebudget(fsf_server_level,*server);
221 giacomo 283
 
284
  level_free_descriptor(local_scheduler_level);
285
 
286
  remove_contract(*server);
287
 
288
  *server = -1;
289
 
290
  return 0;
291
 
292
}
293
 
294
int fsf_renegotiate_contract
295
  (const fsf_contract_parameters_t *new_contract,
296
   fsf_server_id_t server)
297
{
298
 
299
  #ifdef FSF_DEBUG
300
    kern_printf("(Renegotiate for server %d)",server);
301
  #endif
302
 
303
  if (!new_contract)
304
    return FSF_ERR_NOT_INITIALIZED;
305
 
306
  if (server < 0)
307
    return FSF_ERR_INVALID_SERVER;
308
 
241 giacomo 309
  return adjust_SERVER_budget_from_contract(new_contract,server);
221 giacomo 310
 
311
}
241 giacomo 312