Subversion Repositories shark

Rev

Rev 996 | 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>
975 trimarchi 16
#include <sem/sem/sem.h>
17
#include <hartport/hartport/hartport.h>
18
#include <cabs/cabs/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"
944 trimarchi 29
#include "tdstar.h"
1008 trimarchi 30
#include "fedfstar.h"
868 trimarchi 31
 
221 giacomo 32
#include <pthread.h>
33
#include <stdlib.h>
808 trimarchi 34
#include "pistar.h"
975 trimarchi 35
#include <posix/posix/comm_message.h>
221 giacomo 36
 
417 giacomo 37
//#define FSF_DEBUG
221 giacomo 38
 
410 trimarchi 39
int current_server=0;
407 giacomo 40
server_elem server_list[FSF_MAX_N_SERVERS];
406 giacomo 41
bandwidth_t fsf_max_bw = 0;
405 trimarchi 42
 
241 giacomo 43
int fsf_server_level;
868 trimarchi 44
int fsf_posix_level = -1;
808 trimarchi 45
int shared_object_level;
679 trimarchi 46
PID server_task;
868 trimarchi 47
fsf_contract_parameters_t contract;
221 giacomo 48
 
868 trimarchi 49
 
679 trimarchi 50
PORT channel[2];
51
 
868 trimarchi 52
fsf_server_id_t service_server = -1;
53
fsf_contract_parameters_t service_contract;
54
 
896 trimarchi 55
bandwidth_t SERVER_return_bandwidth();
56
 
808 trimarchi 57
int FSF_register_shared_object_module(void) {
811 trimarchi 58
  fsf_register_shared_object();
808 trimarchi 59
  return PISTAR_register_module();
60
}
61
 
62
 
810 trimarchi 63
int FSF_get_shared_object_level() {
64
  return shared_object_level;
65
}
66
 
868 trimarchi 67
int FSF_register_module(int posix_level, int server_level, bandwidth_t max_bw)
224 giacomo 68
{
69
  printk("FSF Module\n");
410 trimarchi 70
  current_server=0;
241 giacomo 71
  fsf_server_level = server_level;
868 trimarchi 72
  fsf_posix_level = posix_level;
406 giacomo 73
  fsf_max_bw = max_bw;
811 trimarchi 74
  shared_object_level = FSF_register_shared_object_module();
679 trimarchi 75
 
224 giacomo 76
  return 0;
77
 
78
}
79
 
868 trimarchi 80
void FSF_start_service_task(void) {
679 trimarchi 81
 
868 trimarchi 82
  int err;
881 trimarchi 83
  struct timespec default_period = FSF_SERVICE_THREAD_PERIOD;
84
  struct timespec default_budget = FSF_SERVICE_THREAD_BUDGET;
868 trimarchi 85
  DUMMY_TASK_MODEL m;
881 trimarchi 86
  fsf_sched_params_t pr;
937 trimarchi 87
  int                budget_overrun_sig_notify = FSF_NULL_SIGNAL;
88
  union sigval       budget_overrun_sig_value = {0};
89
  int                deadline_miss_sig_notify = FSF_NULL_SIGNAL;
90
  union sigval       deadline_miss_sig_value = {0};
868 trimarchi 91
 
881 trimarchi 92
  pr.policy=FSF_NONE;
93
  pr.params=&m;
94
 
868 trimarchi 95
  dummy_task_default_model(m);
941 trimarchi 96
 
679 trimarchi 97
  // create the service task
98
  // create the communication channel for negotiation and renegotiation
99
 
100
  channel[1] = port_create("CHANW",sizeof(struct mess),1,STREAM,WRITE);
1008 trimarchi 101
  if (channel[1]<0) exit(-1);
679 trimarchi 102
 
103
  channel[0] = port_create("CHANR",sizeof(struct mess),1,STREAM,READ);
1008 trimarchi 104
  if (channel[0]<0) exit(-1);
679 trimarchi 105
 
1008 trimarchi 106
  //kern_printf("FSF port WRITE %d, READ %d\n", channel[1], channel[0]);
107
 
868 trimarchi 108
  fsf_initialize_contract(&service_contract);
941 trimarchi 109
 
110
  err=fsf_set_contract_basic_parameters(&service_contract,&default_budget,&default_period,FSF_DEFAULT_WORKLOAD);
111
  if (err) exit(err);
868 trimarchi 112
 
941 trimarchi 113
  err=fsf_set_contract_timing_requirements (&service_contract,
937 trimarchi 114
                                        true,NULL,
115
                                        budget_overrun_sig_notify,
116
                                        budget_overrun_sig_value,
117
                                        deadline_miss_sig_notify,
118
                                        deadline_miss_sig_value);
941 trimarchi 119
  if (err) exit(err);
937 trimarchi 120
 
868 trimarchi 121
  negotiate_contract(&service_contract,&service_server);
122
 
123
  //server_task = task_create("stask",service_task,model,NULL);
881 trimarchi 124
  err = fsf_create_local_thread(service_server,&pr, &server_task,NULL,(fsf_thread_code_t)service_task,NULL);
868 trimarchi 125
  if (err) {
679 trimarchi 126
    cprintf("error creating service task\n");
127
    sys_shutdown_message("Could not create service_task");
927 pj 128
    exit(1);
679 trimarchi 129
  }
130
 
131
  task_activate(server_task);
132
 
133
}
134
 
135
 
221 giacomo 136
/* Convert the contract specification to
137
 * budget parameters
138
 */
241 giacomo 139
int set_SERVER_budget_from_contract
221 giacomo 140
  (const fsf_contract_parameters_t *contract,
141
   int *budget)
142
{
143
 
144
  int local_scheduler_level = 0;
145
 
868 trimarchi 146
   switch (contract->policy) {
952 trimarchi 147
     case FSF_RR:
241 giacomo 148
       local_scheduler_level = POSIXSTAR_register_level(fsf_server_level,5000,32);
221 giacomo 149
       break;
868 trimarchi 150
     case FSF_EDF:
241 giacomo 151
       local_scheduler_level = EDFSTAR_register_level(fsf_server_level);
221 giacomo 152
       break;
1008 trimarchi 153
     case FSF_FEDF:
154
       local_scheduler_level = FEDFSTAR_register_level(fsf_server_level);
155
       break;
952 trimarchi 156
     case FSF_FP:
241 giacomo 157
       local_scheduler_level = RMSTAR_register_level(fsf_server_level);
221 giacomo 158
       break;
868 trimarchi 159
     case FSF_NONE:
855 trimarchi 160
       local_scheduler_level = NONESTAR_register_level(fsf_server_level);
334 giacomo 161
       break;
944 trimarchi 162
     case FSF_TABLE_DRIVEN:
163
       kern_printf("Register level");
164
       local_scheduler_level = TDSTAR_register_level(fsf_server_level);
165
       break;
221 giacomo 166
   }    
405 trimarchi 167
 
908 trimarchi 168
   if (contract->d_equals_t == true) {
241 giacomo 169
  *budget = SERVER_setbudget(fsf_server_level,
221 giacomo 170
                              TIMESPEC2USEC(&(contract->budget_min)),
171
                              TIMESPEC2USEC(&(contract->period_max)),
661 giacomo 172
                              TIMESPEC2USEC(&(contract->period_max)),
868 trimarchi 173
                              local_scheduler_level,contract->policy);
661 giacomo 174
  } else {
175
  *budget = SERVER_setbudget(fsf_server_level,
176
                              TIMESPEC2USEC(&(contract->budget_min)),
177
                              TIMESPEC2USEC(&(contract->period_max)),
178
                              TIMESPEC2USEC(&(contract->deadline)),
868 trimarchi 179
                              local_scheduler_level,contract->policy);
661 giacomo 180
  }
221 giacomo 181
 
182
  return 0;
183
 
184
}
185
 
405 trimarchi 186
int adjust_SERVER_budget
187
   (int budget, const TIME budget_actual,
661 giacomo 188
    const TIME period_actual, const TIME dline_actual)
221 giacomo 189
{
190
 
241 giacomo 191
  SERVER_adjust_budget(fsf_server_level,
405 trimarchi 192
                       budget_actual,
193
                       period_actual,
661 giacomo 194
                       dline_actual,
241 giacomo 195
                       budget);
221 giacomo 196
 
197
  return 0;
198
 
199
}
200
 
201
/* Admission Test function */
202
int add_contract(const fsf_contract_parameters_t *contract)
203
{
896 trimarchi 204
  bandwidth_t current_bandwidth,U;
205
 
206
  TIME T,Q;
897 trimarchi 207
 
208
#ifdef FSF_DEBUG
209
  kern_printf("(GA TEST)");
210
#endif                                                                     
896 trimarchi 211
  T=TIMESPEC2USEC(&(contract->period_max));
212
  Q=TIMESPEC2USEC(&(contract->budget_min));
213
 
214
  mul32div32to32(MAX_BANDWIDTH,Q,T,U);
215
   /* The current bandwidth is the min bandwidth */
216
  current_bandwidth=SERVER_return_bandwidth(fsf_server_level);
217
 
897 trimarchi 218
  if (fsf_max_bw<current_bandwidth+U) return -1;
896 trimarchi 219
 
221 giacomo 220
  return 0;
221
 
222
}
223
 
687 trimarchi 224
void contract_to_server(const fsf_contract_parameters_t *contract, int i) {
225
 
410 trimarchi 226
  TIME T,Q;
227
#ifdef FSF_DEBUG
228
  int temp;
229
#endif
230
 
231
  T=TIMESPEC2USEC(&contract->period_min);
232
  Q=TIMESPEC2USEC(&contract->budget_max);
908 trimarchi 233
  server_list[i].Cmax=Q;
234
 
410 trimarchi 235
  mul32div32to32(MAX_BANDWIDTH,Q,T,server_list[current_server].Umax);
236
 
417 giacomo 237
  T=TIMESPEC2USEC(&contract->period_min);
238
  server_list[i].Tmin=T;
239
 
410 trimarchi 240
  T=TIMESPEC2USEC(&contract->period_max);
241
  server_list[i].Tmax=T;
417 giacomo 242
 
410 trimarchi 243
  Q=TIMESPEC2USEC(&contract->budget_min);
244
  server_list[i].Cmin=Q;
245
 
246
  mul32div32to32(MAX_BANDWIDTH,Q,T,server_list[i].Umin);
416 trimarchi 247
  server_list[i].U=server_list[i].Umin;
661 giacomo 248
 
908 trimarchi 249
  if (contract->d_equals_t == true) {
661 giacomo 250
    server_list[i].deadline = 0;
908 trimarchi 251
    server_list[i].d_equals_t = true;
661 giacomo 252
  } else {
253
    server_list[i].deadline = TIMESPEC2USEC(&contract->deadline);;
908 trimarchi 254
    server_list[i].d_equals_t = false;
661 giacomo 255
  }
256
 
843 trimarchi 257
  server_list[i].Qs = contract->quality;
258
  server_list[i].Is = contract->importance;
259
 
410 trimarchi 260
#ifdef FSF_DEBUG
261
  mul32div32to32(server_list[i].Umax,100, MAX_BANDWIDTH, temp);
262
  kern_printf("(Umax %d)",temp);
263
  mul32div32to32(server_list[i].Umin,100, MAX_BANDWIDTH, temp);
264
  kern_printf("(Umin %d)",temp);
265
#endif
266
 
687 trimarchi 267
}
268
 
269
int relink_contract_to_server(const fsf_contract_parameters_t *contract,
270
                              fsf_server_id_t server)
271
{
272
  int i=0;
273
#ifdef FSF_DEBUG
274
  kern_printf("(Relink Server %d)",server);
275
#endif
276
  // find contract
277
  while(i<current_server) {
278
    if (server_list[i].server==server) break;
279
    i++;
280
  }
281
 
282
  server_list[i].server=server;
843 trimarchi 283
//  server_list[i].Qs=1;
687 trimarchi 284
 
285
  contract_to_server(contract, i);
286
 
287
 
410 trimarchi 288
 return 0;
289
 
290
}
291
 
221 giacomo 292
int link_contract_to_server(const fsf_contract_parameters_t *contract,
293
                            fsf_server_id_t server)
294
{
407 giacomo 295
#ifdef FSF_DEBUG
405 trimarchi 296
  kern_printf("(Link Server %d)",server);
297
#endif
298
 
410 trimarchi 299
  server_list[current_server].server=server;
843 trimarchi 300
  //server_list[current_server].Qs=1;
405 trimarchi 301
 
687 trimarchi 302
  contract_to_server(contract,current_server);    
405 trimarchi 303
 
410 trimarchi 304
  current_server++;
221 giacomo 305
  return 0;
306
 
307
}
308
 
309
int remove_contract(fsf_server_id_t server)
310
{
405 trimarchi 311
  int i=0;
312
  // find the contract
410 trimarchi 313
  while(i<current_server) {
405 trimarchi 314
     if (server_list[i].server==server) break;
315
     i++;
316
  }
221 giacomo 317
 
405 trimarchi 318
  // compress the array;
410 trimarchi 319
  while (i<(current_server-1)) {
405 trimarchi 320
     server_list[i].server=server_list[i+1].server;
321
     server_list[i].Umin=server_list[i+1].Umin;
416 trimarchi 322
     server_list[i].U=server_list[i+1].Umin;    
405 trimarchi 323
     server_list[i].Umax=server_list[i+1].Umax;
324
     server_list[i].Cmin=server_list[i+1].Cmin;
908 trimarchi 325
     server_list[i].Cmax=server_list[i+1].Cmax;
417 giacomo 326
     server_list[i].Tmin=server_list[i+1].Tmin;
405 trimarchi 327
     server_list[i].Tmax=server_list[i+1].Tmax;
328
     server_list[i].Qs=server_list[i+1].Qs;
661 giacomo 329
     server_list[i].deadline = server_list[i+1].deadline;
330
     server_list[i].d_equals_t = server_list[i+1].d_equals_t;
843 trimarchi 331
     server_list[i].Is = server_list[i+1].Is;
417 giacomo 332
 
405 trimarchi 333
     i++;
334
  }
410 trimarchi 335
  current_server--;
405 trimarchi 336
 
337
 
221 giacomo 338
  return 0;
339
 
340
}
341
 
868 trimarchi 342
int
343
fsf_get_renegotiation_status
344
  (fsf_server_id_t server,
345
   fsf_renegotiation_status_t *renegotiation_status)
346
{
221 giacomo 347
 
868 trimarchi 348
 if (SERVER_get_renegotiation_status(fsf_server_level,server))
349
   *renegotiation_status=FSF_IN_PROGRESS;
350
 else
351
   *renegotiation_status=FSF_ADMITTED;
352
 
353
 return 0;
354
 
355
 
356
}
357
 
896 trimarchi 358
int
359
fsf_request_change_quality_and_importance
360
  (fsf_server_id_t server,
361
   int new_importance,
362
   int new_quality)
363
{
364
   struct mess m;
868 trimarchi 365
 
896 trimarchi 366
  // send response server is -1 if the operation fail
367
  m.type=CHANGE_PARAMETER;
908 trimarchi 368
  m.server=server;
369
  m.qi.quality = new_quality;
370
  m.qi.importance =  new_importance;
896 trimarchi 371
  //memmove(&m.contract,contract, sizeof(fsf_contract_parameters_t));
372
 
373
  port_send(channel[1],&m,BLOCK);
374
 
375
  port_receive(channel[0], &m, BLOCK);
376
 
377
  if (m.server==-1)
378
    return FSF_ERR_CONTRACT_REJECTED;
379
 
380
  //*server=m.server;
381
 
908 trimarchi 382
  return 0;
896 trimarchi 383
}
384
 
385
 
1008 trimarchi 386
void copy_contract(fsf_contract_parameters_t *contractd, const fsf_contract_parameters_t *contracts) {
387
 
388
  contractd->budget_min=contracts->budget_min;              
389
  contractd->period_max=contracts->period_max;
390
  contractd->budget_max=contracts->budget_max;
391
  contractd->period_min=contracts->period_min;
392
  contractd->workload=contracts->workload;
393
  contractd->d_equals_t=contracts->d_equals_t;
394
  contractd->deadline=contracts->deadline;
395
  contractd->quality=contracts->quality;
396
  contractd->policy=contracts->policy;
397
  /*
398
  int                     budget_overrun_sig_notify;
399
  union sigval            budget_overrun_sig_value;  
400
  int                     deadline_miss_sig_notify;  
401
  union sigval            deadline_miss_sig_value;  
402
 
403
  fsf_granularity_t       granularity;              
404
  fsf_utilization_set_t   utilization_set;          
405
  int                     quality;                  
406
  int                     importance;                
407
 
408
  fsf_preemption_level_t  preemption_level;          
409
  fsf_critical_sections_t critical_sections;        
410
 
411
  fsf_sched_policy_t      policy;                    
412
 
413
  fsf_network_id_t        network_id;                
414
  bool                    granted_capacity_flag;    
415
  */                                                
416
 
417
 
418
}
419
 
221 giacomo 420
int fsf_negotiate_contract
421
  (const fsf_contract_parameters_t *contract,
422
   fsf_server_id_t                 *server)
423
{
880 trimarchi 424
  struct mess m;
221 giacomo 425
 
679 trimarchi 426
  // send response server is -1 if the operation fail
880 trimarchi 427
  m.type=NEGOTIATE_CONTRACT;
1008 trimarchi 428
  copy_contract(&m.contract,contract);
880 trimarchi 429
  port_send(channel[1],&m,BLOCK);
430
  port_receive(channel[0], &m, BLOCK);
963 trimarchi 431
  if (m.server==-1) {
432
    *server=0;
1008 trimarchi 433
    return FSF_ERR_CONTRACT_REJECTED;
963 trimarchi 434
  }
221 giacomo 435
 
880 trimarchi 436
  *server=m.server;
679 trimarchi 437
 
221 giacomo 438
  return 0;
439
 
440
}
441
 
872 trimarchi 442
int
443
fsf_negotiate_contract_for_new_thread
444
  (const fsf_contract_parameters_t *contract,
445
   fsf_server_id_t      *server,
446
   pthread_t            *thread,
447
   pthread_attr_t       *attr,
448
   fsf_thread_code_t     thread_code,
449
   void                 *arg) {
450
 
451
  int err=0;
452
 
453
  err = fsf_negotiate_contract(contract,server);
454
  if (!err) {    
455
    err = pthread_create(thread, attr, thread_code, arg);    
456
    if (!err)
457
      err = fsf_bind_thread_to_server(*server,*thread);
458
  } else return err;
459
 
460
  return err;
461
}
462
 
463
int
464
fsf_negotiate_contract_for_myself
465
  (const fsf_contract_parameters_t *contract,
466
   fsf_server_id_t      *server) {
467
 
468
  int err=0;
469
 
470
  err = fsf_negotiate_contract(contract,server);
471
  if (!err) {
937 trimarchi 472
#ifdef FSF_DEBUG
473
    kern_printf("Bind task");
474
#endif
872 trimarchi 475
     err = fsf_bind_thread_to_server(*server,exec_shadow);
937 trimarchi 476
 
872 trimarchi 477
  } else return err;
478
 
479
  return err;
480
}
481
 
868 trimarchi 482
int fsf_unbind_thread_from_server
483
  (pthread_t       thread)
484
{
485
 
486
  int local_scheduler_level, scheduler_id;
963 trimarchi 487
  SYS_FLAGS f;
868 trimarchi 488
  /* Move thread from the local scheduler module to posix level */
489
 
490
  #ifdef FSF_DEBUG
491
    kern_printf("(UnBind thread = %d)",thread);
492
  #endif
963 trimarchi 493
  f=kern_fsave();
868 trimarchi 494
  /* Check if thread exsists */
963 trimarchi 495
  if (thread == -1) {
496
    kern_frestore(f);
868 trimarchi 497
    return FSF_ERR_BAD_ARGUMENT;
963 trimarchi 498
  }
868 trimarchi 499
 
500
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level,thread);
501
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level,thread);
963 trimarchi 502
 
868 trimarchi 503
  /* Check if thread is already bind */
504
  if (scheduler_id == FSF_NONE) {
505
      /* Check if it is bind to a server */
963 trimarchi 506
    if (NONESTAR_getbudget(local_scheduler_level,thread) == -1) {
507
      kern_frestore(f);
868 trimarchi 508
        return FSF_ERR_BAD_ARGUMENT;
963 trimarchi 509
      }
868 trimarchi 510
      else {
511
 
512
        STD_command_message *msg;
513
        NRT_TASK_MODEL nrt;
514
 
515
        nrt_task_default_model(nrt);
516
        nrt_task_def_save_arrivals(nrt);
963 trimarchi 517
        nrt_task_def_weight(nrt,0);
518
        nrt_task_def_policy(nrt,NRT_RR_POLICY);
519
        nrt_task_def_inherit(nrt,NRT_EXPLICIT_SCHED);
868 trimarchi 520
 
521
        /* Send change level command to local scheduler */
522
        msg = (STD_command_message *)malloc(sizeof(STD_command_message));
523
 
524
        msg->command = STD_SET_NEW_MODEL;
525
        msg->param = (void *)(&nrt);
526
        level_table[fsf_posix_level]->public_message(fsf_posix_level,thread,msg);
527
 
528
        msg->command = STD_SET_NEW_LEVEL;
529
        msg->param = (void *)(fsf_posix_level);
530
        task_message(msg,thread,0);
963 trimarchi 531
        //if (exec_shadow!=thread) 
532
        level_table[proc_table[thread].task_level]->public_epilogue(proc_table[thread].task_level, thread);
533
        //else {
534
        //scheduler();
535
        //kern_context_load(proc_table[exec_shadow].context);
536
        //}
537
        kern_frestore(f);
868 trimarchi 538
 
539
        free(msg);
540
      }
963 trimarchi 541
  } else {
542
    kern_frestore(f);
543
    return FSF_ERR_BAD_ARGUMENT;
868 trimarchi 544
  }
545
 
546
  return 0;
547
 
548
}
549
 
873 trimarchi 550
int  
551
fsf_bind_local_thread_to_server
552
  (fsf_server_id_t      server,
553
   pthread_t            thread,
554
   fsf_sched_params_t  *sched_params)
555
{
868 trimarchi 556
 
873 trimarchi 557
  STD_command_message *msg;
558
  int local_scheduler_level,scheduler_id;
559
 
560
  /* Move thread from the posix module to local scheduler */
561
 
562
  #ifdef FSF_DEBUG 
563
    kern_printf("(Bind thread = %d to Server = %d)",thread,server);
564
  #endif
565
 
566
  /* Check if server and thread exsist */
567
  if (server == -1 || thread == -1)
568
    return FSF_ERR_BAD_ARGUMENT;
569
 
570
  local_scheduler_level = SERVER_get_local_scheduler_level_from_budget(fsf_server_level,server);
571
  if (local_scheduler_level==-1)
952 trimarchi 572
    return FSF_ERR_UNKNOWN_SCHEDULED_THREAD;
873 trimarchi 573
 
574
  scheduler_id = SERVER_get_local_scheduler_id_from_budget(fsf_server_level,server);
881 trimarchi 575
 
576
  if (scheduler_id!=sched_params->policy)
577
     return FSF_ERR_SCHED_POLICY_NOT_COMPATIBLE;
873 trimarchi 578
 
579
  /* Check if thread is already bind */
580
  switch(scheduler_id) {
581
 
952 trimarchi 582
     case FSF_FP:
873 trimarchi 583
       {
881 trimarchi 584
         TASK_MODEL      *m=(TASK_MODEL*)(sched_params->params);
585
         HARD_TASK_MODEL *h=(HARD_TASK_MODEL *)(sched_params->params);
873 trimarchi 586
 
587
         if (m->pclass != HARD_PCLASS)
588
           return FSF_ERR_SCHED_POLICY_NOT_COMPATIBLE;
589
 
590
         h = (HARD_TASK_MODEL *)m;
591
 
592
         if (!h->wcet || !h->mit) return FSF_ERR_SCHED_POLICY_NOT_COMPATIBLE;
593
 
594
         /* now we know that m is a valid model */
595
         if (RMSTAR_getbudget(local_scheduler_level,thread) != -1)
596
           return FSF_ERR_BAD_ARGUMENT;
597
 
598
         /* Set server on local scheduler */
599
         RMSTAR_setbudget(local_scheduler_level,thread,(int)(server));
600
 
601
         /* Send change level command to posix level */
602
       }
877 trimarchi 603
       break;
604
 
873 trimarchi 605
     case FSF_EDF:
606
       {
881 trimarchi 607
         TASK_MODEL      *m=(TASK_MODEL*)(sched_params->params);
608
         HARD_TASK_MODEL *h=(HARD_TASK_MODEL *)(sched_params->params);
873 trimarchi 609
 
610
         if (m->pclass != HARD_PCLASS)
611
           return FSF_ERR_SCHED_POLICY_NOT_COMPATIBLE;
612
 
613
         h = (HARD_TASK_MODEL *)m;
614
 
615
         if (!h->wcet || !h->mit) return FSF_ERR_SCHED_POLICY_NOT_COMPATIBLE;
616
 
617
         if (EDFSTAR_getbudget(local_scheduler_level,thread) != -1)
618
           return FSF_ERR_BAD_ARGUMENT;
619
 
620
         /* Set server on local scheduler */
621
         EDFSTAR_setbudget(local_scheduler_level,thread,(int)(server));
622
 
623
       }
624
       break;
1008 trimarchi 625
 
626
     case FSF_FEDF:
627
       {
628
         TASK_MODEL      *m=(TASK_MODEL*)(sched_params->params);
629
         HARD_TASK_MODEL *h=(HARD_TASK_MODEL *)(sched_params->params);
630
 
631
         if (m->pclass != HARD_PCLASS)
632
           return FSF_ERR_SCHED_POLICY_NOT_COMPATIBLE;
633
 
634
         h = (HARD_TASK_MODEL *)m;
635
 
636
         if (!h->wcet || !h->mit) return FSF_ERR_SCHED_POLICY_NOT_COMPATIBLE;
637
 
638
         if (FEDFSTAR_getbudget(local_scheduler_level,thread) != -1)
639
           return FSF_ERR_BAD_ARGUMENT;
640
 
641
         /* Set server on local scheduler */
642
         FEDFSTAR_setbudget(local_scheduler_level,thread,(int)(server));
643
 
644
       }
873 trimarchi 645
 
952 trimarchi 646
     case FSF_RR:
873 trimarchi 647
       {
881 trimarchi 648
         TASK_MODEL      *m=(TASK_MODEL*)(sched_params->params);
873 trimarchi 649
 
650
         if (m->pclass != NRT_PCLASS)
651
           return  FSF_ERR_SCHED_POLICY_NOT_COMPATIBLE;
652
 
653
         if (POSIXSTAR_getbudget(local_scheduler_level,thread) != -1)
654
           return FSF_ERR_BAD_ARGUMENT;
655
 
656
         /* Set server on local scheduler */
657
         POSIXSTAR_setbudget(local_scheduler_level,thread,(int)(server));        
658
       }
877 trimarchi 659
       break;
873 trimarchi 660
 
877 trimarchi 661
     default:
662
 
873 trimarchi 663
       return FSF_ERR_BAD_ARGUMENT;
877 trimarchi 664
 
873 trimarchi 665
  }
666
 
667
  msg = (STD_command_message *)malloc(sizeof(STD_command_message));
877 trimarchi 668
  if (msg) {
669
    SYS_FLAGS f;
670
    f=kern_fsave();
873 trimarchi 671
    msg->command = STD_SET_NEW_MODEL;
881 trimarchi 672
    msg->param = (void *)(sched_params->params);
873 trimarchi 673
    level_table[local_scheduler_level]->public_message(local_scheduler_level,thread,msg);
674
 
675
    msg->command = STD_SET_NEW_LEVEL;
676
    msg->param = (void *)(local_scheduler_level);
677
    task_message(msg,thread,0);
977 trimarchi 678
    level_table[proc_table[thread].task_level]->public_dispatch(proc_table[thread].task_level, thread, 0);
679
    level_table[proc_table[thread].task_level]->public_epilogue(proc_table[thread].task_level, thread);
680
    //} else {
681
    if (cap_timer != NIL) {
682
      event_delete(cap_timer);
683
      cap_timer = NIL;
684
    }
685
 
940 trimarchi 686
    scheduler();
687
    kern_context_load(proc_table[exec_shadow].context);
977 trimarchi 688
 
877 trimarchi 689
    kern_frestore(f);
873 trimarchi 690
    free(msg);
691
  } else return FSF_ERR_INTERNAL_ERROR;
692
 
693
  return 0;
694
 
695
}
696
 
697
 
868 trimarchi 698
int fsf_bind_thread_to_server
699
  (fsf_server_id_t server,
700
   pthread_t       thread)
701
{
702
 
963 trimarchi 703
  STD_command_message *msg=0;
868 trimarchi 704
  int local_scheduler_level,scheduler_id;
937 trimarchi 705
  SYS_FLAGS f;
868 trimarchi 706
  /* Move thread from the posix module to local scheduler */
707
 
963 trimarchi 708
  f=kern_fsave();
868 trimarchi 709
  #ifdef FSF_DEBUG 
880 trimarchi 710
    kern_printf("(Bthr=%d to Sr=%d)",thread,server);
868 trimarchi 711
  #endif
712
 
713
  /* Check if server and thread exsist */
714
  if (server == -1 || thread == -1)
715
    return FSF_ERR_BAD_ARGUMENT;
716
 
717
  local_scheduler_level = SERVER_get_local_scheduler_level_from_budget(fsf_server_level,server);
873 trimarchi 718
  if (local_scheduler_level==-1)
952 trimarchi 719
    return FSF_ERR_UNKNOWN_SCHEDULED_THREAD;
873 trimarchi 720
 
868 trimarchi 721
  scheduler_id = SERVER_get_local_scheduler_id_from_budget(fsf_server_level,server);
722
  /* Check if thread is already bind */
723
  if (scheduler_id == FSF_NONE) {
724
      DUMMY_TASK_MODEL rt_arg;
963 trimarchi 725
      if (NONESTAR_getbudget(local_scheduler_level,thread) != -1) {
726
        kern_frestore(f);
868 trimarchi 727
        return FSF_ERR_BAD_ARGUMENT;
963 trimarchi 728
      }
868 trimarchi 729
      /* Set server on local scheduler */
730
      NONESTAR_setbudget(local_scheduler_level,thread,(int)(server));
963 trimarchi 731
 
868 trimarchi 732
      /* Send change level command to posix level */
733
      msg = (STD_command_message *)malloc(sizeof(STD_command_message));
963 trimarchi 734
      if (!msg) exit(-1);      
868 trimarchi 735
      msg->command = STD_SET_NEW_MODEL;
736
      msg->param = (void *)(&rt_arg);
937 trimarchi 737
      level_table[local_scheduler_level]->public_message(local_scheduler_level,thread,msg);      
868 trimarchi 738
      msg->command = STD_SET_NEW_LEVEL;
739
      msg->param = (void *)(local_scheduler_level);
963 trimarchi 740
      task_message(msg,thread,0);      
741
      //if (thread!=exec_shadow) {
742
          level_table[proc_table[thread].task_level]->public_dispatch(proc_table[thread].task_level, thread, 0);
743
          level_table[proc_table[thread].task_level]->public_epilogue(proc_table[thread].task_level, thread);
744
      //} else {
745
      if (cap_timer != NIL) {
746
        event_delete(cap_timer);
747
        cap_timer = NIL;
748
      }
749
 
937 trimarchi 750
      scheduler();
751
      kern_context_load(proc_table[exec_shadow].context);
963 trimarchi 752
      //}
937 trimarchi 753
      kern_frestore(f);
754
 
755
 
963 trimarchi 756
      if (msg) free(msg);
937 trimarchi 757
 
963 trimarchi 758
   } else {
759
       kern_frestore(f);
760
       return FSF_ERR_BAD_ARGUMENT;
761
   }
868 trimarchi 762
  return 0;
763
}
764
 
881 trimarchi 765
int fsf_create_local_thread
766
(fsf_server_id_t        server,
767
   fsf_sched_params_t    *local_scheduler_arg,
768
   pthread_t             *thread,
769
   pthread_attr_t        *attr,
770
   fsf_thread_code_t      thread_code,
771
   void                  *arg)
221 giacomo 772
{
773
 
774
  int local_scheduler_level,scheduler_id;
775
 
776
  /* Check if server and thread exsist */
241 giacomo 777
  if (server == NIL)
873 trimarchi 778
    return  FSF_ERR_BAD_ARGUMENT;
221 giacomo 779
 
241 giacomo 780
  local_scheduler_level = SERVER_get_local_scheduler_level_from_budget(fsf_server_level,server);
781
  scheduler_id = SERVER_get_local_scheduler_id_from_budget(fsf_server_level,server);
868 trimarchi 782
#ifdef FSF_DEBUG
783
  kern_printf("sched policy %d", scheduler_id);
784
#endif
888 trimarchi 785
 
786
  if (scheduler_id!=local_scheduler_arg->policy)
787
    return FSF_ERR_SCHED_POLICY_NOT_COMPATIBLE;
788
 
221 giacomo 789
  /* Check if thread is already bind */
790
  switch (scheduler_id) {
952 trimarchi 791
     case FSF_RR:
221 giacomo 792
 
888 trimarchi 793
      nrt_task_def_arg(*(NRT_TASK_MODEL *)(local_scheduler_arg->params),arg);
794
      nrt_task_def_level(*(NRT_TASK_MODEL *)(local_scheduler_arg->params),local_scheduler_level);
221 giacomo 795
 
888 trimarchi 796
      *thread = task_create("POSIXSTAR", thread_code, local_scheduler_arg->params, NULL);
267 giacomo 797
      if (*thread == NIL) {
798
        #ifdef FSF_DEBUG
799
          kern_printf("(FSF:Error creating thread)");
800
        #endif
873 trimarchi 801
        return FSF_ERR_INTERNAL_ERROR;
267 giacomo 802
      }
221 giacomo 803
 
241 giacomo 804
      POSIXSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
234 giacomo 805
 
221 giacomo 806
    break;
868 trimarchi 807
    case FSF_EDF:
221 giacomo 808
 
888 trimarchi 809
      hard_task_def_arg(*(HARD_TASK_MODEL *)(local_scheduler_arg->params),arg);
810
      hard_task_def_level(*(HARD_TASK_MODEL *)(local_scheduler_arg->params),local_scheduler_level);
250 giacomo 811
 
888 trimarchi 812
      *thread = task_create("EDFSTAR", thread_code, local_scheduler_arg->params, NULL);
250 giacomo 813
      if (*thread == NIL)
873 trimarchi 814
        return  FSF_ERR_INTERNAL_ERROR;
250 giacomo 815
 
816
      EDFSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
817
 
221 giacomo 818
      break;
235 giacomo 819
 
1008 trimarchi 820
    case FSF_FEDF:
821
      hard_task_def_arg(*(HARD_TASK_MODEL *)(local_scheduler_arg->params),arg);
822
      hard_task_def_level(*(HARD_TASK_MODEL *)(local_scheduler_arg->params),local_scheduler_level);
823
 
824
      *thread = task_create("FEDFSTAR", thread_code, local_scheduler_arg->params, NULL);
825
      if (*thread == NIL)
826
        return  FSF_ERR_INTERNAL_ERROR;
827
 
828
      FEDFSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
829
 
830
      break;
831
 
952 trimarchi 832
    case FSF_FP:
235 giacomo 833
 
888 trimarchi 834
      hard_task_def_arg(*(HARD_TASK_MODEL *)(local_scheduler_arg->params),arg);
835
      hard_task_def_level(*(HARD_TASK_MODEL *)(local_scheduler_arg->params),local_scheduler_level);
273 giacomo 836
 
888 trimarchi 837
      *thread = task_create("RMSTAR", thread_code, local_scheduler_arg->params, NULL);
273 giacomo 838
      if (*thread == NIL)
873 trimarchi 839
        return  FSF_ERR_INTERNAL_ERROR;
273 giacomo 840
 
841
      RMSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
842
 
843
      break;
868 trimarchi 844
    case FSF_NONE:
334 giacomo 845
 
888 trimarchi 846
      dummy_task_def_arg(*( DUMMY_TASK_MODEL *)(local_scheduler_arg->params),arg);
847
      dummy_task_def_level(*( DUMMY_TASK_MODEL *)(local_scheduler_arg->params),local_scheduler_level);
910 trimarchi 848
 
888 trimarchi 849
      *thread = task_create("NONESTAR", thread_code, local_scheduler_arg->params, NULL);
334 giacomo 850
      if (*thread == NIL)
873 trimarchi 851
        return  FSF_ERR_INTERNAL_ERROR;
334 giacomo 852
 
855 trimarchi 853
      NONESTAR_setbudget(local_scheduler_level, *thread, (int)(server));
334 giacomo 854
 
855
      break;
910 trimarchi 856
 
857
    case FSF_TABLE_DRIVEN:
858
      {
944 trimarchi 859
        HARD_TASK_MODEL ht;
860
        hard_task_default_model(ht);
861
        hard_task_def_aperiodic(ht);
910 trimarchi 862
 
944 trimarchi 863
        hard_task_def_arg(ht,arg);
864
        hard_task_def_level(ht,local_scheduler_level);
910 trimarchi 865
 
944 trimarchi 866
        *thread = task_create("TDSTAR", thread_code, &ht, NULL);
910 trimarchi 867
        if (*thread == NIL)
868
          return  FSF_ERR_INTERNAL_ERROR;
869
 
930 trimarchi 870
        TDSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
944 trimarchi 871
        TDSTAR_settable(local_scheduler_level, (fsf_table_driven_params_t *)(local_scheduler_arg->params),*thread);
910 trimarchi 872
      }
873
      break;
874
 
334 giacomo 875
 
221 giacomo 876
    default:
873 trimarchi 877
      return FSF_ERR_INTERNAL_ERROR;
221 giacomo 878
      break;
879
  }
811 trimarchi 880
 
881
  #ifdef FSF_DEBUG
882
    kern_printf("(FSF:Insert thread = %d to Server = %d)",*thread,server);
883
  #endif
221 giacomo 884
 
885
  return 0;
886
 
887
}
888
 
808 trimarchi 889
int  fsf_settask_nopreemptive
221 giacomo 890
  (fsf_server_id_t *server,
891
   pthread_t       thread)
892
{
893
  int local_scheduler_level, scheduler_id;
894
 
241 giacomo 895
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level,thread);
896
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, thread);
221 giacomo 897
 
898
  switch (scheduler_id) {
952 trimarchi 899
    case FSF_RR:
816 trimarchi 900
      POSIXSTAR_set_nopreemtive_current(local_scheduler_level);
901
      return 1;
808 trimarchi 902
      break;
868 trimarchi 903
    case FSF_EDF:
808 trimarchi 904
      EDFSTAR_set_nopreemtive_current(local_scheduler_level);
905
      return 1;
906
      break;
1008 trimarchi 907
    case FSF_FEDF:
908
      FEDFSTAR_set_nopreemtive_current(local_scheduler_level);
909
      return 1;
910
      break;
911
 
952 trimarchi 912
    case FSF_FP:
812 trimarchi 913
      RMSTAR_set_nopreemtive_current(local_scheduler_level);
914
      return 1;
808 trimarchi 915
      break;
868 trimarchi 916
    case FSF_NONE:
808 trimarchi 917
      break;
918
    default:
919
      return -1;
920
  }
921
  return -1;
922
}
923
 
924
 
925
int  fsf_settask_preemptive
926
  (fsf_server_id_t *server,
927
   pthread_t       thread)
928
{
929
  int local_scheduler_level, scheduler_id;
930
 
931
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level,thread);
932
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, thread);
933
 
934
  switch (scheduler_id) {
952 trimarchi 935
    case FSF_RR:
823 trimarchi 936
      POSIXSTAR_unset_nopreemtive_current(local_scheduler_level);
816 trimarchi 937
      return 1;
808 trimarchi 938
      break;
868 trimarchi 939
    case FSF_EDF:
808 trimarchi 940
      EDFSTAR_unset_nopreemtive_current(local_scheduler_level);
941
      return 1;
942
      break;
1008 trimarchi 943
 
944
    case FSF_FEDF:
945
      EDFSTAR_unset_nopreemtive_current(local_scheduler_level);
946
      return 1;
947
      break;
948
 
952 trimarchi 949
    case FSF_FP:
812 trimarchi 950
      RMSTAR_unset_nopreemtive_current(local_scheduler_level);
951
      return 1;
808 trimarchi 952
      break;
868 trimarchi 953
    case FSF_NONE:
808 trimarchi 954
      break;
955
    default:
956
      return -1;
957
  }
958
 
959
  return -1;
960
 
961
}
962
 
963
 
964
int fsf_get_server
868 trimarchi 965
  (pthread_t       thread,
966
   fsf_server_id_t *server)
808 trimarchi 967
{
968
  int local_scheduler_level, scheduler_id;
969
 
970
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level,thread);
971
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, thread);
972
 
973
  switch (scheduler_id) {
952 trimarchi 974
    case FSF_RR:  
829 giacomo 975
      *server = POSIXSTAR_getbudget(local_scheduler_level,thread);
976
      return 0;
868 trimarchi 977
    case FSF_EDF:
829 giacomo 978
      *server = EDFSTAR_getbudget(local_scheduler_level,thread);
979
      return 0;
1008 trimarchi 980
   case FSF_FEDF:
981
      *server = FEDFSTAR_getbudget(local_scheduler_level,thread);
982
      return 0;
983
 
952 trimarchi 984
    case FSF_FP:
829 giacomo 985
      *server = RMSTAR_getbudget(local_scheduler_level,thread);
986
      return 0;
868 trimarchi 987
    case FSF_NONE:
855 trimarchi 988
      *server = NONESTAR_getbudget(local_scheduler_level,thread);
829 giacomo 989
      return 0;
235 giacomo 990
    default:
221 giacomo 991
      return -1;
992
  }
993
 
994
  return -1;
995
 
996
}
997
 
339 giacomo 998
int fsf_get_server_level(void)
999
{
1000
 
1001
  return fsf_server_level;
1002
 
1003
}
1004
 
221 giacomo 1005
int fsf_cancel_contract
868 trimarchi 1006
  (fsf_server_id_t server)
221 giacomo 1007
{
1008
 
1009
  int local_scheduler_level, scheduler_id;
411 trimarchi 1010
  SYS_FLAGS f;
1011
  TIME T,Q;
963 trimarchi 1012
  int i=0,err=0;
221 giacomo 1013
 
963 trimarchi 1014
 
221 giacomo 1015
  #ifdef FSF_DEBUG
868 trimarchi 1016
    kern_printf("(Remove server %d)",server);
221 giacomo 1017
  #endif
1018
 
1019
  /* Check server id */
868 trimarchi 1020
  if (server < 0)
873 trimarchi 1021
    return FSF_ERR_BAD_ARGUMENT;
221 giacomo 1022
 
868 trimarchi 1023
  local_scheduler_level = SERVER_get_local_scheduler_level_from_budget(fsf_server_level,server);
1024
  scheduler_id = SERVER_get_local_scheduler_id_from_budget(fsf_server_level,server);
221 giacomo 1025
 
1026
  switch (scheduler_id) {
952 trimarchi 1027
    case FSF_RR:
221 giacomo 1028
 
1029
      /* Check if some thread use the server */
868 trimarchi 1030
      if(POSIXSTAR_budget_has_thread(local_scheduler_level,server))
873 trimarchi 1031
        return FSF_ERR_NOT_CONTRACTED_SERVER;
221 giacomo 1032
 
1033
      break;
868 trimarchi 1034
    case FSF_EDF:
235 giacomo 1035
      /* Check if some thread use the server */
868 trimarchi 1036
      if(EDFSTAR_budget_has_thread(local_scheduler_level,server))
873 trimarchi 1037
        return FSF_ERR_NOT_CONTRACTED_SERVER;
235 giacomo 1038
      break;
1039
 
1008 trimarchi 1040
    case FSF_FEDF:
1041
      /* Check if some thread use the server */
1042
      if(FEDFSTAR_budget_has_thread(local_scheduler_level,server))
1043
        return FSF_ERR_NOT_CONTRACTED_SERVER;
1044
      break;
1045
 
952 trimarchi 1046
    case FSF_FP:
235 giacomo 1047
      /* Check if some thread use the server */
868 trimarchi 1048
      if(RMSTAR_budget_has_thread(local_scheduler_level,server))
873 trimarchi 1049
        return FSF_ERR_NOT_CONTRACTED_SERVER;
235 giacomo 1050
 
221 giacomo 1051
      break;
334 giacomo 1052
 
868 trimarchi 1053
    case FSF_NONE:
334 giacomo 1054
      /* Check if some thread use the server */
963 trimarchi 1055
      if(NONESTAR_budget_has_thread(local_scheduler_level,server)) {
1056
        err=fsf_unbind_thread_from_server(NONESTAR_get_current(local_scheduler_level));
1057
        if (err) return err;
1058
      }
334 giacomo 1059
 
1060
      break;
1061
 
221 giacomo 1062
  }
963 trimarchi 1063
 
868 trimarchi 1064
  SERVER_removebudget(fsf_server_level,server);
221 giacomo 1065
 
1066
  level_free_descriptor(local_scheduler_level);
405 trimarchi 1067
 
868 trimarchi 1068
  remove_contract(server);
411 trimarchi 1069
 
1070
  f=kern_fsave();              
1071
  if (recalculate_contract(fsf_max_bw)==-1)  {
1072
       kern_frestore(f);
873 trimarchi 1073
       return  FSF_ERR_INTERNAL_ERROR;
411 trimarchi 1074
  }
1075
#ifdef  FSF_DEBUG
1076
  kern_printf("(Adjust budget)");
1077
#endif    
1078
  for (i=0; i<current_server; i++) {
963 trimarchi 1079
 
411 trimarchi 1080
    mul32div32to32(MAX_BANDWIDTH,server_list[i].Cmin,server_list[i].U,T);
963 trimarchi 1081
 
417 giacomo 1082
    if (T > server_list[i].Tmin ) {
411 trimarchi 1083
      server_list[i].actual_budget = server_list[i].Cmin;
963 trimarchi 1084
 
1085
      if (T > server_list[i].Tmax)
1086
        T=server_list[i].Tmax;
1087
 
411 trimarchi 1088
      server_list[i].actual_period = T;
963 trimarchi 1089
      server_list[i].actual_budget = server_list[i].Cmin;
1090
 
417 giacomo 1091
      #ifdef FSF_DEBUG
1092
        kern_printf("(1 - Q %ld T %ld)", server_list[i].actual_budget, server_list[i].actual_period);
1093
      #endif
963 trimarchi 1094
 
908 trimarchi 1095
      if (server_list[i].d_equals_t == true)
963 trimarchi 1096
        adjust_SERVER_budget(server_list[i].server,server_list[i].Cmin, T, T);
661 giacomo 1097
      else
963 trimarchi 1098
        adjust_SERVER_budget(server_list[i].server,server_list[i].Cmin, T, T); // server_list[i].deadline);
1099
 
411 trimarchi 1100
    } else {
963 trimarchi 1101
 
417 giacomo 1102
      mul32div32to32(server_list[i].Tmin,server_list[i].U,MAX_BANDWIDTH,Q);
963 trimarchi 1103
 
1104
 
1105
      if (Q>server_list[i].Cmax)
1106
        Q=server_list[i].Cmax;
1107
 
411 trimarchi 1108
      server_list[i].actual_budget = Q;
417 giacomo 1109
      server_list[i].actual_period = server_list[i].Tmin;
1110
      #ifdef FSF_DEBUG
1111
         kern_printf("(2 - Q %ld T %ld)", server_list[i].actual_budget, server_list[i].actual_period);
1112
      #endif
661 giacomo 1113
 
908 trimarchi 1114
      if (server_list[i].d_equals_t == true)
963 trimarchi 1115
        adjust_SERVER_budget(server_list[i].server,Q, server_list[i].Tmin, server_list[i].Tmin);
661 giacomo 1116
      else
963 trimarchi 1117
        adjust_SERVER_budget(server_list[i].server,Q, server_list[i].Tmin, server_list[i].Tmin); //server_list[i].deadline);  
661 giacomo 1118
 
963 trimarchi 1119
 
411 trimarchi 1120
    }
416 trimarchi 1121
    server_list[i].U=server_list[i].Umin;
411 trimarchi 1122
 
1123
  }                                          
221 giacomo 1124
 
405 trimarchi 1125
 
411 trimarchi 1126
  kern_frestore(f);
221 giacomo 1127
 
1128
  return 0;
411 trimarchi 1129
 
221 giacomo 1130
}
1131
 
881 trimarchi 1132
bandwidth_t SERVER_return_bandwidth() {
1133
  int i=0;
1134
  bandwidth_t U;
1135
  U=0;
1136
  for(i=0;i<current_server;i++) {
1137
 
1138
    U+=server_list[i].Umin;
1139
 
1140
  }
1141
 
1142
  return U;
1143
}
1144
 
405 trimarchi 1145
int recalculate_contract(bandwidth_t U) {
416 trimarchi 1146
  bandwidth_t current_bandwidth;
418 giacomo 1147
  unsigned int temp_U;
416 trimarchi 1148
  int        Qt;
405 trimarchi 1149
  int isok=0;
1150
  int i=0;
868 trimarchi 1151
  int target_importance=FSF_DEFAULT_IMPORTANCE;
1152
 
1153
#define MAX_IMPORTANCE 5
405 trimarchi 1154
 
896 trimarchi 1155
#ifdef FSF_DEBUG
1156
  int temp;
1157
 
908 trimarchi 1158
  kern_printf("(RC)");
896 trimarchi 1159
#endif
405 trimarchi 1160
 
1161
  /* The current bandwidth is the min bandwidth */
881 trimarchi 1162
  current_bandwidth=SERVER_return_bandwidth(fsf_server_level);
405 trimarchi 1163
  #ifdef FSF_DEBUG
908 trimarchi 1164
     kern_printf("(SER%d)", current_server);
405 trimarchi 1165
  #endif  
880 trimarchi 1166
  //kern_printf("(CS:%d)", current_server); 
405 trimarchi 1167
  do  {
1168
    current_bandwidth=0;
1169
    Qt=0;
410 trimarchi 1170
    for (i=0; i<current_server; i++) {
843 trimarchi 1171
      if (server_list[i].Is==target_importance
1172
          && server_list[i].U<server_list[i].Umax && server_list[i].Qs>0)
405 trimarchi 1173
         Qt+=server_list[i].Qs;
416 trimarchi 1174
       current_bandwidth+=server_list[i].U;
868 trimarchi 1175
#ifdef FSF_DEBUG
843 trimarchi 1176
       kern_printf("(Qs %d, Qt %d, Is %d)", server_list[i].Qs, Qt,server_list[i].Is);
868 trimarchi 1177
#endif
405 trimarchi 1178
    }
413 trimarchi 1179
 
868 trimarchi 1180
#ifdef FSF_DEBUG
908 trimarchi 1181
    kern_printf("(TQ%d)", Qt);
868 trimarchi 1182
#endif
405 trimarchi 1183
    isok=1;
410 trimarchi 1184
    for (i=0; i<current_server; i++) {
843 trimarchi 1185
      if (server_list[i].Is==target_importance && server_list[i].U<server_list[i].Umax && server_list[i].Qs>0) {
416 trimarchi 1186
        temp_U=server_list[i].U;
1187
        server_list[i].U=U-current_bandwidth;
963 trimarchi 1188
        //kern_printf("before mull");
416 trimarchi 1189
        mul32div32to32(server_list[i].U, server_list[i].Qs, Qt, server_list[i].U);
963 trimarchi 1190
        //kern_printf("after mull");
416 trimarchi 1191
        temp_U+=server_list[i].U;
1192
 
1193
        if (temp_U<=server_list[i].Umin) {
405 trimarchi 1194
           server_list[i].U=server_list[i].Umin;
416 trimarchi 1195
        } else if (temp_U>server_list[i].Umax)  {
1196
           server_list[i].U=server_list[i].Umax;
405 trimarchi 1197
           isok=0;
1198
        } else server_list[i].U=temp_U;
1199
 
1200
#ifdef FSF_DEBUG
1201
        mul32div32to32(server_list[i].U,100, MAX_BANDWIDTH, temp);
908 trimarchi 1202
        kern_printf("(SER %d BW %d)", server_list[i].server, temp);
405 trimarchi 1203
#endif 
1204
      }
1205
    }  
843 trimarchi 1206
    target_importance++;
880 trimarchi 1207
  } while (!isok || target_importance<=MAX_IMPORTANCE);
963 trimarchi 1208
 
405 trimarchi 1209
 return 0;
1210
}
1211
 
937 trimarchi 1212
 
1213
int fsf_negotiate_group
1214
   (const fsf_contracts_group_t *contracts_up,
1215
    const fsf_servers_group_t   *severs_down,
1216
    fsf_servers_group_t         *severs_up,
1217
    bool                        *accepted) {
1218
 
1219
  return 0;
1220
}
1221
 
221 giacomo 1222
int fsf_renegotiate_contract
1223
  (const fsf_contract_parameters_t *new_contract,
1224
   fsf_server_id_t server)
1225
{
679 trimarchi 1226
 
908 trimarchi 1227
  struct mess msg;
221 giacomo 1228
 
679 trimarchi 1229
  // send response server is -1 if the operation fail
908 trimarchi 1230
  msg.type=RENEGOTIATE_CONTRACT;
1008 trimarchi 1231
  copy_contract(&msg.contract,new_contract);
908 trimarchi 1232
  msg.server = server;
1233
  //kern_printf("(REN %d)", server);
1234
  port_send(channel[1],&msg,BLOCK);
963 trimarchi 1235
  //kern_printf("After send\n");
908 trimarchi 1236
  port_receive(channel[0], &msg, BLOCK);
963 trimarchi 1237
  //kern_printf("After receive\n");
1238
  //kern_printf("(EREN %d)", msg.server);
908 trimarchi 1239
  if (msg.server==-1) return FSF_ERR_CONTRACT_REJECTED;
679 trimarchi 1240
 
405 trimarchi 1241
   return 0;
221 giacomo 1242
}
241 giacomo 1243
 
868 trimarchi 1244
int fsf_request_contract_renegotiation
1245
  (const fsf_contract_parameters_t *new_contract,
1246
   fsf_server_id_t                  server,
1247
   int                              sig_notify,
1248
   union sigval                     sig_value)
1249
{
1250
 
908 trimarchi 1251
  struct mess msg;
868 trimarchi 1252
 
1253
  // send response server is -1 if the operation fail
908 trimarchi 1254
  msg.type=REQUEST_RENEGOTIATE_CONTRACT;
1008 trimarchi 1255
  copy_contract(&msg.contract,new_contract);
908 trimarchi 1256
  msg.server = server;
910 trimarchi 1257
  msg.sig_notify=sig_notify;
1258
  msg.sig_value=sig_value;
1259
  msg.process=exec_shadow;
868 trimarchi 1260
 
908 trimarchi 1261
  port_send(channel[1],&msg,BLOCK);
868 trimarchi 1262
 
908 trimarchi 1263
  port_receive(channel[0], &msg, BLOCK);
868 trimarchi 1264
 
908 trimarchi 1265
  if (msg.server==-1) return FSF_ERR_CONTRACT_REJECTED;
868 trimarchi 1266
 
1267
   return 0;
1268
}
1269
 
407 giacomo 1270
void print_server_list()
1271
{
1272
 
1273
  int i;
1274
 
1275
  kern_printf("Server List\n");
1276
 
410 trimarchi 1277
  for(i=0;i<current_server;i++) {
407 giacomo 1278
 
662 giacomo 1279
    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 1280
 
1281
  }
1282
 
1283
}
808 trimarchi 1284
 
963 trimarchi 1285
int
1286
fsf_get_remaining_budget
1287
   (fsf_server_id_t server,
1288
    struct timespec *budget)  {
1289
  TIME t;
1290
  NULL_TIMESPEC(budget);
1291
  t=SERVER_get_remain_capacity(fsf_server_level, server);
1292
  ADDUSEC2TIMESPEC(t, budget);
1293
  return 0;
1294
 
1295
 
1296
}
1297
/*
1298
int fsf_get_remaining_budget(fsf_server_id_t server) {
1299
 
825 trimarchi 1300
  return SERVER_get_remain_capacity(fsf_server_level, server);
808 trimarchi 1301
}
963 trimarchi 1302
*/
868 trimarchi 1303
int fsf_get_budget_and_period
1304
   (fsf_server_id_t server,
1305
    struct timespec *budget,
1306
    struct timespec *period) {
1307
  TIME bg;
1308
  TIME pd;
1309
 
1310
  if (!SERVER_getbudgetinfo(fsf_server_level, &bg, &pd, NULL, server)) {
1311
    if (budget) {
1312
      NULL_TIMESPEC(budget);
1313
      ADDUSEC2TIMESPEC(bg, budget);
1314
    }
1315
    if (period) {
1316
      NULL_TIMESPEC(period);
1317
      ADDUSEC2TIMESPEC(pd, period);
1318
    }
1319
 
1320
    return 0;
1321
  }
1322
  return FSF_ERR_BAD_ARGUMENT;
1323
}
1324
 
1325
int
1326
fsf_set_service_thread_data
1327
   (const struct timespec *budget,
1328
    const struct timespec *period,
1329
    bool                  *accepted) {
1330
 
1331
  if (budget==NULL && period==NULL) return FSF_ERR_BAD_ARGUMENT;
1332
  fsf_set_contract_basic_parameters(&service_contract,budget,period,FSF_DEFAULT_WORKLOAD);
1333
  *accepted = !fsf_renegotiate_contract(&service_contract,service_server)?true:false;
1334
  return 0;
1335
 
1336
}
1337
 
1338
 
1339
 
1340
int fsf_get_service_thread_data
1341
   (struct timespec *budget,
1342
    struct timespec *period) {
1343
 
1344
  return fsf_get_budget_and_period(service_server, budget, period);
1345
 
1346
}
944 trimarchi 1347
 
1348
int fsf_init_local_scheduler(fsf_server_id_t server,
1349
                             fsf_sched_init_info_t info)  {
1350
  int scheduler_id, local_scheduler_level;
1351
 
1352
  struct timespec *duration=(struct timespec *)info;
1353
 
1354
  local_scheduler_level=SERVER_get_local_scheduler_level_from_budget(fsf_server_level, server);
1355
  scheduler_id = SERVER_get_local_scheduler_id_from_budget(fsf_server_level,server);
1356
 
1357
  if (scheduler_id!=FSF_TABLE_DRIVEN)
1358
    return FSF_ERR_SCHED_POLICY_NOT_COMPATIBLE;
1359
 
1360
  if (duration->tv_sec < 0 || duration->tv_nsec > 1000000000)
1361
    return FSF_ERR_BAD_ARGUMENT;
1362
 
1363
  //TDSTAR_debugtable(local_scheduler_level);
1364
  TDSTAR_start_simulation(local_scheduler_level);
1365
  return 0;
1366
 
1367
}  
963 trimarchi 1368
 
1369
int
1370
fsf_get_total_quality
1371
(fsf_server_id_t server, int *total_quality) {
996 trimarchi 1372
  int server_importance;
1373
  int i=0,Qt=0;
963 trimarchi 1374
 
996 trimarchi 1375
  while(i<current_server) {
1376
    if (server_list[i].server==server) break;
1377
    i++;
1378
  }
1379
  if (i==current_server) return  FSF_ERR_BAD_ARGUMENT;
1380
  else server_importance=server_list[i].Is;
1381
 
1382
  for (i=0; i<current_server; i++) {
1383
    if (server_list[i].Is==server_importance)
1384
      Qt+=server_list[i].Qs;
1385
  }
1386
 
1387
  return Qt;
963 trimarchi 1388
}
1389
 
1390
int
1391
fsf_get_available_capacity (
1392
    fsf_server_id_t server, uint32_t *capacity){
1393
 
1394
  return 0;
1395
}
1396
 
1397
bool
1398
fsf_is_admission_test_enabled() {
1399
  return true;
1400
}
1401
 
1402
 
1403
int
1404
fsf_get_cpu_time
1405
   (fsf_server_id_t server,
1406
    struct timespec *cpu_time) {
1407
 
1408
  return 0;
1409
}
1410
 
1411
 
1412
int
1413
fsf_get_contract
1414
   (fsf_server_id_t server,
1415
    fsf_contract_parameters_t *contract) {
1416
 
1417
  return 0;
1418
}