Subversion Repositories shark

Rev

Rev 783 | Rev 785 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
221 giacomo 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
 * Copyright (C) 2001 Paolo Gai
21
 *
22
 * This program is free software; you can redistribute it and/or modify
23
 * it under the terms of the GNU General Public License as published by
24
 * the Free Software Foundation; either version 2 of the License, or
25
 * (at your option) any later version.
26
 *
27
 * This program is distributed in the hope that it will be useful,
28
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
30
 * GNU General Public License for more details.
31
 *
32
 * You should have received a copy of the GNU General Public License
33
 * along with this program; if not, write to the Free Software
34
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
35
 *
36
 */
37
 
38
#include "edfstar.h"
39
#include <ll/stdio.h>
40
#include <ll/string.h>
41
#include <kernel/model.h>
42
#include <kernel/descr.h>
43
#include <kernel/var.h>
44
#include <kernel/func.h>
45
 
783 giacomo 46
#include <tracer.h>
221 giacomo 47
 
48
#define EDFSTAR_CHANGE_LEVEL 1
49
 
50
/* for iqueues */
51
/* #include "iqueue.h" Now iqueues are the only queue type available
52
   into the kernel */
53
#include <kernel/iqueue.h>
54
 
55
/* for BUDGET_TASK_MODEL */
241 giacomo 56
#include "fsf_server.h"
221 giacomo 57
 
58
/*
59
 * DEBUG stuffs begin
60
 */
61
 
224 giacomo 62
//#define EDFSTAR_DEBUG
221 giacomo 63
 
64
#ifdef EDFSTAR_DEBUG
65
 
66
static __inline__ fake_printf(char *fmt, ...) {}
67
 
68
//#define edfstar_printf fake_printf
69
//#define edfstar_printf2 fake_printf
70
//#define edfstar_printf3 fake_printf
71
 
72
#define edfstar_printf kern_printf
73
#define edfstar_printf2 kern_printf
74
#define edfstar_printf3 kern_printf
75
#endif
76
 
77
/*
78
 * DEBUG stuffs end
79
 */
80
 
81
/* Status used in the level */
82
#define EDFSTAR_READY         MODULE_STATUS_BASE    /* - Ready status        */
83
#define EDFSTAR_IDLE          MODULE_STATUS_BASE+4  /* to wait the deadline  */
84
 
85
/* flags */
86
#define EDFSTAR_FLAG_NORAISEEXC  2
348 trimarchi 87
#define EDFSTAR_FLAG_SPORADIC    1
221 giacomo 88
 
348 trimarchi 89
 
221 giacomo 90
/* the level redefinition for the Earliest Deadline First level */
91
typedef struct {
92
  level_des l;     /* the standard level descriptor          */
93
 
94
  TIME period[MAX_PROC]; /* The task periods; the deadlines are
95
                       stored in the priority field           */
96
  int deadline_timer[MAX_PROC];
97
                   /* The task deadline timers               */
98
 
99
  struct timespec deadline_timespec[MAX_PROC];
100
 
101
  int dline_miss[MAX_PROC]; /* Deadline miss counter */
102
  int wcet_miss[MAX_PROC];  /* Wcet miss counter */
103
 
104
  int nact[MAX_PROC];       /* Wcet miss counter */
105
 
106
  int flag[MAX_PROC];
107
                   /* used to manage the JOB_TASK_MODEL and the
108
                       periodicity                            */
109
 
110
  IQUEUE ready;     /* the ready queue                        */
111
 
112
  PID activated;   /* the task that has been inserted into the
113
                       master module */
114
 
115
  int budget[MAX_PROC];
116
 
117
  int scheduling_level;
118
 
296 trimarchi 119
  int cap_lev;
120
  struct timespec cap_lasttime;
121
 
122
 
221 giacomo 123
} EDFSTAR_level_des;
124
 
296 trimarchi 125
static void capacity_handler(void *l)
126
{
127
  EDFSTAR_level_des *lev = l;
128
  lev->cap_lev = NIL;
129
  event_need_reschedule();
130
}
131
 
221 giacomo 132
static void EDFSTAR_check_preemption(EDFSTAR_level_des *lev)
133
{
134
  PID first;
135
 
351 giacomo 136
  #ifdef EDFSTAR_DEBUG
137
    edfstar_printf("(E:chk)");
138
  #endif
221 giacomo 139
 
140
  if ((first = iq_query_first(&lev->ready)) != lev->activated) {
141
    if (lev->activated != NIL)
142
      level_table[ lev->scheduling_level ]->
143
        private_extract(lev->scheduling_level, lev->activated);
144
 
145
    lev->activated = first;
146
 
147
    if (first != NIL) {
148
      BUDGET_TASK_MODEL b;
149
      budget_task_default_model(b, lev->budget[first]);
150
 
151
      level_table[ lev->scheduling_level ]->
152
        private_insert(lev->scheduling_level, first, (TASK_MODEL *)&b);
153
    }
154
  }
155
}
156
 
157
static void EDFSTAR_timer_deadline(void *par);
158
 
159
static void EDFSTAR_internal_activate(EDFSTAR_level_des *lev, PID p,
160
                                      struct timespec *t)
161
{
162
 
351 giacomo 163
  #ifdef EDFSTAR_DEBUG
164
    edfstar_printf("(E:iact)");
165
  #endif
166
 
221 giacomo 167
  ADDUSEC2TIMESPEC(lev->period[p], t);
168
 
169
  *iq_query_timespec(p, &lev->ready) = *t;
170
  lev->deadline_timespec[p] = *t;
171
 
172
  /* Insert task in the correct position */
173
  proc_table[p].status = EDFSTAR_READY;
174
  iq_timespec_insert(p,&lev->ready);
296 trimarchi 175
  proc_table[p].control &= ~CONTROL_CAP;
221 giacomo 176
 
177
  /* check for preemption */
178
  EDFSTAR_check_preemption(lev);
179
}
180
 
181
static void EDFSTAR_timer_deadline(void *par)
182
{
183
  PID p = (PID) par;
184
  EDFSTAR_level_des *lev;
185
 
186
  lev = (EDFSTAR_level_des *)level_table[proc_table[p].task_level];
187
 
188
  switch (proc_table[p].status) {
189
    case EDFSTAR_IDLE:
190
      /* set the request time */
350 giacomo 191
      if (!(lev->flag[p] & EDFSTAR_FLAG_SPORADIC))
192
        EDFSTAR_internal_activate(lev,p,iq_query_timespec(p, &lev->ready));
221 giacomo 193
 
194
      event_need_reschedule();
195
      break;
196
 
197
    default:
351 giacomo 198
      #ifdef EDFSTAR_DEBUG
199
        kern_printf("(E:Dl:%d)",p);
200
      #endif
221 giacomo 201
      /* else, a deadline miss occurred!!! */
202
      lev->dline_miss[p]++;
783 giacomo 203
      TRACER_LOGEVENT(FTrace_EVT_task_deadline_miss,proc_table[p].context,proc_table[p].task_level);
221 giacomo 204
 
205
      /* the task is into another state */
351 giacomo 206
      if (!(lev->flag[p] & EDFSTAR_FLAG_SPORADIC)) {
207
        lev->nact[p]++;
208
        ADDUSEC2TIMESPEC(lev->period[p], &lev->deadline_timespec[p]);
209
      }
221 giacomo 210
  }
211
 
212
  /* Set the deadline timer */
350 giacomo 213
  if (!(lev->flag[p] & EDFSTAR_FLAG_SPORADIC))
214
    lev->deadline_timer[p] = kern_event_post(&lev->deadline_timespec[p],
215
                                             EDFSTAR_timer_deadline,
216
                                             (void *)p);
221 giacomo 217
 
218
}
219
 
220
static void EDFSTAR_timer_guest_deadline(void *par)
221
{
222
  PID p = (PID) par;
223
 
351 giacomo 224
  #ifdef EDFSTAR_DEBUG
225
    edfstar_printf("(E:gdl)");
226
  #endif
221 giacomo 227
 
228
  kern_raise(XDEADLINE_MISS,p);
229
}
230
 
231
static int EDFSTAR_public_create(LEVEL l, PID p, TASK_MODEL *m)
232
{
233
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
234
 
235
  /* if the EDFSTAR_task_create is called, then the pclass must be a
236
     valid pclass. */
237
  HARD_TASK_MODEL *h;
238
 
239
  if (m->pclass != HARD_PCLASS) return -1;
240
  if (m->level != 0 && m->level != l) return -1;
241
  h = (HARD_TASK_MODEL *)m;
351 giacomo 242
  if (!h->wcet || !h->mit) return -1;
221 giacomo 243
  /* now we know that m is a valid model */
244
 
351 giacomo 245
  #ifdef EDFSTAR_DEBUG
246
    edfstar_printf("(E:Crt)");
247
  #endif
221 giacomo 248
 
249
  lev->period[p] = h->mit;
250
 
251
  lev->flag[p] = 0;
348 trimarchi 252
 
253
  if (h->periodicity == APERIODIC)
254
       lev->flag[p] |= EDFSTAR_FLAG_SPORADIC;
255
 
221 giacomo 256
  lev->deadline_timer[p] = -1;
257
  lev->dline_miss[p]     = 0;
258
  lev->wcet_miss[p]      = 0;
259
  lev->nact[p]           = 0;
260
 
261
  /* Enable wcet check */
262
  proc_table[p].avail_time = h->wcet;
263
  proc_table[p].wcet       = h->wcet;
264
 
265
  return 0; /* OK, also if the task cannot be guaranteed... */
266
}
267
 
296 trimarchi 268
 
269
static void EDFSTAR_account_capacity(EDFSTAR_level_des *lev, PID p)
270
{
271
  struct timespec ty;
272
  TIME tx;
273
 
274
  SUBTIMESPEC(&schedule_time, &lev->cap_lasttime, &ty);
275
  tx = TIMESPEC2USEC(&ty);
276
 
277
  proc_table[p].avail_time -= tx;
351 giacomo 278
}
296 trimarchi 279
 
221 giacomo 280
static int EDFSTAR_public_eligible(LEVEL l, PID p)
281
{
282
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
283
 
351 giacomo 284
  #ifdef EDFSTAR_DEBUG
285
    edfstar_printf2("(E:eli)");
286
  #endif
221 giacomo 287
 
288
  return level_table[ lev->scheduling_level ]->
289
    private_eligible(lev->scheduling_level,p);
351 giacomo 290
 
221 giacomo 291
}
292
 
293
static void EDFSTAR_public_dispatch(LEVEL l, PID p, int nostop)
294
{
295
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
296 trimarchi 296
  struct timespec ty;
221 giacomo 297
 
351 giacomo 298
  #ifdef EDFSTAR_DEBUG
299
    edfstar_printf("(E:dis)");
300
  #endif
301
 
296 trimarchi 302
  if (!nostop || proc_table[exec].task_level==l) {
303
      TIMESPEC_ASSIGN(&ty, &schedule_time);
304
      TIMESPEC_ASSIGN(&lev->cap_lasttime, &schedule_time);
221 giacomo 305
 
296 trimarchi 306
      /* ...and finally, we have to post a capacity event on exec task because the shadow_task consume
307
       *      *        capacity on exe task always */
784 giacomo 308
      if (proc_table[exec].avail_time > 0) {
309
        ADDUSEC2TIMESPEC(proc_table[exec].avail_time ,&ty);
310
        lev->cap_lev = kern_event_post(&ty,capacity_handler, lev);
311
      }
296 trimarchi 312
      level_table[lev->scheduling_level]->private_dispatch(lev->scheduling_level, p, nostop);
313
  }
314
  else
315
      level_table[proc_table[exec].task_level]->public_dispatch(proc_table[exec].task_level, p, nostop);
316
 
221 giacomo 317
}
318
 
319
static void EDFSTAR_public_epilogue(LEVEL l, PID p)
320
{
321
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
322
 
351 giacomo 323
  #ifdef EDFSTAR_DEBUG
324
    edfstar_printf("(E:epi ");
325
  #endif
221 giacomo 326
 
296 trimarchi 327
  if (lev->cap_lev!=NIL) {
328
       kern_event_delete(lev->cap_lev);
329
       lev->cap_lev=NIL;
330
  }
331
 
332
 
333
  if ( proc_table[exec].task_level==l ) {
334
 
335
     EDFSTAR_account_capacity(lev,exec);
336
 
337
     /* check if the wcet is finished... */
784 giacomo 338
     if (proc_table[exec].avail_time < 0) {
296 trimarchi 339
        /* wcet finished: disable wcet event and count wcet miss */
351 giacomo 340
 
341
       #ifdef EDFSTAR_DEBUG
342
         edfstar_printf2("W%d",p);
343
       #endif
296 trimarchi 344
        //proc_table[p].control &= ~CONTROL_CAP;
345
        lev->wcet_miss[exec]++;
784 giacomo 346
        proc_table[exec].avail_time = 0;
347
        TRACER_LOGEVENT(FTrace_EVT_task_wcet_violation,proc_table[exec].context,proc_table[exec].task_level);
296 trimarchi 348
     }
221 giacomo 349
 
351 giacomo 350
     #ifdef EDFSTAR_DEBUG
351
       edfstar_printf(")");
352
     #endif
221 giacomo 353
 
351 giacomo 354
     level_table[ lev->scheduling_level ]->
355
       private_epilogue(lev->scheduling_level,p);
356
 
357
     proc_table[exec].status = EDFSTAR_READY;
296 trimarchi 358
    } else
359
        level_table[proc_table[exec].task_level]->public_epilogue(proc_table[exec].task_level,p);
360
 
221 giacomo 361
}
362
 
783 giacomo 363
static void EDFSTAR_public_activate(LEVEL l, PID p, struct timespec *o)
221 giacomo 364
{
365
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
366
  struct timespec t;
367
 
368
  #ifdef EDFSTAR_DEBUG
369
    edfstar_printf("(E:act:%d)",p);
370
  #endif
371
 
372
  /* Test if we are trying to activate a non sleeping task    */
373
  /* save activation (only if needed... */
374
  if (proc_table[p].status != SLEEP) {
375
    /* a periodic task cannot be activated when it is already active */
348 trimarchi 376
    /* but aperiodic task can be reactivate before */
351 giacomo 377
    if (lev->flag[p] & EDFSTAR_FLAG_SPORADIC) {
378
       if (proc_table[p].status != EDFSTAR_IDLE) {
379
         lev->nact[p]++;
380
         return;
381
       }
382
    } else {
348 trimarchi 383
       kern_raise(XACTIVATION,p);
351 giacomo 384
    }
221 giacomo 385
  }
386
 
387
  kern_gettime(&t);
388
 
389
  EDFSTAR_internal_activate(lev,p, &t);
390
 
391
  /* Set the deadline timer */
392
  lev->deadline_timer[p] = kern_event_post(&lev->deadline_timespec[p],
393
                                           EDFSTAR_timer_deadline,
394
                                           (void *)p);
395
 
396
}
397
 
398
static void EDFSTAR_public_unblock(LEVEL l, PID p)
399
{
400
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
401
 
351 giacomo 402
  #ifdef EDFSTAR_DEBUG
403
    edfstar_printf("(E:ins)");
404
  #endif
221 giacomo 405
 
351 giacomo 406
  /* Insert task in the correct position */
407
  proc_table[p].status = EDFSTAR_READY;
408
  iq_timespec_insert(p,&lev->ready);
221 giacomo 409
 
351 giacomo 410
  /* and check for preemption! */
411
  EDFSTAR_check_preemption(lev);
412
 
221 giacomo 413
}
414
 
415
static void EDFSTAR_public_block(LEVEL l, PID p)
416
{
417
 
351 giacomo 418
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
221 giacomo 419
 
351 giacomo 420
  #ifdef EDFSTAR_DEBUG
421
   edfstar_printf("(E:ext)");
422
  #endif
221 giacomo 423
 
351 giacomo 424
  /* the task is blocked on a synchronization primitive. we have to
425
     remove it from the master module -and- from the local queue! */
426
  iq_extract(p,&lev->ready);
427
 
428
  /* and finally, a preemption check! (it will also call guest_end) */
429
  EDFSTAR_check_preemption(lev);
221 giacomo 430
}
431
 
432
static int EDFSTAR_public_message(LEVEL l, PID p, void *m)
433
{
434
 
351 giacomo 435
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
436
  struct timespec temp;
221 giacomo 437
 
351 giacomo 438
  #ifdef EDFSTAR_DEBUG
439
    edfstar_printf("(E:ecy ");
440
  #endif
221 giacomo 441
 
351 giacomo 442
  switch ((long)(m)) {
221 giacomo 443
 
351 giacomo 444
    /* Task EndCycle */
445
    case (long)(NULL):
348 trimarchi 446
 
351 giacomo 447
       /* we call guest_end directly here because the same task may
448
         be reinserted in the queue before calling the preemption check! */
449
       level_table[ lev->scheduling_level ]->
450
         private_extract(lev->scheduling_level,p);
451
       lev->activated = NIL;
348 trimarchi 452
 
351 giacomo 453
       iq_extract(p,&lev->ready);
348 trimarchi 454
 
351 giacomo 455
       /* we reset the capacity counters... */
456
       proc_table[p].avail_time = proc_table[p].wcet;
457
 
458
       if (lev->nact[p] > 0) {
221 giacomo 459
 
351 giacomo 460
         #ifdef EDFSTAR_DEBUG
461
           edfstar_printf2("E%d",p);
462
         #endif
221 giacomo 463
 
351 giacomo 464
         /* Pending activation: reactivate the thread!!! */
465
         lev->nact[p]--;
221 giacomo 466
 
351 giacomo 467
         /* see also EDFSTAR_timer_deadline */
468
         kern_gettime(&temp);
221 giacomo 469
 
351 giacomo 470
         EDFSTAR_internal_activate(lev,p, &temp);
221 giacomo 471
 
351 giacomo 472
         /* check if the deadline has already expired */
473
         temp = *iq_query_timespec(p, &lev->ready);
474
         if (TIMESPEC_A_LT_B(&temp, &schedule_time)) {
475
           /* count the deadline miss */
476
           lev->dline_miss[p]++;
477
           kern_event_delete(lev->deadline_timer[p]);
478
         }
783 giacomo 479
 
351 giacomo 480
       } else {
221 giacomo 481
 
351 giacomo 482
         #ifdef EDFSTAR_DEBUG
483
           edfstar_printf("e%d",p);
484
         #endif
221 giacomo 485
 
351 giacomo 486
         /* the task has terminated his job before it consume the wcet. All OK! */
487
         proc_table[p].status = EDFSTAR_IDLE;
488
 
489
         if (lev->flag[p] & EDFSTAR_FLAG_SPORADIC && lev->deadline_timer[p] != NIL)
490
           kern_event_delete(lev->deadline_timer[p]);
221 giacomo 491
 
351 giacomo 492
         /* and finally, a preemption check! */
493
         EDFSTAR_check_preemption(lev);
221 giacomo 494
 
351 giacomo 495
         /* when the deadline timer fire, it recognize the situation and set
496
           correctly all the stuffs (like reactivation, etc... ) */
497
       }
498
 
499
    #ifdef EDFSTAR_DEBUG
500
      edfstar_printf(")");
501
    #endif
783 giacomo 502
 
503
    TRACER_LOGEVENT(FTrace_EVT_task_end_cycle,proc_table[p].context,proc_table[p].task_level);
221 giacomo 504
    jet_update_endcycle(); /* Update the Jet data... */
505
    break;
506
 
507
  default:
508
 
241 giacomo 509
    break;
221 giacomo 510
 
511
  }
512
  return 0;
513
}
514
 
515
static void EDFSTAR_public_end(LEVEL l, PID p)
516
{
517
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
518
 
351 giacomo 519
  #ifdef EDFSTAR_DEBUG
520
    edfstar_printf("(E:end)");
521
  #endif
221 giacomo 522
 
523
  iq_extract(p,&lev->ready);
524
 
525
  /* we finally put the task in the ready queue */
526
  proc_table[p].status = FREE;
527
 
528
  iq_insertfirst(p,&freedesc);
348 trimarchi 529
  lev->activated=NIL;
221 giacomo 530
 
531
  if (lev->deadline_timer[p] != -1) {
532
    kern_event_delete(lev->deadline_timer[p]);
533
  }
534
 
535
  /* and finally, a preemption check! (it will also call guest_end) */
536
  EDFSTAR_check_preemption(lev);
537
}
538
 
539
/* Guest Functions
540
   These functions manages a JOB_TASK_MODEL, that is used to put
541
   a guest task in the EDFSTAR ready queue. */
542
 
543
static void EDFSTAR_private_insert(LEVEL l, PID p, TASK_MODEL *m)
544
{
545
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
546
  JOB_TASK_MODEL *job;
547
 
548
  if (m->pclass != JOB_PCLASS || (m->level != 0 && m->level != l) ) {
549
    kern_raise(XINVALID_TASK, p);
550
    return;
551
  }
552
 
553
  job = (JOB_TASK_MODEL *)m;
554
 
555
  /* if the EDFSTAR_guest_create is called, then the pclass must be a
556
     valid pclass. */
557
 
558
  *iq_query_timespec(p, &lev->ready) = job->deadline;
559
 
560
  lev->deadline_timer[p] = -1;
561
  lev->dline_miss[p]     = 0;
562
  lev->wcet_miss[p]      = 0;
563
  lev->nact[p]           = 0;
564
 
565
  if (job->noraiseexc)
566
    lev->flag[p] |= EDFSTAR_FLAG_NORAISEEXC;
567
  else {
568
    lev->flag[p] &= ~EDFSTAR_FLAG_NORAISEEXC;
569
    lev->deadline_timer[p] = kern_event_post(iq_query_timespec(p, &lev->ready),
570
                                             EDFSTAR_timer_guest_deadline,
571
                                             (void *)p);
572
  }
573
 
574
  lev->period[p] = job->period;
575
 
576
  /* Insert task in the correct position */
577
  iq_timespec_insert(p,&lev->ready);
578
  proc_table[p].status = EDFSTAR_READY;
579
 
580
  /* check for preemption */
581
  EDFSTAR_check_preemption(lev);
582
 
583
  /* there is no bandwidth guarantee at this level, it is performed
584
     by the level that inserts guest tasks... */
585
}
586
 
587
static void EDFSTAR_private_dispatch(LEVEL l, PID p, int nostop)
588
{
589
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
590
 
591
  level_table[ lev->scheduling_level ]->
592
    private_dispatch(lev->scheduling_level,p,nostop);
593
}
594
 
595
static void EDFSTAR_private_epilogue(LEVEL l, PID p)
596
{
597
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
598
 
599
  /* the task has been preempted. it returns into the ready queue... */
600
  level_table[ lev->scheduling_level ]->
601
    private_epilogue(lev->scheduling_level,p);
602
 
603
  proc_table[p].status = EDFSTAR_READY;
604
}
605
 
606
static void EDFSTAR_private_extract(LEVEL l, PID p)
607
{
608
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
609
 
610
#ifdef EDFSTAR_DEBUG
611
  //kern_printf("EDFSTAR_guest_end: dline timer %d\n",lev->deadline_timer[p]);
612
#endif
613
 
614
  iq_extract(p, &lev->ready);
615
 
616
  /* we remove the deadline timer, because the slice is finished */
617
  if (lev->deadline_timer[p] != NIL) {
618
#ifdef EDFSTAR_DEBUG
619
//    kern_printf("EDFSTAR_guest_end: dline timer %d\n",lev->deadline_timer[p]);
620
#endif
621
    kern_event_delete(lev->deadline_timer[p]);
622
    lev->deadline_timer[p] = NIL;
623
  }
624
 
625
  /* and finally, a preemption check! (it will also call guest_end() */
626
  EDFSTAR_check_preemption(lev);
627
}
628
 
629
/* Registration functions */
630
 
631
/* Registration function:
632
    int flags                 the init flags ... see EDFSTAR.h */
633
 
634
LEVEL EDFSTAR_register_level(int master)
635
{
636
  LEVEL l;            /* the level that we register */
637
  EDFSTAR_level_des *lev;  /* for readableness only */
638
  PID i;              /* a counter */
639
 
640
#ifdef EDFSTAR_DEBUG
641
  printk("EDFSTAR_register_level\n");
642
#endif
643
 
644
  /* request an entry in the level_table */
645
  l = level_alloc_descriptor(sizeof(EDFSTAR_level_des));
646
 
647
  lev = (EDFSTAR_level_des *)level_table[l];
648
 
649
  /* fill the standard descriptor */
650
  lev->l.private_insert   = EDFSTAR_private_insert;
651
  lev->l.private_extract  = EDFSTAR_private_extract;
652
  lev->l.private_dispatch = EDFSTAR_private_dispatch;
653
  lev->l.private_epilogue = EDFSTAR_private_epilogue;
654
 
655
  lev->l.public_guarantee = NULL;
656
  lev->l.public_eligible  = EDFSTAR_public_eligible;
657
  lev->l.public_create    = EDFSTAR_public_create;
658
  lev->l.public_end       = EDFSTAR_public_end;
659
  lev->l.public_dispatch  = EDFSTAR_public_dispatch;
660
  lev->l.public_epilogue  = EDFSTAR_public_epilogue;
661
  lev->l.public_activate  = EDFSTAR_public_activate;
662
  lev->l.public_unblock   = EDFSTAR_public_unblock;
663
  lev->l.public_block     = EDFSTAR_public_block;
664
  lev->l.public_message   = EDFSTAR_public_message;
665
 
666
  /* fill the EDFSTAR descriptor part */
667
  for(i=0; i<MAX_PROC; i++) {
668
    lev->period[i]         = 0;
669
    lev->deadline_timer[i] = -1;
670
    lev->flag[i]           = 0;
671
    lev->dline_miss[i]     = 0;
672
    lev->wcet_miss[i]      = 0;
673
    lev->nact[i]           = 0;
674
    lev->budget[i]         = NIL;
675
  }
676
 
677
  iq_init(&lev->ready, NULL, IQUEUE_NO_PRIORITY);
678
  lev->activated = NIL;
679
 
680
  lev->scheduling_level = master;
298 giacomo 681
  lev->cap_lev = NIL;
296 trimarchi 682
  NULL_TIMESPEC(&lev->cap_lasttime);
221 giacomo 683
 
684
  return l;
685
}
686
 
687
int EDFSTAR_get_dline_miss(PID p)
688
{
689
  LEVEL l = proc_table[p].task_level;
690
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
691
 
692
  return lev->dline_miss[p];
693
}
694
 
695
int EDFSTAR_get_wcet_miss(PID p)
696
{
697
  LEVEL l = proc_table[p].task_level;
698
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
699
 
700
  return lev->wcet_miss[p];
701
}
702
 
703
int EDFSTAR_get_nact(PID p)
704
{
705
  LEVEL l = proc_table[p].task_level;
706
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
707
 
708
  return lev->nact[p];
709
}
710
 
711
int EDFSTAR_reset_dline_miss(PID p)
712
{
713
  LEVEL l = proc_table[p].task_level;
714
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
715
 
716
  lev->dline_miss[p] = 0;
717
  return 0;
718
}
719
 
720
int EDFSTAR_reset_wcet_miss(PID p)
721
{
722
  LEVEL l = proc_table[p].task_level;
723
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
724
 
725
  lev->wcet_miss[p] = 0;
726
  return 0;
727
}
728
 
729
int EDFSTAR_setbudget(LEVEL l, PID p, int budget)
730
{
731
 
732
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
733
 
734
  lev->budget[p] = budget;
735
 
736
  return 0;
737
 
738
}
739
 
740
int EDFSTAR_getbudget(LEVEL l, PID p)
741
{
742
 
743
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
744
 
745
  return lev->budget[p];
746
 
747
}
236 giacomo 748
 
749
int EDFSTAR_budget_has_thread(LEVEL l, int budget)
750
{
751
 
752
  EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
753
  int i;
754
 
755
  for(i = 0; i< MAX_PROC; i++)
756
    if (lev->budget[i] == budget) return 1;
757
 
758
  return 0;
759
 
760
}