Subversion Repositories shark

Rev

Rev 657 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 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
 ------------
657 anton 23
 CVS :        $Id: cbs.c,v 1.11 2004-05-17 15:03:51 anton Exp $
2 pj 24
 
25
 File:        $File$
657 anton 26
 Revision:    $Revision: 1.11 $
27
 Last update: $Date: 2004-05-17 15:03:51 $
2 pj 28
 ------------
29
 
30
 This file contains the aperiodic server CBS (Total Bandwidth Server)
31
 
32
 Read CBS.h for further details.
33
 
34
**/
35
 
36
/*
37
 * Copyright (C) 2000 Paolo Gai
38
 *
39
 * This program is free software; you can redistribute it and/or modify
40
 * it under the terms of the GNU General Public License as published by
41
 * the Free Software Foundation; either version 2 of the License, or
42
 * (at your option) any later version.
43
 *
44
 * This program is distributed in the hope that it will be useful,
45
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
46
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
47
 * GNU General Public License for more details.
48
 *
49
 * You should have received a copy of the GNU General Public License
50
 * along with this program; if not, write to the Free Software
51
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
52
 *
53
 */
54
 
55
 
56
#include <modules/cbs.h>
57
#include <ll/stdio.h>
58
#include <ll/string.h>
59
#include <kernel/model.h>
60
#include <kernel/descr.h>
61
#include <kernel/var.h>
62
#include <kernel/func.h>
63
 
353 giacomo 64
#include <tracer.h>
65
 
2 pj 66
/*+ 4 debug purposes +*/
67
#undef CBS_TEST
68
#undef CBS_COUNTER
69
 
70
#ifdef TESTG
71
#include "drivers/glib.h"
72
TIME x,oldx;
73
extern TIME starttime;
74
#endif
75
 
76
 
77
/*+ Status used in the level +*/
78
#define CBS_IDLE          APER_STATUS_BASE   /*+ waiting the activation +*/
79
#define CBS_ZOMBIE        APER_STATUS_BASE+1 /*+ waiting the period end +*/
80
 
81
/*+ task flags +*/
82
#define CBS_SAVE_ARRIVALS 1
83
#define CBS_APERIODIC     2
212 giacomo 84
#define CBS_SLEEP         4
2 pj 85
 
86
/*+ the level redefinition for the Total Bandwidth Server level +*/
87
typedef struct {
88
  level_des l;     /*+ the standard level descriptor          +*/
89
 
90
  /* The wcet are stored in the task descriptor, but we need
91
     an array for the deadlines. We can't use the timespec_priority
92
     field because it is used by the master level!!!...
93
     Notice that however the use of the timespec_priority field
94
     does not cause any problem...                     */
95
 
96
  struct timespec cbs_dline[MAX_PROC]; /*+ CBS deadlines      +*/
97
 
98
  TIME period[MAX_PROC]; /*+ CBS activation period            +*/
99
 
100
  struct timespec reactivation_time[MAX_PROC];
101
        /*+ the time at witch  the reactivation timer is post +*/
102
  int reactivation_timer[MAX_PROC];
103
                                   /*+ the recativation timer +*/
104
 
105
  int nact[MAX_PROC]; /*+ number of pending activations       +*/
106
 
107
  BYTE flag[MAX_PROC]; /*+ task flags                         +*/
108
 
109
  int flags;       /*+ the init flags...                      +*/
110
 
111
  bandwidth_t U;   /*+ the used bandwidth by the server       +*/
112
 
113
  LEVEL scheduling_level;
114
 
115
} CBS_level_des;
116
 
117
#ifdef CBS_COUNTER
118
int cbs_counter=0;
119
int cbs_counter2=0;
120
#endif
121
 
122
 
123
static void CBS_activation(CBS_level_des *lev,
124
                           PID p,
125
                           struct timespec *acttime)
126
{
127
  JOB_TASK_MODEL job;
128
 
129
  /* we have to check if the deadline and the wcet are correct before
130
     activating a new task or an old task... */
131
 
132
  /* check 1: if the deadline is before than the actual scheduling time */
133
 
134
  /* check 2: if ( avail_time >= (cbs_dline - acttime)* (wcet/period) )
135
     (rule 7 in the CBS article!) */
136
  TIME t;
137
  struct timespec t2,t3;
138
 
139
  t = (lev->period[p] * proc_table[p].avail_time) / proc_table[p].wcet;
140
  t3.tv_sec = t / 1000000;
141
  t3.tv_nsec = (t % 1000000) * 1000;
142
 
143
  SUBTIMESPEC(&lev->cbs_dline[p], acttime, &t2);
144
 
145
  if (/* 1 */ TIMESPEC_A_LT_B(&lev->cbs_dline[p], acttime) ||
146
      /* 2 */ TIMESPEC_A_GT_B(&t3, &t2) ) {
147
/*    if (TIMESPEC_A_LT_B(&lev->cbs_dline[p], acttime) )
148
      kern_printf("$");
149
    else
212 giacomo 150
      kern_printf("(Ûdline%d.%d act%d.%d wcet%d per%d avail%dÛ)",
2 pj 151
                  lev->cbs_dline[p].tv_sec,lev->cbs_dline[p].tv_nsec/1000,
152
                  acttime->tv_sec, acttime->tv_nsec/1000,
153
                  proc_table[p].wcet, lev->period[p], proc_table[p].avail_time);
154
*/  /* we modify the deadline ... */
155
    TIMESPEC_ASSIGN(&lev->cbs_dline[p], acttime);
156
    ADDUSEC2TIMESPEC(lev->period[p], &lev->cbs_dline[p]);
157
 
158
    /* and the capacity */
159
    proc_table[p].avail_time = proc_table[p].wcet;
160
  }
161
 
162
#ifdef TESTG
163
      if (starttime && p == 3) {
164
      oldx = x;
165
      x = ((lev->cbs_dline[p].tv_sec*1000000+lev->cbs_dline[p].tv_nsec/1000)/5000 - starttime) + 20;
166
//      kern_printf("(a%d)",lev->cbs_dline[p].tv_sec*1000000+lev->cbs_dline[p].tv_nsec/1000);
167
      if (oldx > x) sys_end();
168
      if (x<640)
169
        grx_plot(x, 15, 8);
170
      }
171
#endif
172
 
173
  /* and, finally, we reinsert the task in the master level */
174
  job_task_default_model(job, lev->cbs_dline[p]);
175
  job_task_def_noexc(job);
176
  level_table[ lev->scheduling_level ]->
38 pj 177
    private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
2 pj 178
}
179
 
180
static void CBS_avail_time_check(CBS_level_des *lev, PID p)
181
{
182
  /* there is a while because if the wcet is << than the system tick
183
     we need to postpone the deadline many times */
184
  while (proc_table[p].avail_time <= 0) {
185
    ADDUSEC2TIMESPEC(lev->period[p], &lev->cbs_dline[p]);
186
    proc_table[p].avail_time += proc_table[p].wcet;
187
 
188
#ifdef TESTG
189
    if (starttime && p == 3) {
190
    oldx = x;
191
    x = ((lev->cbs_dline[p].tv_sec*1000000+lev->cbs_dline[p].tv_nsec/1000)/5000 - starttime) + 20;
192
//      kern_printf("(e%d avail%d)",lev->cbs_dline[p].tv_sec*1000000+lev->cbs_dline[p].tv_nsec/1000,proc_table[p].avail_time);
193
    if (oldx > x) sys_end();
194
    if (x<640)
195
      grx_plot(x, 15, 2);
196
    }
197
#endif
198
  }
199
}
200
 
201
 
202
/* this is the periodic reactivation of the task... it is posted only
203
   if the task is a periodic task */
204
static void CBS_timer_reactivate(void *par)
205
{
206
  PID p = (PID) par;
207
  CBS_level_des *lev;
208
 
209
  lev = (CBS_level_des *)level_table[proc_table[p].task_level];
210
 
211
  #ifdef CBS_COUNTER
212
    if (p==5) cbs_counter++;
213
  #endif
214
 
212 giacomo 215
  if (lev->flag[p] & CBS_SLEEP && proc_table[p].status == CBS_IDLE) {
216
    proc_table[p].status = SLEEP;
217
    proc_table[p].avail_time = proc_table[p].wcet;
218
    NULL_TIMESPEC(&lev->cbs_dline[p]);
219
    return;
220
  }
221
 
2 pj 222
  if (proc_table[p].status == CBS_IDLE) {
223
    /* the task has finished the current activation and must be
224
       reactivated */
225
    CBS_activation(lev,p,&lev->reactivation_time[p]);
226
 
227
    event_need_reschedule();
228
  }
229
  else if (lev->flag[p] & CBS_SAVE_ARRIVALS)
230
    /* the task has not completed the current activation, so we save
231
       the activation incrementing nact... */
232
    lev->nact[p]++;
233
 
234
  /* repost the event at the next period end... */
235
  ADDUSEC2TIMESPEC(lev->period[p], &lev->reactivation_time[p]);
236
  lev->reactivation_timer[p] = kern_event_post(&lev->reactivation_time[p],
237
                                               CBS_timer_reactivate,
238
                                               (void *)p);
239
  #ifdef CBS_COUNTER
240
    if (p==5) cbs_counter2++;
241
  #endif
242
  /* tracer stuff */
502 giacomo 243
  TRACER_LOGEVENT(FTrace_EVT_task_timer,(unsigned short int)proc_table[p].context,(unsigned int)proc_table[p].task_level);
2 pj 244
 
245
}
246
 
247
/*+ this function is called when a killed or ended task reach the
248
    period end +*/
249
static void CBS_timer_zombie(void *par)
250
{
251
  PID p = (PID) par;
252
  CBS_level_des *lev;
253
 
254
  lev = (CBS_level_des *)level_table[proc_table[p].task_level];
255
 
256
  /* we finally put the task in the ready queue */
257
  proc_table[p].status = FREE;
29 pj 258
  iq_insertfirst(p,&freedesc);
2 pj 259
 
260
  /* and free the allocated bandwidth */
261
  lev->U -= (MAX_BANDWIDTH/lev->period[p]) * proc_table[p].wcet;
262
 
263
}
264
 
265
 
266
/* The on-line guarantee is enabled only if the appropriate flag is set... */
38 pj 267
static int CBS_public_guarantee(LEVEL l, bandwidth_t *freebandwidth)
2 pj 268
{
269
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
270
 
159 pj 271
  if (*freebandwidth >= lev->U) {
272
    *freebandwidth -= lev->U;
273
    return 1;
2 pj 274
  }
275
  else
159 pj 276
    return 0;
2 pj 277
}
278
 
38 pj 279
static int CBS_public_create(LEVEL l, PID p, TASK_MODEL *m)
2 pj 280
{
281
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
38 pj 282
  SOFT_TASK_MODEL *soft;
2 pj 283
 
38 pj 284
  if (m->pclass != SOFT_PCLASS) return -1;
285
  if (m->level != 0 && m->level != l) return -1;
286
  soft = (SOFT_TASK_MODEL *)m;
287
  if (!(soft->met && soft->period)) return -1;
2 pj 288
 
38 pj 289
  soft = (SOFT_TASK_MODEL *)m;
290
 
159 pj 291
  if (lev->flags & CBS_ENABLE_GUARANTEE) {
292
    bandwidth_t b;
293
    b = (MAX_BANDWIDTH / soft->period) * soft->met;
294
 
295
    /* really update lev->U, checking an overflow... */
296
    if (MAX_BANDWIDTH - lev->U > b)
297
      lev->U += b;
298
    else
299
      return -1;
300
  }
301
 
2 pj 302
  /* Enable wcet check */
303
  proc_table[p].avail_time = soft->met;
304
  proc_table[p].wcet       = soft->met;
305
  proc_table[p].control   |= CONTROL_CAP;
306
 
307
  lev->nact[p] = 0;
308
  lev->period[p] = soft->period;
309
  NULL_TIMESPEC(&lev->cbs_dline[p]);
310
 
311
  if (soft->periodicity == APERIODIC)
312
    lev->flag[p] = CBS_APERIODIC;
313
  else
314
    lev->flag[p] = 0;
315
 
316
  if (soft->arrivals == SAVE_ARRIVALS)
317
    lev->flag[p] |= CBS_SAVE_ARRIVALS;
318
 
319
  return 0; /* OK, also if the task cannot be guaranteed... */
320
}
321
 
38 pj 322
static void CBS_public_detach(LEVEL l, PID p)
2 pj 323
{
324
  /* the CBS level doesn't introduce any dinamic allocated new field.
159 pj 325
     we have only to decrement the allocated bandwidth */
2 pj 326
 
327
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
328
 
159 pj 329
  if (lev->flags & CBS_ENABLE_GUARANTEE) {
2 pj 330
    lev->U -= (MAX_BANDWIDTH / lev->period[p]) * proc_table[p].wcet;
159 pj 331
  }
2 pj 332
}
333
 
38 pj 334
static int CBS_public_eligible(LEVEL l, PID p)
2 pj 335
{
336
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
337
  JOB_TASK_MODEL job;
338
 
339
  /* we have to check if the deadline and the wcet are correct...
340
     if the CBS level schedules in background with respect to others
341
     levels, there can be the case in witch a task is scheduled by
342
     schedule_time > CBS_deadline; in this case (not covered in the
343
     article because if there is only the standard scheduling policy
344
     this never apply) we reassign the deadline */
345
 
346
  if ( TIMESPEC_A_LT_B(&lev->cbs_dline[p], &schedule_time) ) {
347
    /* we kill the current activation */
348
    level_table[ lev->scheduling_level ]->
38 pj 349
      private_extract(lev->scheduling_level, p);
2 pj 350
 
351
    /* we modify the deadline ... */
352
    TIMESPEC_ASSIGN(&lev->cbs_dline[p], &schedule_time);
353
    ADDUSEC2TIMESPEC(lev->period[p], &lev->cbs_dline[p]);
354
 
355
    /* and the capacity */
356
    proc_table[p].avail_time = proc_table[p].wcet;
357
 
358
    /* and, finally, we reinsert the task in the master level */
359
    job_task_default_model(job, lev->cbs_dline[p]);
360
    job_task_def_noexc(job);
361
    level_table[ lev->scheduling_level ]->
38 pj 362
      private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
2 pj 363
 
364
    return -1;
365
  }
366
 
367
  return 0;
368
}
369
 
38 pj 370
static void CBS_public_dispatch(LEVEL l, PID p, int nostop)
2 pj 371
{
372
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
373
  level_table[ lev->scheduling_level ]->
38 pj 374
    private_dispatch(lev->scheduling_level,p,nostop);
2 pj 375
}
376
 
38 pj 377
static void CBS_public_epilogue(LEVEL l, PID p)
2 pj 378
{
379
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
380
  JOB_TASK_MODEL job;
381
 
382
  /* check if the wcet is finished... */
383
  if ( proc_table[p].avail_time <= 0) {
384
    /* we kill the current activation */
385
    level_table[ lev->scheduling_level ]->
38 pj 386
      private_extract(lev->scheduling_level, p);
2 pj 387
 
388
    /* we modify the deadline according to rule 4 ... */
389
    CBS_avail_time_check(lev, p);
390
 
391
    /* and, finally, we reinsert the task in the master level */
392
    job_task_default_model(job, lev->cbs_dline[p]);
393
    job_task_def_noexc(job);
394
    level_table[ lev->scheduling_level ]->
38 pj 395
      private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
2 pj 396
//    kern_printf("epil : dl %d per %d p %d |\n",
397
//              lev->cbs_dline[p].tv_nsec/1000,lev->period[p],p);
398
 
399
  }
400
  else
401
    /* the task has been preempted. it returns into the ready queue by
402
       calling the guest_epilogue... */
403
    level_table[ lev->scheduling_level ]->
38 pj 404
      private_epilogue(lev->scheduling_level,p);
2 pj 405
}
406
 
657 anton 407
static void CBS_public_activate(LEVEL l, PID p, struct timespec *t)
2 pj 408
{
409
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
410
 
212 giacomo 411
  if (lev->flag[p] & CBS_SLEEP) {
412
    lev->flag[p] &= ~CBS_SLEEP;
413
    if (proc_table[p].status != SLEEP) return;
414
  }
415
 
2 pj 416
  /* save activation (only if needed... */
417
  if (proc_table[p].status != SLEEP) {
418
    if (lev->flag[p] & CBS_SAVE_ARRIVALS)
419
      lev->nact[p]++;
420
    return;
421
  }
422
 
657 anton 423
  CBS_activation(lev, p, t);
2 pj 424
 
425
  /* Set the reactivation timer */
426
  if (!(lev->flag[p] & CBS_APERIODIC))
427
  {
428
    /* we cannot use the deadline computed by CBS_activation because
429
       the deadline may be != from actual_time + period
430
       (if we call the task_activate after a task_sleep, and the
431
       deadline was postponed a lot...) */
657 anton 432
    TIMESPEC_ASSIGN(&lev->reactivation_time[p], t);
2 pj 433
    ADDUSEC2TIMESPEC(lev->period[p], &lev->reactivation_time[p]);
434
//    TIMESPEC_ASSIGN(&lev->reactivation_time[p], &lev->cbs_dline[p]);
435
    lev->reactivation_timer[p] = kern_event_post(&lev->reactivation_time[p],
436
                                                 CBS_timer_reactivate,
437
                                                 (void *)p);
438
    #ifdef CBS_COUNTER
439
      if (p==5) cbs_counter2++;
440
    #endif
441
  }
442
//  kern_printf("act : %d %d |",lev->cbs_dline[p].tv_nsec/1000,p);
443
}
444
 
38 pj 445
static void CBS_public_unblock(LEVEL l, PID p)
2 pj 446
{
447
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
448
  struct timespec acttime;
449
 
38 pj 450
  kern_gettime(&acttime);
2 pj 451
 
452
  CBS_activation(lev,p,&acttime);
453
}
454
 
38 pj 455
static void CBS_public_block(LEVEL l, PID p)
2 pj 456
{
457
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
458
 
459
  /* check if the wcet is finished... */
460
  CBS_avail_time_check(lev, p);
461
 
462
  level_table[ lev->scheduling_level ]->
38 pj 463
    private_extract(lev->scheduling_level,p);
2 pj 464
}
465
 
38 pj 466
static int CBS_public_message(LEVEL l, PID p, void *m)
2 pj 467
{
468
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
469
 
212 giacomo 470
  switch((long)(m)) {
2 pj 471
 
212 giacomo 472
    case (long)(NULL):
2 pj 473
 
212 giacomo 474
      /* check if the wcet is finished... */
475
      CBS_avail_time_check(lev, p);
476
 
477
      if (lev->nact[p]) {
478
        /* continue!!!! */
479
        lev->nact[p]--;
480
        level_table[ lev->scheduling_level ]->
481
          private_epilogue(lev->scheduling_level,p);
482
      } else {
483
        level_table[ lev->scheduling_level ]->
484
          private_extract(lev->scheduling_level,p);
485
 
486
        if (lev->flag[p] & CBS_APERIODIC)
487
          proc_table[p].status = SLEEP;
488
        else  /* the task is soft_periodic */
489
          proc_table[p].status = CBS_IDLE;
490
      }
491
 
492
      jet_update_endcycle(); /* Update the Jet data... */
502 giacomo 493
      TRACER_LOGEVENT(FTrace_EVT_task_end_cycle,(unsigned short int)proc_table[p].context,(unsigned int)l);
212 giacomo 494
 
495
      break;
496
 
497
    case 1:
498
 
499
      lev->flag[p] |= CBS_SLEEP;
502 giacomo 500
      TRACER_LOGEVENT(FTrace_EVT_task_disable,(unsigned short int)proc_table[p].context,(unsigned int)l);
212 giacomo 501
 
502
      break;
503
 
38 pj 504
  }
2 pj 505
 
212 giacomo 506
  return 0;
38 pj 507
 
2 pj 508
}
509
 
38 pj 510
static void CBS_public_end(LEVEL l, PID p)
2 pj 511
{
512
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
513
 
514
  /* check if the wcet is finished... */
515
  CBS_avail_time_check(lev, p);
516
 
517
  level_table[ lev->scheduling_level ]->
38 pj 518
    private_extract(lev->scheduling_level,p);
2 pj 519
 
520
  /* we delete the reactivation timer */
521
  if (!(lev->flag[p] & CBS_APERIODIC)) {
38 pj 522
    kern_event_delete(lev->reactivation_timer[p]);
2 pj 523
    lev->reactivation_timer[p] = -1;
524
  }
525
 
526
  /* Finally, we post the zombie event. when the end period is reached,
527
     the task descriptor and banwidth are freed */
528
  proc_table[p].status = CBS_ZOMBIE;
529
  lev->reactivation_timer[p] = kern_event_post(&lev->cbs_dline[p],
530
                                               CBS_timer_zombie,
531
                                               (void *)p);
532
}
533
 
534
/* Registration functions */
535
 
536
/*+ Registration function:
537
    int flags                 the init flags ... see CBS.h +*/
38 pj 538
LEVEL CBS_register_level(int flags, LEVEL master)
2 pj 539
{
540
  LEVEL l;            /* the level that we register */
541
  CBS_level_des *lev;  /* for readableness only */
542
  PID i;              /* a counter */
543
 
544
  printk("CBS_register_level\n");
545
 
546
  /* request an entry in the level_table */
38 pj 547
  l = level_alloc_descriptor(sizeof(CBS_level_des));
2 pj 548
 
38 pj 549
  lev = (CBS_level_des *)level_table[l];
2 pj 550
 
551
  /* fill the standard descriptor */
552
  if (flags & CBS_ENABLE_GUARANTEE)
38 pj 553
    lev->l.public_guarantee = CBS_public_guarantee;
2 pj 554
  else
38 pj 555
    lev->l.public_guarantee = NULL;
556
  lev->l.public_create    = CBS_public_create;
557
  lev->l.public_detach    = CBS_public_detach;
558
  lev->l.public_end       = CBS_public_end;
559
  lev->l.public_eligible  = CBS_public_eligible;
560
  lev->l.public_dispatch  = CBS_public_dispatch;
561
  lev->l.public_epilogue  = CBS_public_epilogue;
562
  lev->l.public_activate  = CBS_public_activate;
563
  lev->l.public_unblock   = CBS_public_unblock;
564
  lev->l.public_block     = CBS_public_block;
565
  lev->l.public_message   = CBS_public_message;
2 pj 566
 
567
  /* fill the CBS descriptor part */
568
  for (i=0; i<MAX_PROC; i++) {
569
     NULL_TIMESPEC(&lev->cbs_dline[i]);
570
     lev->period[i] = 0;
571
     NULL_TIMESPEC(&lev->reactivation_time[i]);
572
     lev->reactivation_timer[i] = -1;
573
     lev->nact[i] = 0;
574
     lev->flag[i] = 0;
575
  }
576
 
577
 
578
  lev->U = 0;
579
 
580
  lev->scheduling_level = master;
581
 
159 pj 582
  lev->flags = flags;
38 pj 583
 
584
  return l;
2 pj 585
}
586
 
587
bandwidth_t CBS_usedbandwidth(LEVEL l)
588
{
589
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
38 pj 590
 
591
  return lev->U;
2 pj 592
}
593
 
594
int CBS_get_nact(LEVEL l, PID p)
595
{
596
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
597
 
598
  return lev->nact[p];
599
}
600