Subversion Repositories shark

Rev

Rev 214 | 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
 ------------
353 giacomo 23
 CVS :        $Id: cbs.c,v 1.8 2003-12-10 16:54:59 giacomo Exp $
2 pj 24
 
25
 File:        $File$
353 giacomo 26
 Revision:    $Revision: 1.8 $
27
 Last update: $Date: 2003-12-10 16:54:59 $
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 */
353 giacomo 243
  TRACER_LOGEVENT(FTrace_EVT_task_timer,3,p,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
 
38 pj 407
static void CBS_public_activate(LEVEL l, PID p)
2 pj 408
{
409
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
38 pj 410
  struct timespec t;
2 pj 411
 
212 giacomo 412
  if (lev->flag[p] & CBS_SLEEP) {
413
    lev->flag[p] &= ~CBS_SLEEP;
414
    if (proc_table[p].status != SLEEP) return;
415
  }
416
 
2 pj 417
  /* save activation (only if needed... */
418
  if (proc_table[p].status != SLEEP) {
419
    if (lev->flag[p] & CBS_SAVE_ARRIVALS)
420
      lev->nact[p]++;
421
    return;
422
  }
423
 
38 pj 424
  kern_gettime(&t);
2 pj 425
 
38 pj 426
  CBS_activation(lev, p, &t);
2 pj 427
 
428
  /* Set the reactivation timer */
429
  if (!(lev->flag[p] & CBS_APERIODIC))
430
  {
431
    /* we cannot use the deadline computed by CBS_activation because
432
       the deadline may be != from actual_time + period
433
       (if we call the task_activate after a task_sleep, and the
434
       deadline was postponed a lot...) */
38 pj 435
    TIMESPEC_ASSIGN(&lev->reactivation_time[p], &t);
2 pj 436
    ADDUSEC2TIMESPEC(lev->period[p], &lev->reactivation_time[p]);
437
//    TIMESPEC_ASSIGN(&lev->reactivation_time[p], &lev->cbs_dline[p]);
438
    lev->reactivation_timer[p] = kern_event_post(&lev->reactivation_time[p],
439
                                                 CBS_timer_reactivate,
440
                                                 (void *)p);
441
    #ifdef CBS_COUNTER
442
      if (p==5) cbs_counter2++;
443
    #endif
444
  }
445
//  kern_printf("act : %d %d |",lev->cbs_dline[p].tv_nsec/1000,p);
446
}
447
 
38 pj 448
static void CBS_public_unblock(LEVEL l, PID p)
2 pj 449
{
450
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
451
  struct timespec acttime;
452
 
38 pj 453
  kern_gettime(&acttime);
2 pj 454
 
455
  CBS_activation(lev,p,&acttime);
456
}
457
 
38 pj 458
static void CBS_public_block(LEVEL l, PID p)
2 pj 459
{
460
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
461
 
462
  /* check if the wcet is finished... */
463
  CBS_avail_time_check(lev, p);
464
 
465
  level_table[ lev->scheduling_level ]->
38 pj 466
    private_extract(lev->scheduling_level,p);
2 pj 467
}
468
 
38 pj 469
static int CBS_public_message(LEVEL l, PID p, void *m)
2 pj 470
{
471
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
472
 
212 giacomo 473
  switch((long)(m)) {
2 pj 474
 
212 giacomo 475
    case (long)(NULL):
2 pj 476
 
212 giacomo 477
      /* check if the wcet is finished... */
478
      CBS_avail_time_check(lev, p);
479
 
480
      if (lev->nact[p]) {
481
        /* continue!!!! */
482
        lev->nact[p]--;
483
        level_table[ lev->scheduling_level ]->
484
          private_epilogue(lev->scheduling_level,p);
485
      } else {
486
        level_table[ lev->scheduling_level ]->
487
          private_extract(lev->scheduling_level,p);
488
 
489
        if (lev->flag[p] & CBS_APERIODIC)
490
          proc_table[p].status = SLEEP;
491
        else  /* the task is soft_periodic */
492
          proc_table[p].status = CBS_IDLE;
493
      }
494
 
495
      jet_update_endcycle(); /* Update the Jet data... */
353 giacomo 496
      TRACER_LOGEVENT(FTrace_EVT_task_end_cycle,3,p,l);
212 giacomo 497
 
498
      break;
499
 
500
    case 1:
501
 
502
      lev->flag[p] |= CBS_SLEEP;
353 giacomo 503
      TRACER_LOGEVENT(FTrace_EVT_task_disable,3,p,l);
212 giacomo 504
 
505
      break;
506
 
38 pj 507
  }
2 pj 508
 
212 giacomo 509
  return 0;
38 pj 510
 
2 pj 511
}
512
 
38 pj 513
static void CBS_public_end(LEVEL l, PID p)
2 pj 514
{
515
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
516
 
517
  /* check if the wcet is finished... */
518
  CBS_avail_time_check(lev, p);
519
 
520
  level_table[ lev->scheduling_level ]->
38 pj 521
    private_extract(lev->scheduling_level,p);
2 pj 522
 
523
  /* we delete the reactivation timer */
524
  if (!(lev->flag[p] & CBS_APERIODIC)) {
38 pj 525
    kern_event_delete(lev->reactivation_timer[p]);
2 pj 526
    lev->reactivation_timer[p] = -1;
527
  }
528
 
529
  /* Finally, we post the zombie event. when the end period is reached,
530
     the task descriptor and banwidth are freed */
531
  proc_table[p].status = CBS_ZOMBIE;
532
  lev->reactivation_timer[p] = kern_event_post(&lev->cbs_dline[p],
533
                                               CBS_timer_zombie,
534
                                               (void *)p);
535
}
536
 
537
/* Registration functions */
538
 
539
/*+ Registration function:
540
    int flags                 the init flags ... see CBS.h +*/
38 pj 541
LEVEL CBS_register_level(int flags, LEVEL master)
2 pj 542
{
543
  LEVEL l;            /* the level that we register */
544
  CBS_level_des *lev;  /* for readableness only */
545
  PID i;              /* a counter */
546
 
547
  printk("CBS_register_level\n");
548
 
549
  /* request an entry in the level_table */
38 pj 550
  l = level_alloc_descriptor(sizeof(CBS_level_des));
2 pj 551
 
38 pj 552
  lev = (CBS_level_des *)level_table[l];
2 pj 553
 
554
  printk("    lev=%d\n",(int)lev);
555
 
556
  /* fill the standard descriptor */
557
  if (flags & CBS_ENABLE_GUARANTEE)
38 pj 558
    lev->l.public_guarantee = CBS_public_guarantee;
2 pj 559
  else
38 pj 560
    lev->l.public_guarantee = NULL;
561
  lev->l.public_create    = CBS_public_create;
562
  lev->l.public_detach    = CBS_public_detach;
563
  lev->l.public_end       = CBS_public_end;
564
  lev->l.public_eligible  = CBS_public_eligible;
565
  lev->l.public_dispatch  = CBS_public_dispatch;
566
  lev->l.public_epilogue  = CBS_public_epilogue;
567
  lev->l.public_activate  = CBS_public_activate;
568
  lev->l.public_unblock   = CBS_public_unblock;
569
  lev->l.public_block     = CBS_public_block;
570
  lev->l.public_message   = CBS_public_message;
2 pj 571
 
572
  /* fill the CBS descriptor part */
573
  for (i=0; i<MAX_PROC; i++) {
574
     NULL_TIMESPEC(&lev->cbs_dline[i]);
575
     lev->period[i] = 0;
576
     NULL_TIMESPEC(&lev->reactivation_time[i]);
577
     lev->reactivation_timer[i] = -1;
578
     lev->nact[i] = 0;
579
     lev->flag[i] = 0;
580
  }
581
 
582
 
583
  lev->U = 0;
584
 
585
  lev->scheduling_level = master;
586
 
159 pj 587
  lev->flags = flags;
38 pj 588
 
589
  return l;
2 pj 590
}
591
 
592
bandwidth_t CBS_usedbandwidth(LEVEL l)
593
{
594
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
38 pj 595
 
596
  return lev->U;
2 pj 597
}
598
 
599
int CBS_get_nact(LEVEL l, PID p)
600
{
601
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
602
 
603
  return lev->nact[p];
604
}
605