Subversion Repositories shark

Rev

Rev 841 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
221 giacomo 1
/*
2
 * Project: S.Ha.R.K.
3
 *
4
 * Coordinators:
5
 *   Giorgio Buttazzo    <giorgio@sssup.it>
6
 *   Paolo Gai           <pj@gandalf.sssup.it>
7
 *
8
 * Authors     :
9
 *   Paolo Gai           <pj@gandalf.sssup.it>
10
 *   Massimiliano Giorgi <massy@gandalf.sssup.it>
11
 *   Luca Abeni          <luca@gandalf.sssup.it>
12
 *   (see the web pages for full authors list)
13
 *
14
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
15
 *
16
 * http://www.sssup.it
17
 * http://retis.sssup.it
18
 * http://shark.sssup.it
19
 */
20
 
21
/*
22
 * Copyright (C) 2002 Paolo Gai
23
 *
24
 * This program is free software; you can redistribute it and/or modify
25
 * it under the terms of the GNU General Public License as published by
26
 * the Free Software Foundation; either version 2 of the License, or
27
 * (at your option) any later version.
28
 *
29
 * This program is distributed in the hope that it will be useful,
30
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
31
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
32
 * GNU General Public License for more details.
33
 *
34
 * You should have received a copy of the GNU General Public License
35
 * along with this program; if not, write to the Free Software
36
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
37
 *
38
 */
39
 
40
#include "cbsstar.h"
830 trimarchi 41
#include "ll/i386/64bit.h"
42
#include <tracer.h>
221 giacomo 43
 
44
/*
45
 * DEBUG stuffs begin
46
 */
263 giacomo 47
//#define CBSSTAR_DEBUG
221 giacomo 48
#ifdef CBSSTAR_DEBUG
49
 
50
static __inline__ void fake_printf(char *fmt, ...) {}
51
 
52
#define cbsstar_printf kern_printf
53
#define cbsstar_printf2 kern_printf
54
#define cbsstar_printf3 kern_printf
55
 
56
//#define cbsstar_printf fake_printf
57
//#define cbsstar_printf2 fake_printf
58
//#define cbsstar_printf3 fake_printf
59
 
60
#endif
61
/*
62
 * DEBUG stuffs end
63
 */
64
 
65
/* this structure contains the status for a single budget */
66
struct budget_struct {
67
  TIME Q;                 /* budget */
68
  TIME T;                 /* period */
830 trimarchi 69
  TIME D;                 /* deadline */
221 giacomo 70
 
71
  struct timespec dline;  /* deadline */
830 trimarchi 72
  struct timespec replenish; /* server period */
73
 
74
  int replenish_timer;        /* oslib event for budget reactivation*/
221 giacomo 75
  int avail;              /* current budget */
76
 
77
  LEVEL l;                /* Current CBSSTAR level */
78
  int loc_sched_id;       /* Local scheduler id */
79
  LEVEL loc_sched_level;  /* Local scheduler level */
80
 
81
  PID current;            /* the task currently put in execution */
82
  int flags;
83
 
84
  IQUEUE tasks;           /* a FIFO queue for the tasks handled
85
                             using the budget */
86
 
87
};
88
 
241 giacomo 89
#define CBSSTAR_NOACTIVE   0
90
#define CBSSTAR_ACTIVE     1
221 giacomo 91
 
92
typedef struct {
93
  level_des l;               /* the standard level descriptor */
94
 
95
  struct budget_struct *b;   /* the budgets! */
96
  int n;                     /* the maximum index for the budgets */
97
  int freebudgets;           /* number of free budgets; starts from n */
98
 
99
  int tb[MAX_PROC];          /* link task->budget (used in guest_end) */
100
 
263 giacomo 101
  bandwidth_t U;             /*+ the used bandwidth by the server       +*/
221 giacomo 102
 
103
  int cap_lev;
279 giacomo 104
  struct timespec cap_lasttime;
221 giacomo 105
 
106
  LEVEL scheduling_level;
107
 
108
} CBSSTAR_level_des;
109
 
110
 
830 trimarchi 111
static void CBSSTAR_replenish_timer_hardreservation(void *a)
221 giacomo 112
{
113
  struct budget_struct *b = a;
114
  PID p;
263 giacomo 115
 
221 giacomo 116
  #ifdef CBSSTAR_DEBUG
117
    cbsstar_printf("(CS:HrdRes:");  
118
  #endif
119
 
830 trimarchi 120
  b->replenish_timer = NIL;
221 giacomo 121
 
122
  /* we modify the deadline according to rule 4 ... */
123
  /* there is a while because if the wcet is << than the system tick
124
     we need to postpone the deadline many times */
125
 
126
  b->avail += b->Q;
127
  if (b->avail > b->Q) b->avail = b->Q;
128
 
129
  if (b->avail > 0) b->flags = CBSSTAR_ACTIVE;
130
 
830 trimarchi 131
 /* Tracer */
132
  TRACER_LOGEVENT(FTrace_EVT_server_replenish,0,(unsigned int)(b));
133
 
221 giacomo 134
  /* avail may be <0 because a task executed via a shadow fo many time
135
     b->current == NIL only if the prec task was finished and there
136
     was not any other task to be put in the ready queue
137
     ... we are now activating the next task */
138
  if (b->current == NIL && b->flags) {
139
      if (iq_query_first(&(b->tasks)) != NIL) {
263 giacomo 140
        CBSSTAR_level_des *lev;
221 giacomo 141
        JOB_TASK_MODEL job;
142
 
143
        p = iq_getfirst(&b->tasks);
144
 
145
        #ifdef CBSSTAR_DEBUG
146
          cbsstar_printf("%d",p);
147
        #endif
148
 
840 trimarchi 149
        kern_gettime(&b->replenish);
150
        TIMESPEC_ASSIGN(&b->dline, &b->replenish);
151
        ADDUSEC2TIMESPEC(b->D, &b->dline);
152
        ADDUSEC2TIMESPEC(b->T, &b->replenish);
221 giacomo 153
 
154
        b->current = p;
155
 
263 giacomo 156
        lev = (CBSSTAR_level_des *)(level_table[b->l]);
221 giacomo 157
 
158
        job_task_default_model(job, b->dline);
159
        job_task_def_noexc(job);
160
        level_table[ lev->scheduling_level ]->
161
          private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
162
 
163
        event_need_reschedule();
164
 
165
    }
234 giacomo 166
  }
241 giacomo 167
 
168
  if (b->flags == CBSSTAR_NOACTIVE) {
830 trimarchi 169
 
170
    kern_gettime(&b->replenish);
171
    ADDUSEC2TIMESPEC(b->T, &b->replenish);;
241 giacomo 172
 
830 trimarchi 173
    b->replenish_timer=kern_event_post(&b->replenish, CBSSTAR_replenish_timer_hardreservation, b);
241 giacomo 174
  }
221 giacomo 175
 
241 giacomo 176
  #ifdef CBSSTAR_DEBUG
177
    cbsstar_printf(")");
178
  #endif
237 giacomo 179
 
241 giacomo 180
}
181
 
221 giacomo 182
static void CBSSTAR_activation(CBSSTAR_level_des *lev,
241 giacomo 183
                           PID p,
184
                           struct timespec *acttime)
221 giacomo 185
{
186
  JOB_TASK_MODEL job;
187
  struct budget_struct *b = &lev->b[lev->tb[p]];
188
  /* we have to check if the deadline and the wcet are correct before
189
     activating a new task or an old task... */
190
 
241 giacomo 191
  /* we have to check if the deadline and the wcet are correct before
192
   *      activating a new task or an old task... */
193
 
194
   /* check 1: if the deadline is before than the actual scheduling time */
195
 
196
   /* check 2: if ( avail_time >= (cbs_dline - acttime)* (wcet/period) )
197
    *      (rule 7 in the CBS article!) */
198
   TIME t;
199
   struct timespec t2,t3;
200
 
830 trimarchi 201
   mul32div32to32(b->D,b->avail,b->Q,t);
202
 
241 giacomo 203
   t3.tv_sec = t / 1000000;
204
   t3.tv_nsec = (t % 1000000) * 1000;
830 trimarchi 205
   SUBTIMESPEC(&b->dline, acttime, &t2);
241 giacomo 206
 
830 trimarchi 207
   TRACER_LOGEVENT(FTrace_EVT_server_active,0,(unsigned int)b);
208
 
241 giacomo 209
   if (/* 1 */ TIMESPEC_A_LT_B(&b->dline, acttime) ||
210
       /* 2 */ TIMESPEC_A_GT_B(&t3, &t2) ) {
830 trimarchi 211
       TIMESPEC_ASSIGN(&b->replenish, acttime);
212
       ADDUSEC2TIMESPEC(b->T, &b->replenish);
241 giacomo 213
       TIMESPEC_ASSIGN(&b->dline, acttime);
830 trimarchi 214
       ADDUSEC2TIMESPEC(b->D, &b->dline);
241 giacomo 215
       b->avail=b->Q;
216
       b->flags=CBSSTAR_ACTIVE;
237 giacomo 217
  }
221 giacomo 218
 
219
  /* record the current task inserted in the master module */
220
  b->current = p;
221
 
222
  job_task_default_model(job, b->dline);
223
  job_task_def_noexc(job);
224
  level_table[ lev->scheduling_level ]->
225
    private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
226
 
227
}
228
 
229
static void CBSSTAR_account_capacity(CBSSTAR_level_des *lev, PID p)
230
{
231
  struct timespec ty;
232
  TIME tx;
233
  struct budget_struct *b = &lev->b[lev->tb[p]];
234
 
841 trimarchi 235
  if (lev->cap_lev != NIL) {
221 giacomo 236
    kern_event_delete(lev->cap_lev);
237
    lev->cap_lev = NIL;
238
  }
239
 
279 giacomo 240
  SUBTIMESPEC(&schedule_time, &lev->cap_lasttime, &ty);
221 giacomo 241
  tx = TIMESPEC2USEC(&ty);
263 giacomo 242
  b->avail -= tx;
221 giacomo 243
 
244
  #ifdef CBSSTAR_DEBUG
842 trimarchi 245
    kern_printf("(CS:Cap p%d av=%d tx=%d)", p, b->avail,tx);
221 giacomo 246
  #endif
247
 
830 trimarchi 248
  if (b->avail <= 0) {
249
    b->flags = CBSSTAR_NOACTIVE;
250
    TRACER_LOGEVENT(FTrace_EVT_server_exhaust,0,(unsigned int)(b));
251
  }
221 giacomo 252
 
241 giacomo 253
  if (TIMESPEC_A_LT_B(&b->dline, &schedule_time)) {
254
    /* we modify the deadline ... */
255
    TIMESPEC_ASSIGN(&b->dline, &schedule_time);
830 trimarchi 256
    ADDUSEC2TIMESPEC(b->D, &b->dline);
257
    TIMESPEC_ASSIGN(&b->replenish, &schedule_time);
258
    ADDUSEC2TIMESPEC(b->T, &b->replenish);
241 giacomo 259
  }
221 giacomo 260
 
830 trimarchi 261
  if (b->flags == CBSSTAR_NOACTIVE && b->replenish_timer == NIL)  {
262
    b->replenish_timer=kern_event_post(&b->replenish, CBSSTAR_replenish_timer_hardreservation, b);
241 giacomo 263
  }
264
 
221 giacomo 265
}
266
 
267
 
268
/* The on-line guarantee is enabled only if the appropriate flag is set... */
269
static int CBSSTAR_public_guarantee(LEVEL l, bandwidth_t *freebandwidth)
270
{
271
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
272
 
273
  #ifdef CBSSTAR_DEBUG
274
    cbsstar_printf("(CS:Gua)");
275
  #endif
276
 
277
  if (*freebandwidth >= lev->U) {
278
    *freebandwidth -= lev->U;
279
    return 1;
280
  }
281
  else
282
    return 0;
283
}
284
 
285
static void capacity_handler(void *l)
286
{
287
 
288
  CBSSTAR_level_des *lev = l;
289
  lev->cap_lev = NIL;
290
  event_need_reschedule();
291
 
292
}
293
 
294
static int CBSSTAR_private_eligible(LEVEL l, PID p)
295
{
296
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
297
  struct budget_struct *b = &lev->b[lev->tb[p]];
298
  JOB_TASK_MODEL job;
299
 
300
  /* we have to check if the deadline and the wcet are correct...
301
     if the CBSSTAR level schedules in background with respect to others
302
     levels, there can be the case in witch a task is scheduled by
303
     schedule_time > CBSSTAR_deadline; in this case (not covered in the
304
     article because if there is only the standard scheduling policy
305
     this never apply) we reassign the deadline */
830 trimarchi 306
 
221 giacomo 307
    if ( TIMESPEC_A_LT_B(&b->dline, &schedule_time)) {
308
      if (lev->cap_lev!=NIL) {
309
        kern_event_delete(lev->cap_lev);
310
        lev->cap_lev=NIL;
311
      }
312
 
313
      /* we kill the current activation */
314
      level_table[ lev->scheduling_level ]->
315
        private_extract(lev->scheduling_level, p);
316
      /* we modify the deadline ... */
830 trimarchi 317
      kern_gettime(&b->replenish);
318
      TIMESPEC_ASSIGN(&b->dline, &b->replenish);
319
      ADDUSEC2TIMESPEC(b->D, &b->dline);
320
      ADDUSEC2TIMESPEC(b->T, &b->replenish);      
221 giacomo 321
 
322
      /* and the capacity */
323
      b->avail = b->Q;
842 trimarchi 324
 
221 giacomo 325
      b->flags = CBSSTAR_ACTIVE;
326
 
830 trimarchi 327
      /* Tracer */
328
      TRACER_LOGEVENT(FTrace_EVT_server_replenish,0,(unsigned int)(b));
329
 
330
      if (b->replenish_timer!=NIL)  {
331
        kern_event_delete(b->replenish_timer);
332
        b->replenish_timer=NIL;
221 giacomo 333
      }
334
 
335
      /* and, finally, we reinsert the task in the master level */
336
      job_task_default_model(job, b->dline);
337
      job_task_def_noexc(job);
338
      level_table[ lev->scheduling_level ]->
339
        private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
340
 
341
      return -1;
342
 
343
    }  
830 trimarchi 344
 
221 giacomo 345
 
346
  return 0;
347
 
348
}
349
 
350
static void CBSSTAR_private_insert(LEVEL l, PID p, TASK_MODEL *m)
351
{
352
  /* A task has been activated for some reason. Basically, the task is
353
  inserted in the queue if the queue is empty, otherwise the task is
354
  inserted into the master module, and an oslib event is posted. */
355
 
356
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
357
  BUDGET_TASK_MODEL *budget;
358
 
359
  if (m->pclass != BUDGET_PCLASS ||
360
      (m->level != 0 && m->level != l)) {
361
    kern_raise(XINVALID_TASK, p);
362
    return;
363
  }
364
  budget = (BUDGET_TASK_MODEL *)m;
365
 
366
  #ifdef CBSSTAR_DEBUG
367
    cbsstar_printf("(CS:PriIns:%d:%d", p, budget->b);
368
  #endif
369
 
370
  if (budget->b == -1)
371
    return;
372
 
373
  lev->tb[p] = budget->b;
374
 
375
  if (lev->b[budget->b].current == NIL && lev->b[budget->b].flags ) {
376
    /* This is the first task in the budget,
377
       the task have to be inserted into the master module */
241 giacomo 378
    struct timespec t;
379
    kern_gettime(&t);
380
    CBSSTAR_activation(lev,p,&t);
221 giacomo 381
  } else {
382
    /* The budget is not empty, another task is already into the
383
       master module, so the task is inserted at the end of the budget
384
       queue */
385
    iq_insertlast(p,&lev->b[budget->b].tasks);
386
  }
387
 
388
  #ifdef CBSSTAR_DEBUG
389
    cbsstar_printf(")");
390
  #endif
391
 
392
}
393
 
394
static void CBSSTAR_private_extract(LEVEL l, PID p)
395
{
396
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
397
 
398
  #ifdef CBSSTAR_DEBUG
399
    kern_printf("(CS:Ext:%d)", p);
400
  #endif
401
 
402
  /* a task is removed from execution for some reasons. It must be
403
     that it is the first in its budget queue (only the first task in
404
     a budget queue is put into execution!) */
405
 
406
  /* remove the task from execution (or from the ready queue) */
407
  if (lev->b[lev->tb[p]].current == p) {
408
 
241 giacomo 409
   CBSSTAR_account_capacity(lev,p);
221 giacomo 410
    /* remove the task from the master module */
411
    level_table[ lev->scheduling_level ]->
412
      private_extract(lev->scheduling_level, p);
413
 
414
    /* check if the buffer has someone else to schedule */
415
    if (iq_query_first(&lev->b[lev->tb[p]].tasks) == NIL) {
416
      /* the buffer has no tasks! */
417
      lev->b[lev->tb[p]].current = NIL;
418
    }
419
    else if (lev->b[lev->tb[p]].flags) {
420
      /* if so, insert the new task into the master module */
421
      PID n;
241 giacomo 422
      struct timespec t;
423
 
424
      kern_gettime(&t);
237 giacomo 425
      n = iq_getfirst(&lev->b[lev->tb[p]].tasks);
241 giacomo 426
      CBSSTAR_activation(lev,n,&t);  // it modifies b[lev->tb[p]].current
221 giacomo 427
    }
428
    else
429
      lev->b[lev->tb[p]].current=NIL;
430
 
431
  }
432
  else  {
433
    iq_extract(p, &lev->b[lev->tb[p]].tasks);
434
  }
435
}
436
 
437
static void CBSSTAR_private_dispatch(LEVEL l, PID p, int nostop)
438
{
439
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
440
  struct timespec ty;
441
 
442
  #ifdef CBSSTAR_DEBUG
443
    kern_printf("(CS:Dsp:%d)", p);
444
  #endif
445
 
446
  /* the current task (that is the only one inserted in the master module
447
     for the corresponding budget) is dispatched. Note that the current
448
     task is not inserted in any FIFO queue, so the task does not have to
449
     be extracted! */
450
 
451
  /* ... then, we dispatch it to the master level */
830 trimarchi 452
  if (!nostop)
453
    level_table[ lev->scheduling_level ]->
454
            private_dispatch(lev->scheduling_level,p,nostop);
221 giacomo 455
 
456
  /* ...and finally, we have to post a capacity event */
830 trimarchi 457
  TIMESPEC_ASSIGN(&ty, &schedule_time);
458
  TIMESPEC_ASSIGN(&lev->cap_lasttime, &schedule_time);
839 trimarchi 459
  ADDUSEC2TIMESPEC(lev->b[lev->tb[exec]].avail,&ty);
830 trimarchi 460
  lev->cap_lev = kern_event_post(&ty,capacity_handler, lev);
279 giacomo 461
 
830 trimarchi 462
 
221 giacomo 463
 
464
}
465
 
466
static void CBSSTAR_private_epilogue(LEVEL l, PID p)
467
{
468
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
830 trimarchi 469
  struct budget_struct *b;
470
  int skip_epilog;
471
  skip_epilog = 0;
221 giacomo 472
 
473
  #ifdef CBSSTAR_DEBUG
474
    kern_printf("(CS:Epi:%d)",p);
475
  #endif
476
 
830 trimarchi 477
  if (p==exec) b = &lev->b[lev->tb[p]];
478
    else if (lev->tb[exec]!=NIL)  {
479
          b = &lev->b[lev->tb[exec]];
480
          p=exec;
481
          skip_epilog=1;
482
       }
483
       else return;    
221 giacomo 484
 
830 trimarchi 485
  CBSSTAR_account_capacity(lev,p);
221 giacomo 486
 
830 trimarchi 487
  // L'evento di capacità va cancellato perchè sarà ripristinato nella successiva dispatch
488
  /* we have to check if the capacity is still available */
489
  if (b->flags)  {
490
    /* there is capacity available, maybe it is simply a preemption;
491
       the task have to return to the ready queue */
492
    if (!skip_epilog)
221 giacomo 493
      level_table[ lev->scheduling_level ]->
494
        private_epilogue(lev->scheduling_level,p);
495
 
830 trimarchi 496
  } else {
497
    /* we kill the current activation */
498
    level_table[ lev->scheduling_level ]->
499
      private_extract(lev->scheduling_level, p);    
500
 
501
    iq_insertfirst(p, &b->tasks);
502
    b->current = NIL;
503
 
504
  }
221 giacomo 505
 
506
}
507
 
508
/* Registration functions }*/
509
 
510
/*+ Registration function:
511
    int flags                 the init flags ... see CBSSTAR.h +*/
512
LEVEL CBSSTAR_register_level(int n, LEVEL master)
513
{
514
  LEVEL l;            /* the level that we register */
515
  CBSSTAR_level_des *lev;  /* for readableness only */
516
  PID i;              /* a counter */
517
 
263 giacomo 518
  printk("CBSSTAR_register_level\n");
221 giacomo 519
 
520
  /* request an entry in the level_table */
521
  l = level_alloc_descriptor(sizeof(CBSSTAR_level_des));
522
 
523
  lev = (CBSSTAR_level_des *)level_table[l];
524
 
525
  /* fill the standard descriptor */
526
  lev->l.private_insert   = CBSSTAR_private_insert;
527
  lev->l.private_extract  = CBSSTAR_private_extract;
528
  lev->l.private_eligible = CBSSTAR_private_eligible;
529
  lev->l.private_dispatch = CBSSTAR_private_dispatch;
530
  lev->l.private_epilogue = CBSSTAR_private_epilogue;
531
 
532
  lev->l.public_guarantee = CBSSTAR_public_guarantee;
533
 
534
  /* fill the CBSSTAR descriptor part */
535
  lev->b = (struct budget_struct *)kern_alloc(sizeof(struct budget_struct)*n);
536
 
537
  for (i=0; i<n; i++) {
538
    lev->b[i].Q = 0;
539
    lev->b[i].T = 0;
842 trimarchi 540
    lev->b[i].D = 0;
221 giacomo 541
    NULL_TIMESPEC(&lev->b[i].dline);
830 trimarchi 542
    NULL_TIMESPEC(&lev->b[i].replenish);
543
    lev->b[i].replenish_timer = NIL;
221 giacomo 544
    lev->b[i].avail = 0;
545
    lev->b[i].current = -1;
241 giacomo 546
    lev->b[i].flags = CBSSTAR_ACTIVE;
221 giacomo 547
    lev->b[i].l=l;
241 giacomo 548
    iq_init(&lev->b[i].tasks, /* &freedesc */NULL, 0);
221 giacomo 549
  }
550
 
551
  lev->n = n;
552
  lev->freebudgets = 0;
553
 
554
  for (i=0; i<MAX_PROC; i++)
555
    lev->tb[i] = NIL;
556
 
557
  lev->U = 0;
558
  lev->cap_lev = NIL;
279 giacomo 559
  NULL_TIMESPEC(&lev->cap_lasttime);
221 giacomo 560
  lev->scheduling_level = master;
561
 
562
  return l;
563
 
564
}
565
 
830 trimarchi 566
int CBSSTAR_setbudget(LEVEL l, TIME Q, TIME T, TIME D, LEVEL local_scheduler_level, int scheduler_id)
221 giacomo 567
{
568
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
569
  int r;
570
 
571
  #ifdef CBSSTAR_DEBUG
572
    cbsstar_printf("(CS:SetBud)");
573
  #endif
574
 
575
  for (r = 0; r < lev->n; r++)
576
    if (lev->b[r].Q == 0) break;
577
 
578
  if (r != lev->n) {
579
    bandwidth_t b;
580
    b = (MAX_BANDWIDTH / T) * Q;
581
 
582
    /* really update lev->U, checking an overflow... */
583
    if (Q< T && MAX_BANDWIDTH - lev->U > b) {
584
 
585
      lev->U += b;
586
      lev->freebudgets++;
587
 
588
      lev->b[r].Q = Q;
589
      lev->b[r].T = T;
830 trimarchi 590
      lev->b[r].D = D;
241 giacomo 591
      lev->b[r].avail = Q;
592
      lev->b[r].flags = CBSSTAR_ACTIVE;
221 giacomo 593
      lev->b[r].loc_sched_id = scheduler_id;
594
      lev->b[r].loc_sched_level = local_scheduler_level;
595
 
596
      return r;
597
    }
598
    else
599
      return -2;
600
  }
601
  else
602
    return -1;
603
}
604
 
830 trimarchi 605
int CBSSTAR_get_remain_capacity(LEVEL l, int budget)
606
{
607
  struct timespec actual,ty;
608
  int    tx;
609
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
610
  kern_gettime(&actual);
611
  SUBTIMESPEC(&actual, &schedule_time, &ty);
612
  tx = TIMESPEC2USEC(&ty);
613
  // the remain capacity is from the first dispatch so is less then
614
  // actual capacity
615
  return (lev->b[budget].avail-tx);
616
 
617
}
618
 
221 giacomo 619
int CBSSTAR_removebudget(LEVEL l, int budget)
620
{
621
 
622
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
623
 
624
  bandwidth_t b;
625
 
626
  b = (MAX_BANDWIDTH / lev->b[budget].T) * lev->b[budget].Q;
627
 
628
  lev->U -= b;
629
 
630
  lev->b[budget].Q = 0;
631
  lev->b[budget].T = 0;
842 trimarchi 632
  lev->b[budget].D = 0;
221 giacomo 633
  NULL_TIMESPEC(&lev->b[budget].dline);
841 trimarchi 634
  NULL_TIMESPEC(&lev->b[budget].replenish);
830 trimarchi 635
  lev->b[budget].replenish_timer = NIL;
221 giacomo 636
  lev->b[budget].avail = 0;
637
  lev->b[budget].current = -1;
241 giacomo 638
  lev->b[budget].flags = CBSSTAR_ACTIVE;
221 giacomo 639
 
640
  return 0;
641
 
642
}
643
 
830 trimarchi 644
int CBSSTAR_adjust_budget(LEVEL l, TIME Q, TIME T, TIME D, int budget)
221 giacomo 645
{
646
 
647
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
648
 
649
  lev->b[budget].Q = Q;
650
  lev->b[budget].T = T;
830 trimarchi 651
  lev->b[budget].D = D;
221 giacomo 652
 
653
  return 0;
654
 
655
}
656
 
830 trimarchi 657
int CBSSTAR_getbudgetinfo(LEVEL l, TIME *Q, TIME *T, TIME *D, int budget)
221 giacomo 658
{
659
 
660
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
661
 
662
  *Q = lev->b[budget].Q;
663
  *T = lev->b[budget].T;
830 trimarchi 664
  *D = lev->b[budget].D;
221 giacomo 665
 
666
  return 0;
667
 
668
}
669
 
288 giacomo 670
int CBSSTAR_get_last_reclaiming(LEVEL l, PID p)
273 giacomo 671
{
672
 
673
  return 0;
674
 
675
}
676
 
221 giacomo 677
int CBSSTAR_is_active(LEVEL l, int budget)
678
{
679
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
680
 
681
  return lev->b[budget].flags;
682
 
683
}
684
 
685
int CBSSTAR_get_local_scheduler_level_from_budget(LEVEL l, int budget)
686
{
687
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
688
 
689
  return lev->b[budget].loc_sched_level;
690
 
691
}
692
 
693
int CBSSTAR_get_local_scheduler_level_from_pid(LEVEL l, PID p)
694
{
695
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
696
 
697
  return lev->b[lev->tb[p]].loc_sched_level;
698
 
699
}
700
 
701
int CBSSTAR_get_local_scheduler_id_from_budget(LEVEL l, int budget)
702
{
703
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
704
 
705
  return lev->b[budget].loc_sched_id;
706
 
707
}
708
 
709
int CBSSTAR_get_local_scheduler_id_from_pid(LEVEL l, PID p)
710
{
711
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
712
 
713
  return lev->b[lev->tb[p]].loc_sched_id;
714
 
715
}
716
 
830 trimarchi 717
void CBSSTAR_disable_server(LEVEL l, int budget)
718
{
719
 CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
720
 int avail_budget;
721
 int spare;
722
 
723
 /* force a hard reservation event */
724
 avail_budget=lev->b[lev->tb[exec]].avail;
725
 lev->b[lev->tb[exec]].flags = CBSSTAR_NOACTIVE;
726
 //kern_printf("(CBS DS %d)", exec);
727
 /* save the unused capacity */
728
 spare=avail_budget+lev->b[lev->tb[exec]].avail;
729
 if (spare<=0) spare=0;
730
 
731
}