Subversion Repositories shark

Rev

Rev 224 | Rev 234 | 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"
15
#include "cbsstar.h"
16
#include "posixstar.h"
17
#include "edfstar.h"
18
#include "posix.h"
19
#include "comm_message.h"
20
 
21
#include <pthread.h>
22
#include <stdlib.h>
23
 
224 giacomo 24
//#define FSF_DEBUG
221 giacomo 25
 
224 giacomo 26
int fsf_cbsstar_level;
27
int fsf_posix_level;
221 giacomo 28
 
224 giacomo 29
int FSF_register_module(int posix_level, int cbsstar_level)
30
{
31
 
32
  printk("FSF Module\n");
33
 
34
  fsf_posix_level = posix_level;
35
  fsf_cbsstar_level = cbsstar_level;
36
 
37
  return 0;
38
 
39
}
40
 
221 giacomo 41
/* Convert the contract specification to
42
 * budget parameters
43
 */
44
int set_CBSSTAR_budget_from_contract
45
  (const fsf_contract_parameters_t *contract,
46
   int *budget)
47
{
48
 
49
  int local_scheduler_level = 0;
50
 
51
   switch (contract->local_scheduler_id) {
52
     case FSF_SCHEDULER_POSIX:
224 giacomo 53
       local_scheduler_level = POSIXSTAR_register_level(fsf_cbsstar_level,5000,32);
221 giacomo 54
       break;
55
     case FSF_SCHEDULER_EDF:
224 giacomo 56
       local_scheduler_level = EDFSTAR_register_level(fsf_cbsstar_level);
221 giacomo 57
       break;
58
     case FSF_SCHEDULER_RM:
59
       break;
60
   }    
61
 
224 giacomo 62
  *budget = CBSSTAR_setbudget(fsf_cbsstar_level,
221 giacomo 63
                              TIMESPEC2USEC(&(contract->budget_min)),
64
                              TIMESPEC2USEC(&(contract->period_max)),
65
                              local_scheduler_level,contract->local_scheduler_id);
66
 
67
  return 0;
68
 
69
}
70
 
71
int adjust_CBSSTAR_budget_from_contract
72
  (const fsf_contract_parameters_t *contract,
73
   int budget)
74
{
75
 
224 giacomo 76
  CBSSTAR_adjust_budget(fsf_cbsstar_level,
221 giacomo 77
                        TIMESPEC2USEC(&(contract->budget_min)),
78
                        TIMESPEC2USEC(&(contract->period_max)),
79
                        budget);
80
 
81
  return 0;
82
 
83
}
84
 
85
/* Admission Test function */
86
int add_contract(const fsf_contract_parameters_t *contract)
87
{
88
 
89
  return 0;
90
 
91
}
92
 
93
int link_contract_to_server(const fsf_contract_parameters_t *contract,
94
                            fsf_server_id_t server)
95
{
96
 
97
  return 0;
98
 
99
}
100
 
101
int remove_contract(fsf_server_id_t server)
102
{
103
 
104
  return 0;
105
 
106
}
107
 
108
 
109
int fsf_negotiate_contract
110
  (const fsf_contract_parameters_t *contract,
111
   fsf_server_id_t                 *server)
112
{
113
 
114
  /* Check if contract is initialized */
115
  if (!contract) return FSF_ERR_NOT_INITIALIZED;
116
 
117
  /* Admission Test */
118
  if (FSF_ADMISSION_TEST_IS_ENABLED)
119
    if (add_contract(contract))
120
      return FSF_ERR_CONTRACT_REJECTED;
121
 
122
  /* SERVER = BUDGET */    
123
  set_CBSSTAR_budget_from_contract(contract,server);
124
 
125
  #ifdef FSF_DEBUG
126
    kern_printf("(New Server %d)",*server);
127
  #endif
128
 
129
  if (*server >= 0)
130
    link_contract_to_server(contract,*server);
131
  else
132
    return FSF_ERR_CREATE_SERVER;
133
 
134
  return 0;
135
 
136
}
137
 
138
int fsf_bind_thread_to_server
139
  (fsf_server_id_t server,
140
   pthread_t       thread,
141
   void            *rt_arg)
142
{
143
 
144
  STD_command_message *msg;
145
  int local_scheduler_level,scheduler_id;
146
 
147
  /* Move thread from the posix module to local scheduler */
148
 
149
  #ifdef FSF_DEBUG 
150
    kern_printf("(Bind thread = %d to Server = %d)",thread,server);
151
  #endif
152
 
153
  /* Check if server and thread exsist */
154
  if (server == -1 || thread == -1)
155
    return FSF_ERR_BIND_THREAD;
156
 
224 giacomo 157
  local_scheduler_level = CBSSTAR_get_local_scheduler_level_from_budget(fsf_cbsstar_level,server);
158
  scheduler_id = CBSSTAR_get_local_scheduler_id_from_budget(fsf_cbsstar_level,server);
221 giacomo 159
 
160
  /* Check if thread is already bind */
161
  switch (scheduler_id) {
162
    case FSF_SCHEDULER_POSIX:
163
      if (POSIXSTAR_getbudget(local_scheduler_level,thread) != -1)
164
        return FSF_ERR_BIND_THREAD;
165
 
166
      /* Set server on local scheduler */
167
      POSIXSTAR_setbudget(local_scheduler_level,thread,(int)(server));
168
 
169
      /* Send change level command to posix level */
170
      msg = (STD_command_message *)malloc(sizeof(STD_command_message));
171
 
172
      msg->command = STD_SET_NEW_MODEL;
173
      msg->param = (void *)(rt_arg);
174
      level_table[local_scheduler_level]->public_message(local_scheduler_level,thread,msg);
175
 
176
      msg->command = STD_SET_NEW_LEVEL;
177
      msg->param = (void *)(local_scheduler_level);
178
      task_message(msg,thread,0);
179
 
180
      free(msg);
181
 
182
    break;
183
    case FSF_SCHEDULER_EDF:
184
 
185
      if (EDFSTAR_getbudget(local_scheduler_level,thread) != -1)
186
        return FSF_ERR_BIND_THREAD;
187
 
188
      /* Set server on local scheduler */
189
      EDFSTAR_setbudget(local_scheduler_level,thread,(int)(server));
190
 
191
      /* Send change level command to posix level */
192
      msg = (STD_command_message *)malloc(sizeof(STD_command_message));
193
 
226 giacomo 194
      #ifdef FSF_DEBUG
195
         kern_printf("(MSG EDFSTAR LEV %d SEV %d THR %d)",local_scheduler_level,server,thread);
196
      #endif
197
 
221 giacomo 198
      msg->command = STD_SET_NEW_MODEL;
199
      msg->param = (void *)(rt_arg);
200
      level_table[local_scheduler_level]->public_message(local_scheduler_level,thread,msg);
201
 
202
      msg->command = STD_SET_NEW_LEVEL;
203
      msg->param = (void *)(local_scheduler_level);
204
      task_message(msg,thread,0);
205
 
206
      free(msg);
207
 
208
      break;
209
    case FSF_SCHEDULER_RM:
210
    default:
211
      return FSF_ERR_BIND_THREAD;
212
      break;
213
  }
214
 
215
  return 0;
216
 
217
}
218
 
219
int fsf_unbind_thread_from_server
220
  (pthread_t       thread)
221
{
222
 
223
  int local_scheduler_level, scheduler_id;
224
 
225
  /* Move thread from the local scheduler module to posix level */
226
 
227
  #ifdef FSF_DEBUG
228
    kern_printf("(UnBind thread = %d)",thread);
229
  #endif
230
 
231
  /* Check if thread exsists */
232
  if (thread == -1)
233
    return FSF_ERR_UNBIND_THREAD;
234
 
224 giacomo 235
  local_scheduler_level = CBSSTAR_get_local_scheduler_level_from_pid(fsf_cbsstar_level,thread);
236
  scheduler_id = CBSSTAR_get_local_scheduler_id_from_pid(fsf_cbsstar_level,thread);
221 giacomo 237
 
238
  switch (scheduler_id) {
239
    case FSF_SCHEDULER_POSIX:
240
      /* Check if it is bind to a server */
241
      if (POSIXSTAR_getbudget(local_scheduler_level,thread) == -1)
242
        return FSF_ERR_UNBIND_THREAD;
243
      else {
244
 
245
        STD_command_message *msg;
246
        NRT_TASK_MODEL nrt;
247
 
248
        nrt_task_default_model(nrt);
249
        nrt_task_def_save_arrivals(nrt);
250
 
251
        /* Send change level command to local scheduler */
252
        msg = (STD_command_message *)malloc(sizeof(STD_command_message));
253
 
254
        msg->command = STD_SET_NEW_MODEL;
255
        msg->param = (void *)(&nrt);
224 giacomo 256
        level_table[fsf_posix_level]->public_message(fsf_posix_level,thread,msg);
221 giacomo 257
 
258
        msg->command = STD_SET_NEW_LEVEL;
224 giacomo 259
        msg->param = (void *)(fsf_posix_level);
221 giacomo 260
        task_message(msg,thread,0);
261
 
262
        free(msg);
263
 
264
      }
265
    break;
266
    case FSF_SCHEDULER_EDF:
267
 
268
      if (EDFSTAR_getbudget(local_scheduler_level,thread) == -1)
269
        return FSF_ERR_UNBIND_THREAD;
270
      else {
271
 
272
        STD_command_message *msg;
273
        NRT_TASK_MODEL nrt;
274
 
275
        nrt_task_default_model(nrt);
276
        nrt_task_def_save_arrivals(nrt);
277
 
278
        /* Send change level command to local scheduler */
279
        msg = (STD_command_message *)malloc(sizeof(STD_command_message));
280
 
281
        msg->command = STD_SET_NEW_MODEL;
282
        msg->param = (void *)(&nrt);
224 giacomo 283
        level_table[fsf_posix_level]->public_message(fsf_posix_level,thread,msg);
221 giacomo 284
 
285
        msg->command = STD_SET_NEW_LEVEL;
224 giacomo 286
        msg->param = (void *)(fsf_posix_level);
221 giacomo 287
        task_message(msg,thread,0);
288
 
289
        free(msg);
290
 
291
      }
292
      break;
293
 
294
    case FSF_SCHEDULER_RM:
295
      break;
296
  }
297
 
298
  return 0;
299
 
300
}
301
 
302
int fsf_negotiate_contract_for_new_thread
303
  (const fsf_contract_parameters_t *contract,
304
   fsf_server_id_t      *server,
305
   pthread_t            *thread,
306
   pthread_attr_t       *attr,
307
   fsf_thread_code_t     thread_code,
308
   void                 *arg,
309
   void                 *rt_arg)
310
 
311
{
312
 
313
  int error;
314
 
315
  /* Create server */
316
  error = fsf_negotiate_contract(contract, server);
317
  if (error) return error;
318
 
319
  /* Create pthread */
320
  if (pthread_create(thread, attr, thread_code, arg))
321
    return FSF_ERR_CREATE_THREAD;
322
 
323
  /* Bind thread to server */
324
  error = fsf_bind_thread_to_server(*server, *thread, rt_arg);
325
  if (error) return error;
326
 
327
  return 0;
328
 
329
}
330
 
331
int fsf_negotiate_contract_for_myself
332
  (const fsf_contract_parameters_t *contract,
333
   fsf_server_id_t *server,
334
   void            *rt_arg)
335
{
336
 
337
  int error;
338
 
339
  /* Create server */
340
  error = fsf_negotiate_contract(contract, server);
341
  if (error) return error;
342
 
343
  /* Bind current thread to server */
344
  error = fsf_bind_thread_to_server(*server, exec_shadow, rt_arg);
345
  if (error) return error;
346
 
347
  return 0;
348
 
349
}
350
 
351
int fsf_get_server
352
  (fsf_server_id_t *server,
353
   pthread_t       thread)
354
{
355
  int local_scheduler_level, scheduler_id;
356
 
224 giacomo 357
  local_scheduler_level = CBSSTAR_get_local_scheduler_level_from_pid(fsf_cbsstar_level,thread);
358
  scheduler_id = CBSSTAR_get_local_scheduler_id_from_pid(fsf_cbsstar_level, thread);
221 giacomo 359
 
360
  switch (scheduler_id) {
361
    case FSF_SCHEDULER_POSIX:  
362
      return POSIXSTAR_getbudget(local_scheduler_level,thread);
363
    case FSF_SCHEDULER_EDF:
364
    case FSF_SCHEDULER_RM:
365
      return -1;
366
  }
367
 
368
  return -1;
369
 
370
}
371
 
372
int fsf_cancel_contract
373
  (fsf_server_id_t *server)
374
{
375
 
376
  int local_scheduler_level, scheduler_id;
377
 
378
  #ifdef FSF_DEBUG
379
    kern_printf("(Remove server %d)",*server);
380
  #endif
381
 
382
  /* Check server id */
383
  if (*server < 0)
384
    return FSF_ERR_INVALID_SERVER;
385
 
224 giacomo 386
  local_scheduler_level = CBSSTAR_get_local_scheduler_level_from_budget(fsf_cbsstar_level,*server);
387
  scheduler_id = CBSSTAR_get_local_scheduler_id_from_budget(fsf_cbsstar_level,*server);
221 giacomo 388
 
389
  switch (scheduler_id) {
390
    case FSF_SCHEDULER_POSIX:
391
 
392
      /* Check if some thread use the server */
393
      if(POSIXSTAR_budget_has_thread(local_scheduler_level,*server))
394
        return FSF_ERR_SERVER_USED;
395
 
396
      break;
397
    case FSF_SCHEDULER_EDF:
398
    case FSF_SCHEDULER_RM:
399
      break;
400
  }
401
 
224 giacomo 402
  CBSSTAR_removebudget(fsf_cbsstar_level,*server);
221 giacomo 403
 
404
  level_free_descriptor(local_scheduler_level);
405
 
406
  remove_contract(*server);
407
 
408
  *server = -1;
409
 
410
  return 0;
411
 
412
}
413
 
414
int fsf_renegotiate_contract
415
  (const fsf_contract_parameters_t *new_contract,
416
   fsf_server_id_t server)
417
{
418
 
419
  #ifdef FSF_DEBUG
420
    kern_printf("(Renegotiate for server %d)",server);
421
  #endif
422
 
423
  if (!new_contract)
424
    return FSF_ERR_NOT_INITIALIZED;
425
 
426
  if (server < 0)
427
    return FSF_ERR_INVALID_SERVER;
428
 
429
  return adjust_CBSSTAR_budget_from_contract(new_contract,server);
430
 
431
}