Subversion Repositories shark

Rev

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