Subversion Repositories shark

Rev

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