Subversion Repositories shark

Rev

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