Subversion Repositories shark

Rev

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