Subversion Repositories shark

Rev

Rev 234 | Go to most recent revision | Details | 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
 */
45
//#define CBSSTAR_DEBUG
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*/
70
  int avail;              /* current budget */
71
 
72
  LEVEL l;                /* Current CBSSTAR level */
73
  int loc_sched_id;       /* Local scheduler id */
74
  LEVEL loc_sched_level;  /* Local scheduler level */
75
 
76
  PID current;            /* the task currently put in execution */
77
 
78
  int flags;
79
  int overran;            /* overran flag */
80
 
81
  IQUEUE tasks;           /* a FIFO queue for the tasks handled
82
                             using the budget */
83
 
84
};
85
 
86
#define CBSSTAR_NOACTIVE 0
87
#define CBSSTAR_ACTIVE   1
88
#define CBSSTAR_INIT     2
89
 
90
typedef struct {
91
  level_des l;               /* the standard level descriptor */
92
 
93
  struct budget_struct *b;   /* the budgets! */
94
  int n;                     /* the maximum index for the budgets */
95
  int freebudgets;           /* number of free budgets; starts from n */
96
 
97
  int tb[MAX_PROC];          /* link task->budget (used in guest_end) */
98
 
99
  bandwidth_t U;   /*+ the used bandwidth by the server       +*/
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;
112
 
113
  #ifdef CBSSTAR_DEBUG
114
    cbsstar_printf("(CS:HrdRes:");  
115
  #endif
116
 
117
  b->dline_timer = NIL;
118
  b->overran = 0;
119
 
120
  /* we modify the deadline according to rule 4 ... */
121
  /* there is a while because if the wcet is << than the system tick
122
     we need to postpone the deadline many times */
123
 
124
  b->avail += b->Q;
125
  if (b->avail > b->Q) b->avail = b->Q;
126
 
127
  if (b->avail > 0) b->flags = CBSSTAR_ACTIVE;
128
 
129
  /* avail may be <0 because a task executed via a shadow fo many time
130
     b->current == NIL only if the prec task was finished and there
131
     was not any other task to be put in the ready queue
132
     ... we are now activating the next task */
133
  if (b->current == NIL && b->flags) {
134
      if (iq_query_first(&(b->tasks)) != NIL) {
135
        CBSSTAR_level_des *lev;
136
        JOB_TASK_MODEL job;
137
 
138
        p = iq_getfirst(&b->tasks);
139
 
140
        #ifdef CBSSTAR_DEBUG
141
          cbsstar_printf("%d",p);
142
        #endif
143
 
144
        kern_gettime(&b->dline);
145
        ADDUSEC2TIMESPEC(b->T, &b->dline);
146
 
147
        b->current = p;
148
 
149
        lev = (CBSSTAR_level_des *)(level_table[b->l]);
150
 
151
        job_task_default_model(job, b->dline);
152
        job_task_def_noexc(job);
153
        level_table[ lev->scheduling_level ]->
154
          private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
155
 
156
        event_need_reschedule();
157
 
158
    }
159
  } else
160
    if (b->current != NIL && b->avail > 0) {
161
      #ifdef CBSSTAR_DEBUG
162
        cbsstar_printf("#");
163
      #endif
164
    }
165
 
166
  if (b->flags == CBSSTAR_NOACTIVE && b->dline_timer != NIL) {
167
    kern_gettime(&b->dline);
168
    ADDUSEC2TIMESPEC(b->T, &b->dline);
169
 
170
    b->dline_timer=kern_event_post(&b->dline, CBSSTAR_deadline_timer_hardreservation, b);
171
  }
172
 
173
  #ifdef CBSSTAR_DEBUG
174
    cbsstar_printf(")");
175
  #endif
176
 
177
}
178
 
179
static void CBSSTAR_activation(CBSSTAR_level_des *lev,
180
                           PID p,
181
                           struct timespec *acttime)
182
{
183
  JOB_TASK_MODEL job;
184
  struct budget_struct *b = &lev->b[lev->tb[p]];
185
  /* we have to check if the deadline and the wcet are correct before
186
     activating a new task or an old task... */
187
 
188
  /* check 1: if the deadline is before than the actual scheduling time */
189
 
190
  /* check 2: if ( avail_time >= (cbs_dline - acttime)* (wcet/period) )
191
     (rule 7 in the CBS article!) */
192
  TIME t;
193
  struct timespec t2,t3;
194
 
195
  t = (b->T * b->avail) / b->Q;
196
  t3.tv_sec = t / 1000000;
197
  t3.tv_nsec = (t % 1000000) * 1000;
198
 
199
  SUBTIMESPEC(&b->dline, acttime, &t2);
200
  if (/* 1 */ TIMESPEC_A_LT_B(&b->dline, acttime) ||
201
      /* 2 */ TIMESPEC_A_GT_B(&t3, &t2) ) {
202
    TIMESPEC_ASSIGN(&b->dline, acttime);
203
    ADDUSEC2TIMESPEC(b->T, &b->dline);
204
  }  
205
 
206
  /* and the capacity */
207
  if (b->flags == CBSSTAR_INIT) {
208
    b->avail = b->Q;
209
    b->flags = CBSSTAR_ACTIVE;
210
  }  
211
 
212
  /* record the current task inserted in the master module */
213
  b->current = p;
214
 
215
  /* reset overran flag */
216
  b->overran = 0;
217
 
218
  job_task_default_model(job, b->dline);
219
  job_task_def_noexc(job);
220
  level_table[ lev->scheduling_level ]->
221
    private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
222
 
223
}
224
 
225
static void CBSSTAR_account_capacity(CBSSTAR_level_des *lev, PID p)
226
{
227
  struct timespec ty;
228
  TIME tx;
229
  struct budget_struct *b = &lev->b[lev->tb[p]];
230
  TIME t;
231
  struct timespec t2,t3, acttime;
232
 
233
  if (lev->cap_lev != NIL && b->current == p) {
234
    kern_event_delete(lev->cap_lev);
235
    lev->cap_lev = NIL;
236
  }
237
 
238
  kern_gettime(&acttime);
239
 
240
  t = (b->T * b->avail) / b->Q;
241
  t3.tv_sec = t / 1000000;
242
  t3.tv_nsec = (t % 1000000) * 1000;
243
 
244
  SUBTIMESPEC(&b->dline, &acttime, &t2);
245
 
246
  SUBTIMESPEC(&schedule_time, &cap_lasttime, &ty);
247
  tx = TIMESPEC2USEC(&ty);
248
  lev->b[lev->tb[p]].avail -= tx;
249
 
250
  #ifdef CBSSTAR_DEBUG
251
    cbsstar_printf2("(CS:Cap p%d av=%d)", p, lev->b[lev->tb[p]].avail);
252
  #endif
253
 
254
  if (lev->b[lev->tb[p]].avail <= 0 || TIMESPEC_A_GT_B(&t3, &t2)) {
255
    lev->b[lev->tb[p]].avail = 0;
256
    lev->b[lev->tb[p]].flags = CBSSTAR_NOACTIVE;
257
  }
258
 
259
  if (TIMESPEC_A_LT_B(&b->dline, &schedule_time)) {
260
    /* we modify the deadline ... */
261
    b->overran = 1;
262
    TIMESPEC_ASSIGN(&b->dline, &schedule_time);
263
    ADDUSEC2TIMESPEC(b->T, &b->dline);
264
  }
265
 
266
  if (b->flags == CBSSTAR_NOACTIVE && b->dline_timer == NIL)  {
267
    b->dline_timer=kern_event_post(&b->dline, CBSSTAR_deadline_timer_hardreservation, b);
268
  }
269
 
270
}
271
 
272
 
273
/* The on-line guarantee is enabled only if the appropriate flag is set... */
274
static int CBSSTAR_public_guarantee(LEVEL l, bandwidth_t *freebandwidth)
275
{
276
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
277
 
278
  #ifdef CBSSTAR_DEBUG
279
    cbsstar_printf("(CS:Gua)");
280
  #endif
281
 
282
  if (*freebandwidth >= lev->U) {
283
    *freebandwidth -= lev->U;
284
    return 1;
285
  }
286
  else
287
    return 0;
288
}
289
 
290
static void capacity_handler(void *l)
291
{
292
 
293
  CBSSTAR_level_des *lev = l;
294
  lev->cap_lev = NIL;
295
  event_need_reschedule();
296
 
297
}
298
 
299
static int CBSSTAR_private_eligible(LEVEL l, PID p)
300
{
301
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
302
  struct budget_struct *b = &lev->b[lev->tb[p]];
303
  JOB_TASK_MODEL job;
304
 
305
  /* we have to check if the deadline and the wcet are correct...
306
     if the CBSSTAR level schedules in background with respect to others
307
     levels, there can be the case in witch a task is scheduled by
308
     schedule_time > CBSSTAR_deadline; in this case (not covered in the
309
     article because if there is only the standard scheduling policy
310
     this never apply) we reassign the deadline */
311
  if (b->current == p) {
312
    if ( TIMESPEC_A_LT_B(&b->dline, &schedule_time)) {
313
      if (lev->cap_lev!=NIL) {
314
        kern_event_delete(lev->cap_lev);
315
        lev->cap_lev=NIL;
316
      }
317
 
318
      /* we kill the current activation */
319
      level_table[ lev->scheduling_level ]->
320
        private_extract(lev->scheduling_level, p);
321
      /* we modify the deadline ... */
322
      b->overran = 1;
323
      TIMESPEC_ASSIGN(&b->dline, &schedule_time);
324
      ADDUSEC2TIMESPEC(b->T, &b->dline);
325
 
326
      /* and the capacity */
327
      b->avail = b->Q;
328
      b->flags = CBSSTAR_ACTIVE;
329
 
330
      if (b->dline_timer!=NIL)  {
331
        kern_event_delete(b->dline_timer);
332
        b->dline_timer=NIL;
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
    }  
344
  }
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 */
378
    struct timespec t;
379
    kern_gettime(&t);
380
    CBSSTAR_activation(lev,p,&t);
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
 
409
   CBSSTAR_account_capacity(lev,p);
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;
422
      struct timespec t;
423
 
424
      kern_gettime(&t);
425
      n = iq_getfirst(&lev->b[lev->tb[p]].tasks);
426
      CBSSTAR_activation(lev,n,&t);  // it modifies b[lev->tb[p]].current
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 */
452
  level_table[ lev->scheduling_level ]->
453
    private_dispatch(lev->scheduling_level,p,nostop);
454
 
455
  /* ...and finally, we have to post a capacity event */
456
  if (!nostop) {
457
    TIMESPEC_ASSIGN(&ty, &schedule_time);
458
    ADDUSEC2TIMESPEC(lev->b[lev->tb[p]].avail,&ty);
459
    lev->cap_lev = kern_event_post(&ty,capacity_handler, lev);
460
  }
461
 
462
}
463
 
464
static void CBSSTAR_private_epilogue(LEVEL l, PID p)
465
{
466
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
467
  struct budget_struct *b = &lev->b[lev->tb[p]];
468
 
469
  #ifdef CBSSTAR_DEBUG
470
    kern_printf("(CS:Epi:%d)",p);
471
  #endif
472
 
473
  if (p==b->current)  {
474
 
475
    CBSSTAR_account_capacity(lev,p);
476
 
477
    // L'evento di capacità va cancellato perchè sarà ripristinato nella successiva dispatch
478
    /* we have to check if the capacity is still available */
479
    if (b->flags)  {
480
      /* there is capacity available, maybe it is simply a preemption;
481
         the task have to return to the ready queue */
482
      level_table[ lev->scheduling_level ]->
483
        private_epilogue(lev->scheduling_level,p);
484
 
485
    } else {
486
      /* we kill the current activation */
487
      level_table[ lev->scheduling_level ]->
488
        private_extract(lev->scheduling_level, p);    
489
 
490
      iq_insertfirst(p, &b->tasks);
491
 
492
      b->current = NIL;
493
 
494
    }
495
 
496
  }
497
 
498
}
499
 
500
/* Registration functions }*/
501
 
502
/*+ Registration function:
503
    int flags                 the init flags ... see CBSSTAR.h +*/
504
LEVEL CBSSTAR_register_level(int n, LEVEL master)
505
{
506
  LEVEL l;            /* the level that we register */
507
  CBSSTAR_level_des *lev;  /* for readableness only */
508
  PID i;              /* a counter */
509
 
510
  kern_printf("CBSSTAR_register_level\n");
511
 
512
  /* request an entry in the level_table */
513
  l = level_alloc_descriptor(sizeof(CBSSTAR_level_des));
514
 
515
  lev = (CBSSTAR_level_des *)level_table[l];
516
 
517
  /* fill the standard descriptor */
518
  lev->l.private_insert   = CBSSTAR_private_insert;
519
  lev->l.private_extract  = CBSSTAR_private_extract;
520
  lev->l.private_eligible = CBSSTAR_private_eligible;
521
  lev->l.private_dispatch = CBSSTAR_private_dispatch;
522
  lev->l.private_epilogue = CBSSTAR_private_epilogue;
523
 
524
  lev->l.public_guarantee = CBSSTAR_public_guarantee;
525
 
526
  /* fill the CBSSTAR descriptor part */
527
  lev->b = (struct budget_struct *)kern_alloc(sizeof(struct budget_struct)*n);
528
 
529
  for (i=0; i<n; i++) {
530
    lev->b[i].Q = 0;
531
    lev->b[i].T = 0;
532
    NULL_TIMESPEC(&lev->b[i].dline);
533
    lev->b[i].dline_timer = NIL;
534
    lev->b[i].avail = 0;
535
    lev->b[i].current = -1;
536
    lev->b[i].flags = CBSSTAR_INIT;
537
    lev->b[i].l=l;
538
    iq_init(&lev->b[i].tasks, &freedesc, 0);
539
  }
540
 
541
  lev->n = n;
542
  lev->freebudgets = 0;
543
 
544
  for (i=0; i<MAX_PROC; i++)
545
    lev->tb[i] = NIL;
546
 
547
  lev->U = 0;
548
  lev->cap_lev = NIL;
549
  lev->scheduling_level = master;
550
 
551
  return l;
552
 
553
}
554
 
555
int CBSSTAR_setbudget(LEVEL l, TIME Q, TIME T, LEVEL local_scheduler_level, int scheduler_id)
556
{
557
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
558
  int r;
559
 
560
  #ifdef CBSSTAR_DEBUG
561
    cbsstar_printf("(CS:SetBud)");
562
  #endif
563
 
564
  for (r = 0; r < lev->n; r++)
565
    if (lev->b[r].Q == 0) break;
566
 
567
  if (r != lev->n) {
568
    bandwidth_t b;
569
    b = (MAX_BANDWIDTH / T) * Q;
570
 
571
    /* really update lev->U, checking an overflow... */
572
    if (Q< T && MAX_BANDWIDTH - lev->U > b) {
573
 
574
      lev->U += b;
575
      lev->freebudgets++;
576
 
577
      lev->b[r].Q = Q;
578
      lev->b[r].T = T;
579
 
580
      lev->b[r].loc_sched_id = scheduler_id;
581
      lev->b[r].loc_sched_level = local_scheduler_level;
582
 
583
      return r;
584
    }
585
    else
586
      return -2;
587
  }
588
  else
589
    return -1;
590
}
591
 
592
int CBSSTAR_removebudget(LEVEL l, int budget)
593
{
594
 
595
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
596
 
597
  bandwidth_t b;
598
 
599
  b = (MAX_BANDWIDTH / lev->b[budget].T) * lev->b[budget].Q;
600
 
601
  lev->U -= b;
602
 
603
  lev->b[budget].Q = 0;
604
  lev->b[budget].T = 0;
605
  NULL_TIMESPEC(&lev->b[budget].dline);
606
  lev->b[budget].dline_timer = NIL;
607
  lev->b[budget].avail = 0;
608
  lev->b[budget].current = -1;
609
  lev->b[budget].flags = CBSSTAR_INIT;
610
  iq_init(&lev->b[budget].tasks, &freedesc, 0);
611
 
612
  return 0;
613
 
614
}
615
 
616
int CBSSTAR_adjust_budget(LEVEL l, TIME Q, TIME T, int budget)
617
{
618
 
619
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
620
 
621
  lev->b[budget].Q = Q;
622
  lev->b[budget].T = T;
623
 
624
  return 0;
625
 
626
}
627
 
628
int CBSSTAR_getbudgetinfo(LEVEL l, TIME *Q, TIME *T, int budget)
629
{
630
 
631
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
632
 
633
  *Q = lev->b[budget].Q;
634
  *T = lev->b[budget].T;
635
 
636
  return 0;
637
 
638
}
639
 
640
int CBSSTAR_was_budget_overran(LEVEL l, int budget)
641
{
642
 
643
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
644
 
645
  return lev->b[budget].overran;
646
 
647
}
648
 
649
int CBSSTAR_is_active(LEVEL l, int budget)
650
{
651
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
652
 
653
  return lev->b[budget].flags;
654
 
655
}
656
 
657
int CBSSTAR_get_local_scheduler_level_from_budget(LEVEL l, int budget)
658
{
659
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
660
 
661
  return lev->b[budget].loc_sched_level;
662
 
663
}
664
 
665
int CBSSTAR_get_local_scheduler_level_from_pid(LEVEL l, PID p)
666
{
667
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
668
 
669
  return lev->b[lev->tb[p]].loc_sched_level;
670
 
671
}
672
 
673
int CBSSTAR_get_local_scheduler_id_from_budget(LEVEL l, int budget)
674
{
675
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
676
 
677
  return lev->b[budget].loc_sched_id;
678
 
679
}
680
 
681
int CBSSTAR_get_local_scheduler_id_from_pid(LEVEL l, PID p)
682
{
683
  CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
684
 
685
  return lev->b[lev->tb[p]].loc_sched_id;
686
 
687
}
688