Subversion Repositories shark

Rev

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