Subversion Repositories shark

Rev

Rev 661 | Rev 679 | 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"
15
 
221 giacomo 16
#include "fsf_contract.h"
241 giacomo 17
#include "fsf_server.h"
221 giacomo 18
 
19
#include <pthread.h>
20
#include <stdlib.h>
21
 
417 giacomo 22
//#define FSF_DEBUG
221 giacomo 23
 
410 trimarchi 24
int current_server=0;
407 giacomo 25
server_elem server_list[FSF_MAX_N_SERVERS];
406 giacomo 26
bandwidth_t fsf_max_bw = 0;
405 trimarchi 27
 
241 giacomo 28
int fsf_server_level;
221 giacomo 29
 
406 giacomo 30
int FSF_register_module(int server_level, bandwidth_t max_bw)
224 giacomo 31
{
32
  printk("FSF Module\n");
410 trimarchi 33
  current_server=0;
241 giacomo 34
  fsf_server_level = server_level;
406 giacomo 35
  fsf_max_bw = max_bw;
224 giacomo 36
 
37
  return 0;
38
 
39
}
40
 
221 giacomo 41
/* Convert the contract specification to
42
 * budget parameters
43
 */
241 giacomo 44
int set_SERVER_budget_from_contract
221 giacomo 45
  (const fsf_contract_parameters_t *contract,
46
   int *budget)
47
{
48
 
49
  int local_scheduler_level = 0;
50
 
51
   switch (contract->local_scheduler_id) {
52
     case FSF_SCHEDULER_POSIX:
241 giacomo 53
       local_scheduler_level = POSIXSTAR_register_level(fsf_server_level,5000,32);
221 giacomo 54
       break;
55
     case FSF_SCHEDULER_EDF:
241 giacomo 56
       local_scheduler_level = EDFSTAR_register_level(fsf_server_level);
221 giacomo 57
       break;
58
     case FSF_SCHEDULER_RM:
241 giacomo 59
       local_scheduler_level = RMSTAR_register_level(fsf_server_level);
221 giacomo 60
       break;
334 giacomo 61
     case FSF_SCHEDULER_MPEG:
62
       local_scheduler_level = MPEGSTAR_register_level(fsf_server_level);
63
       break;
221 giacomo 64
   }    
405 trimarchi 65
 
661 giacomo 66
   if (contract->d_equals_t == TRUE) {
241 giacomo 67
  *budget = SERVER_setbudget(fsf_server_level,
221 giacomo 68
                              TIMESPEC2USEC(&(contract->budget_min)),
69
                              TIMESPEC2USEC(&(contract->period_max)),
661 giacomo 70
                              TIMESPEC2USEC(&(contract->period_max)),
221 giacomo 71
                              local_scheduler_level,contract->local_scheduler_id);
661 giacomo 72
  } else {
73
  *budget = SERVER_setbudget(fsf_server_level,
74
                              TIMESPEC2USEC(&(contract->budget_min)),
75
                              TIMESPEC2USEC(&(contract->period_max)),
76
                              TIMESPEC2USEC(&(contract->deadline)),
77
                              local_scheduler_level,contract->local_scheduler_id);
78
  }
221 giacomo 79
 
80
  return 0;
81
 
82
}
83
 
405 trimarchi 84
int adjust_SERVER_budget
85
   (int budget, const TIME budget_actual,
661 giacomo 86
    const TIME period_actual, const TIME dline_actual)
221 giacomo 87
{
88
 
241 giacomo 89
  SERVER_adjust_budget(fsf_server_level,
405 trimarchi 90
                       budget_actual,
91
                       period_actual,
661 giacomo 92
                       dline_actual,
241 giacomo 93
                       budget);
221 giacomo 94
 
95
  return 0;
96
 
97
}
98
 
99
/* Admission Test function */
100
int add_contract(const fsf_contract_parameters_t *contract)
101
{
102
  return 0;
103
 
104
}
105
 
410 trimarchi 106
int relink_contract_to_server(const fsf_contract_parameters_t *contract,
107
                              fsf_server_id_t server)
108
{
109
  TIME T,Q;
110
  int i=0;
111
#ifdef FSF_DEBUG
112
  int temp;
113
  kern_printf("(Relink Server %d)",server);
114
#endif
115
  // find contract
116
  while(i<current_server) {
117
    if (server_list[i].server==server) break;
118
    i++;
119
  }
120
 
121
  server_list[i].server=server;
122
  server_list[i].Qs=1;
123
 
124
  T=TIMESPEC2USEC(&contract->period_min);
125
  Q=TIMESPEC2USEC(&contract->budget_max);
126
  mul32div32to32(MAX_BANDWIDTH,Q,T,server_list[current_server].Umax);
127
 
417 giacomo 128
  T=TIMESPEC2USEC(&contract->period_min);
129
  server_list[i].Tmin=T;
130
 
410 trimarchi 131
  T=TIMESPEC2USEC(&contract->period_max);
132
  server_list[i].Tmax=T;
417 giacomo 133
 
410 trimarchi 134
  Q=TIMESPEC2USEC(&contract->budget_min);
135
  server_list[i].Cmin=Q;
136
 
137
  mul32div32to32(MAX_BANDWIDTH,Q,T,server_list[i].Umin);
416 trimarchi 138
  server_list[i].U=server_list[i].Umin;
661 giacomo 139
 
140
  if (contract->d_equals_t == TRUE) {
141
    server_list[i].deadline = 0;
142
    server_list[i].d_equals_t = TRUE;
143
  } else {
144
    server_list[i].deadline = TIMESPEC2USEC(&contract->deadline);;
145
    server_list[i].d_equals_t = FALSE;
146
  }
147
 
410 trimarchi 148
#ifdef FSF_DEBUG
149
  mul32div32to32(server_list[i].Umax,100, MAX_BANDWIDTH, temp);
150
  kern_printf("(Umax %d)",temp);
151
  mul32div32to32(server_list[i].Umin,100, MAX_BANDWIDTH, temp);
152
  kern_printf("(Umin %d)",temp);
153
#endif
154
 
155
 return 0;
156
 
157
}
158
 
221 giacomo 159
int link_contract_to_server(const fsf_contract_parameters_t *contract,
160
                            fsf_server_id_t server)
161
{
405 trimarchi 162
  TIME T,Q;
407 giacomo 163
#ifdef FSF_DEBUG
405 trimarchi 164
  int temp;
407 giacomo 165
 
405 trimarchi 166
  kern_printf("(Link Server %d)",server);
167
#endif
168
 
410 trimarchi 169
  server_list[current_server].server=server;
170
  server_list[current_server].Qs=1;
405 trimarchi 171
 
172
  T=TIMESPEC2USEC(&contract->period_min);
173
  Q=TIMESPEC2USEC(&contract->budget_max);
410 trimarchi 174
  mul32div32to32(MAX_BANDWIDTH,Q,T,server_list[current_server].Umax);
405 trimarchi 175
 
417 giacomo 176
  T=TIMESPEC2USEC(&contract->period_min);
177
  server_list[current_server].Tmin=T;
178
 
405 trimarchi 179
  T=TIMESPEC2USEC(&contract->period_max);
410 trimarchi 180
  server_list[current_server].Tmax=T;
405 trimarchi 181
 
182
  Q=TIMESPEC2USEC(&contract->budget_min);
410 trimarchi 183
  server_list[current_server].Cmin=Q;
405 trimarchi 184
 
410 trimarchi 185
  mul32div32to32(MAX_BANDWIDTH,Q,T,server_list[current_server].Umin);
416 trimarchi 186
  server_list[current_server].U=server_list[current_server].Umin;
221 giacomo 187
 
661 giacomo 188
  if (contract->d_equals_t == TRUE) {
189
    server_list[current_server].deadline = 0;
190
    server_list[current_server].d_equals_t = TRUE;
191
  } else {
192
    server_list[current_server].deadline = TIMESPEC2USEC(&contract->deadline);
193
    server_list[current_server].d_equals_t = FALSE;
194
  }
195
 
405 trimarchi 196
#ifdef FSF_DEBUG
410 trimarchi 197
  mul32div32to32(server_list[current_server].Umax,100, MAX_BANDWIDTH, temp);
405 trimarchi 198
  kern_printf("(Umax %d)",temp);
410 trimarchi 199
  mul32div32to32(server_list[current_server].Umin,100, MAX_BANDWIDTH, temp);
405 trimarchi 200
  kern_printf("(Umin %d)",temp);
201
#endif
202
 
203
 
410 trimarchi 204
  current_server++;
221 giacomo 205
  return 0;
206
 
207
}
208
 
209
int remove_contract(fsf_server_id_t server)
210
{
405 trimarchi 211
  int i=0;
212
  // find the contract
410 trimarchi 213
  while(i<current_server) {
405 trimarchi 214
     if (server_list[i].server==server) break;
215
     i++;
216
  }
221 giacomo 217
 
405 trimarchi 218
  // compress the array;
410 trimarchi 219
  while (i<(current_server-1)) {
405 trimarchi 220
     server_list[i].server=server_list[i+1].server;
221
     server_list[i].Umin=server_list[i+1].Umin;
416 trimarchi 222
     server_list[i].U=server_list[i+1].Umin;    
405 trimarchi 223
     server_list[i].Umax=server_list[i+1].Umax;
224
     server_list[i].Cmin=server_list[i+1].Cmin;
417 giacomo 225
     server_list[i].Tmin=server_list[i+1].Tmin;
405 trimarchi 226
     server_list[i].Tmax=server_list[i+1].Tmax;
227
     server_list[i].Qs=server_list[i+1].Qs;
661 giacomo 228
     server_list[i].deadline = server_list[i+1].deadline;
229
     server_list[i].d_equals_t = server_list[i+1].d_equals_t;
417 giacomo 230
 
405 trimarchi 231
     i++;
232
  }
410 trimarchi 233
  current_server--;
405 trimarchi 234
 
235
 
221 giacomo 236
  return 0;
237
 
238
}
239
 
240
 
241
int fsf_negotiate_contract
242
  (const fsf_contract_parameters_t *contract,
243
   fsf_server_id_t                 *server)
244
{
405 trimarchi 245
  SYS_FLAGS f;
246
  int i=0;
247
  TIME T;
248
  TIME Q;
221 giacomo 249
  /* Check if contract is initialized */
250
  if (!contract) return FSF_ERR_NOT_INITIALIZED;
251
 
252
  /* Admission Test */
253
  if (FSF_ADMISSION_TEST_IS_ENABLED)
254
    if (add_contract(contract))
255
      return FSF_ERR_CONTRACT_REJECTED;
405 trimarchi 256
  f = kern_fsave();
221 giacomo 257
 
241 giacomo 258
  /* SERVER => BUDGET */    
259
  set_SERVER_budget_from_contract(contract,server);
221 giacomo 260
 
261
  #ifdef FSF_DEBUG
262
    kern_printf("(New Server %d)",*server);
263
  #endif
264
 
405 trimarchi 265
  if (*server >= 0) {
221 giacomo 266
    link_contract_to_server(contract,*server);
406 giacomo 267
    if (recalculate_contract(fsf_max_bw)==-1)  {
405 trimarchi 268
       kern_frestore(f);
269
       return FSF_ERR_CREATE_SERVER;
270
    }
271
#ifdef  FSF_DEBUG
272
    kern_printf("(Adjust budget)");
273
#endif    
410 trimarchi 274
    for (i=0; i<current_server; i++) {
405 trimarchi 275
       mul32div32to32(MAX_BANDWIDTH,server_list[i].Cmin,server_list[i].U,T);
417 giacomo 276
       if (T > server_list[i].Tmin ) {
277
          server_list[i].actual_budget = server_list[i].Cmin;
278
          server_list[i].actual_period = T;
405 trimarchi 279
       #ifdef FSF_DEBUG
417 giacomo 280
          kern_printf("(1 - Q %ld T %ld)", server_list[i].actual_budget, server_list[i].actual_period);
405 trimarchi 281
       #endif
417 giacomo 282
 
661 giacomo 283
          if (server_list[i].d_equals_t == TRUE)
284
            adjust_SERVER_budget(server_list[i].server,server_list[i].Cmin, T , T);
285
          else
286
            adjust_SERVER_budget(server_list[i].server,server_list[i].Cmin, T , server_list[i].deadline);
287
 
407 giacomo 288
       } else {
417 giacomo 289
         mul32div32to32(server_list[i].Tmin,server_list[i].U,MAX_BANDWIDTH,Q);
407 giacomo 290
         server_list[i].actual_budget = Q;
417 giacomo 291
         server_list[i].actual_period = server_list[i].Tmin;
292
       #ifdef FSF_DEBUG
293
          kern_printf("(2 - Q %ld T %ld)", server_list[i].actual_budget, server_list[i].actual_period);
294
       #endif
295
 
661 giacomo 296
          if (server_list[i].d_equals_t == TRUE)
297
            adjust_SERVER_budget(server_list[i].server,Q, server_list[i].Tmin , server_list[i].Tmin);
298
          else
299
            adjust_SERVER_budget(server_list[i].server,Q, server_list[i].Tmin , server_list[i].deadline);
405 trimarchi 300
 
661 giacomo 301
        }
417 giacomo 302
 
661 giacomo 303
 
417 giacomo 304
       server_list[i].U=server_list[i].Umin;
305
 
405 trimarchi 306
    }
307
  }
308
  else  {
309
    kern_frestore(f);
221 giacomo 310
    return FSF_ERR_CREATE_SERVER;
405 trimarchi 311
  }
312
  kern_frestore(f);
313
 
221 giacomo 314
  return 0;
315
 
316
}
317
 
241 giacomo 318
int fsf_create_thread
319
  (fsf_server_id_t    server,
320
   pthread_t         *thread,
321
   pthread_attr_t    *attr,
322
   fsf_thread_code_t  thread_code,
323
   void              *arg,
324
   void              *local_scheduler_arg)
221 giacomo 325
{
326
 
327
  int local_scheduler_level,scheduler_id;
328
 
329
  #ifdef FSF_DEBUG 
267 giacomo 330
    kern_printf("(FSF:Insert thread = %d to Server = %d)",*thread,server);
221 giacomo 331
  #endif
332
 
333
  /* Check if server and thread exsist */
241 giacomo 334
  if (server == NIL)
335
    return FSF_ERR_INVALID_SERVER;
221 giacomo 336
 
241 giacomo 337
  local_scheduler_level = SERVER_get_local_scheduler_level_from_budget(fsf_server_level,server);
338
  scheduler_id = SERVER_get_local_scheduler_id_from_budget(fsf_server_level,server);
221 giacomo 339
 
340
  /* Check if thread is already bind */
341
  switch (scheduler_id) {
342
    case FSF_SCHEDULER_POSIX:
343
 
298 giacomo 344
      nrt_task_def_arg(*(NRT_TASK_MODEL *)(local_scheduler_arg),arg);
345
      nrt_task_def_level(*(NRT_TASK_MODEL *)(local_scheduler_arg),local_scheduler_level);
221 giacomo 346
 
298 giacomo 347
      *thread = task_create("POSIXSTAR", thread_code, local_scheduler_arg, NULL);
267 giacomo 348
      if (*thread == NIL) {
349
        #ifdef FSF_DEBUG
350
          kern_printf("(FSF:Error creating thread)");
351
        #endif
241 giacomo 352
        return FSF_ERR_CREATE_THREAD;
267 giacomo 353
      }
221 giacomo 354
 
241 giacomo 355
      POSIXSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
234 giacomo 356
 
221 giacomo 357
    break;
358
    case FSF_SCHEDULER_EDF:
359
 
250 giacomo 360
      hard_task_def_arg(*(HARD_TASK_MODEL *)(local_scheduler_arg),arg);
361
      hard_task_def_level(*(HARD_TASK_MODEL *)(local_scheduler_arg),local_scheduler_level);
362
 
363
      *thread = task_create("EDFSTAR", thread_code, local_scheduler_arg, NULL);
364
      if (*thread == NIL)
365
        return FSF_ERR_CREATE_THREAD;
366
 
367
      EDFSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
368
 
221 giacomo 369
      break;
235 giacomo 370
 
221 giacomo 371
    case FSF_SCHEDULER_RM:
235 giacomo 372
 
273 giacomo 373
      hard_task_def_arg(*(HARD_TASK_MODEL *)(local_scheduler_arg),arg);
374
      hard_task_def_level(*(HARD_TASK_MODEL *)(local_scheduler_arg),local_scheduler_level);
375
 
376
      *thread = task_create("RMSTAR", thread_code, local_scheduler_arg, NULL);
377
      if (*thread == NIL)
378
        return FSF_ERR_CREATE_THREAD;
379
 
380
      RMSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
381
 
382
      break;
334 giacomo 383
    case FSF_SCHEDULER_MPEG:
384
 
385
      hard_task_def_arg(*(HARD_TASK_MODEL *)(local_scheduler_arg),arg);
386
      hard_task_def_level(*(HARD_TASK_MODEL *)(local_scheduler_arg),local_scheduler_level);
387
 
338 giacomo 388
      *thread = task_create("MPEGSTAR", thread_code, local_scheduler_arg, NULL);
334 giacomo 389
      if (*thread == NIL)
390
        return FSF_ERR_CREATE_THREAD;
391
 
392
      MPEGSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
393
 
394
      break;
395
 
221 giacomo 396
    default:
241 giacomo 397
      return FSF_ERR_INVALID_SERVER;
221 giacomo 398
      break;
399
  }
400
 
401
  return 0;
402
 
403
}
404
 
405
int fsf_get_server
406
  (fsf_server_id_t *server,
407
   pthread_t       thread)
408
{
409
  int local_scheduler_level, scheduler_id;
410
 
241 giacomo 411
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level,thread);
412
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, thread);
221 giacomo 413
 
414
  switch (scheduler_id) {
415
    case FSF_SCHEDULER_POSIX:  
416
      return POSIXSTAR_getbudget(local_scheduler_level,thread);
417
    case FSF_SCHEDULER_EDF:
235 giacomo 418
      return EDFSTAR_getbudget(local_scheduler_level,thread);
221 giacomo 419
    case FSF_SCHEDULER_RM:
235 giacomo 420
      return RMSTAR_getbudget(local_scheduler_level,thread);
334 giacomo 421
    case FSF_SCHEDULER_MPEG:
422
      return MPEGSTAR_getbudget(local_scheduler_level,thread);
235 giacomo 423
    default:
221 giacomo 424
      return -1;
425
  }
426
 
427
  return -1;
428
 
429
}
430
 
339 giacomo 431
int fsf_get_server_level(void)
432
{
433
 
434
  return fsf_server_level;
435
 
436
}
437
 
221 giacomo 438
int fsf_cancel_contract
439
  (fsf_server_id_t *server)
440
{
441
 
442
  int local_scheduler_level, scheduler_id;
411 trimarchi 443
  SYS_FLAGS f;
444
  TIME T,Q;
445
  int i=0;
221 giacomo 446
 
447
  #ifdef FSF_DEBUG
448
    kern_printf("(Remove server %d)",*server);
449
  #endif
450
 
451
  /* Check server id */
452
  if (*server < 0)
453
    return FSF_ERR_INVALID_SERVER;
454
 
241 giacomo 455
  local_scheduler_level = SERVER_get_local_scheduler_level_from_budget(fsf_server_level,*server);
456
  scheduler_id = SERVER_get_local_scheduler_id_from_budget(fsf_server_level,*server);
221 giacomo 457
 
458
  switch (scheduler_id) {
459
    case FSF_SCHEDULER_POSIX:
460
 
461
      /* Check if some thread use the server */
462
      if(POSIXSTAR_budget_has_thread(local_scheduler_level,*server))
463
        return FSF_ERR_SERVER_USED;
464
 
465
      break;
466
    case FSF_SCHEDULER_EDF:
235 giacomo 467
      /* Check if some thread use the server */
468
      if(EDFSTAR_budget_has_thread(local_scheduler_level,*server))
469
        return FSF_ERR_SERVER_USED;
470
      break;
471
 
221 giacomo 472
    case FSF_SCHEDULER_RM:
235 giacomo 473
      /* Check if some thread use the server */
474
      if(RMSTAR_budget_has_thread(local_scheduler_level,*server))
475
        return FSF_ERR_SERVER_USED;
476
 
221 giacomo 477
      break;
334 giacomo 478
 
479
    case FSF_SCHEDULER_MPEG:
480
      /* Check if some thread use the server */
481
      if(MPEGSTAR_budget_has_thread(local_scheduler_level,*server))
482
        return FSF_ERR_SERVER_USED;
483
 
484
      break;
485
 
221 giacomo 486
  }
487
 
241 giacomo 488
  SERVER_removebudget(fsf_server_level,*server);
221 giacomo 489
 
490
  level_free_descriptor(local_scheduler_level);
405 trimarchi 491
 
221 giacomo 492
  remove_contract(*server);
411 trimarchi 493
 
494
  f=kern_fsave();              
495
  if (recalculate_contract(fsf_max_bw)==-1)  {
496
       kern_frestore(f);
497
       return FSF_ERR_CREATE_SERVER;
498
  }
499
#ifdef  FSF_DEBUG
500
  kern_printf("(Adjust budget)");
501
#endif    
502
  for (i=0; i<current_server; i++) {
503
    mul32div32to32(MAX_BANDWIDTH,server_list[i].Cmin,server_list[i].U,T);
417 giacomo 504
    if (T > server_list[i].Tmin ) {
411 trimarchi 505
      server_list[i].actual_budget = server_list[i].Cmin;
506
      server_list[i].actual_period = T;
417 giacomo 507
      #ifdef FSF_DEBUG
508
        kern_printf("(1 - Q %ld T %ld)", server_list[i].actual_budget, server_list[i].actual_period);
509
      #endif
661 giacomo 510
 
511
      if (server_list[i].d_equals_t == TRUE)
512
        adjust_SERVER_budget(server_list[i].server,server_list[i].Cmin, T, T);
513
      else
514
        adjust_SERVER_budget(server_list[i].server,server_list[i].Cmin, T, server_list[i].deadline);
515
 
411 trimarchi 516
    } else {
417 giacomo 517
      mul32div32to32(server_list[i].Tmin,server_list[i].U,MAX_BANDWIDTH,Q);
411 trimarchi 518
      server_list[i].actual_budget = Q;
417 giacomo 519
      server_list[i].actual_period = server_list[i].Tmin;
520
      #ifdef FSF_DEBUG
521
         kern_printf("(2 - Q %ld T %ld)", server_list[i].actual_budget, server_list[i].actual_period);
522
      #endif
661 giacomo 523
 
524
      if (server_list[i].d_equals_t == TRUE)
525
        adjust_SERVER_budget(server_list[i].server,Q, server_list[i].Tmin, server_list[i].Tmin);
526
      else
527
        adjust_SERVER_budget(server_list[i].server,Q, server_list[i].Tmin, server_list[i].deadline);
528
 
411 trimarchi 529
    }
416 trimarchi 530
    server_list[i].U=server_list[i].Umin;
411 trimarchi 531
 
532
  }                                          
221 giacomo 533
 
405 trimarchi 534
 
221 giacomo 535
  *server = -1;
411 trimarchi 536
  kern_frestore(f);
221 giacomo 537
 
538
  return 0;
411 trimarchi 539
 
221 giacomo 540
}
541
 
405 trimarchi 542
int recalculate_contract(bandwidth_t U) {
416 trimarchi 543
  bandwidth_t current_bandwidth;
418 giacomo 544
  unsigned int temp_U;
416 trimarchi 545
  int        Qt;
405 trimarchi 546
  int isok=0;
547
  int i=0;
548
 
407 giacomo 549
  #ifdef FSF_DEBUG
550
    int temp;
551
 
552
    kern_printf("(Recalculate contract)");
553
  #endif
405 trimarchi 554
 
555
  /* The current bandwidth is the min bandwidth */
556
  //current_bandwidth=SERVER_return_bandwidth(fsf_server_level);
557
  #ifdef FSF_DEBUG
410 trimarchi 558
     kern_printf("(nserver %d)", current_server);
405 trimarchi 559
  #endif  
560
 
561
  do  {
562
    current_bandwidth=0;
563
    Qt=0;
410 trimarchi 564
    for (i=0; i<current_server; i++) {
416 trimarchi 565
      if (server_list[i].Qs!=0 && server_list[i].U<server_list[i].Umax)
405 trimarchi 566
         Qt+=server_list[i].Qs;
416 trimarchi 567
       current_bandwidth+=server_list[i].U;
405 trimarchi 568
    }
413 trimarchi 569
 
405 trimarchi 570
    #ifdef FSF_DEBUG
571
    kern_printf("(Total Quality %d)", Qt);
572
    #endif
573
    isok=1;
410 trimarchi 574
    for (i=0; i<current_server; i++) {
416 trimarchi 575
      if (server_list[i].Qs!=0 && server_list[i].U<server_list[i].Umax) {
576
        temp_U=server_list[i].U;
577
        server_list[i].U=U-current_bandwidth;
578
        mul32div32to32(server_list[i].U, server_list[i].Qs, Qt, server_list[i].U);
579
        temp_U+=server_list[i].U;
580
 
581
        if (temp_U<=server_list[i].Umin) {
405 trimarchi 582
           server_list[i].U=server_list[i].Umin;
416 trimarchi 583
        } else if (temp_U>server_list[i].Umax)  {
584
           server_list[i].U=server_list[i].Umax;
405 trimarchi 585
           isok=0;
586
        } else server_list[i].U=temp_U;
587
 
588
#ifdef FSF_DEBUG
589
        mul32div32to32(server_list[i].U,100, MAX_BANDWIDTH, temp);
590
        kern_printf("(Server %d bw %d)", server_list[i].server, temp);
591
#endif 
592
      }
593
    }  
594
 
595
  } while (!isok);
596
 
597
 return 0;
598
}
599
 
600
 
221 giacomo 601
int fsf_renegotiate_contract
602
  (const fsf_contract_parameters_t *new_contract,
603
   fsf_server_id_t server)
604
{
410 trimarchi 605
  SYS_FLAGS f;
606
  TIME T,Q;
607
  int i;
608
 
221 giacomo 609
  #ifdef FSF_DEBUG
610
    kern_printf("(Renegotiate for server %d)",server);
611
  #endif
612
 
613
  if (!new_contract)
614
    return FSF_ERR_NOT_INITIALIZED;
615
 
616
  if (server < 0)
617
    return FSF_ERR_INVALID_SERVER;
405 trimarchi 618
  // compute the new value
619
   f = kern_fsave();
410 trimarchi 620
   // change the parameter
621
   relink_contract_to_server(new_contract, server);
406 giacomo 622
   if (recalculate_contract(fsf_max_bw)==-1)  {
405 trimarchi 623
       kern_frestore(f);
624
       return FSF_ERR_CREATE_SERVER;
625
   }
406 giacomo 626
 
410 trimarchi 627
   for (i=0; i<current_server; i++) {
417 giacomo 628
      mul32div32to32(MAX_BANDWIDTH,server_list[i].Cmin,server_list[i].U,T);
629
      if (T > server_list[i].Tmin ) {
630
         server_list[i].actual_budget = server_list[i].Cmin;
631
         server_list[i].actual_period = T;
632
      #ifdef FSF_DEBUG
633
         kern_printf("(1 - Q %ld T %ld)", server_list[i].actual_budget, server_list[i].actual_period);
634
      #endif
661 giacomo 635
         if (server_list[i].d_equals_t == TRUE)
636
           adjust_SERVER_budget(server_list[i].server,server_list[i].Cmin, T, T);
637
         else
638
           adjust_SERVER_budget(server_list[i].server,server_list[i].Cmin, T, server_list[i].deadline);
639
 
417 giacomo 640
      } else {
641
        mul32div32to32(server_list[i].Tmin,server_list[i].U,MAX_BANDWIDTH,Q);
642
        server_list[i].actual_budget = Q;
643
        server_list[i].actual_period = server_list[i].Tmin;
644
      #ifdef FSF_DEBUG
645
         kern_printf("(2 - Q %ld T %ld)", server_list[i].actual_budget, server_list[i].actual_period);
646
      #endif
661 giacomo 647
 
648
         if (server_list[i].d_equals_t == TRUE)
649
           adjust_SERVER_budget(server_list[i].server,server_list[i].Cmin, server_list[i].Tmin, server_list[i].Tmin);
650
         else
651
           adjust_SERVER_budget(server_list[i].server,server_list[i].Cmin, server_list[i].Tmin, server_list[i].deadline);                                                                                                        
410 trimarchi 652
     }
417 giacomo 653
 
416 trimarchi 654
     server_list[i].U=server_list[i].Umin;
410 trimarchi 655
   }
405 trimarchi 656
   kern_frestore(f);
657
   return 0;
221 giacomo 658
}
241 giacomo 659
 
407 giacomo 660
void print_server_list()
661
{
662
 
663
  int i;
664
 
665
  kern_printf("Server List\n");
666
 
410 trimarchi 667
  for(i=0;i<current_server;i++) {
407 giacomo 668
 
662 giacomo 669
    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 670
 
671
  }
672
 
673
}