Subversion Repositories shark

Rev

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