Subversion Repositories shark

Rev

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