Subversion Repositories shark

Rev

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