Subversion Repositories shark

Rev

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

Rev Author Line No. Line
235 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 "rmstar.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>
47
 
235 giacomo 48
#define RMSTAR_CHANGE_LEVEL 1
49
 
50
/* for iqueues */
51
/* #include "iqueue.h" Now iqueues are the only queue type into the kernel */
52
 
53
/* for BUDGET_TASK_MODEL */
808 trimarchi 54
#include "fsf_contract.h"
241 giacomo 55
#include "fsf_server.h"
235 giacomo 56
 
57
/*
58
 * DEBUG stuffs begin
59
 */
60
 
61
//#define RMSTAR_DEBUG
62
 
63
#ifdef RMSTAR_DEBUG
64
 
65
static __inline__ fake_printf(char *fmt, ...) {}
66
 
67
#define rmstar_printf fake_printf
68
#define rmstar_printf2 fake_printf
69
#define rmstar_printf3 fake_printf
70
 
71
//#define rmstar_printf kern_printf
72
//#define rmstar_printf2 kern_printf
73
//#define rmstar_printf3 kern_printf
74
#endif
75
 
76
/*
77
 * DEBUG stuffs end
78
 */
79
 
80
/* Status used in the level */
81
#define RMSTAR_READY         MODULE_STATUS_BASE    /* - Ready status        */
82
#define RMSTAR_IDLE          MODULE_STATUS_BASE+4  /* to wait the deadline  */
83
 
84
/* flags */
813 trimarchi 85
#define RMSTAR_FLAG_NOPREEMPT   4
235 giacomo 86
#define RMSTAR_FLAG_NORAISEEXC  2
394 trimarchi 87
#define RMSTAR_FLAG_SPORADIC    1
235 giacomo 88
 
89
/* the level redefinition for the Earliest Deadline First level */
90
typedef struct {
91
  level_des l;     /* the standard level descriptor          */
92
 
93
  TIME period[MAX_PROC]; /* The task periods; the deadlines are
94
                       stored in the priority field           */
95
  int deadline_timer[MAX_PROC];
96
                   /* The task deadline timers               */
97
 
98
  struct timespec deadline_timespec[MAX_PROC];
99
 
100
  int dline_miss[MAX_PROC]; /* Deadline miss counter */
101
  int wcet_miss[MAX_PROC];  /* Wcet miss counter */
102
 
103
  int nact[MAX_PROC];       /* Wcet miss counter */
104
 
105
  int flag[MAX_PROC];
106
                   /* used to manage the JOB_TASK_MODEL and the
107
                       periodicity                            */
108
 
109
  IQUEUE ready;     /* the ready queue                        */
110
 
111
  PID activated;   /* the task that has been inserted into the
112
                       master module */
113
 
114
  int budget[MAX_PROC];
115
 
116
  int scheduling_level;
117
 
394 trimarchi 118
  int cap_lev;
119
 
120
  struct timespec cap_lasttime;
121
 
235 giacomo 122
} RMSTAR_level_des;
123
 
394 trimarchi 124
static void capacity_handler(void *l)
125
{
126
  RMSTAR_level_des *lev = l;
127
  lev->cap_lev = NIL;
128
  event_need_reschedule();
129
}
130
 
235 giacomo 131
static void RMSTAR_check_preemption(RMSTAR_level_des *lev)
132
{
133
  PID first;
134
 
135
#ifdef RMSTAR_DEBUG
136
  rmstar_printf("(E:chk)");
137
#endif
813 trimarchi 138
  /* check if the task is preempteble or not */
139
  if (lev->flag[lev->activated] & RMSTAR_FLAG_NOPREEMPT) return;
235 giacomo 140
 
141
  if ((first = iq_query_first(&lev->ready)) != lev->activated) {
142
    if (lev->activated != NIL)
143
      level_table[ lev->scheduling_level ]->
144
        private_extract(lev->scheduling_level, lev->activated);
145
 
146
    lev->activated = first;
147
 
148
    if (first != NIL) {
149
      BUDGET_TASK_MODEL b;
150
      budget_task_default_model(b, lev->budget[first]);
151
 
152
      level_table[ lev->scheduling_level ]->
153
        private_insert(lev->scheduling_level, first, (TASK_MODEL *)&b);
154
    }
155
  }
156
}
157
 
158
static void RMSTAR_timer_deadline(void *par);
159
 
160
static void RMSTAR_internal_activate(RMSTAR_level_des *lev, PID p,
161
                                     struct timespec *t)
162
{
163
#ifdef RMSTAR_DEBUG
164
  rmstar_printf("(E:iact)");
165
#endif
166
 
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 = RMSTAR_READY;
174
  iq_priority_insert(p,&lev->ready);
175
 
394 trimarchi 176
  proc_table[p].control &= ~CONTROL_CAP;
235 giacomo 177
 
178
  /* check for preemption */
179
  RMSTAR_check_preemption(lev);
180
}
181
 
182
static void RMSTAR_timer_deadline(void *par)
183
{
184
  PID p = (PID) par;
185
  RMSTAR_level_des *lev;
186
 
187
#ifdef RMSTAR_DEBUG
188
//  rmstar_printf("(E:tdl ");
189
#endif
190
 
191
  lev = (RMSTAR_level_des *)level_table[proc_table[p].task_level];
799 giacomo 192
  lev->deadline_timer[p] = NIL;
235 giacomo 193
 
194
  switch (proc_table[p].status) {
195
    case RMSTAR_IDLE:
196
#ifdef RMSTAR_DEBUG
197
//      rmstar_printf2("I%d",p);
198
#endif
199
      /* set the request time */
394 trimarchi 200
      if (!(lev->flag[p] & RMSTAR_FLAG_SPORADIC))
201
          RMSTAR_internal_activate(lev,p,iq_query_timespec(p, &lev->ready));
235 giacomo 202
 
203
      event_need_reschedule();
204
      break;
205
 
206
    default:
207
#ifdef RMSTAR_DEBUG
208
//      rmstar_printf2("D%d",p);
209
#endif
210
      /* else, a deadline miss occurred!!! */
211
      lev->dline_miss[p]++;
783 giacomo 212
      TRACER_LOGEVENT(FTrace_EVT_task_deadline_miss,proc_table[p].context,proc_table[p].task_level);
213
 
394 trimarchi 214
      if (!(lev->flag[p] & RMSTAR_FLAG_SPORADIC)) {
215
         lev->nact[p]++;
216
         ADDUSEC2TIMESPEC(lev->period[p], &lev->deadline_timespec[p]);
217
      }
235 giacomo 218
  }
219
 
220
  /* Set the deadline timer */
394 trimarchi 221
  if (!(lev->flag[p] & RMSTAR_FLAG_SPORADIC))
222
     lev->deadline_timer[p] = kern_event_post(&lev->deadline_timespec[p],
223
                                              RMSTAR_timer_deadline,
224
                                              (void *)p);
235 giacomo 225
 
226
#ifdef RMSTAR_DEBUG
227
//  rmstar_printf(")");
228
#endif
229
}
230
 
231
static void RMSTAR_timer_guest_deadline(void *par)
232
{
233
  PID p = (PID) par;
234
 
235
#ifdef RMSTAR_DEBUG
236
  rmstar_printf("(E:gdl)");
237
#endif
238
 
239
  kern_raise(XDEADLINE_MISS,p);
240
}
241
 
394 trimarchi 242
static void RMSTAR_account_capacity(RMSTAR_level_des *lev, PID p)
243
{
244
  struct timespec ty;
245
  TIME tx;
246
 
247
  SUBTIMESPEC(&schedule_time, &lev->cap_lasttime, &ty);
248
  tx = TIMESPEC2USEC(&ty);
249
 
250
  proc_table[p].avail_time -= tx;
251
}
252
 
253
 
235 giacomo 254
static int RMSTAR_public_create(LEVEL l, PID p, TASK_MODEL *m)
255
{
256
  RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
394 trimarchi 257
 
235 giacomo 258
  /* if the RMSTAR_task_create is called, then the pclass must be a
259
     valid pclass. */
260
  HARD_TASK_MODEL *h;
394 trimarchi 261
 
235 giacomo 262
  if (m->pclass != HARD_PCLASS) return -1;
263
  if (m->level != 0 && m->level != l) return -1;
264
  h = (HARD_TASK_MODEL *)m;
394 trimarchi 265
  if (!h->wcet || !h->mit) return -1;
235 giacomo 266
  /* now we know that m is a valid model */
267
 
394 trimarchi 268
  if (h->periodicity == APERIODIC)
269
        lev->flag[p] |= RMSTAR_FLAG_SPORADIC;
270
 
235 giacomo 271
#ifdef RMSTAR_DEBUG
272
  rmstar_printf("(E:tcr)");
273
#endif
274
 
275
  lev->period[p] = h->mit;
276
  *iq_query_priority(p, &lev->ready) = h->mit;
277
 
278
  lev->flag[p] = 0;
279
  lev->deadline_timer[p] = -1;
280
  lev->dline_miss[p]     = 0;
281
  lev->wcet_miss[p]      = 0;
282
  lev->nact[p]           = 0;
283
 
284
  /* Enable wcet check */
285
  proc_table[p].avail_time = h->wcet;
286
  proc_table[p].wcet       = h->wcet;
394 trimarchi 287
  //proc_table[p].control |= CONTROL_CAP;
235 giacomo 288
 
289
  return 0; /* OK, also if the task cannot be guaranteed... */
290
}
291
 
292
static void RMSTAR_public_dispatch(LEVEL l, PID p, int nostop)
293
{
294
  RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
394 trimarchi 295
  struct timespec ty;
235 giacomo 296
 
297
#ifdef RMSTAR_DEBUG
298
  rmstar_printf("(E:dis)");
299
 
300
  rmstar_printf3("(%d %d)",
301
                  iq_query_timespec(p, &lev->ready)->tv_nsec/1000000,
302
                  schedule_time.tv_nsec/1000000);
303
#endif
304
 
394 trimarchi 305
  if (!nostop || proc_table[exec].task_level==l) {
306
      TIMESPEC_ASSIGN(&ty, &schedule_time);
307
      TIMESPEC_ASSIGN(&lev->cap_lasttime, &schedule_time);
308
 
309
      /* ...and finally, we have to post a capacity event on exec task because the shadow_task consume
310
       *      *        capacity on exe task always */
786 trimarchi 311
      if (proc_table[exec].avail_time > 0) {
312
        ADDUSEC2TIMESPEC(proc_table[exec].avail_time ,&ty);
313
        lev->cap_lev = kern_event_post(&ty,capacity_handler, lev);
314
      }
394 trimarchi 315
      level_table[lev->scheduling_level]->private_dispatch(lev->scheduling_level, p, nostop);
316
  }
317
  else
318
      level_table[proc_table[exec].task_level]->public_dispatch(proc_table[exec].task_level, p, nostop);
319
 
235 giacomo 320
}
321
 
322
static void RMSTAR_public_epilogue(LEVEL l, PID p)
323
{
324
  RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
325
 
326
#ifdef RMSTAR_DEBUG
327
  rmstar_printf("(E:epi ");
328
#endif
329
 
394 trimarchi 330
  if (lev->cap_lev!=NIL) {
331
    kern_event_delete(lev->cap_lev);
332
    lev->cap_lev=NIL;
333
  }
334
 
335
 
336
  if ( proc_table[exec].task_level==l ) {
337
 
786 trimarchi 338
    if (proc_table[exec].avail_time > 0) RMSTAR_account_capacity(lev,exec);
394 trimarchi 339
 
340
    /* check if the wcet is finished... */
786 trimarchi 341
    if (proc_table[exec].avail_time) {
394 trimarchi 342
      /* wcet finished: disable wcet event and count wcet miss */
235 giacomo 343
#ifdef RMSTAR_DEBUG
394 trimarchi 344
      rmstar_printf2("W%d",p);
235 giacomo 345
#endif
394 trimarchi 346
      //proc_table[p].control &= ~CONTROL_CAP;
783 giacomo 347
      TRACER_LOGEVENT(FTrace_EVT_task_wcet_violation,proc_table[p].context,proc_table[p].task_level);
394 trimarchi 348
      lev->wcet_miss[p]++;
349
    }
235 giacomo 350
#ifdef RMSTAR_DEBUG
394 trimarchi 351
    rmstar_printf(")");
235 giacomo 352
#endif
394 trimarchi 353
 
354
    level_table[ lev->scheduling_level ]->
355
      private_epilogue(lev->scheduling_level,p);
356
 
357
    proc_table[p].status = RMSTAR_READY;
358
  } else
359
    level_table[proc_table[exec].task_level]->public_epilogue(proc_table[exec].task_level,p);
235 giacomo 360
}
361
 
783 giacomo 362
static void RMSTAR_public_activate(LEVEL l, PID p, struct timespec *o)
235 giacomo 363
{
364
  RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
365
  struct timespec t;
366
 
367
#ifdef RMSTAR_DEBUG
368
  rmstar_printf("(E:act)");
369
#endif
394 trimarchi 370
 /* Test if we are trying to activate a non sleeping task    */
371
 /* save activation (only if needed... */
235 giacomo 372
 
394 trimarchi 373
 if (proc_table[p].status != SLEEP) {
374
     /* a periodic task cannot be activated when it is already active */
375
     /* but aperiodic task can be reactivate before */
802 giacomo 376
     if (lev->flag[p] & RMSTAR_FLAG_SPORADIC) {
377
        if (proc_table[p].status != RMSTAR_IDLE) {
378
          lev->nact[p]++;
379
          return;
380
        }
381
     } else {
382
        kern_raise(XACTIVATION,p);
394 trimarchi 383
     }
384
  }
385
 
235 giacomo 386
  /* Test if we are trying to activate a non sleeping task    */
387
  /* save activation (only if needed... */
388
 
389
  kern_gettime(&t);
390
 
391
  RMSTAR_internal_activate(lev,p, &t);
392
 
393
  /* Set the deadline timer */
394
  lev->deadline_timer[p] = kern_event_post(&lev->deadline_timespec[p],
395
                                           RMSTAR_timer_deadline,
396
                                           (void *)p);
397
 
398
}
399
 
400
static void RMSTAR_public_unblock(LEVEL l, PID p)
401
{
402
  RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
403
 
404
#ifdef RMSTAR_DEBUG
405
  rmstar_printf("(E:ins)");
406
#endif
407
 
408
  /* Insert task in the correct position */
409
  proc_table[p].status = RMSTAR_READY;
410
  iq_priority_insert(p,&lev->ready);
411
 
412
  /* and check for preemption! */
413
  RMSTAR_check_preemption(lev);
414
}
415
 
416
static void RMSTAR_public_block(LEVEL l, PID p)
417
{
418
  RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
419
 
420
#ifdef RMSTAR_DEBUG
421
  rmstar_printf("(E:ext)");
422
#endif
423
 
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
  RMSTAR_check_preemption(lev);
430
}
431
 
432
static int RMSTAR_public_message(LEVEL l, PID p, void *m)
433
{
434
  RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
435
  struct timespec temp;
436
 
437
#ifdef RMSTAR_DEBUG
438
  rmstar_printf("(E:ecy ");
439
#endif
440
 
441
  switch ((long)(m))
442
    {
443
 
444
      /* Task EndCycle */
445
    case (long)(NULL):
446
 
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);  lev->activated = NIL;
451
 
452
      iq_extract(p,&lev->ready);
453
 
454
      /* we reset the capacity counters... */
455
      proc_table[p].avail_time = proc_table[p].wcet;
456
 
457
      if (lev->nact[p] > 0) {
458
#ifdef RMSTAR_DEBUG
459
        rmstar_printf2("E%d",p);
460
#endif
461
 
462
        /* Pending activation: reactivate the thread!!! */
463
        lev->nact[p]--;
464
 
465
        /* see also RMSTAR_timer_deadline */
466
        kern_gettime(&temp);
467
 
468
        RMSTAR_internal_activate(lev,p,&temp);
469
 
470
        /* check if the deadline has already expired */
471
        temp = *iq_query_timespec(p, &lev->ready);
472
        if (TIMESPEC_A_LT_B(&temp, &schedule_time)) {
473
          /* count the deadline miss */
474
          lev->dline_miss[p]++;
475
          kern_event_delete(lev->deadline_timer[p]);
799 giacomo 476
          lev->deadline_timer[p] = NIL;
235 giacomo 477
        }
478
 
479
      }
480
      else {
481
#ifdef RMSTAR_DEBUG
482
        rmstar_printf("e%d",p);
483
#endif
799 giacomo 484
        if (lev->flag[p] & RMSTAR_FLAG_SPORADIC && lev->deadline_timer[p] != NIL) {
394 trimarchi 485
            kern_event_delete(lev->deadline_timer[p]);
799 giacomo 486
            lev->deadline_timer[p] = NIL;
487
        }
394 trimarchi 488
 
235 giacomo 489
        /* the task has terminated his job before it consume the wcet. All OK! */
799 giacomo 490
        if (lev->flag[p] & RMSTAR_FLAG_SPORADIC)
491
                proc_table[p].status = SLEEP;
492
         else
493
                proc_table[p].status = RMSTAR_IDLE;
235 giacomo 494
 
495
        /* and finally, a preemption check! */
496
        RMSTAR_check_preemption(lev);
497
 
498
        /* when the deadline timer fire, it recognize the situation and set
499
           correctly all the stuffs (like reactivation, etc... ) */
500
      }
501
#ifdef RMSTAR_DEBUG
502
      rmstar_printf(")");
503
#endif
783 giacomo 504
      TRACER_LOGEVENT(FTrace_EVT_task_end_cycle,proc_table[p].context,proc_table[p].task_level);      
235 giacomo 505
      jet_update_endcycle(); /* Update the Jet data... */
506
      break;
507
    default:
508
 
509
      break;
510
 
511
    }
512
  return 0;
513
}
514
 
515
static void RMSTAR_public_end(LEVEL l, PID p)
516
{
517
  RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
518
 
519
#ifdef RMSTAR_DEBUG
520
  rmstar_printf("(E:end)");
521
#endif
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);
529
 
530
  if (lev->deadline_timer[p] != -1) {
531
    kern_event_delete(lev->deadline_timer[p]);
799 giacomo 532
    lev->deadline_timer[p] = NIL;
235 giacomo 533
  }
534
 
535
  /* and finally, a preemption check! (it will also call guest_end) */
536
  RMSTAR_check_preemption(lev);
537
}
538
 
539
 
540
/* Guest Functions
541
   These functions manages a JOB_TASK_MODEL, that is used to put
542
   a guest task in the RMSTAR ready queue. */
543
 
544
static void RMSTAR_private_insert(LEVEL l, PID p, TASK_MODEL *m)
545
{
546
  RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
547
  JOB_TASK_MODEL *job;
548
 
549
  if (m->pclass != JOB_PCLASS || (m->level != 0 && m->level != l) ) {
550
    kern_raise(XINVALID_TASK, p);
551
    return;
552
  }
553
 
554
  job = (JOB_TASK_MODEL *)m;
555
 
556
  *iq_query_timespec(p, &lev->ready) = job->deadline;
557
 
558
  lev->deadline_timer[p] = -1;
559
  lev->dline_miss[p]     = 0;
560
  lev->wcet_miss[p]      = 0;
561
  lev->nact[p]           = 0;
562
 
563
  if (job->noraiseexc)
564
    lev->flag[p] = RMSTAR_FLAG_NORAISEEXC;
565
  else {
566
    lev->flag[p] = 0;
567
    lev->deadline_timer[p] = kern_event_post(iq_query_timespec(p, &lev->ready),
568
                                             RMSTAR_timer_guest_deadline,
569
                                             (void *)p);
570
   }
571
 
572
  lev->period[p] = job->period;
573
  *iq_query_priority(p, &lev->ready) = job->period;
574
 
575
  /* there is no bandwidth guarantee at this level, it is performed
576
     by the level that inserts guest tasks... */
577
 
578
  /* Insert task in the correct position */
579
  iq_priority_insert(p,&lev->ready);
580
  proc_table[p].status = RMSTAR_READY;
581
 
582
  /* check for preemption */
583
  RMSTAR_check_preemption(lev);
584
}
585
 
586
 
587
static void RMSTAR_private_dispatch(LEVEL l, PID p, int nostop)
588
{
589
  RMSTAR_level_des *lev = (RMSTAR_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 RMSTAR_private_epilogue(LEVEL l, PID p)
596
{
597
  RMSTAR_level_des *lev = (RMSTAR_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 = RMSTAR_READY;
604
}
605
 
606
static void RMSTAR_private_extract(LEVEL l, PID p)
607
{
608
  RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
609
 
610
#ifdef RMSTAR_DEBUG
611
  //kern_printf("RMSTAR_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 RMSTAR_DEBUG
619
//    kern_printf("RMSTAR_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
  RMSTAR_check_preemption(lev);
627
}
628
 
629
/* Registration functions */
630
 
631
/* Registration function:
632
    int flags                 the init flags ... see RMSTAR.h */
633
LEVEL RMSTAR_register_level(int master)
634
{
635
  LEVEL l;            /* the level that we register */
636
  RMSTAR_level_des *lev;  /* for readableness only */
637
  PID i;              /* a counter */
638
 
639
#ifdef RMSTAR_DEBUG
640
  printk("RMSTAR_register_level\n");
641
#endif
642
 
643
  /* request an entry in the level_table */
644
  l = level_alloc_descriptor(sizeof(RMSTAR_level_des));
645
 
646
  lev = (RMSTAR_level_des *)level_table[l];
647
 
648
  /* fill the standard descriptor */
649
  lev->l.private_insert   = RMSTAR_private_insert;
650
  lev->l.private_extract  = RMSTAR_private_extract;
651
  lev->l.private_dispatch = RMSTAR_private_dispatch;
652
  lev->l.private_epilogue = RMSTAR_private_epilogue;
653
 
654
  lev->l.public_guarantee = NULL;
655
  lev->l.public_create    = RMSTAR_public_create;
656
  lev->l.public_end       = RMSTAR_public_end;
657
  lev->l.public_dispatch  = RMSTAR_public_dispatch;
658
  lev->l.public_epilogue  = RMSTAR_public_epilogue;
659
  lev->l.public_activate  = RMSTAR_public_activate;
660
  lev->l.public_unblock   = RMSTAR_public_unblock;
661
  lev->l.public_block     = RMSTAR_public_block;
662
  lev->l.public_message   = RMSTAR_public_message;
663
 
664
  /* fill the RMSTAR descriptor part */
665
  for(i=0; i<MAX_PROC; i++) {
666
    lev->period[i]         = 0;
667
    lev->deadline_timer[i] = -1;
668
    lev->flag[i]           = 0;
669
    lev->dline_miss[i]     = 0;
670
    lev->wcet_miss[i]      = 0;
671
    lev->nact[i]           = 0;
672
    lev->budget[i]         = NIL;
673
  }
674
 
675
  iq_init(&lev->ready, NULL, 0);
676
  lev->activated = NIL;
677
 
678
  lev->scheduling_level = master;
679
 
394 trimarchi 680
  lev->cap_lev = NIL;
681
  NULL_TIMESPEC(&lev->cap_lasttime);
682
 
235 giacomo 683
  return l;
684
}
685
 
686
int RMSTAR_get_dline_miss(PID p)
687
{
688
  LEVEL l = proc_table[p].task_level;
689
  RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
690
 
691
  return lev->dline_miss[p];
692
}
693
 
694
int RMSTAR_get_wcet_miss(PID p)
695
{
696
  LEVEL l = proc_table[p].task_level;
697
  RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
698
 
699
  return lev->wcet_miss[p];
700
}
701
 
702
int RMSTAR_get_nact(PID p)
703
{
704
  LEVEL l = proc_table[p].task_level;
705
  RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
706
 
707
  return lev->nact[p];
708
}
709
 
710
int RMSTAR_reset_dline_miss(PID p)
711
{
712
  LEVEL l = proc_table[p].task_level;
713
  RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
714
 
715
  lev->dline_miss[p] = 0;
716
  return 0;
717
}
718
 
719
int RMSTAR_reset_wcet_miss(PID p)
720
{
721
  LEVEL l = proc_table[p].task_level;
722
  RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
723
 
724
  lev->wcet_miss[p] = 0;
725
  return 0;
726
}
727
 
728
 
729
int RMSTAR_setbudget(LEVEL l, PID p, int budget)
730
{
731
 
732
  RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
733
 
734
  lev->budget[p] = budget;
735
 
736
  return 0;
737
 
738
}
739
 
740
int RMSTAR_getbudget(LEVEL l, PID p)
741
{
742
 
743
  RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
744
 
745
  return lev->budget[p];
746
 
747
}
748
 
749
int RMSTAR_budget_has_thread(LEVEL l, int budget)
750
{
751
 
752
  RMSTAR_level_des *lev = (RMSTAR_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
}
813 trimarchi 761
 
762
 
763
void RMSTAR_set_nopreemtive_current(LEVEL l) {
764
 
765
  RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
766
 
767
  lev->flag[lev->activated]|=RMSTAR_FLAG_NOPREEMPT;
768
}
769
 
818 trimarchi 770
void RMSTAR_unset_nopreemtive_current(LEVEL l) {
813 trimarchi 771
 
772
  RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
773
 
774
  lev->flag[lev->activated]&=~RMSTAR_FLAG_NOPREEMPT;
775
}
776