Subversion Repositories shark

Rev

Rev 1008 | Details | Compare with Previous | Last modification | View Log | RSS feed

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