Subversion Repositories shark

Rev

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