Subversion Repositories shark

Rev

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