Subversion Repositories shark

Rev

Rev 346 | Rev 406 | 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
 
22
 
405 trimarchi 23
#define FSF_DEBUG
24
int current=0;
25
server_elem server_list[MAX_PROC];
26
bandwidth_t min_bandwidth=0;
27
 
241 giacomo 28
int fsf_server_level;
221 giacomo 29
 
241 giacomo 30
int FSF_register_module(int server_level)
224 giacomo 31
{
32
  printk("FSF Module\n");
405 trimarchi 33
  current=0;
241 giacomo 34
  fsf_server_level = server_level;
224 giacomo 35
 
36
  return 0;
37
 
38
}
39
 
221 giacomo 40
/* Convert the contract specification to
41
 * budget parameters
42
 */
241 giacomo 43
int set_SERVER_budget_from_contract
221 giacomo 44
  (const fsf_contract_parameters_t *contract,
45
   int *budget)
46
{
47
 
48
  int local_scheduler_level = 0;
49
 
50
   switch (contract->local_scheduler_id) {
51
     case FSF_SCHEDULER_POSIX:
241 giacomo 52
       local_scheduler_level = POSIXSTAR_register_level(fsf_server_level,5000,32);
221 giacomo 53
       break;
54
     case FSF_SCHEDULER_EDF:
241 giacomo 55
       local_scheduler_level = EDFSTAR_register_level(fsf_server_level);
221 giacomo 56
       break;
57
     case FSF_SCHEDULER_RM:
241 giacomo 58
       local_scheduler_level = RMSTAR_register_level(fsf_server_level);
221 giacomo 59
       break;
334 giacomo 60
     case FSF_SCHEDULER_MPEG:
61
       local_scheduler_level = MPEGSTAR_register_level(fsf_server_level);
62
       break;
221 giacomo 63
   }    
405 trimarchi 64
 
241 giacomo 65
  *budget = SERVER_setbudget(fsf_server_level,
221 giacomo 66
                              TIMESPEC2USEC(&(contract->budget_min)),
67
                              TIMESPEC2USEC(&(contract->period_max)),
68
                              local_scheduler_level,contract->local_scheduler_id);
69
 
70
  return 0;
71
 
72
}
73
 
405 trimarchi 74
int adjust_SERVER_budget
75
   (int budget, const TIME budget_actual,
76
    const TIME period_actual)
221 giacomo 77
{
78
 
241 giacomo 79
  SERVER_adjust_budget(fsf_server_level,
405 trimarchi 80
                       budget_actual,
81
                       period_actual,
241 giacomo 82
                       budget);
221 giacomo 83
 
84
  return 0;
85
 
86
}
87
 
88
/* Admission Test function */
89
int add_contract(const fsf_contract_parameters_t *contract)
90
{
91
  return 0;
92
 
93
}
94
 
95
int link_contract_to_server(const fsf_contract_parameters_t *contract,
96
                            fsf_server_id_t server)
97
{
405 trimarchi 98
  TIME T,Q;
99
  int temp;
100
#ifdef FSF_DEBUG
101
  kern_printf("(Link Server %d)",server);
102
#endif
103
 
104
  server_list[current].server=server;
105
  server_list[current].Qs=1;
106
 
107
  T=TIMESPEC2USEC(&contract->period_min);
108
  Q=TIMESPEC2USEC(&contract->budget_max);
109
  mul32div32to32(MAX_BANDWIDTH,Q,T,server_list[current].Umax);
110
 
111
  T=TIMESPEC2USEC(&contract->period_max);
112
  server_list[current].Tmax=T;
113
 
114
  Q=TIMESPEC2USEC(&contract->budget_min);
115
  server_list[current].Cmin=Q;
116
 
117
  mul32div32to32(MAX_BANDWIDTH,Q,T,server_list[current].Umin);
118
  min_bandwidth+=server_list[current].Umin;
119
  server_list[current].U=server_list[current].Umax;
221 giacomo 120
 
405 trimarchi 121
#ifdef FSF_DEBUG
122
  mul32div32to32(server_list[current].Umax,100, MAX_BANDWIDTH, temp);
123
  kern_printf("(Umax %d)",temp);
124
  mul32div32to32(server_list[current].Umin,100, MAX_BANDWIDTH, temp);
125
  kern_printf("(Umin %d)",temp);
126
#endif
127
 
128
 
129
  current++;
221 giacomo 130
  return 0;
131
 
132
}
133
 
134
int remove_contract(fsf_server_id_t server)
135
{
405 trimarchi 136
  int i=0;
137
  // find the contract
138
  while(i<current) {
139
     if (server_list[i].server==server) break;
140
     i++;
141
  }
221 giacomo 142
 
405 trimarchi 143
  // compress the array;
144
  while (i<(current-1)) {
145
     server_list[i].server=server_list[i+1].server;
146
     TIMESPEC_ASSIGN(&(server_list[i+1].budget_actual), &(server_list[i].budget_actual));
147
     TIMESPEC_ASSIGN(&(server_list[i+1].period_actual), &(server_list[i].period_actual));
148
     server_list[i].Umin=server_list[i+1].Umin;
149
     server_list[i].U=server_list[i+1].U;    
150
     server_list[i].Umax=server_list[i+1].Umax;
151
     server_list[i].Cmin=server_list[i+1].Cmin;
152
     server_list[i].Tmax=server_list[i+1].Tmax;
153
     server_list[i].Qs=server_list[i+1].Qs;
154
     i++;
155
  }
156
  current--;
157
 
158
 
221 giacomo 159
  return 0;
160
 
161
}
162
 
163
 
164
int fsf_negotiate_contract
165
  (const fsf_contract_parameters_t *contract,
166
   fsf_server_id_t                 *server)
167
{
405 trimarchi 168
  SYS_FLAGS f;
169
  int i=0;
170
  TIME T;
171
  TIME Q;
221 giacomo 172
  /* Check if contract is initialized */
173
  if (!contract) return FSF_ERR_NOT_INITIALIZED;
174
 
175
  /* Admission Test */
176
  if (FSF_ADMISSION_TEST_IS_ENABLED)
177
    if (add_contract(contract))
178
      return FSF_ERR_CONTRACT_REJECTED;
405 trimarchi 179
  f = kern_fsave();
221 giacomo 180
 
241 giacomo 181
  /* SERVER => BUDGET */    
182
  set_SERVER_budget_from_contract(contract,server);
221 giacomo 183
 
184
  #ifdef FSF_DEBUG
185
    kern_printf("(New Server %d)",*server);
186
  #endif
187
 
405 trimarchi 188
  if (*server >= 0) {
221 giacomo 189
    link_contract_to_server(contract,*server);
405 trimarchi 190
    if (recalculate_contract(MAX_BANDWIDTH)==-1)  {
191
       kern_frestore(f);
192
       return FSF_ERR_CREATE_SERVER;
193
    }
194
#ifdef  FSF_DEBUG
195
    kern_printf("(Adjust budget)");
196
#endif    
197
    for (i=0; i<current; i++) {
198
       mul32div32to32(MAX_BANDWIDTH,server_list[i].Cmin,server_list[i].U,T);
199
       #ifdef FSF_DEBUG
200
       kern_printf("(T %ld)", T);
201
       #endif
202
       if (T<=server_list[i].Tmax)
203
          adjust_SERVER_budget(server_list[i].server,server_list[i].Cmin, T);
204
       else {
205
         mul32div32to32(server_list[i].Tmax,server_list[i].U,MAX_BANDWIDTH,Q);
206
         #ifdef FSF_DEBUG
207
         kern_printf("(Q %ld)", Q);
208
         #endif
209
         adjust_SERVER_budget(server_list[i].server,Q, server_list[i].Tmax);
210
       }
211
 
212
    }
213
  }
214
  else  {
215
    kern_frestore(f);
221 giacomo 216
    return FSF_ERR_CREATE_SERVER;
405 trimarchi 217
  }
218
  kern_frestore(f);
219
 
221 giacomo 220
  return 0;
221
 
222
}
223
 
241 giacomo 224
int fsf_create_thread
225
  (fsf_server_id_t    server,
226
   pthread_t         *thread,
227
   pthread_attr_t    *attr,
228
   fsf_thread_code_t  thread_code,
229
   void              *arg,
230
   void              *local_scheduler_arg)
221 giacomo 231
{
232
 
233
  int local_scheduler_level,scheduler_id;
234
 
235
  #ifdef FSF_DEBUG 
267 giacomo 236
    kern_printf("(FSF:Insert thread = %d to Server = %d)",*thread,server);
221 giacomo 237
  #endif
238
 
239
  /* Check if server and thread exsist */
241 giacomo 240
  if (server == NIL)
241
    return FSF_ERR_INVALID_SERVER;
221 giacomo 242
 
241 giacomo 243
  local_scheduler_level = SERVER_get_local_scheduler_level_from_budget(fsf_server_level,server);
244
  scheduler_id = SERVER_get_local_scheduler_id_from_budget(fsf_server_level,server);
221 giacomo 245
 
246
  /* Check if thread is already bind */
247
  switch (scheduler_id) {
248
    case FSF_SCHEDULER_POSIX:
249
 
298 giacomo 250
      nrt_task_def_arg(*(NRT_TASK_MODEL *)(local_scheduler_arg),arg);
251
      nrt_task_def_level(*(NRT_TASK_MODEL *)(local_scheduler_arg),local_scheduler_level);
221 giacomo 252
 
298 giacomo 253
      *thread = task_create("POSIXSTAR", thread_code, local_scheduler_arg, NULL);
267 giacomo 254
      if (*thread == NIL) {
255
        #ifdef FSF_DEBUG
256
          kern_printf("(FSF:Error creating thread)");
257
        #endif
241 giacomo 258
        return FSF_ERR_CREATE_THREAD;
267 giacomo 259
      }
221 giacomo 260
 
241 giacomo 261
      POSIXSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
234 giacomo 262
 
221 giacomo 263
    break;
264
    case FSF_SCHEDULER_EDF:
265
 
250 giacomo 266
      hard_task_def_arg(*(HARD_TASK_MODEL *)(local_scheduler_arg),arg);
267
      hard_task_def_level(*(HARD_TASK_MODEL *)(local_scheduler_arg),local_scheduler_level);
268
 
269
      *thread = task_create("EDFSTAR", thread_code, local_scheduler_arg, NULL);
270
      if (*thread == NIL)
271
        return FSF_ERR_CREATE_THREAD;
272
 
273
      EDFSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
274
 
221 giacomo 275
      break;
235 giacomo 276
 
221 giacomo 277
    case FSF_SCHEDULER_RM:
235 giacomo 278
 
273 giacomo 279
      hard_task_def_arg(*(HARD_TASK_MODEL *)(local_scheduler_arg),arg);
280
      hard_task_def_level(*(HARD_TASK_MODEL *)(local_scheduler_arg),local_scheduler_level);
281
 
282
      *thread = task_create("RMSTAR", thread_code, local_scheduler_arg, NULL);
283
      if (*thread == NIL)
284
        return FSF_ERR_CREATE_THREAD;
285
 
286
      RMSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
287
 
288
      break;
334 giacomo 289
    case FSF_SCHEDULER_MPEG:
290
 
291
      hard_task_def_arg(*(HARD_TASK_MODEL *)(local_scheduler_arg),arg);
292
      hard_task_def_level(*(HARD_TASK_MODEL *)(local_scheduler_arg),local_scheduler_level);
293
 
338 giacomo 294
      *thread = task_create("MPEGSTAR", thread_code, local_scheduler_arg, NULL);
334 giacomo 295
      if (*thread == NIL)
296
        return FSF_ERR_CREATE_THREAD;
297
 
298
      MPEGSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
299
 
300
      break;
301
 
221 giacomo 302
    default:
241 giacomo 303
      return FSF_ERR_INVALID_SERVER;
221 giacomo 304
      break;
305
  }
306
 
307
  return 0;
308
 
309
}
310
 
311
int fsf_get_server
312
  (fsf_server_id_t *server,
313
   pthread_t       thread)
314
{
315
  int local_scheduler_level, scheduler_id;
316
 
241 giacomo 317
  local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level,thread);
318
  scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, thread);
221 giacomo 319
 
320
  switch (scheduler_id) {
321
    case FSF_SCHEDULER_POSIX:  
322
      return POSIXSTAR_getbudget(local_scheduler_level,thread);
323
    case FSF_SCHEDULER_EDF:
235 giacomo 324
      return EDFSTAR_getbudget(local_scheduler_level,thread);
221 giacomo 325
    case FSF_SCHEDULER_RM:
235 giacomo 326
      return RMSTAR_getbudget(local_scheduler_level,thread);
334 giacomo 327
    case FSF_SCHEDULER_MPEG:
328
      return MPEGSTAR_getbudget(local_scheduler_level,thread);
235 giacomo 329
    default:
221 giacomo 330
      return -1;
331
  }
332
 
333
  return -1;
334
 
335
}
336
 
339 giacomo 337
int fsf_get_server_level(void)
338
{
339
 
340
  return fsf_server_level;
341
 
342
}
343
 
221 giacomo 344
int fsf_cancel_contract
345
  (fsf_server_id_t *server)
346
{
347
 
348
  int local_scheduler_level, scheduler_id;
349
 
350
  #ifdef FSF_DEBUG
351
    kern_printf("(Remove server %d)",*server);
352
  #endif
353
 
354
  /* Check server id */
355
  if (*server < 0)
356
    return FSF_ERR_INVALID_SERVER;
357
 
241 giacomo 358
  local_scheduler_level = SERVER_get_local_scheduler_level_from_budget(fsf_server_level,*server);
359
  scheduler_id = SERVER_get_local_scheduler_id_from_budget(fsf_server_level,*server);
221 giacomo 360
 
361
  switch (scheduler_id) {
362
    case FSF_SCHEDULER_POSIX:
363
 
364
      /* Check if some thread use the server */
365
      if(POSIXSTAR_budget_has_thread(local_scheduler_level,*server))
366
        return FSF_ERR_SERVER_USED;
367
 
368
      break;
369
    case FSF_SCHEDULER_EDF:
235 giacomo 370
      /* Check if some thread use the server */
371
      if(EDFSTAR_budget_has_thread(local_scheduler_level,*server))
372
        return FSF_ERR_SERVER_USED;
373
      break;
374
 
221 giacomo 375
    case FSF_SCHEDULER_RM:
235 giacomo 376
      /* Check if some thread use the server */
377
      if(RMSTAR_budget_has_thread(local_scheduler_level,*server))
378
        return FSF_ERR_SERVER_USED;
379
 
221 giacomo 380
      break;
334 giacomo 381
 
382
    case FSF_SCHEDULER_MPEG:
383
      /* Check if some thread use the server */
384
      if(MPEGSTAR_budget_has_thread(local_scheduler_level,*server))
385
        return FSF_ERR_SERVER_USED;
386
 
387
      break;
388
 
221 giacomo 389
  }
390
 
241 giacomo 391
  SERVER_removebudget(fsf_server_level,*server);
221 giacomo 392
 
393
  level_free_descriptor(local_scheduler_level);
405 trimarchi 394
 
221 giacomo 395
  remove_contract(*server);
396
 
405 trimarchi 397
  recalculate_contract(MAX_BANDWIDTH);
398
 
221 giacomo 399
  *server = -1;
400
 
401
  return 0;
402
 
403
}
404
 
405 trimarchi 405
int recalculate_contract(bandwidth_t U) {
406
  long int current_bandwidth,temp_U;
407
  int        Qt;
408
  int isok=0;
409
  int i=0;
410
  int temp;
411
 
412
   #ifdef FSF_DEBUG
413
      kern_printf("(Recalculate contract)");
414
   #endif
415
 
416
  /* The current bandwidth is the min bandwidth */
417
  //current_bandwidth=SERVER_return_bandwidth(fsf_server_level);
418
  #ifdef FSF_DEBUG
419
     kern_printf("(nserver %d)", current);
420
  #endif  
421
 
422
  do  {
423
    current_bandwidth=0;
424
    Qt=0;
425
    for (i=0; i<current; i++) {
426
      if (server_list[i].U>server_list[i].Umin
427
          && server_list[i].Qs!=0)
428
         Qt+=server_list[i].Qs;
429
       current_bandwidth+=server_list[i].U;
430
    }
431
 
432
    #ifdef FSF_DEBUG
433
    kern_printf("(Total Quality %d)", Qt);
434
    #endif
435
    isok=1;
436
    for (i=0; i<current; i++) {
437
      if (server_list[i].U>server_list[i].Umin &&
438
          server_list[i].Qs!=0) {
439
        temp_U=server_list[i].U;
440
        temp_U=temp_U-(current_bandwidth-U)*server_list[i].Qs/Qt;
441
#ifdef FSF_DEBUG
442
        mul32div32to32(temp_U,100, MAX_BANDWIDTH, temp);
443
        kern_printf("(Server %d bw %d)", server_list[i].server, temp);
444
#endif
445
 
446
        if (temp_U<server_list[i].Umin) {
447
           server_list[i].U=server_list[i].Umin;
448
           isok=0;
449
        } else if (temp_U>=server_list[i].Umax)  {
450
           server_list[i].U=server_list[i].Umax;
451
        } else server_list[i].U=temp_U;
452
 
453
#ifdef FSF_DEBUG
454
        mul32div32to32(server_list[i].U,100, MAX_BANDWIDTH, temp);
455
        kern_printf("(Server %d bw %d)", server_list[i].server, temp);
456
#endif 
457
      }
458
    }  
459
 
460
  } while (!isok);
461
 
462
 return 0;
463
}
464
 
465
 
221 giacomo 466
int fsf_renegotiate_contract
467
  (const fsf_contract_parameters_t *new_contract,
468
   fsf_server_id_t server)
469
{
405 trimarchi 470
  SYS_FLAGS f;
471
  int i=0;
221 giacomo 472
  #ifdef FSF_DEBUG
473
    kern_printf("(Renegotiate for server %d)",server);
474
  #endif
475
 
476
  if (!new_contract)
477
    return FSF_ERR_NOT_INITIALIZED;
478
 
479
  if (server < 0)
480
    return FSF_ERR_INVALID_SERVER;
405 trimarchi 481
  // compute the new value
482
  //
483
   f = kern_fsave();
484
   if (recalculate_contract(MAX_BANDWIDTH)==-1)  {
485
       kern_frestore(f);
486
       return FSF_ERR_CREATE_SERVER;
487
   }
488
/*
489
   for (i=0; i<current; i++)
490
      adjust_SERVER_budget(server_list[i].server,server_list[i].budget_actual, server_list[i].period_actual);
491
*/
492
   kern_frestore(f);
493
   return 0;
221 giacomo 494
}
241 giacomo 495