Subversion Repositories shark

Rev

Rev 14 | 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
 ------------
29 pj 23
 CVS :        $Id: cbs.c,v 1.3 2002-11-11 08:32:06 pj Exp $
2 pj 24
 
25
 File:        $File$
29 pj 26
 Revision:    $Revision: 1.3 $
27
 Last update: $Date: 2002-11-11 08:32:06 $
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
#include <kernel/trace.h>
64
 
65
/*+ 4 debug purposes +*/
66
#undef CBS_TEST
67
#undef CBS_COUNTER
68
 
69
#ifdef TESTG
70
#include "drivers/glib.h"
71
TIME x,oldx;
72
extern TIME starttime;
73
#endif
74
 
75
 
76
/*+ Status used in the level +*/
77
#define CBS_IDLE          APER_STATUS_BASE   /*+ waiting the activation +*/
78
#define CBS_ZOMBIE        APER_STATUS_BASE+1 /*+ waiting the period end +*/
79
 
80
/*+ task flags +*/
81
#define CBS_SAVE_ARRIVALS 1
82
#define CBS_APERIODIC     2
83
 
84
/*+ the level redefinition for the Total Bandwidth Server level +*/
85
typedef struct {
86
  level_des l;     /*+ the standard level descriptor          +*/
87
 
88
  /* The wcet are stored in the task descriptor, but we need
89
     an array for the deadlines. We can't use the timespec_priority
90
     field because it is used by the master level!!!...
91
     Notice that however the use of the timespec_priority field
92
     does not cause any problem...                     */
93
 
94
  struct timespec cbs_dline[MAX_PROC]; /*+ CBS deadlines      +*/
95
 
96
  TIME period[MAX_PROC]; /*+ CBS activation period            +*/
97
 
98
  struct timespec reactivation_time[MAX_PROC];
99
        /*+ the time at witch  the reactivation timer is post +*/
100
  int reactivation_timer[MAX_PROC];
101
                                   /*+ the recativation timer +*/
102
 
103
  int nact[MAX_PROC]; /*+ number of pending activations       +*/
104
 
105
  BYTE flag[MAX_PROC]; /*+ task flags                         +*/
106
 
107
  int flags;       /*+ the init flags...                      +*/
108
 
109
  bandwidth_t U;   /*+ the used bandwidth by the server       +*/
110
 
111
  LEVEL scheduling_level;
112
 
113
} CBS_level_des;
114
 
115
#ifdef CBS_COUNTER
116
int cbs_counter=0;
117
int cbs_counter2=0;
118
#endif
119
 
120
 
121
static void CBS_activation(CBS_level_des *lev,
122
                           PID p,
123
                           struct timespec *acttime)
124
{
125
  JOB_TASK_MODEL job;
126
 
127
  /* we have to check if the deadline and the wcet are correct before
128
     activating a new task or an old task... */
129
 
130
  /* check 1: if the deadline is before than the actual scheduling time */
131
 
132
  /* check 2: if ( avail_time >= (cbs_dline - acttime)* (wcet/period) )
133
     (rule 7 in the CBS article!) */
134
  TIME t;
135
  struct timespec t2,t3;
136
 
137
  t = (lev->period[p] * proc_table[p].avail_time) / proc_table[p].wcet;
138
  t3.tv_sec = t / 1000000;
139
  t3.tv_nsec = (t % 1000000) * 1000;
140
 
141
  SUBTIMESPEC(&lev->cbs_dline[p], acttime, &t2);
142
 
143
  if (/* 1 */ TIMESPEC_A_LT_B(&lev->cbs_dline[p], acttime) ||
144
      /* 2 */ TIMESPEC_A_GT_B(&t3, &t2) ) {
145
/*    if (TIMESPEC_A_LT_B(&lev->cbs_dline[p], acttime) )
146
      kern_printf("$");
147
    else
148
      kern_printf("(Ûdline%d.%d act%d.%d wcet%d per%d avail%dÛ)",
149
                  lev->cbs_dline[p].tv_sec,lev->cbs_dline[p].tv_nsec/1000,
150
                  acttime->tv_sec, acttime->tv_nsec/1000,
151
                  proc_table[p].wcet, lev->period[p], proc_table[p].avail_time);
152
*/  /* we modify the deadline ... */
153
    TIMESPEC_ASSIGN(&lev->cbs_dline[p], acttime);
154
    ADDUSEC2TIMESPEC(lev->period[p], &lev->cbs_dline[p]);
155
 
156
    /* and the capacity */
157
    proc_table[p].avail_time = proc_table[p].wcet;
158
  }
159
 
160
#ifdef TESTG
161
      if (starttime && p == 3) {
162
      oldx = x;
163
      x = ((lev->cbs_dline[p].tv_sec*1000000+lev->cbs_dline[p].tv_nsec/1000)/5000 - starttime) + 20;
164
//      kern_printf("(a%d)",lev->cbs_dline[p].tv_sec*1000000+lev->cbs_dline[p].tv_nsec/1000);
165
      if (oldx > x) sys_end();
166
      if (x<640)
167
        grx_plot(x, 15, 8);
168
      }
169
#endif
170
 
171
  /* and, finally, we reinsert the task in the master level */
172
  job_task_default_model(job, lev->cbs_dline[p]);
173
  job_task_def_noexc(job);
174
  level_table[ lev->scheduling_level ]->
175
    guest_create(lev->scheduling_level, p, (TASK_MODEL *)&job);
176
  level_table[ lev->scheduling_level ]->
177
    guest_activate(lev->scheduling_level, p);
178
 
179
}
180
 
181
 
182
static char *CBS_status_to_a(WORD status)
183
{
184
  if (status < MODULE_STATUS_BASE)
185
    return status_to_a(status);
186
 
187
  switch (status) {
188
    case CBS_IDLE   : return "CBS_Idle";
189
    case CBS_ZOMBIE : return "CBS_Zombie";
190
    default         : return "CBS_Unknown";
191
  }
192
}
193
 
194
static void CBS_avail_time_check(CBS_level_des *lev, PID p)
195
{
196
  /* there is a while because if the wcet is << than the system tick
197
     we need to postpone the deadline many times */
198
  while (proc_table[p].avail_time <= 0) {
199
    ADDUSEC2TIMESPEC(lev->period[p], &lev->cbs_dline[p]);
200
    proc_table[p].avail_time += proc_table[p].wcet;
201
 
202
#ifdef TESTG
203
    if (starttime && p == 3) {
204
    oldx = x;
205
    x = ((lev->cbs_dline[p].tv_sec*1000000+lev->cbs_dline[p].tv_nsec/1000)/5000 - starttime) + 20;
206
//      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);
207
    if (oldx > x) sys_end();
208
    if (x<640)
209
      grx_plot(x, 15, 2);
210
    }
211
#endif
212
  }
213
}
214
 
215
 
216
/* this is the periodic reactivation of the task... it is posted only
217
   if the task is a periodic task */
218
static void CBS_timer_reactivate(void *par)
219
{
220
  PID p = (PID) par;
221
  CBS_level_des *lev;
222
 
223
  lev = (CBS_level_des *)level_table[proc_table[p].task_level];
224
 
225
  #ifdef CBS_COUNTER
226
    if (p==5) cbs_counter++;
227
  #endif
228
 
229
  if (proc_table[p].status == CBS_IDLE) {
230
    /* the task has finished the current activation and must be
231
       reactivated */
232
    CBS_activation(lev,p,&lev->reactivation_time[p]);
233
 
234
    event_need_reschedule();
235
  }
236
  else if (lev->flag[p] & CBS_SAVE_ARRIVALS)
237
    /* the task has not completed the current activation, so we save
238
       the activation incrementing nact... */
239
    lev->nact[p]++;
240
 
241
  /* repost the event at the next period end... */
242
  ADDUSEC2TIMESPEC(lev->period[p], &lev->reactivation_time[p]);
243
  lev->reactivation_timer[p] = kern_event_post(&lev->reactivation_time[p],
244
                                               CBS_timer_reactivate,
245
                                               (void *)p);
246
  #ifdef CBS_COUNTER
247
    if (p==5) cbs_counter2++;
248
  #endif
249
  /* tracer stuff */
250
  trc_logevent(TRC_INTACTIVATION,&p);
251
 
252
}
253
 
254
/*+ this function is called when a killed or ended task reach the
255
    period end +*/
256
static void CBS_timer_zombie(void *par)
257
{
258
  PID p = (PID) par;
259
  CBS_level_des *lev;
260
 
261
  lev = (CBS_level_des *)level_table[proc_table[p].task_level];
262
 
263
  /* we finally put the task in the ready queue */
264
  proc_table[p].status = FREE;
29 pj 265
  iq_insertfirst(p,&freedesc);
2 pj 266
 
267
  /* and free the allocated bandwidth */
268
  lev->U -= (MAX_BANDWIDTH/lev->period[p]) * proc_table[p].wcet;
269
 
270
}
271
 
272
 
273
static int CBS_level_accept_task_model(LEVEL l, TASK_MODEL *m)
274
{
275
  if (m->pclass == SOFT_PCLASS || m->pclass == (SOFT_PCLASS | l)) {
276
    SOFT_TASK_MODEL *s = (SOFT_TASK_MODEL *)m;
277
    if (s->met && s->period)
278
      return 0;
279
  }
280
 
281
  return -1;
282
}
283
 
284
static int CBS_level_accept_guest_model(LEVEL l, TASK_MODEL *m)
285
{
286
  return -1;
287
}
288
 
289
static char *onoff(int i)
290
{
291
  if (i)
292
    return "On ";
293
  else
294
    return "Off";
295
}
296
 
297
static void CBS_level_status(LEVEL l)
298
{
299
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
300
  PID p;
301
 
302
  kern_printf("On-line guarantee : %s\n",
303
            onoff(lev->flags & CBS_ENABLE_GUARANTEE));
304
  kern_printf("Used Bandwidth    : %u/%u\n",
305
            lev->U, MAX_BANDWIDTH);
306
 
307
  for (p=0; p<MAX_PROC; p++)
308
    if (proc_table[p].task_level == l && proc_table[p].status != FREE )
309
      kern_printf("Pid: %2d Name: %10s Period: %9ld Dline: %9ld.%6ld Stat: %s\n",
310
                p,
311
                proc_table[p].name,
312
                lev->period[p],
313
                lev->cbs_dline[p].tv_sec,
314
                lev->cbs_dline[p].tv_nsec/1000,
315
                CBS_status_to_a(proc_table[p].status));
316
}
317
 
318
static PID CBS_level_scheduler(LEVEL l)
319
{
320
  /* the CBS don't schedule anything...
321
     it's an EDF level or similar that do it! */
322
  return NIL;
323
}
324
 
325
/* The on-line guarantee is enabled only if the appropriate flag is set... */
326
static int CBS_level_guarantee(LEVEL l, bandwidth_t *freebandwidth)
327
{
328
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
329
 
330
  if (lev->flags & CBS_FAILED_GUARANTEE) {
331
    *freebandwidth = 0;
332
    return 0;
333
  }
334
  else
335
    if (*freebandwidth >= lev->U) {
336
      *freebandwidth -= lev->U;
337
      return 1;
338
    }
339
    else
340
      return 0;
341
}
342
 
343
static int CBS_task_create(LEVEL l, PID p, TASK_MODEL *m)
344
{
345
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
346
 
347
  /* if the CBS_task_create is called, then the pclass must be a
348
     valid pclass. */
349
  SOFT_TASK_MODEL *soft = (SOFT_TASK_MODEL *)m;
350
 
351
  /* Enable wcet check */
352
  proc_table[p].avail_time = soft->met;
353
  proc_table[p].wcet       = soft->met;
354
  proc_table[p].control   |= CONTROL_CAP;
355
 
356
  lev->nact[p] = 0;
357
  lev->period[p] = soft->period;
358
  NULL_TIMESPEC(&lev->cbs_dline[p]);
359
 
360
  if (soft->periodicity == APERIODIC)
361
    lev->flag[p] = CBS_APERIODIC;
362
  else
363
    lev->flag[p] = 0;
364
 
365
  if (soft->arrivals == SAVE_ARRIVALS)
366
    lev->flag[p] |= CBS_SAVE_ARRIVALS;
367
 
368
  /* update the bandwidth... */
369
  if (lev->flags & CBS_ENABLE_GUARANTEE) {
370
    bandwidth_t b;
371
    b = (MAX_BANDWIDTH / soft->period) * soft->met;
372
 
373
    /* really update lev->U, checking an overflow... */
374
    if (MAX_BANDWIDTH - lev->U > b)
375
      lev->U += b;
376
    else
377
      /* The task can NOT be guaranteed (U>MAX_BANDWIDTH)...
378
         (see EDF.c) */
379
      lev->flags |= CBS_FAILED_GUARANTEE;
380
  }
381
 
382
 
383
  return 0; /* OK, also if the task cannot be guaranteed... */
384
}
385
 
386
static void CBS_task_detach(LEVEL l, PID p)
387
{
388
  /* the CBS level doesn't introduce any dinamic allocated new field.
389
     we have only to reset the NO_GUARANTEE FIELD and decrement the allocated
390
     bandwidth */
391
 
392
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
393
 
394
  if (lev->flags & CBS_FAILED_GUARANTEE)
395
    lev->flags &= ~CBS_FAILED_GUARANTEE;
396
  else
397
    lev->U -= (MAX_BANDWIDTH / lev->period[p]) * proc_table[p].wcet;
398
}
399
 
400
static int CBS_task_eligible(LEVEL l, PID p)
401
{
402
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
403
  JOB_TASK_MODEL job;
404
 
405
  /* we have to check if the deadline and the wcet are correct...
406
     if the CBS level schedules in background with respect to others
407
     levels, there can be the case in witch a task is scheduled by
408
     schedule_time > CBS_deadline; in this case (not covered in the
409
     article because if there is only the standard scheduling policy
410
     this never apply) we reassign the deadline */
411
 
412
  if ( TIMESPEC_A_LT_B(&lev->cbs_dline[p], &schedule_time) ) {
413
    /* we kill the current activation */
414
    level_table[ lev->scheduling_level ]->
415
      guest_end(lev->scheduling_level, p);
416
 
417
    /* we modify the deadline ... */
418
    TIMESPEC_ASSIGN(&lev->cbs_dline[p], &schedule_time);
419
    ADDUSEC2TIMESPEC(lev->period[p], &lev->cbs_dline[p]);
420
 
421
    /* and the capacity */
422
    proc_table[p].avail_time = proc_table[p].wcet;
423
 
424
    /* and, finally, we reinsert the task in the master level */
425
    job_task_default_model(job, lev->cbs_dline[p]);
426
    job_task_def_noexc(job);
427
    level_table[ lev->scheduling_level ]->
428
      guest_create(lev->scheduling_level, p, (TASK_MODEL *)&job);
429
    level_table[ lev->scheduling_level ]->
430
      guest_activate(lev->scheduling_level, p);
431
 
432
    return -1;
433
  }
434
 
435
  return 0;
436
}
437
 
438
static void CBS_task_dispatch(LEVEL l, PID p, int nostop)
439
{
440
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
441
  level_table[ lev->scheduling_level ]->
442
    guest_dispatch(lev->scheduling_level,p,nostop);
443
}
444
 
445
static void CBS_task_epilogue(LEVEL l, PID p)
446
{
447
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
448
  JOB_TASK_MODEL job;
449
 
450
  /* check if the wcet is finished... */
451
  if ( proc_table[p].avail_time <= 0) {
452
    /* we kill the current activation */
453
    level_table[ lev->scheduling_level ]->
454
      guest_end(lev->scheduling_level, p);
455
 
456
    /* we modify the deadline according to rule 4 ... */
457
    CBS_avail_time_check(lev, p);
458
 
459
    /* and, finally, we reinsert the task in the master level */
460
    job_task_default_model(job, lev->cbs_dline[p]);
461
    job_task_def_noexc(job);
462
    level_table[ lev->scheduling_level ]->
463
      guest_create(lev->scheduling_level, p, (TASK_MODEL *)&job);
464
    level_table[ lev->scheduling_level ]->
465
      guest_activate(lev->scheduling_level, p);
466
//    kern_printf("epil : dl %d per %d p %d |\n",
467
//              lev->cbs_dline[p].tv_nsec/1000,lev->period[p],p);
468
 
469
  }
470
  else
471
    /* the task has been preempted. it returns into the ready queue by
472
       calling the guest_epilogue... */
473
    level_table[ lev->scheduling_level ]->
474
      guest_epilogue(lev->scheduling_level,p);
475
}
476
 
477
static void CBS_task_activate(LEVEL l, PID p)
478
{
479
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
480
 
481
  /* save activation (only if needed... */
482
  if (proc_table[p].status != SLEEP) {
483
    if (lev->flag[p] & CBS_SAVE_ARRIVALS)
484
      lev->nact[p]++;
485
    return;
486
  }
487
 
488
  ll_gettime(TIME_EXACT, &proc_table[p].request_time);
489
 
490
  CBS_activation(lev, p, &proc_table[p].request_time);
491
 
492
  /* Set the reactivation timer */
493
  if (!(lev->flag[p] & CBS_APERIODIC))
494
  {
495
    /* we cannot use the deadline computed by CBS_activation because
496
       the deadline may be != from actual_time + period
497
       (if we call the task_activate after a task_sleep, and the
498
       deadline was postponed a lot...) */
499
    TIMESPEC_ASSIGN(&lev->reactivation_time[p], &proc_table[p].request_time);
500
    ADDUSEC2TIMESPEC(lev->period[p], &lev->reactivation_time[p]);
501
//    TIMESPEC_ASSIGN(&lev->reactivation_time[p], &lev->cbs_dline[p]);
502
    lev->reactivation_timer[p] = kern_event_post(&lev->reactivation_time[p],
503
                                                 CBS_timer_reactivate,
504
                                                 (void *)p);
505
    #ifdef CBS_COUNTER
506
      if (p==5) cbs_counter2++;
507
    #endif
508
  }
509
//  kern_printf("act : %d %d |",lev->cbs_dline[p].tv_nsec/1000,p);
510
}
511
 
512
static void CBS_task_insert(LEVEL l, PID p)
513
{
514
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
515
  struct timespec acttime;
516
 
517
  ll_gettime(TIME_EXACT, &acttime);
518
 
519
  CBS_activation(lev,p,&acttime);
520
}
521
 
522
static void CBS_task_extract(LEVEL l, PID p)
523
{
524
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
525
 
526
  /* check if the wcet is finished... */
527
  CBS_avail_time_check(lev, p);
528
 
529
  level_table[ lev->scheduling_level ]->
530
    guest_end(lev->scheduling_level,p);
531
}
532
 
533
static void CBS_task_endcycle(LEVEL l, PID p)
534
{
535
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
536
 
537
  /* check if the wcet is finished... */
538
  CBS_avail_time_check(lev, p);
539
 
540
  if (lev->nact[p]) {
541
    /* continue!!!! */
542
    ll_gettime(TIME_EXACT, &proc_table[p].request_time);
543
    lev->nact[p]--;
544
    level_table[ lev->scheduling_level ]->
545
      guest_epilogue(lev->scheduling_level,p);
546
  }
547
  else {
548
    level_table[ lev->scheduling_level ]->
549
      guest_end(lev->scheduling_level,p);
550
 
551
    if (lev->flag[p] & CBS_APERIODIC)
552
      proc_table[p].status = SLEEP;
553
    else  /* the task is soft_periodic */
554
      proc_table[p].status = CBS_IDLE;
555
 
556
  }
557
}
558
 
559
static void CBS_task_end(LEVEL l, PID p)
560
{
561
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
562
 
563
  /* check if the wcet is finished... */
564
  CBS_avail_time_check(lev, p);
565
 
566
  level_table[ lev->scheduling_level ]->
567
    guest_end(lev->scheduling_level,p);
568
 
569
  /* we delete the reactivation timer */
570
  if (!(lev->flag[p] & CBS_APERIODIC)) {
571
    event_delete(lev->reactivation_timer[p]);
572
    lev->reactivation_timer[p] = -1;
573
  }
574
 
575
  /* Finally, we post the zombie event. when the end period is reached,
576
     the task descriptor and banwidth are freed */
577
  proc_table[p].status = CBS_ZOMBIE;
578
  lev->reactivation_timer[p] = kern_event_post(&lev->cbs_dline[p],
579
                                               CBS_timer_zombie,
580
                                               (void *)p);
581
}
582
 
583
static void CBS_task_sleep(LEVEL l, PID p)
584
{
585
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
586
 
587
  /* check if the wcet is finished... */
588
  CBS_avail_time_check(lev, p);
589
 
590
  /* a task activation is finished, but we are using a JOB_TASK_MODEL
591
     that implements a single activation, so we have to call
592
     the guest_end, that representsa single activation... */
593
  level_table[ lev->scheduling_level ]->
594
    guest_end(lev->scheduling_level,p);
595
 
596
  /* we delete the reactivation timer */
597
  if (!(lev->flag[p] & CBS_APERIODIC)) {
598
    event_delete(lev->reactivation_timer[p]);
599
    lev->reactivation_timer[p] = -1;
600
  }
601
 
602
  proc_table[p].status = SLEEP;
603
 
604
  /* the sleep forgets pending activations... */
605
  lev->nact[p] = 0;
606
}
607
 
608
static int CBS_guest_create(LEVEL l, PID p, TASK_MODEL *m)
14 pj 609
{ kern_raise(XINVALID_GUEST,exec_shadow); return 0; }
2 pj 610
 
611
static void CBS_guest_detach(LEVEL l, PID p)
14 pj 612
{ kern_raise(XINVALID_GUEST,exec_shadow); }
2 pj 613
 
614
static void CBS_guest_dispatch(LEVEL l, PID p, int nostop)
14 pj 615
{ kern_raise(XINVALID_GUEST,exec_shadow); }
2 pj 616
 
617
static void CBS_guest_epilogue(LEVEL l, PID p)
14 pj 618
{ kern_raise(XINVALID_GUEST,exec_shadow); }
2 pj 619
 
620
static void CBS_guest_activate(LEVEL l, PID p)
14 pj 621
{ kern_raise(XINVALID_GUEST,exec_shadow); }
2 pj 622
 
623
static void CBS_guest_insert(LEVEL l, PID p)
14 pj 624
{ kern_raise(XINVALID_GUEST,exec_shadow); }
2 pj 625
 
626
static void CBS_guest_extract(LEVEL l, PID p)
14 pj 627
{ kern_raise(XINVALID_GUEST,exec_shadow); }
2 pj 628
 
629
static void CBS_guest_endcycle(LEVEL l, PID p)
14 pj 630
{ kern_raise(XINVALID_GUEST,exec_shadow); }
2 pj 631
 
632
static void CBS_guest_end(LEVEL l, PID p)
14 pj 633
{ kern_raise(XINVALID_GUEST,exec_shadow); }
2 pj 634
 
635
static void CBS_guest_sleep(LEVEL l, PID p)
14 pj 636
{ kern_raise(XINVALID_GUEST,exec_shadow); }
2 pj 637
 
638
 
639
/* Registration functions */
640
 
641
/*+ Registration function:
642
    int flags                 the init flags ... see CBS.h +*/
643
void CBS_register_level(int flags, LEVEL master)
644
{
645
  LEVEL l;            /* the level that we register */
646
  CBS_level_des *lev;  /* for readableness only */
647
  PID i;              /* a counter */
648
 
649
  printk("CBS_register_level\n");
650
 
651
  /* request an entry in the level_table */
652
  l = level_alloc_descriptor();
653
 
654
  printk("    alloco descrittore %d %d\n",l,(int)sizeof(CBS_level_des));
655
 
656
  /* alloc the space needed for the CBS_level_des */
657
  lev = (CBS_level_des *)kern_alloc(sizeof(CBS_level_des));
658
 
659
  printk("    lev=%d\n",(int)lev);
660
 
661
  /* update the level_table with the new entry */
662
  level_table[l] = (level_des *)lev;
663
 
664
  /* fill the standard descriptor */
665
  strncpy(lev->l.level_name,  CBS_LEVELNAME, MAX_LEVELNAME);
666
  lev->l.level_code               = CBS_LEVEL_CODE;
667
  lev->l.level_version            = CBS_LEVEL_VERSION;
668
 
669
  lev->l.level_accept_task_model  = CBS_level_accept_task_model;
670
  lev->l.level_accept_guest_model = CBS_level_accept_guest_model;
671
  lev->l.level_status             = CBS_level_status;
672
  lev->l.level_scheduler          = CBS_level_scheduler;
673
 
674
  if (flags & CBS_ENABLE_GUARANTEE)
675
    lev->l.level_guarantee        = CBS_level_guarantee;
676
  else
677
    lev->l.level_guarantee        = NULL;
678
 
679
  lev->l.task_create              = CBS_task_create;
680
  lev->l.task_detach              = CBS_task_detach;
681
  lev->l.task_eligible            = CBS_task_eligible;
682
  lev->l.task_dispatch            = CBS_task_dispatch;
683
  lev->l.task_epilogue            = CBS_task_epilogue;
684
  lev->l.task_activate            = CBS_task_activate;
685
  lev->l.task_insert              = CBS_task_insert;
686
  lev->l.task_extract             = CBS_task_extract;
687
  lev->l.task_endcycle            = CBS_task_endcycle;
688
  lev->l.task_end                 = CBS_task_end;
689
  lev->l.task_sleep               = CBS_task_sleep;
690
 
691
  lev->l.guest_create             = CBS_guest_create;
692
  lev->l.guest_detach             = CBS_guest_detach;
693
  lev->l.guest_dispatch           = CBS_guest_dispatch;
694
  lev->l.guest_epilogue           = CBS_guest_epilogue;
695
  lev->l.guest_activate           = CBS_guest_activate;
696
  lev->l.guest_insert             = CBS_guest_insert;
697
  lev->l.guest_extract            = CBS_guest_extract;
698
  lev->l.guest_endcycle           = CBS_guest_endcycle;
699
  lev->l.guest_end                = CBS_guest_end;
700
  lev->l.guest_sleep              = CBS_guest_sleep;
701
 
702
  /* fill the CBS descriptor part */
703
  for (i=0; i<MAX_PROC; i++) {
704
     NULL_TIMESPEC(&lev->cbs_dline[i]);
705
     lev->period[i] = 0;
706
     NULL_TIMESPEC(&lev->reactivation_time[i]);
707
     lev->reactivation_timer[i] = -1;
708
     lev->nact[i] = 0;
709
     lev->flag[i] = 0;
710
  }
711
 
712
 
713
  lev->U = 0;
714
 
715
  lev->scheduling_level = master;
716
 
717
  lev->flags = flags & 0x01;
718
}
719
 
720
bandwidth_t CBS_usedbandwidth(LEVEL l)
721
{
722
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
723
  if (lev->l.level_code    == CBS_LEVEL_CODE &&
724
      lev->l.level_version == CBS_LEVEL_VERSION)
725
    return lev->U;
726
  else
727
    return 0;
728
}
729
 
730
int CBS_get_nact(LEVEL l, PID p)
731
{
732
  CBS_level_des *lev = (CBS_level_des *)(level_table[l]);
733
 
734
  return lev->nact[p];
735
}
736