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
 ------------
1107 pj 21
 CVS :        $Id: edfact.c,v 1.3 2002-11-11 07:55:55 pj Exp $
1085 pj 22
 
23
 File:        $File$
1107 pj 24
 Revision:    $Revision: 1.3 $
25
 Last update: $Date: 2002-11-11 07:55:55 $
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
 
1107 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
{
1107 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);
1107 pj 106
  ADDUSEC2TIMESPEC(lev->period[p], temp);
1085 pj 107
 
108
  TIMESPEC_ASSIGN(&lev->deadline_timespec[p],
1107 pj 109
                  temp);
1085 pj 110
 
111
  /* Insert task in the correct position */
112
  proc_table[p].status = EDFACT_READY;
1107 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
 
1107 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]);
1107 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],
1107 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));
1107 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],
1107 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
  */
1107 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!!! */
1107 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... */
1107 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;
1107 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 */
1107 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;
1107 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
 
471
/* Guest Functions
472
   These functions manages a JOB_TASK_MODEL, that is used to put
473
   a guest task in the EDFACT ready queue. */
474
 
475
static int EDFACT_guest_create(LEVEL l, PID p, TASK_MODEL *m)
476
{
477
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
478
  JOB_TASK_MODEL *job = (JOB_TASK_MODEL *)m;
479
 
480
  /* if the EDFACT_guest_create is called, then the pclass must be a
481
     valid pclass. */
482
 
1107 pj 483
  TIMESPEC_ASSIGN(iq_query_timespec(p, &lev->ready), &job->deadline);
1085 pj 484
 
485
  lev->deadline_timer[p] = -1;
486
  lev->dline_miss[p]     = 0;
487
  lev->wcet_miss[p]      = 0;
488
  lev->nact[p]           = 0;
489
 
490
  if (job->noraiseexc)
491
    lev->flag[p] = EDFACT_FLAG_NORAISEEXC;
492
  else
493
    lev->flag[p] = 0;
494
 
495
  lev->period[p] = job->period;
496
 
497
  /* there is no bandwidth guarantee at this level, it is performed
498
     by the level that inserts guest tasks... */
499
 
500
  return 0; /* OK, also if the task cannot be guaranteed... */
501
}
502
 
503
static void EDFACT_guest_detach(LEVEL l, PID p)
504
{
505
  /* the EDFACT level doesn't introduce any dinamic allocated new field.
506
     No guarantee is performed on guest tasks... so we don't have to reset
507
     the NO_GUARANTEE FIELD */
508
}
509
 
510
static void EDFACT_guest_dispatch(LEVEL l, PID p, int nostop)
511
{
512
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
513
 
514
  /* the task state is set to EXE by the scheduler()
515
     we extract the task from the ready queue
516
     NB: we can't assume that p is the first task in the queue!!! */
1107 pj 517
  iq_extract(p, &lev->ready);
1085 pj 518
}
519
 
520
static void EDFACT_guest_epilogue(LEVEL l, PID p)
521
{
522
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
523
 
524
  /* the task has been preempted. it returns into the ready queue... */
1107 pj 525
  iq_timespec_insert(p,&lev->ready);
1085 pj 526
  proc_table[p].status = EDFACT_READY;
527
}
528
 
529
static void EDFACT_guest_activate(LEVEL l, PID p)
530
{
531
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
532
 
533
  /* Insert task in the correct position */
1107 pj 534
  iq_timespec_insert(p,&lev->ready);
1085 pj 535
  proc_table[p].status = EDFACT_READY;
536
 
537
  /* Set the deadline timer */
538
  if (!(lev->flag[p] & EDFACT_FLAG_NORAISEEXC))
1107 pj 539
    lev->deadline_timer[p] = kern_event_post(iq_query_timespec(p, &lev->ready),
1085 pj 540
                                             EDFACT_timer_guest_deadline,
541
                                             (void *)p);
542
 
543
}
544
 
545
static void EDFACT_guest_insert(LEVEL l, PID p)
546
{
547
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
548
 
549
  /* Insert task in the correct position */
1107 pj 550
  iq_timespec_insert(p,&lev->ready);
1085 pj 551
  proc_table[p].status = EDFACT_READY;
552
}
553
 
554
static void EDFACT_guest_extract(LEVEL l, PID p)
555
{
556
}
557
 
558
static void EDFACT_guest_endcycle(LEVEL l, PID p)
1100 pj 559
{ kern_raise(XINVALID_GUEST,exec_shadow); }
1085 pj 560
 
561
static void EDFACT_guest_end(LEVEL l, PID p)
562
{
563
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
564
 
565
  //kern_printf("EDFACT_guest_end: dline timer %d\n",lev->deadline_timer[p]);
566
  if (proc_table[p].status == EDFACT_READY)
567
  {
1107 pj 568
    iq_extract(p, &lev->ready);
1085 pj 569
    //kern_printf("(g_end rdy extr)");
570
  }
571
 
572
  /* we remove the deadline timer, because the slice is finished */
573
  if (lev->deadline_timer[p] != NIL) {
574
//    kern_printf("EDFACT_guest_end: dline timer %d\n",lev->deadline_timer[p]);
575
    event_delete(lev->deadline_timer[p]);
576
    lev->deadline_timer[p] = NIL;
577
  }
578
 
579
}
580
 
581
static void EDFACT_guest_sleep(LEVEL l, PID p)
1100 pj 582
{ kern_raise(XINVALID_GUEST,exec_shadow); }
1085 pj 583
 
584
/* Registration functions */
585
 
586
/*+ Registration function:
587
    int flags                 the init flags ... see EDFACT.h +*/
588
void EDFACT_register_level(int flags)
589
{
590
  LEVEL l;            /* the level that we register */
591
  EDFACT_level_des *lev;  /* for readableness only */
592
  PID i;              /* a counter */
593
 
594
  printk("EDFACT_register_level\n");
595
 
596
  /* request an entry in the level_table */
597
  l = level_alloc_descriptor();
598
 
599
  printk("    alloco descrittore %d %d\n",l,(int)sizeof(EDFACT_level_des));
600
 
601
  /* alloc the space needed for the EDFACT_level_des */
602
  lev = (EDFACT_level_des *)kern_alloc(sizeof(EDFACT_level_des));
603
 
604
  printk("    lev=%d\n",(int)lev);
605
 
606
  /* update the level_table with the new entry */
607
  level_table[l] = (level_des *)lev;
608
 
609
  /* fill the standard descriptor */
610
  strncpy(lev->l.level_name,  EDFACT_LEVELNAME, MAX_LEVELNAME);
611
  lev->l.level_code               = EDFACT_LEVEL_CODE;
612
  lev->l.level_version            = EDFACT_LEVEL_VERSION;
613
 
614
  lev->l.level_accept_task_model  = EDFACT_level_accept_task_model;
615
  lev->l.level_accept_guest_model = EDFACT_level_accept_guest_model;
616
  lev->l.level_status             = EDFACT_level_status;
617
  lev->l.level_scheduler          = EDFACT_level_scheduler;
618
 
619
  if (flags & EDFACT_ENABLE_GUARANTEE)
620
    lev->l.level_guarantee        = EDFACT_level_guarantee;
621
  else
622
    lev->l.level_guarantee        = NULL;
623
 
624
  lev->l.task_create              = EDFACT_task_create;
625
  lev->l.task_detach              = EDFACT_task_detach;
626
  lev->l.task_eligible            = EDFACT_task_eligible;
627
  lev->l.task_dispatch            = EDFACT_task_dispatch;
628
  lev->l.task_epilogue            = EDFACT_task_epilogue;
629
  lev->l.task_activate            = EDFACT_task_activate;
630
  lev->l.task_insert              = EDFACT_task_insert;
631
  lev->l.task_extract             = EDFACT_task_extract;
632
  lev->l.task_endcycle            = EDFACT_task_endcycle;
633
  lev->l.task_end                 = EDFACT_task_end;
634
  lev->l.task_sleep               = EDFACT_task_sleep;
635
 
636
  lev->l.guest_create             = EDFACT_guest_create;
637
  lev->l.guest_detach             = EDFACT_guest_detach;
638
  lev->l.guest_dispatch           = EDFACT_guest_dispatch;
639
  lev->l.guest_epilogue           = EDFACT_guest_epilogue;
640
  lev->l.guest_activate           = EDFACT_guest_activate;
641
  lev->l.guest_insert             = EDFACT_guest_insert;
642
  lev->l.guest_extract            = EDFACT_guest_extract;
643
  lev->l.guest_endcycle           = EDFACT_guest_endcycle;
644
  lev->l.guest_end                = EDFACT_guest_end;
645
  lev->l.guest_sleep              = EDFACT_guest_sleep;
646
 
647
  /* fill the EDFACT descriptor part */
648
  for(i=0; i<MAX_PROC; i++) {
649
    lev->period[i]         = 0;
650
    lev->deadline_timer[i] = -1;
651
    lev->flag[i]           = 0;
652
    lev->dline_miss[i]     = 0;
653
    lev->wcet_miss[i]      = 0;
654
    lev->nact[i]           = 0;
655
  }
656
 
1107 pj 657
  iq_init(&lev->ready,&freedesc, 0);
1085 pj 658
  lev->flags = flags & 0x07;
659
  lev->U     = 0;
660
}
661
 
662
bandwidth_t EDFACT_usedbandwidth(LEVEL l)
663
{
664
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
665
  if (lev->l.level_code    == EDFACT_LEVEL_CODE &&
666
      lev->l.level_version == EDFACT_LEVEL_VERSION)
667
    return lev->U;
668
  else
669
    return 0;
670
}
671
 
672
int EDFACT_get_dline_miss(PID p)
673
{
674
  LEVEL l = proc_table[p].task_level;
675
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
676
  if (lev->l.level_code    == EDFACT_LEVEL_CODE &&
677
      lev->l.level_version == EDFACT_LEVEL_VERSION)
678
    return lev->dline_miss[p];
679
  else
680
    return -1;
681
}
682
 
683
int EDFACT_get_wcet_miss(PID p)
684
{
685
  LEVEL l = proc_table[p].task_level;
686
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
687
  if (lev->l.level_code    == EDFACT_LEVEL_CODE &&
688
      lev->l.level_version == EDFACT_LEVEL_VERSION)
689
    return lev->wcet_miss[p];
690
  else
691
    return -1;
692
}
693
 
694
int EDFACT_get_nact(PID p)
695
{
696
  LEVEL l = proc_table[p].task_level;
697
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
698
  if (lev->l.level_code    == EDFACT_LEVEL_CODE &&
699
      lev->l.level_version == EDFACT_LEVEL_VERSION)
700
    return lev->nact[p];
701
  else
702
    return -1;
703
}
704
 
705
int EDFACT_reset_dline_miss(PID p)
706
{
707
  LEVEL l = proc_table[p].task_level;
708
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
709
  if (lev->l.level_code    == EDFACT_LEVEL_CODE &&
710
      lev->l.level_version == EDFACT_LEVEL_VERSION)
711
  {
712
    lev->dline_miss[p] = 0;
713
    return 0;
714
  }
715
  else
716
    return -1;
717
}
718
 
719
int EDFACT_reset_wcet_miss(PID p)
720
{
721
  LEVEL l = proc_table[p].task_level;
722
  EDFACT_level_des *lev = (EDFACT_level_des *)(level_table[l]);
723
  if (lev->l.level_code    == EDFACT_LEVEL_CODE &&
724
      lev->l.level_version == EDFACT_LEVEL_VERSION)
725
  {
726
    lev->wcet_miss[p] = 0;
727
    return 0;
728
  }
729
  else
730
    return -1;
731
}
732