Subversion Repositories shark

Rev

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