Subversion Repositories shark

Rev

Rev 881 | Rev 896 | 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
 
405 trimarchi 14
#include "ll/i386/64bit.h"
679 trimarchi 15
#include <kernel/kern.h>
16
#include <modules/sem.h>
17
#include <modules/hartport.h>
18
#include <modules/cabs.h>
405 trimarchi 19
 
881 trimarchi 20
#include "fsf.h"
679 trimarchi 21
#include "fsf_service_task.h"
22
#include "message.h"
221 giacomo 23
 
868 trimarchi 24
#include "posixstar.h"
25
#include "edfstar.h"
26
#include "nonestar.h"
27
#include "rmstar.h"
28
 
221 giacomo 29
#include <pthread.h>
30
#include <stdlib.h>
808 trimarchi 31
#include "pistar.h"
868 trimarchi 32
#include <modules/comm_message.h>
221 giacomo 33
 
417 giacomo 34
//#define FSF_DEBUG
221 giacomo 35
 
410 trimarchi 36
int current_server=0;
407 giacomo 37
server_elem server_list[FSF_MAX_N_SERVERS];
406 giacomo 38
bandwidth_t fsf_max_bw = 0;
405 trimarchi 39
 
241 giacomo 40
int fsf_server_level;
868 trimarchi 41
int fsf_posix_level = -1;
808 trimarchi 42
int shared_object_level;
679 trimarchi 43
PID server_task;
868 trimarchi 44
fsf_contract_parameters_t contract;
221 giacomo 45
 
868 trimarchi 46
 
679 trimarchi 47
PORT channel[2];
48
 
868 trimarchi 49
fsf_server_id_t service_server = -1;
50
fsf_contract_parameters_t service_contract;
51
 
808 trimarchi 52
int FSF_register_shared_object_module(void) {
811 trimarchi 53
  fsf_register_shared_object();
808 trimarchi 54
  return PISTAR_register_module();
55
}
56
 
57
 
810 trimarchi 58
int FSF_get_shared_object_level() {
59
  return shared_object_level;
60
}
61
 
868 trimarchi 62
int FSF_register_module(int posix_level, int server_level, bandwidth_t max_bw)
224 giacomo 63
{
64
  printk("FSF Module\n");
410 trimarchi 65
  current_server=0;
241 giacomo 66
  fsf_server_level = server_level;
868 trimarchi 67
  fsf_posix_level = posix_level;
406 giacomo 68
  fsf_max_bw = max_bw;
811 trimarchi 69
  shared_object_level = FSF_register_shared_object_module();
679 trimarchi 70
 
224 giacomo 71
  return 0;
72
 
73
}
74
 
868 trimarchi 75
void FSF_start_service_task(void) {
679 trimarchi 76
 
868 trimarchi 77
  int err;
881 trimarchi 78
  struct timespec default_period = FSF_SERVICE_THREAD_PERIOD;
79
  struct timespec default_budget = FSF_SERVICE_THREAD_BUDGET;
868 trimarchi 80
  DUMMY_TASK_MODEL m;
881 trimarchi 81
  fsf_sched_params_t pr;
868 trimarchi 82
 
881 trimarchi 83
  pr.policy=FSF_NONE;
84
  pr.params=&m;
85
 
868 trimarchi 86
  dummy_task_default_model(m);
87
 
679 trimarchi 88
  // create the service task
89
  // create the communication channel for negotiation and renegotiation
90
 
91
  channel[1] = port_create("CHANW",sizeof(struct mess),1,STREAM,WRITE);
92
 
93
  channel[0] = port_create("CHANR",sizeof(struct mess),1,STREAM,READ);
94
 
868 trimarchi 95
  fsf_initialize_contract(&service_contract);
96
 
97
  fsf_set_contract_basic_parameters(&service_contract,&default_budget,&default_period,FSF_DEFAULT_WORKLOAD);
98
  negotiate_contract(&service_contract,&service_server);
99
 
100
  //server_task = task_create("stask",service_task,model,NULL);
881 trimarchi 101
  err = fsf_create_local_thread(service_server,&pr, &server_task,NULL,(fsf_thread_code_t)service_task,NULL);
868 trimarchi 102
  if (err) {
679 trimarchi 103
    cprintf("error creating service task\n");
104
    sys_shutdown_message("Could not create service_task");
105
    sys_end();
106
    return;
107
  }
108
 
109
  task_activate(server_task);
110
 
111
}
112
 
113
 
221 giacomo 114
/* Convert the contract specification to
115
 * budget parameters
116
 */
241 giacomo 117
int set_SERVER_budget_from_contract
221 giacomo 118
  (const fsf_contract_parameters_t *contract,
119
   int *budget)
120
{
121
 
122
  int local_scheduler_level = 0;
123
 
868 trimarchi 124
   switch (contract->policy) {
125
     case FSF_POSIX:
241 giacomo 126
       local_scheduler_level = POSIXSTAR_register_level(fsf_server_level,5000,32);
221 giacomo 127
       break;
868 trimarchi 128
     case FSF_EDF:
241 giacomo 129
       local_scheduler_level = EDFSTAR_register_level(fsf_server_level);
221 giacomo 130
       break;
868 trimarchi 131
     case FSF_RM:
241 giacomo 132
       local_scheduler_level = RMSTAR_register_level(fsf_server_level);
221 giacomo 133
       break;
868 trimarchi 134
     case FSF_NONE:
855 trimarchi 135
       local_scheduler_level = NONESTAR_register_level(fsf_server_level);
334 giacomo 136
       break;
221 giacomo 137
   }    
405 trimarchi 138
 
661 giacomo 139
   if (contract->d_equals_t == TRUE) {
241 giacomo 140
  *budget = SERVER_setbudget(fsf_server_level,
221 giacomo 141
                              TIMESPEC2USEC(&(contract->budget_min)),
142
                              TIMESPEC2USEC(&(contract->period_max)),
661 giacomo 143
                              TIMESPEC2USEC(&(contract->period_max)),
868 trimarchi 144
                              local_scheduler_level,contract->policy);
661 giacomo 145
  } else {
146
  *budget = SERVER_setbudget(fsf_server_level,
147
                              TIMESPEC2USEC(&(contract->budget_min)),
148
                              TIMESPEC2USEC(&(contract->period_max)),
149
                              TIMESPEC2USEC(&(contract->deadline)),
868 trimarchi 150
                              local_scheduler_level,contract->policy);
661 giacomo 151
  }
221 giacomo 152
 
153
  return 0;
154
 
155
}
156
 
405 trimarchi 157
int adjust_SERVER_budget
158
   (int budget, const TIME budget_actual,
661 giacomo 159
    const TIME period_actual, const TIME dline_actual)
221 giacomo 160
{
161
 
241 giacomo 162
  SERVER_adjust_budget(fsf_server_level,
405 trimarchi 163
                       budget_actual,
164
                       period_actual,
661 giacomo 165
                       dline_actual,
241 giacomo 166
                       budget);
221 giacomo 167
 
168
  return 0;
169
 
170
}
171
 
172
/* Admission Test function */
173
int add_contract(const fsf_contract_parameters_t *contract)
174
{
175
  return 0;
176
 
177
}
178
 
687 trimarchi 179
void contract_to_server(const fsf_contract_parameters_t *contract, int i) {
180
 
410 trimarchi 181
  TIME T,Q;
182
#ifdef FSF_DEBUG
183
  int temp;
184
#endif
185
 
186
  T=TIMESPEC2USEC(&contract->period_min);
187
  Q=TIMESPEC2USEC(&contract->budget_max);
188
  mul32div32to32(MAX_BANDWIDTH,Q,T,server_list[current_server].Umax);
189
 
417 giacomo 190
  T=TIMESPEC2USEC(&contract->period_min);
191
  server_list[i].Tmin=T;
192
 
410 trimarchi 193
  T=TIMESPEC2USEC(&contract->period_max);
194
  server_list[i].Tmax=T;
417 giacomo 195
 
410 trimarchi 196
  Q=TIMESPEC2USEC(&contract->budget_min);
197
  server_list[i].Cmin=Q;
198
 
199
  mul32div32to32(MAX_BANDWIDTH,Q,T,server_list[i].Umin);
416 trimarchi 200
  server_list[i].U=server_list[i].Umin;
661 giacomo 201
 
202
  if (contract->d_equals_t == TRUE) {
203
    server_list[i].deadline = 0;
204
    server_list[i].d_equals_t = TRUE;
205
  } else {
206
    server_list[i].deadline = TIMESPEC2USEC(&contract->deadline);;
207
    server_list[i].d_equals_t = FALSE;
208
  }
209
 
843 trimarchi 210
  server_list[i].Qs = contract->quality;
211
  server_list[i].Is = contract->importance;
212
 
410 trimarchi 213
#ifdef FSF_DEBUG
214
  mul32div32to32(server_list[i].Umax,100, MAX_BANDWIDTH, temp);
215
  kern_printf("(Umax %d)",temp);
216
  mul32div32to32(server_list[i].Umin,100, MAX_BANDWIDTH, temp);
217
  kern_printf("(Umin %d)",temp);
218
#endif
219
 
687 trimarchi 220
}
221
 
222
int relink_contract_to_server(const fsf_contract_parameters_t *contract,
223
                              fsf_server_id_t server)
224
{
225
  int i=0;
226
#ifdef FSF_DEBUG
227
  kern_printf("(Relink Server %d)",server);
228
#endif
229
  // find contract
230
  while(i<current_server) {
231
    if (server_list[i].server==server) break;
232
    i++;
233
  }
234
 
235
  server_list[i].server=server;
843 trimarchi 236
//  server_list[i].Qs=1;
687 trimarchi 237
 
238
  contract_to_server(contract, i);
239
 
240
 
410 trimarchi 241
 return 0;
242
 
243
}
244
 
221 giacomo 245
int link_contract_to_server(const fsf_contract_parameters_t *contract,
246
                            fsf_server_id_t server)
247
{
407 giacomo 248
#ifdef FSF_DEBUG
405 trimarchi 249
  kern_printf("(Link Server %d)",server);
250
#endif
251
 
410 trimarchi 252
  server_list[current_server].server=server;
843 trimarchi 253
  //server_list[current_server].Qs=1;
405 trimarchi 254
 
687 trimarchi 255
  contract_to_server(contract,current_server);    
405 trimarchi 256
 
410 trimarchi 257
  current_server++;
221 giacomo 258
  return 0;
259
 
260
}
261
 
262
int remove_contract(fsf_server_id_t server)
263
{
405 trimarchi 264
  int i=0;
265
  // find the contract
410 trimarchi 266
  while(i<current_server) {
405 trimarchi 267
     if (server_list[i].server==server) break;
268
     i++;
269
  }
221 giacomo 270
 
405 trimarchi 271
  // compress the array;
410 trimarchi 272
  while (i<(current_server-1)) {
405 trimarchi 273
     server_list[i].server=server_list[i+1].server;
274
     server_list[i].Umin=server_list[i+1].Umin;
416 trimarchi 275
     server_list[i].U=server_list[i+1].Umin;    
405 trimarchi 276
     server_list[i].Umax=server_list[i+1].Umax;
277
     server_list[i].Cmin=server_list[i+1].Cmin;
417 giacomo 278
     server_list[i].Tmin=server_list[i+1].Tmin;
405 trimarchi 279
     server_list[i].Tmax=server_list[i+1].Tmax;
280
     server_list[i].Qs=server_list[i+1].Qs;
661 giacomo 281
     server_list[i].deadline = server_list[i+1].deadline;
282
     server_list[i].d_equals_t = server_list[i+1].d_equals_t;
843 trimarchi 283
     server_list[i].Is = server_list[i+1].Is;
417 giacomo 284
 
405 trimarchi 285
     i++;
286
  }
410 trimarchi 287
  current_server--;
405 trimarchi 288
 
289
 
221 giacomo 290
  return 0;
291
 
292
}
293
 
868 trimarchi 294
int
295
fsf_get_renegotiation_status
296
  (fsf_server_id_t server,
297
   fsf_renegotiation_status_t *renegotiation_status)
298
{
221 giacomo 299
 
868 trimarchi 300
 if (SERVER_get_renegotiation_status(fsf_server_level,server))
301
   *renegotiation_status=FSF_IN_PROGRESS;
302
 else
303
   *renegotiation_status=FSF_ADMITTED;
304
 
305
 return 0;
306
 
307
 
308
}
309
 
310
 
221 giacomo 311
int fsf_negotiate_contract
312
  (const fsf_contract_parameters_t *contract,
313
   fsf_server_id_t                 *server)
314
{
880 trimarchi 315
  struct mess m;
221 giacomo 316
 
679 trimarchi 317
  // send response server is -1 if the operation fail
880 trimarchi 318
  m.type=NEGOTIATE_CONTRACT;
319
  memmove(&m.contract,contract, sizeof(fsf_contract_parameters_t));
320
  //kern_printf("(SN:%d)",*server);
321
  port_send(channel[1],&m,BLOCK);
322
  //kern_printf("BR:%d)", *server);  
323
  port_receive(channel[0], &m, BLOCK);
324
  //kern_printf("(EN:%d)", *server);
325
  if (m.server==-1)
679 trimarchi 326
    return FSF_ERR_CONTRACT_REJECTED;
221 giacomo 327
 
880 trimarchi 328
  *server=m.server;
679 trimarchi 329
 
221 giacomo 330
  return 0;
331
 
332
}
333
 
872 trimarchi 334
int
335
fsf_negotiate_contract_for_new_thread
336
  (const fsf_contract_parameters_t *contract,
337
   fsf_server_id_t      *server,
338
   pthread_t            *thread,
339
   pthread_attr_t       *attr,
340
   fsf_thread_code_t     thread_code,
341
   void                 *arg) {
342
 
343
  int err=0;
344
 
345
  err = fsf_negotiate_contract(contract,server);
346
  if (!err) {    
347
    err = pthread_create(thread, attr, thread_code, arg);    
348
    if (!err)
349
      err = fsf_bind_thread_to_server(*server,*thread);
350
  } else return err;
351
 
352
  return err;
353
}
354
 
355
int
356
fsf_negotiate_contract_for_myself
357
  (const fsf_contract_parameters_t *contract,
358
   fsf_server_id_t      *server) {
359
 
360
  int err=0;
361
 
362
  err = fsf_negotiate_contract(contract,server);
880 trimarchi 363
  //kern_printf("ENMyS:%d", *server);
872 trimarchi 364
  if (!err) {
365
     err = fsf_bind_thread_to_server(*server,exec_shadow);
880 trimarchi 366
     //kern_printf("EMMyE:%d:%d",*server,err);
872 trimarchi 367
  } else return err;
368
 
369
  return err;
370
}
371
 
868 trimarchi 372
int fsf_unbind_thread_from_server
373
  (pthread_t       thread)
374
{
375
 
376
  int local_scheduler_level, scheduler_id;
377
 
378
  /* Move thread from the local scheduler module to posix level */
379
 
380
  #ifdef FSF_DEBUG
381
    kern_printf("(UnBind thread = %d)",thread);
382
  #endif
383
 
384
  /* Check if thread exsists */
385
  if (thread == -1)
386
    return FSF_ERR_BAD_ARGUMENT;
387
 
388
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level,thread);
389
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level,thread);
390
 
391
  /* Check if thread is already bind */
392
  if (scheduler_id == FSF_NONE) {
393
      /* Check if it is bind to a server */
394
      if (NONESTAR_getbudget(local_scheduler_level,thread) == -1)
395
        return FSF_ERR_BAD_ARGUMENT;
396
      else {
397
 
398
        STD_command_message *msg;
399
        NRT_TASK_MODEL nrt;
400
 
401
        nrt_task_default_model(nrt);
402
        nrt_task_def_save_arrivals(nrt);
403
 
404
        /* Send change level command to local scheduler */
405
        msg = (STD_command_message *)malloc(sizeof(STD_command_message));
406
 
407
        msg->command = STD_SET_NEW_MODEL;
408
        msg->param = (void *)(&nrt);
409
        level_table[fsf_posix_level]->public_message(fsf_posix_level,thread,msg);
410
 
411
        msg->command = STD_SET_NEW_LEVEL;
412
        msg->param = (void *)(fsf_posix_level);
413
        task_message(msg,thread,0);
414
 
415
        free(msg);
416
      }
417
  }
418
 
419
  return 0;
420
 
421
}
422
 
873 trimarchi 423
int  
424
fsf_bind_local_thread_to_server
425
  (fsf_server_id_t      server,
426
   pthread_t            thread,
427
   fsf_sched_params_t  *sched_params)
428
{
868 trimarchi 429
 
873 trimarchi 430
  STD_command_message *msg;
431
  int local_scheduler_level,scheduler_id;
432
 
433
  /* Move thread from the posix module to local scheduler */
434
 
435
  #ifdef FSF_DEBUG 
436
    kern_printf("(Bind thread = %d to Server = %d)",thread,server);
437
  #endif
438
 
439
  /* Check if server and thread exsist */
440
  if (server == -1 || thread == -1)
441
    return FSF_ERR_BAD_ARGUMENT;
442
 
443
  local_scheduler_level = SERVER_get_local_scheduler_level_from_budget(fsf_server_level,server);
444
  if (local_scheduler_level==-1)
445
    return FSF_ERR_UNKNOWN_APPSCHEDULED_THREAD;
446
 
447
  scheduler_id = SERVER_get_local_scheduler_id_from_budget(fsf_server_level,server);
881 trimarchi 448
 
449
  if (scheduler_id!=sched_params->policy)
450
     return FSF_ERR_SCHED_POLICY_NOT_COMPATIBLE;
873 trimarchi 451
 
452
  /* Check if thread is already bind */
453
  switch(scheduler_id) {
454
 
455
     case FSF_RM:
456
       {
881 trimarchi 457
         TASK_MODEL      *m=(TASK_MODEL*)(sched_params->params);
458
         HARD_TASK_MODEL *h=(HARD_TASK_MODEL *)(sched_params->params);
873 trimarchi 459
 
460
         if (m->pclass != HARD_PCLASS)
461
           return FSF_ERR_SCHED_POLICY_NOT_COMPATIBLE;
462
 
463
         h = (HARD_TASK_MODEL *)m;
464
 
465
         if (!h->wcet || !h->mit) return FSF_ERR_SCHED_POLICY_NOT_COMPATIBLE;
466
 
467
         /* now we know that m is a valid model */
468
         if (RMSTAR_getbudget(local_scheduler_level,thread) != -1)
469
           return FSF_ERR_BAD_ARGUMENT;
470
 
471
         /* Set server on local scheduler */
472
         RMSTAR_setbudget(local_scheduler_level,thread,(int)(server));
473
 
474
         /* Send change level command to posix level */
475
       }
877 trimarchi 476
       break;
477
 
873 trimarchi 478
     case FSF_EDF:
479
       {
881 trimarchi 480
         TASK_MODEL      *m=(TASK_MODEL*)(sched_params->params);
481
         HARD_TASK_MODEL *h=(HARD_TASK_MODEL *)(sched_params->params);
873 trimarchi 482
 
483
         if (m->pclass != HARD_PCLASS)
484
           return FSF_ERR_SCHED_POLICY_NOT_COMPATIBLE;
485
 
486
         h = (HARD_TASK_MODEL *)m;
487
 
488
         if (!h->wcet || !h->mit) return FSF_ERR_SCHED_POLICY_NOT_COMPATIBLE;
489
 
490
         if (EDFSTAR_getbudget(local_scheduler_level,thread) != -1)
491
           return FSF_ERR_BAD_ARGUMENT;
492
 
493
         /* Set server on local scheduler */
494
         EDFSTAR_setbudget(local_scheduler_level,thread,(int)(server));
495
 
496
       }
497
       break;
498
 
499
     case FSF_POSIX:
500
       {
881 trimarchi 501
         TASK_MODEL      *m=(TASK_MODEL*)(sched_params->params);
873 trimarchi 502
 
503
         if (m->pclass != NRT_PCLASS)
504
           return  FSF_ERR_SCHED_POLICY_NOT_COMPATIBLE;
505
 
506
         if (POSIXSTAR_getbudget(local_scheduler_level,thread) != -1)
507
           return FSF_ERR_BAD_ARGUMENT;
508
 
509
         /* Set server on local scheduler */
510
         POSIXSTAR_setbudget(local_scheduler_level,thread,(int)(server));        
511
       }
877 trimarchi 512
       break;
873 trimarchi 513
 
877 trimarchi 514
     default:
515
 
873 trimarchi 516
       return FSF_ERR_BAD_ARGUMENT;
877 trimarchi 517
 
873 trimarchi 518
  }
519
 
520
  msg = (STD_command_message *)malloc(sizeof(STD_command_message));
877 trimarchi 521
  if (msg) {
522
    SYS_FLAGS f;
523
    f=kern_fsave();
873 trimarchi 524
    msg->command = STD_SET_NEW_MODEL;
881 trimarchi 525
    msg->param = (void *)(sched_params->params);
873 trimarchi 526
    level_table[local_scheduler_level]->public_message(local_scheduler_level,thread,msg);
527
 
528
    msg->command = STD_SET_NEW_LEVEL;
529
    msg->param = (void *)(local_scheduler_level);
530
    task_message(msg,thread,0);
877 trimarchi 531
    kern_frestore(f);
873 trimarchi 532
    free(msg);
533
  } else return FSF_ERR_INTERNAL_ERROR;
534
 
535
  return 0;
536
 
537
}
538
 
539
 
868 trimarchi 540
int fsf_bind_thread_to_server
541
  (fsf_server_id_t server,
542
   pthread_t       thread)
543
{
544
 
545
  STD_command_message *msg;
546
  int local_scheduler_level,scheduler_id;
547
 
548
  /* Move thread from the posix module to local scheduler */
549
 
550
  #ifdef FSF_DEBUG 
880 trimarchi 551
    kern_printf("(Bthr=%d to Sr=%d)",thread,server);
868 trimarchi 552
  #endif
553
 
554
  /* Check if server and thread exsist */
555
  if (server == -1 || thread == -1)
556
    return FSF_ERR_BAD_ARGUMENT;
557
 
558
  local_scheduler_level = SERVER_get_local_scheduler_level_from_budget(fsf_server_level,server);
873 trimarchi 559
  if (local_scheduler_level==-1)
560
    return FSF_ERR_UNKNOWN_APPSCHEDULED_THREAD;
561
 
868 trimarchi 562
  scheduler_id = SERVER_get_local_scheduler_id_from_budget(fsf_server_level,server);
563
 
564
  /* Check if thread is already bind */
565
  if (scheduler_id == FSF_NONE) {
566
      DUMMY_TASK_MODEL rt_arg;
567
 
568
      if (NONESTAR_getbudget(local_scheduler_level,thread) != -1)
569
        return FSF_ERR_BAD_ARGUMENT;
570
 
571
      /* Set server on local scheduler */
572
      NONESTAR_setbudget(local_scheduler_level,thread,(int)(server));
573
 
574
      /* Send change level command to posix level */
575
      msg = (STD_command_message *)malloc(sizeof(STD_command_message));
576
 
577
      msg->command = STD_SET_NEW_MODEL;
578
      msg->param = (void *)(&rt_arg);
579
      level_table[local_scheduler_level]->public_message(local_scheduler_level,thread,msg);
580
 
581
      msg->command = STD_SET_NEW_LEVEL;
582
      msg->param = (void *)(local_scheduler_level);
583
      task_message(msg,thread,0);
584
      free(msg);
585
   } else return FSF_ERR_BAD_ARGUMENT;
586
 
587
  return 0;
588
}
589
 
881 trimarchi 590
int fsf_create_local_thread
591
(fsf_server_id_t        server,
592
   fsf_sched_params_t    *local_scheduler_arg,
593
   pthread_t             *thread,
594
   pthread_attr_t        *attr,
595
   fsf_thread_code_t      thread_code,
596
   void                  *arg)
221 giacomo 597
{
598
 
599
  int local_scheduler_level,scheduler_id;
600
 
601
  /* Check if server and thread exsist */
241 giacomo 602
  if (server == NIL)
873 trimarchi 603
    return  FSF_ERR_BAD_ARGUMENT;
221 giacomo 604
 
241 giacomo 605
  local_scheduler_level = SERVER_get_local_scheduler_level_from_budget(fsf_server_level,server);
606
  scheduler_id = SERVER_get_local_scheduler_id_from_budget(fsf_server_level,server);
868 trimarchi 607
#ifdef FSF_DEBUG
608
  kern_printf("sched policy %d", scheduler_id);
609
#endif
888 trimarchi 610
 
611
  if (scheduler_id!=local_scheduler_arg->policy)
612
    return FSF_ERR_SCHED_POLICY_NOT_COMPATIBLE;
613
 
221 giacomo 614
  /* Check if thread is already bind */
615
  switch (scheduler_id) {
873 trimarchi 616
     case FSF_POSIX:
221 giacomo 617
 
888 trimarchi 618
      nrt_task_def_arg(*(NRT_TASK_MODEL *)(local_scheduler_arg->params),arg);
619
      nrt_task_def_level(*(NRT_TASK_MODEL *)(local_scheduler_arg->params),local_scheduler_level);
221 giacomo 620
 
888 trimarchi 621
      *thread = task_create("POSIXSTAR", thread_code, local_scheduler_arg->params, NULL);
267 giacomo 622
      if (*thread == NIL) {
623
        #ifdef FSF_DEBUG
624
          kern_printf("(FSF:Error creating thread)");
625
        #endif
873 trimarchi 626
        return FSF_ERR_INTERNAL_ERROR;
267 giacomo 627
      }
221 giacomo 628
 
241 giacomo 629
      POSIXSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
234 giacomo 630
 
221 giacomo 631
    break;
868 trimarchi 632
    case FSF_EDF:
221 giacomo 633
 
888 trimarchi 634
      hard_task_def_arg(*(HARD_TASK_MODEL *)(local_scheduler_arg->params),arg);
635
      hard_task_def_level(*(HARD_TASK_MODEL *)(local_scheduler_arg->params),local_scheduler_level);
250 giacomo 636
 
888 trimarchi 637
      *thread = task_create("EDFSTAR", thread_code, local_scheduler_arg->params, NULL);
250 giacomo 638
      if (*thread == NIL)
873 trimarchi 639
        return  FSF_ERR_INTERNAL_ERROR;
250 giacomo 640
 
641
      EDFSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
642
 
221 giacomo 643
      break;
235 giacomo 644
 
868 trimarchi 645
    case FSF_RM:
235 giacomo 646
 
888 trimarchi 647
      hard_task_def_arg(*(HARD_TASK_MODEL *)(local_scheduler_arg->params),arg);
648
      hard_task_def_level(*(HARD_TASK_MODEL *)(local_scheduler_arg->params),local_scheduler_level);
273 giacomo 649
 
888 trimarchi 650
      *thread = task_create("RMSTAR", thread_code, local_scheduler_arg->params, NULL);
273 giacomo 651
      if (*thread == NIL)
873 trimarchi 652
        return  FSF_ERR_INTERNAL_ERROR;
273 giacomo 653
 
654
      RMSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
655
 
656
      break;
868 trimarchi 657
    case FSF_NONE:
334 giacomo 658
 
888 trimarchi 659
      dummy_task_def_arg(*( DUMMY_TASK_MODEL *)(local_scheduler_arg->params),arg);
660
      dummy_task_def_level(*( DUMMY_TASK_MODEL *)(local_scheduler_arg->params),local_scheduler_level);
879 trimarchi 661
#ifdef FSF_DEBUG
662
      kern_printf("(None Server create task)");
663
#endif                                                                                                                      
888 trimarchi 664
      *thread = task_create("NONESTAR", thread_code, local_scheduler_arg->params, NULL);
334 giacomo 665
      if (*thread == NIL)
873 trimarchi 666
        return  FSF_ERR_INTERNAL_ERROR;
334 giacomo 667
 
855 trimarchi 668
      NONESTAR_setbudget(local_scheduler_level, *thread, (int)(server));
334 giacomo 669
 
670
      break;
671
 
221 giacomo 672
    default:
873 trimarchi 673
      return FSF_ERR_INTERNAL_ERROR;
221 giacomo 674
      break;
675
  }
811 trimarchi 676
 
677
  #ifdef FSF_DEBUG
678
    kern_printf("(FSF:Insert thread = %d to Server = %d)",*thread,server);
679
  #endif
221 giacomo 680
 
681
  return 0;
682
 
683
}
684
 
808 trimarchi 685
int  fsf_settask_nopreemptive
221 giacomo 686
  (fsf_server_id_t *server,
687
   pthread_t       thread)
688
{
689
  int local_scheduler_level, scheduler_id;
690
 
241 giacomo 691
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level,thread);
692
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, thread);
221 giacomo 693
 
694
  switch (scheduler_id) {
868 trimarchi 695
    case FSF_POSIX:
816 trimarchi 696
      POSIXSTAR_set_nopreemtive_current(local_scheduler_level);
697
      return 1;
808 trimarchi 698
      break;
868 trimarchi 699
    case FSF_EDF:
808 trimarchi 700
      EDFSTAR_set_nopreemtive_current(local_scheduler_level);
701
      return 1;
702
      break;
868 trimarchi 703
    case FSF_RM:
812 trimarchi 704
      RMSTAR_set_nopreemtive_current(local_scheduler_level);
705
      return 1;
808 trimarchi 706
      break;
868 trimarchi 707
    case FSF_NONE:
808 trimarchi 708
      break;
709
    default:
710
      return -1;
711
  }
712
  return -1;
713
}
714
 
715
 
716
int  fsf_settask_preemptive
717
  (fsf_server_id_t *server,
718
   pthread_t       thread)
719
{
720
  int local_scheduler_level, scheduler_id;
721
 
722
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level,thread);
723
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, thread);
724
 
725
  switch (scheduler_id) {
868 trimarchi 726
    case FSF_POSIX:
823 trimarchi 727
      POSIXSTAR_unset_nopreemtive_current(local_scheduler_level);
816 trimarchi 728
      return 1;
808 trimarchi 729
      break;
868 trimarchi 730
    case FSF_EDF:
808 trimarchi 731
      EDFSTAR_unset_nopreemtive_current(local_scheduler_level);
732
      return 1;
733
      break;
868 trimarchi 734
    case FSF_RM:
812 trimarchi 735
      RMSTAR_unset_nopreemtive_current(local_scheduler_level);
736
      return 1;
808 trimarchi 737
      break;
868 trimarchi 738
    case FSF_NONE:
808 trimarchi 739
      break;
740
    default:
741
      return -1;
742
  }
743
 
744
  return -1;
745
 
746
}
747
 
748
 
749
int fsf_get_server
868 trimarchi 750
  (pthread_t       thread,
751
   fsf_server_id_t *server)
808 trimarchi 752
{
753
  int local_scheduler_level, scheduler_id;
754
 
755
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level,thread);
756
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, thread);
757
 
758
  switch (scheduler_id) {
868 trimarchi 759
    case FSF_POSIX:  
829 giacomo 760
      *server = POSIXSTAR_getbudget(local_scheduler_level,thread);
761
      return 0;
868 trimarchi 762
    case FSF_EDF:
829 giacomo 763
      *server = EDFSTAR_getbudget(local_scheduler_level,thread);
764
      return 0;
868 trimarchi 765
    case FSF_RM:
829 giacomo 766
      *server = RMSTAR_getbudget(local_scheduler_level,thread);
767
      return 0;
868 trimarchi 768
    case FSF_NONE:
855 trimarchi 769
      *server = NONESTAR_getbudget(local_scheduler_level,thread);
829 giacomo 770
      return 0;
235 giacomo 771
    default:
221 giacomo 772
      return -1;
773
  }
774
 
775
  return -1;
776
 
777
}
778
 
339 giacomo 779
int fsf_get_server_level(void)
780
{
781
 
782
  return fsf_server_level;
783
 
784
}
785
 
221 giacomo 786
int fsf_cancel_contract
868 trimarchi 787
  (fsf_server_id_t server)
221 giacomo 788
{
789
 
790
  int local_scheduler_level, scheduler_id;
411 trimarchi 791
  SYS_FLAGS f;
792
  TIME T,Q;
793
  int i=0;
221 giacomo 794
 
795
  #ifdef FSF_DEBUG
868 trimarchi 796
    kern_printf("(Remove server %d)",server);
221 giacomo 797
  #endif
798
 
799
  /* Check server id */
868 trimarchi 800
  if (server < 0)
873 trimarchi 801
    return FSF_ERR_BAD_ARGUMENT;
221 giacomo 802
 
868 trimarchi 803
  local_scheduler_level = SERVER_get_local_scheduler_level_from_budget(fsf_server_level,server);
804
  scheduler_id = SERVER_get_local_scheduler_id_from_budget(fsf_server_level,server);
221 giacomo 805
 
806
  switch (scheduler_id) {
868 trimarchi 807
    case FSF_POSIX:
221 giacomo 808
 
809
      /* Check if some thread use the server */
868 trimarchi 810
      if(POSIXSTAR_budget_has_thread(local_scheduler_level,server))
873 trimarchi 811
        return FSF_ERR_NOT_CONTRACTED_SERVER;
221 giacomo 812
 
813
      break;
868 trimarchi 814
    case FSF_EDF:
235 giacomo 815
      /* Check if some thread use the server */
868 trimarchi 816
      if(EDFSTAR_budget_has_thread(local_scheduler_level,server))
873 trimarchi 817
        return FSF_ERR_NOT_CONTRACTED_SERVER;
235 giacomo 818
      break;
819
 
868 trimarchi 820
    case FSF_RM:
235 giacomo 821
      /* Check if some thread use the server */
868 trimarchi 822
      if(RMSTAR_budget_has_thread(local_scheduler_level,server))
873 trimarchi 823
        return FSF_ERR_NOT_CONTRACTED_SERVER;
235 giacomo 824
 
221 giacomo 825
      break;
334 giacomo 826
 
868 trimarchi 827
    case FSF_NONE:
334 giacomo 828
      /* Check if some thread use the server */
868 trimarchi 829
      if(NONESTAR_budget_has_thread(local_scheduler_level,server))
873 trimarchi 830
        return   FSF_ERR_NOT_CONTRACTED_SERVER;
334 giacomo 831
 
832
      break;
833
 
221 giacomo 834
  }
835
 
868 trimarchi 836
  SERVER_removebudget(fsf_server_level,server);
221 giacomo 837
 
838
  level_free_descriptor(local_scheduler_level);
405 trimarchi 839
 
868 trimarchi 840
  remove_contract(server);
411 trimarchi 841
 
842
  f=kern_fsave();              
843
  if (recalculate_contract(fsf_max_bw)==-1)  {
844
       kern_frestore(f);
873 trimarchi 845
       return  FSF_ERR_INTERNAL_ERROR;
411 trimarchi 846
  }
847
#ifdef  FSF_DEBUG
848
  kern_printf("(Adjust budget)");
849
#endif    
850
  for (i=0; i<current_server; i++) {
851
    mul32div32to32(MAX_BANDWIDTH,server_list[i].Cmin,server_list[i].U,T);
417 giacomo 852
    if (T > server_list[i].Tmin ) {
411 trimarchi 853
      server_list[i].actual_budget = server_list[i].Cmin;
854
      server_list[i].actual_period = T;
417 giacomo 855
      #ifdef FSF_DEBUG
856
        kern_printf("(1 - Q %ld T %ld)", server_list[i].actual_budget, server_list[i].actual_period);
857
      #endif
661 giacomo 858
 
859
      if (server_list[i].d_equals_t == TRUE)
860
        adjust_SERVER_budget(server_list[i].server,server_list[i].Cmin, T, T);
861
      else
862
        adjust_SERVER_budget(server_list[i].server,server_list[i].Cmin, T, server_list[i].deadline);
863
 
411 trimarchi 864
    } else {
417 giacomo 865
      mul32div32to32(server_list[i].Tmin,server_list[i].U,MAX_BANDWIDTH,Q);
411 trimarchi 866
      server_list[i].actual_budget = Q;
417 giacomo 867
      server_list[i].actual_period = server_list[i].Tmin;
868
      #ifdef FSF_DEBUG
869
         kern_printf("(2 - Q %ld T %ld)", server_list[i].actual_budget, server_list[i].actual_period);
870
      #endif
661 giacomo 871
 
872
      if (server_list[i].d_equals_t == TRUE)
873
        adjust_SERVER_budget(server_list[i].server,Q, server_list[i].Tmin, server_list[i].Tmin);
874
      else
875
        adjust_SERVER_budget(server_list[i].server,Q, server_list[i].Tmin, server_list[i].deadline);
876
 
411 trimarchi 877
    }
416 trimarchi 878
    server_list[i].U=server_list[i].Umin;
411 trimarchi 879
 
880
  }                                          
221 giacomo 881
 
405 trimarchi 882
 
411 trimarchi 883
  kern_frestore(f);
221 giacomo 884
 
885
  return 0;
411 trimarchi 886
 
221 giacomo 887
}
888
 
881 trimarchi 889
bandwidth_t SERVER_return_bandwidth() {
890
  int i=0;
891
  bandwidth_t U;
892
  U=0;
893
  for(i=0;i<current_server;i++) {
894
 
895
    U+=server_list[i].Umin;
896
 
897
  }
898
 
899
  return U;
900
}
901
 
405 trimarchi 902
int recalculate_contract(bandwidth_t U) {
416 trimarchi 903
  bandwidth_t current_bandwidth;
418 giacomo 904
  unsigned int temp_U;
416 trimarchi 905
  int        Qt;
405 trimarchi 906
  int isok=0;
907
  int i=0;
868 trimarchi 908
  int target_importance=FSF_DEFAULT_IMPORTANCE;
909
 
910
#define MAX_IMPORTANCE 5
405 trimarchi 911
 
407 giacomo 912
  #ifdef FSF_DEBUG
913
    int temp;
914
 
915
    kern_printf("(Recalculate contract)");
916
  #endif
405 trimarchi 917
 
918
  /* The current bandwidth is the min bandwidth */
881 trimarchi 919
  current_bandwidth=SERVER_return_bandwidth(fsf_server_level);
405 trimarchi 920
  #ifdef FSF_DEBUG
410 trimarchi 921
     kern_printf("(nserver %d)", current_server);
405 trimarchi 922
  #endif  
880 trimarchi 923
  //kern_printf("(CS:%d)", current_server); 
405 trimarchi 924
  do  {
925
    current_bandwidth=0;
926
    Qt=0;
410 trimarchi 927
    for (i=0; i<current_server; i++) {
843 trimarchi 928
      if (server_list[i].Is==target_importance
929
          && server_list[i].U<server_list[i].Umax && server_list[i].Qs>0)
405 trimarchi 930
         Qt+=server_list[i].Qs;
416 trimarchi 931
       current_bandwidth+=server_list[i].U;
868 trimarchi 932
#ifdef FSF_DEBUG
843 trimarchi 933
       kern_printf("(Qs %d, Qt %d, Is %d)", server_list[i].Qs, Qt,server_list[i].Is);
868 trimarchi 934
#endif
405 trimarchi 935
    }
413 trimarchi 936
 
868 trimarchi 937
#ifdef FSF_DEBUG
405 trimarchi 938
    kern_printf("(Total Quality %d)", Qt);
868 trimarchi 939
#endif
405 trimarchi 940
    isok=1;
410 trimarchi 941
    for (i=0; i<current_server; i++) {
843 trimarchi 942
      if (server_list[i].Is==target_importance && server_list[i].U<server_list[i].Umax && server_list[i].Qs>0) {
416 trimarchi 943
        temp_U=server_list[i].U;
944
        server_list[i].U=U-current_bandwidth;
945
        mul32div32to32(server_list[i].U, server_list[i].Qs, Qt, server_list[i].U);
946
        temp_U+=server_list[i].U;
947
 
948
        if (temp_U<=server_list[i].Umin) {
405 trimarchi 949
           server_list[i].U=server_list[i].Umin;
416 trimarchi 950
        } else if (temp_U>server_list[i].Umax)  {
951
           server_list[i].U=server_list[i].Umax;
405 trimarchi 952
           isok=0;
953
        } else server_list[i].U=temp_U;
954
 
955
#ifdef FSF_DEBUG
956
        mul32div32to32(server_list[i].U,100, MAX_BANDWIDTH, temp);
957
        kern_printf("(Server %d bw %d)", server_list[i].server, temp);
958
#endif 
959
      }
960
    }  
843 trimarchi 961
    target_importance++;
880 trimarchi 962
  } while (!isok || target_importance<=MAX_IMPORTANCE);
963
 //kern_printf("(RNDNL)"); 
405 trimarchi 964
 return 0;
965
}
966
 
221 giacomo 967
int fsf_renegotiate_contract
968
  (const fsf_contract_parameters_t *new_contract,
969
   fsf_server_id_t server)
970
{
679 trimarchi 971
 
972
  struct mess message;
221 giacomo 973
 
679 trimarchi 974
  // send response server is -1 if the operation fail
975
  message.type=RENEGOTIATE_CONTRACT;
976
  memmove(&message.contract,new_contract, sizeof(fsf_contract_parameters_t));
977
  message.server = server;
221 giacomo 978
 
859 trimarchi 979
  port_send(channel[1],&message,BLOCK);
980
 
981
  port_receive(channel[0], &message, BLOCK);
982
 
679 trimarchi 983
  if (message.server==-1) return FSF_ERR_CONTRACT_REJECTED;
984
 
405 trimarchi 985
   return 0;
221 giacomo 986
}
241 giacomo 987
 
868 trimarchi 988
int fsf_request_contract_renegotiation
989
  (const fsf_contract_parameters_t *new_contract,
990
   fsf_server_id_t                  server,
991
   int                              sig_notify,
992
   union sigval                     sig_value)
993
{
994
 
995
  struct mess message;
996
 
997
  // send response server is -1 if the operation fail
998
  message.type=REQUEST_RENEGOTIATE_CONTRACT;
999
  memmove(&message.contract,new_contract, sizeof(fsf_contract_parameters_t));
1000
  message.server = server;
1001
 
1002
  port_send(channel[1],&message,BLOCK);
1003
 
1004
  port_receive(channel[0], &message, BLOCK);
1005
 
1006
  if (message.server==-1) return FSF_ERR_CONTRACT_REJECTED;
1007
 
1008
   return 0;
1009
}
1010
 
407 giacomo 1011
void print_server_list()
1012
{
1013
 
1014
  int i;
1015
 
1016
  kern_printf("Server List\n");
1017
 
410 trimarchi 1018
  for(i=0;i<current_server;i++) {
407 giacomo 1019
 
662 giacomo 1020
    kern_printf("[%d] Q:%d T:%d D:%d [DeT = %d]\n",server_list[i].server,(int)server_list[i].actual_budget,(int)server_list[i].actual_period,(int)server_list[i].deadline,(int)server_list[i].d_equals_t);
407 giacomo 1021
 
1022
  }
1023
 
1024
}
808 trimarchi 1025
 
1026
 
1027
int fsf_get_remain_budget(fsf_server_id_t server) {
1028
 
825 trimarchi 1029
  return SERVER_get_remain_capacity(fsf_server_level, server);
808 trimarchi 1030
}
868 trimarchi 1031
 
1032
int fsf_get_budget_and_period
1033
   (fsf_server_id_t server,
1034
    struct timespec *budget,
1035
    struct timespec *period) {
1036
  TIME bg;
1037
  TIME pd;
1038
 
1039
  if (!SERVER_getbudgetinfo(fsf_server_level, &bg, &pd, NULL, server)) {
1040
    if (budget) {
1041
      NULL_TIMESPEC(budget);
1042
      ADDUSEC2TIMESPEC(bg, budget);
1043
    }
1044
    if (period) {
1045
      NULL_TIMESPEC(period);
1046
      ADDUSEC2TIMESPEC(pd, period);
1047
    }
1048
 
1049
    return 0;
1050
  }
1051
  return FSF_ERR_BAD_ARGUMENT;
1052
}
1053
 
1054
int
1055
fsf_set_service_thread_data
1056
   (const struct timespec *budget,
1057
    const struct timespec *period,
1058
    bool                  *accepted) {
1059
 
1060
  if (budget==NULL && period==NULL) return FSF_ERR_BAD_ARGUMENT;
1061
  fsf_set_contract_basic_parameters(&service_contract,budget,period,FSF_DEFAULT_WORKLOAD);
1062
  *accepted = !fsf_renegotiate_contract(&service_contract,service_server)?true:false;
1063
  return 0;
1064
 
1065
}
1066
 
1067
 
1068
 
1069
int fsf_get_service_thread_data
1070
   (struct timespec *budget,
1071
    struct timespec *period) {
1072
 
1073
  return fsf_get_budget_and_period(service_server, budget, period);
1074
 
1075
}
1076