Subversion Repositories shark

Rev

Rev 896 | Rev 908 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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