Subversion Repositories shark

Rev

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