Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1085 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
 *   (see the web pages for full authors list)
11
 *
12
 * ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
13
 *
14
 * http://www.sssup.it
15
 * http://retis.sssup.it
16
 * http://shark.sssup.it
17
 */
18
 
19
/**
20
 ------------
21
 CVS :        $Id: edfact.c,v 1.1.1.1 2002-09-02 09:37:42 pj Exp $
22
 
23
 File:        $File$
24
 Revision:    $Revision: 1.1.1.1 $
25
 Last update: $Date: 2002-09-02 09:37:42 $
26
 ------------
27
**/
28
 
29
/*
30
 * Copyright (C) 2001 Paolo Gai
31
 *
32
 * This program is free software; you can redistribute it and/or modify
33
 * it under the terms of the GNU General Public License as published by
34
 * the Free Software Foundation; either version 2 of the License, or
35
 * (at your option) any later version.
36
 *
37
 * This program is distributed in the hope that it will be useful,
38
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
39
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
40
 * GNU General Public License for more details.
41
 *
42
 * You should have received a copy of the GNU General Public License
43
 * along with this program; if not, write to the Free Software
44
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
45
 *
46
 */
47
 
48
#include "edfact.h"
49
#include <ll/stdio.h>
50
#include <ll/string.h>
51
#include <kernel/model.h>
52
#include <kernel/descr.h>
53
#include <kernel/var.h>
54
#include <kernel/func.h>
55
#include <kernel/trace.h>
56
 
57
//#define edfact_printf kern_printf
58
#define edfact_printf printk
59
 
60
/*+ Status used in the level +*/
61
#define EDFACT_READY         MODULE_STATUS_BASE    /*+ - Ready status        +*/
62
#define EDFACT_IDLE          MODULE_STATUS_BASE+4  /*+ to wait the deadline  +*/
63
 
64
/*+ flags +*/
65
#define EDFACT_FLAG_NORAISEEXC  2
66
 
67
/*+ the level redefinition for the Earliest Deadline First level +*/
68
typedef struct {
69
  level_des l;     /*+ the standard level descriptor          +*/
70
 
71
  TIME period[MAX_PROC]; /*+ The task periods; the deadlines are
72
                       stored in the priority field           +*/
73
  int deadline_timer[MAX_PROC];
74
                   /*+ The task deadline timers               +*/
75
 
76
  struct timespec deadline_timespec[MAX_PROC];
77
 
78
  int dline_miss[MAX_PROC]; /*+ Deadline miss counter +*/
79
  int wcet_miss[MAX_PROC];  /*+ Wcet miss counter +*/
80
 
81
  int nact[MAX_PROC];       /*+ Wcet miss counter +*/
82
 
83
  int flag[MAX_PROC];
84
                   /*+ used to manage the JOB_TASK_MODEL and the
85
                       periodicity                            +*/
86
 
87
  QUEUE ready;     /*+ the ready queue                        +*/
88
 
89
  int flags;       /*+ the init flags...                      +*/
90
 
91
  bandwidth_t U;   /*+ the used bandwidth                     +*/
92
 
93
} EDFACT_level_des;
94
 
95
 
96
static void EDFACT_timer_deadline(void *par);
97
 
98
static void EDFACT_internal_activate(EDFACT_level_des *lev, PID p)
99
{
100
  TIMESPEC_ASSIGN(&proc_table[p].timespec_priority,
101
                  &proc_table[p].request_time);
102
  ADDUSEC2TIMESPEC(lev->period[p], &proc_table[p].timespec_priority);
103
 
104
  TIMESPEC_ASSIGN(&lev->deadline_timespec[p],
105
                  &proc_table[p].timespec_priority);
106
 
107
  /* Insert task in the correct position */
108
  proc_table[p].status = EDFACT_READY;
109
  q_timespec_insert(p,&lev->ready);
110
 
111
  /* needed because when there is a wcet miss I disable CONTROL_CAP */
112
  proc_table[p].control |= CONTROL_CAP;
113
}
114
 
115
static char *EDFACT_status_to_a(WORD status)
116
{
117
  if (status < MODULE_STATUS_BASE)
118
    return status_to_a(status);
119
 
120
  switch (status) {
121
    case EDFACT_READY        : return "EDFACT_Ready";
122
    case EDFACT_IDLE         : return "EDFACT_Idle";
123
    default               : return "EDFACT_Unknown";
124
  }
125
}
126
 
127
static void EDFACT_timer_deadline(void *par)
128
{
129
  PID p = (PID) par;
130
  EDFACT_level_des *lev;
131
 
132
  lev = (EDFACT_level_des *)level_table[proc_table[p].task_level];
133
 
134
  switch (proc_table[p].status) {
135
    case EDFACT_IDLE:
136
      edfact_printf("I%d",p);
137
      TIMESPEC_ASSIGN(&proc_table[p].request_time,
138
                      &proc_table[p].timespec_priority);
139
 
140
      EDFACT_internal_activate(lev,p);
141
 
142
      event_need_reschedule();
143
      break;
144
 
145
    default:
146
      edfact_printf("D%d",p);
147
      /* else, a deadline miss occurred!!! */
148
      lev->dline_miss[p]++;
149
 
150
      /* the task is into another state */
151
      lev->nact[p]++;
152
 
153
      /* Set the deadline timer */
154
      ADDUSEC2TIMESPEC(lev->period[p], &lev->deadline_timespec[p]);
155
  }
156
 
157
  /* Set the deadline timer */
158
  lev->deadline_timer[p] = kern_event_post(&lev->deadline_timespec[p],
159
                                           EDFACT_timer_deadline,
160
                                           (void *)p);
161
 
162
}
163
 
164
static void EDFACT_timer_guest_deadline(void *par)
165
{
166
  PID p = (PID) par;
167
 
168
  edfact_printf("AAARRRGGGHHH!!!");
169
  kern_raise(XDEADLINE_MISS,p);
170
}
171
 
172
static int EDFACT_level_accept_task_model(LEVEL l, TASK_MODEL *m)
173
{
174
  if (m->pclass == HARD_PCLASS || m->pclass == (HARD_PCLASS | l)) {
175
    HARD_TASK_MODEL *h = (HARD_TASK_MODEL *)m;
176
 
177
    if (h->wcet && h->mit && h->periodicity == PERIODIC)
178
      return 0;
179
  }
180
 
181
  return -1;
182
}
183
 
184
static int EDFACT_level_accept_guest_model(LEVEL l, TASK_MODEL *m)
185
{
186
  if (m->pclass == JOB_PCLASS || m->pclass == (JOB_PCLASS | l))
187
    return 0;
188
  else
189
    return -1;
190
}
191
 
192
 
193
static char *onoff(int i)
194
{
195
  if (i)
196
    return "On ";
197
  else
198
    return "Off";
199
}
200
 
201
static void EDFACT_level_status(LEVEL l)
202
{
203
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
204
  PID p = lev->ready;
205
 
206
  kern_printf("On-line guarantee : %s\n",
207
            onoff(lev->flags & EDFACT_ENABLE_GUARANTEE));
208
  kern_printf("Used Bandwidth    : %u/%u\n",
209
            lev->U, MAX_BANDWIDTH);
210
 
211
  while (p != NIL) {
212
    if ((proc_table[p].pclass) == JOB_PCLASS)
213
      kern_printf("Pid: %2d (GUEST)\n", p);
214
    else
215
      kern_printf("Pid: %2d Name: %10s %s: %9d Dline: %9d.%6d Stat: %s\n",
216
              p,
217
              proc_table[p].name,
218
              "Period  ",
219
              lev->period[p],
220
              proc_table[p].timespec_priority.tv_sec,
221
              proc_table[p].timespec_priority.tv_nsec/1000,
222
              EDFACT_status_to_a(proc_table[p].status));
223
    p = proc_table[p].next;
224
  }
225
 
226
  for (p=0; p<MAX_PROC; p++)
227
    if (proc_table[p].task_level == l && proc_table[p].status != EDFACT_READY
228
        && proc_table[p].status != FREE )
229
      kern_printf("Pid: %2d Name: %10s %s: %9d Dline: %9d.%6d Stat: %s\n",
230
                p,
231
                proc_table[p].name,
232
                "Period  ",
233
                lev->period[p],
234
                proc_table[p].timespec_priority.tv_sec,
235
                proc_table[p].timespec_priority.tv_nsec/1000,
236
                EDFACT_status_to_a(proc_table[p].status));
237
}
238
 
239
/* The scheduler only gets the first task in the queue */
240
static PID EDFACT_level_scheduler(LEVEL l)
241
{
242
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
243
 
244
/*  {  // print 4 dbg the ready queue
245
    PID p= lev->ready;
246
    kern_printf("(s");
247
    while (p != NIL) {
248
      kern_printf("%d ",p);
249
      p = proc_table[p].next;
250
    }
251
    kern_printf(") ");
252
  }
253
  */
254
  return (PID)lev->ready;
255
}
256
 
257
/* The on-line guarantee is enabled only if the appropriate flag is set... */
258
static int EDFACT_level_guarantee(LEVEL l, bandwidth_t *freebandwidth)
259
{
260
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
261
 
262
  if (lev->flags & EDFACT_FAILED_GUARANTEE) {
263
    *freebandwidth = 0;
264
    return 0;
265
  }
266
  else
267
    if (*freebandwidth >= lev->U) {
268
      *freebandwidth -= lev->U;
269
      return 1;
270
    }
271
    else
272
      return 0;
273
 
274
}
275
 
276
static int EDFACT_task_create(LEVEL l, PID p, TASK_MODEL *m)
277
{
278
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
279
 
280
  /* if the EDFACT_task_create is called, then the pclass must be a
281
     valid pclass. */
282
 
283
  HARD_TASK_MODEL *h = (HARD_TASK_MODEL *)m;
284
 
285
  lev->period[p] = h->mit;
286
 
287
  lev->flag[p] = 0;
288
  lev->deadline_timer[p] = -1;
289
  lev->dline_miss[p]     = 0;
290
  lev->wcet_miss[p]      = 0;
291
  lev->nact[p]           = 0;
292
 
293
  /* Enable wcet check */
294
  proc_table[p].avail_time = h->wcet;
295
  proc_table[p].wcet       = h->wcet;
296
  proc_table[p].control |= CONTROL_CAP;
297
 
298
  /* update the bandwidth... */
299
  if (lev->flags & EDFACT_ENABLE_GUARANTEE) {
300
    bandwidth_t b;
301
    b = (MAX_BANDWIDTH / h->mit) * h->wcet;
302
 
303
    /* really update lev->U, checking an overflow... */
304
    if (MAX_BANDWIDTH - lev->U > b)
305
      lev->U += b;
306
    else
307
      /* The task can NOT be guaranteed (U>MAX_BANDWIDTH)...
308
         in this case, we don't raise an exception... in fact, after the
309
         EDFACT_task_create the task_create will call level_guarantee that return
310
         -1... return -1 in EDFACT_task_create isn't correct, because:
311
           . generally, the guarantee must be done when also the resources
312
             are registered
313
           . returning -1 will cause the task_create to return with an errno
314
             ETASK_CREATE instead of ENO_GUARANTEE!!!
315
 
316
         Why I use the flag??? because if the lev->U overflows, if i.e. I set
317
         it to MAX_BANDWIDTH, I lose the correct allocated bandwidth...
318
      */
319
      lev->flags |= EDFACT_FAILED_GUARANTEE;
320
  }
321
 
322
  return 0; /* OK, also if the task cannot be guaranteed... */
323
}
324
 
325
static void EDFACT_task_detach(LEVEL l, PID p)
326
{
327
  /* the EDFACT level doesn't introduce any dinamic allocated new field.
328
     we have only to reset the NO_GUARANTEE FIELD and decrement the allocated
329
     bandwidth */
330
 
331
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
332
 
333
  if (lev->flags & EDFACT_FAILED_GUARANTEE)
334
    lev->flags &= ~EDFACT_FAILED_GUARANTEE;
335
  else
336
    lev->U -= (MAX_BANDWIDTH / lev->period[p]) * proc_table[p].wcet;
337
}
338
 
339
static int EDFACT_task_eligible(LEVEL l, PID p)
340
{
341
  return 0; /* if the task p is chosen, it is always eligible */
342
}
343
 
344
static void EDFACT_task_dispatch(LEVEL l, PID p, int nostop)
345
{
346
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
347
 
348
  /* the task state is set EXE by the scheduler()
349
     we extract the task from the ready queue
350
     NB: we can't assume that p is the first task in the queue!!! */
351
  q_extract(p, &lev->ready);
352
}
353
 
354
static void EDFACT_task_epilogue(LEVEL l, PID p)
355
{
356
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
357
 
358
  /* check if the wcet is finished... */
359
  if (proc_table[p].avail_time <= 0 && proc_table[p].control&CONTROL_CAP) {
360
    /* wcet finished: disable wcet event and count wcet miss */
361
    edfact_printf("W%d",p);
362
    proc_table[p].control &= ~CONTROL_CAP;
363
    lev->wcet_miss[p]++;
364
  }
365
 
366
  /* the task it returns into the ready queue... */
367
  q_timespec_insert(p,&lev->ready);
368
  proc_table[p].status = EDFACT_READY;
369
}
370
 
371
static void EDFACT_task_activate(LEVEL l, PID p)
372
{
373
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
374
 
375
  /* Test if we are trying to activate a non sleeping task    */
376
  /* save activation (only if needed... */
377
  if (proc_table[p].status != SLEEP) {
378
    /* a periodic task cannot be activated when it is already active */
379
    kern_raise(XACTIVATION,p);
380
    return;
381
  }
382
 
383
  ll_gettime(TIME_EXACT, &proc_table[p].request_time);
384
 
385
  EDFACT_internal_activate(lev,p);
386
 
387
  /* Set the deadline timer */
388
  lev->deadline_timer[p] = kern_event_post(&lev->deadline_timespec[p],
389
                                           EDFACT_timer_deadline,
390
                                           (void *)p);
391
 
392
}
393
 
394
static void EDFACT_task_insert(LEVEL l, PID p)
395
{
396
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
397
 
398
  /* Insert task in the coEDFect position */
399
  proc_table[p].status = EDFACT_READY;
400
  q_timespec_insert(p,&lev->ready);
401
}
402
 
403
static void EDFACT_task_extract(LEVEL l, PID p)
404
{
405
}
406
 
407
static void EDFACT_task_endcycle(LEVEL l, PID p)
408
{
409
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
410
 
411
 
412
  /* we reset the capacity counters... */
413
  proc_table[p].avail_time = proc_table[p].wcet;
414
 
415
  if (lev->nact[p] > 0) {
416
    edfact_printf("E%d",p);
417
 
418
    /* Pending activation: reactivate the thread!!! */
419
    lev->nact[p]--;
420
 
421
    /* see also EDFACT_timer_deadline */
422
    ll_gettime(TIME_EXACT, &proc_table[p].request_time);
423
 
424
    EDFACT_internal_activate(lev,p);
425
 
426
    /* check if the deadline has already expired */
427
    if (TIMESPEC_A_LT_B(&proc_table[p].timespec_priority, &schedule_time)) {
428
      /* count the deadline miss */
429
      lev->dline_miss[p]++;
430
      event_delete(lev->deadline_timer[p]);
431
    }
432
 
433
  }
434
  else {
435
    edfact_printf("e%d",p);
436
 
437
    /* the task has terminated his job before it consume the wcet. All OK! */
438
    proc_table[p].status = EDFACT_IDLE;
439
 
440
    /* when the deadline timer fire, it recognize the situation and set
441
       correctly all the stuffs (like reactivation, request_time, etc... ) */
442
  }
443
}
444
 
445
static void EDFACT_task_end(LEVEL l, PID p)
446
{
447
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
448
 
449
  edfact_printf("Û%d",p);
450
 
451
  /* we finally put the task in the ready queue */
452
  proc_table[p].status = FREE;
453
  q_insertfirst(p,&freedesc);
454
  /* and free the allocated bandwidth */
455
  lev->U -= (MAX_BANDWIDTH/lev->period[p]) * proc_table[p].wcet;
456
 
457
  if (lev->deadline_timer[p] != -1) {
458
    edfact_printf("²%d",p);
459
    event_delete(lev->deadline_timer[p]);
460
  }
461
}
462
 
463
static void EDFACT_task_sleep(LEVEL l, PID p)
464
{ kern_raise(XUNVALID_TASK,exec_shadow); }
465
 
466
static void EDFACT_task_delay(LEVEL l, PID p, TIME usdelay)
467
{ kern_raise(XUNVALID_TASK,exec_shadow); }
468
 
469
/* Guest Functions
470
   These functions manages a JOB_TASK_MODEL, that is used to put
471
   a guest task in the EDFACT ready queue. */
472
 
473
static int EDFACT_guest_create(LEVEL l, PID p, TASK_MODEL *m)
474
{
475
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
476
  JOB_TASK_MODEL *job = (JOB_TASK_MODEL *)m;
477
 
478
  /* if the EDFACT_guest_create is called, then the pclass must be a
479
     valid pclass. */
480
 
481
  TIMESPEC_ASSIGN(&proc_table[p].timespec_priority, &job->deadline);
482
 
483
  lev->deadline_timer[p] = -1;
484
  lev->dline_miss[p]     = 0;
485
  lev->wcet_miss[p]      = 0;
486
  lev->nact[p]           = 0;
487
 
488
  if (job->noraiseexc)
489
    lev->flag[p] = EDFACT_FLAG_NORAISEEXC;
490
  else
491
    lev->flag[p] = 0;
492
 
493
  lev->period[p] = job->period;
494
 
495
  /* there is no bandwidth guarantee at this level, it is performed
496
     by the level that inserts guest tasks... */
497
 
498
  return 0; /* OK, also if the task cannot be guaranteed... */
499
}
500
 
501
static void EDFACT_guest_detach(LEVEL l, PID p)
502
{
503
  /* the EDFACT level doesn't introduce any dinamic allocated new field.
504
     No guarantee is performed on guest tasks... so we don't have to reset
505
     the NO_GUARANTEE FIELD */
506
}
507
 
508
static void EDFACT_guest_dispatch(LEVEL l, PID p, int nostop)
509
{
510
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
511
 
512
  /* the task state is set to EXE by the scheduler()
513
     we extract the task from the ready queue
514
     NB: we can't assume that p is the first task in the queue!!! */
515
  q_extract(p, &lev->ready);
516
}
517
 
518
static void EDFACT_guest_epilogue(LEVEL l, PID p)
519
{
520
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
521
 
522
  /* the task has been preempted. it returns into the ready queue... */
523
  q_timespec_insert(p,&lev->ready);
524
  proc_table[p].status = EDFACT_READY;
525
}
526
 
527
static void EDFACT_guest_activate(LEVEL l, PID p)
528
{
529
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
530
 
531
  /* Insert task in the correct position */
532
  q_timespec_insert(p,&lev->ready);
533
  proc_table[p].status = EDFACT_READY;
534
 
535
  /* Set the deadline timer */
536
  if (!(lev->flag[p] & EDFACT_FLAG_NORAISEEXC))
537
    lev->deadline_timer[p] = kern_event_post(&proc_table[p].timespec_priority,
538
                                             EDFACT_timer_guest_deadline,
539
                                             (void *)p);
540
 
541
}
542
 
543
static void EDFACT_guest_insert(LEVEL l, PID p)
544
{
545
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
546
 
547
  /* Insert task in the correct position */
548
  q_timespec_insert(p,&lev->ready);
549
  proc_table[p].status = EDFACT_READY;
550
}
551
 
552
static void EDFACT_guest_extract(LEVEL l, PID p)
553
{
554
}
555
 
556
static void EDFACT_guest_endcycle(LEVEL l, PID p)
557
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
558
 
559
static void EDFACT_guest_end(LEVEL l, PID p)
560
{
561
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
562
 
563
  //kern_printf("EDFACT_guest_end: dline timer %d\n",lev->deadline_timer[p]);
564
  if (proc_table[p].status == EDFACT_READY)
565
  {
566
    q_extract(p, &lev->ready);
567
    //kern_printf("(g_end rdy extr)");
568
  }
569
 
570
  /* we remove the deadline timer, because the slice is finished */
571
  if (lev->deadline_timer[p] != NIL) {
572
//    kern_printf("EDFACT_guest_end: dline timer %d\n",lev->deadline_timer[p]);
573
    event_delete(lev->deadline_timer[p]);
574
    lev->deadline_timer[p] = NIL;
575
  }
576
 
577
}
578
 
579
static void EDFACT_guest_sleep(LEVEL l, PID p)
580
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
581
 
582
static void EDFACT_guest_delay(LEVEL l, PID p, TIME usdelay)
583
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
584
 
585
/* Registration functions */
586
 
587
/*+ Registration function:
588
    int flags                 the init flags ... see EDFACT.h +*/
589
void EDFACT_register_level(int flags)
590
{
591
  LEVEL l;            /* the level that we register */
592
  EDFACT_level_des *lev;  /* for readableness only */
593
  PID i;              /* a counter */
594
 
595
  printk("EDFACT_register_level\n");
596
 
597
  /* request an entry in the level_table */
598
  l = level_alloc_descriptor();
599
 
600
  printk("    alloco descrittore %d %d\n",l,(int)sizeof(EDFACT_level_des));
601
 
602
  /* alloc the space needed for the EDFACT_level_des */
603
  lev = (EDFACT_level_des *)kern_alloc(sizeof(EDFACT_level_des));
604
 
605
  printk("    lev=%d\n",(int)lev);
606
 
607
  /* update the level_table with the new entry */
608
  level_table[l] = (level_des *)lev;
609
 
610
  /* fill the standard descriptor */
611
  strncpy(lev->l.level_name,  EDFACT_LEVELNAME, MAX_LEVELNAME);
612
  lev->l.level_code               = EDFACT_LEVEL_CODE;
613
  lev->l.level_version            = EDFACT_LEVEL_VERSION;
614
 
615
  lev->l.level_accept_task_model  = EDFACT_level_accept_task_model;
616
  lev->l.level_accept_guest_model = EDFACT_level_accept_guest_model;
617
  lev->l.level_status             = EDFACT_level_status;
618
  lev->l.level_scheduler          = EDFACT_level_scheduler;
619
 
620
  if (flags & EDFACT_ENABLE_GUARANTEE)
621
    lev->l.level_guarantee        = EDFACT_level_guarantee;
622
  else
623
    lev->l.level_guarantee        = NULL;
624
 
625
  lev->l.task_create              = EDFACT_task_create;
626
  lev->l.task_detach              = EDFACT_task_detach;
627
  lev->l.task_eligible            = EDFACT_task_eligible;
628
  lev->l.task_dispatch            = EDFACT_task_dispatch;
629
  lev->l.task_epilogue            = EDFACT_task_epilogue;
630
  lev->l.task_activate            = EDFACT_task_activate;
631
  lev->l.task_insert              = EDFACT_task_insert;
632
  lev->l.task_extract             = EDFACT_task_extract;
633
  lev->l.task_endcycle            = EDFACT_task_endcycle;
634
  lev->l.task_end                 = EDFACT_task_end;
635
  lev->l.task_sleep               = EDFACT_task_sleep;
636
  lev->l.task_delay               = EDFACT_task_delay;
637
 
638
  lev->l.guest_create             = EDFACT_guest_create;
639
  lev->l.guest_detach             = EDFACT_guest_detach;
640
  lev->l.guest_dispatch           = EDFACT_guest_dispatch;
641
  lev->l.guest_epilogue           = EDFACT_guest_epilogue;
642
  lev->l.guest_activate           = EDFACT_guest_activate;
643
  lev->l.guest_insert             = EDFACT_guest_insert;
644
  lev->l.guest_extract            = EDFACT_guest_extract;
645
  lev->l.guest_endcycle           = EDFACT_guest_endcycle;
646
  lev->l.guest_end                = EDFACT_guest_end;
647
  lev->l.guest_sleep              = EDFACT_guest_sleep;
648
  lev->l.guest_delay              = EDFACT_guest_delay;
649
 
650
  /* fill the EDFACT descriptor part */
651
  for(i=0; i<MAX_PROC; i++) {
652
    lev->period[i]         = 0;
653
    lev->deadline_timer[i] = -1;
654
    lev->flag[i]           = 0;
655
    lev->dline_miss[i]     = 0;
656
    lev->wcet_miss[i]      = 0;
657
    lev->nact[i]           = 0;
658
  }
659
 
660
  lev->ready = NIL;
661
  lev->flags = flags & 0x07;
662
  lev->U     = 0;
663
}
664
 
665
bandwidth_t EDFACT_usedbandwidth(LEVEL l)
666
{
667
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
668
  if (lev->l.level_code    == EDFACT_LEVEL_CODE &&
669
      lev->l.level_version == EDFACT_LEVEL_VERSION)
670
    return lev->U;
671
  else
672
    return 0;
673
}
674
 
675
int EDFACT_get_dline_miss(PID p)
676
{
677
  LEVEL l = proc_table[p].task_level;
678
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
679
  if (lev->l.level_code    == EDFACT_LEVEL_CODE &&
680
      lev->l.level_version == EDFACT_LEVEL_VERSION)
681
    return lev->dline_miss[p];
682
  else
683
    return -1;
684
}
685
 
686
int EDFACT_get_wcet_miss(PID p)
687
{
688
  LEVEL l = proc_table[p].task_level;
689
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
690
  if (lev->l.level_code    == EDFACT_LEVEL_CODE &&
691
      lev->l.level_version == EDFACT_LEVEL_VERSION)
692
    return lev->wcet_miss[p];
693
  else
694
    return -1;
695
}
696
 
697
int EDFACT_get_nact(PID p)
698
{
699
  LEVEL l = proc_table[p].task_level;
700
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
701
  if (lev->l.level_code    == EDFACT_LEVEL_CODE &&
702
      lev->l.level_version == EDFACT_LEVEL_VERSION)
703
    return lev->nact[p];
704
  else
705
    return -1;
706
}
707
 
708
int EDFACT_reset_dline_miss(PID p)
709
{
710
  LEVEL l = proc_table[p].task_level;
711
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
712
  if (lev->l.level_code    == EDFACT_LEVEL_CODE &&
713
      lev->l.level_version == EDFACT_LEVEL_VERSION)
714
  {
715
    lev->dline_miss[p] = 0;
716
    return 0;
717
  }
718
  else
719
    return -1;
720
}
721
 
722
int EDFACT_reset_wcet_miss(PID p)
723
{
724
  LEVEL l = proc_table[p].task_level;
725
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
726
  if (lev->l.level_code    == EDFACT_LEVEL_CODE &&
727
      lev->l.level_version == EDFACT_LEVEL_VERSION)
728
  {
729
    lev->wcet_miss[p] = 0;
730
    return 0;
731
  }
732
  else
733
    return -1;
734
}
735