Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 28 → Rev 29

/shark/trunk/kernel/modules/rm.c
20,11 → 20,11
 
/**
------------
CVS : $Id: rm.c,v 1.2 2002-10-28 07:55:55 pj Exp $
CVS : $Id: rm.c,v 1.3 2002-11-11 08:32:06 pj Exp $
 
File: $File$
Revision: $Revision: 1.2 $
Last update: $Date: 2002-10-28 07:55:55 $
Revision: $Revision: 1.3 $
Last update: $Date: 2002-11-11 08:32:06 $
------------
 
This file contains the scheduling module RM (Rate Monotonic)
71,7 → 71,6
 
/*+ Status used in the level +*/
#define RM_READY MODULE_STATUS_BASE /*+ - Ready status +*/
#define RM_DELAY MODULE_STATUS_BASE+1 /*+ - Delay status +*/
#define RM_WCET_VIOLATED MODULE_STATUS_BASE+2 /*+ when wcet is finished +*/
#define RM_WAIT MODULE_STATUS_BASE+3 /*+ to wait the deadline +*/
#define RM_IDLE MODULE_STATUS_BASE+4 /*+ to wait the deadline +*/
94,7 → 93,7
/*+ used to manage the JOB_TASK_MODEL and the
periodicity +*/
 
QUEUE ready; /*+ the ready queue +*/
IQUEUE ready; /*+ the ready queue +*/
 
int flags; /*+ the init flags... +*/
 
110,7 → 109,6
 
switch (status) {
case RM_READY : return "RM_Ready";
case RM_DELAY : return "RM_Delay";
case RM_WCET_VIOLATED: return "RM_Wcet_Violated";
case RM_WAIT : return "RM_Sporadic_Wait";
case RM_IDLE : return "RM_Idle";
123,8 → 121,8
{
PID p = (PID) par;
RM_level_des *lev;
struct timespec *temp;
 
 
lev = (RM_level_des *)level_table[proc_table[p].task_level];
 
switch (proc_table[p].status) {
131,7 → 129,7
case RM_ZOMBIE:
/* we finally put the task in the ready queue */
proc_table[p].status = FREE;
q_insertfirst(p,&freedesc);
iq_insertfirst(p,&freedesc);
/* and free the allocated bandwidth */
lev->U -= (MAX_BANDWIDTH/lev->period[p]) * proc_table[p].wcet;
break;
140,12 → 138,12
/* tracer stuff */
trc_logevent(TRC_INTACTIVATION,&p);
/* similar to RM_task_activate */
TIMESPEC_ASSIGN(&proc_table[p].request_time,
&proc_table[p].timespec_priority);
ADDUSEC2TIMESPEC(lev->period[p], &proc_table[p].timespec_priority);
temp = iq_query_timespec(p, &lev->ready);
TIMESPEC_ASSIGN(&proc_table[p].request_time, temp);
ADDUSEC2TIMESPEC(lev->period[p], temp);
proc_table[p].status = RM_READY;
q_insert(p,&lev->ready);
lev->deadline_timer[p] = kern_event_post(&proc_table[p].timespec_priority,
iq_priority_insert(p,&lev->ready);
lev->deadline_timer[p] = kern_event_post(temp,
RM_timer_deadline,
(void *)p);
//printk("(d%d idle priority set to %d)",p,proc_table[p].priority );
173,23 → 171,6
kern_raise(XDEADLINE_MISS,p);
}
 
/*+ this function is called when a task finish his delay +*/
static void RM_timer_delay(void *par)
{
PID p = (PID) par;
RM_level_des *lev;
 
lev = (RM_level_des *)level_table[proc_table[p].task_level];
 
proc_table[p].status = RM_READY;
q_insert(p,&lev->ready);
 
proc_table[p].delay_timer = NIL; /* Paranoia */
 
event_need_reschedule();
}
 
 
static int RM_level_accept_task_model(LEVEL l, TASK_MODEL *m)
{
if (m->pclass == HARD_PCLASS || m->pclass == (HARD_PCLASS | l)) {
222,7 → 203,7
static void RM_level_status(LEVEL l)
{
RM_level_des *lev = (RM_level_des *)(level_table[l]);
PID p = lev->ready;
PID p = iq_query_first(&lev->ready);
 
kern_printf("Wcet Check : %s\n",
onoff(lev->flags & RM_ENABLE_WCET_CHECK));
240,10 → 221,10
proc_table[p].name,
lev->flag[p] & RM_FLAG_SPORADIC ? "MinITime" : "Period ",
lev->period[p],
proc_table[p].timespec_priority.tv_sec,
proc_table[p].timespec_priority.tv_nsec/1000,
iq_query_timespec(p, &lev->ready)->tv_sec,
iq_query_timespec(p, &lev->ready)->tv_nsec/1000,
RM_status_to_a(proc_table[p].status));
p = proc_table[p].next;
p = iq_query_next(p, &lev->ready);
}
 
for (p=0; p<MAX_PROC; p++)
254,8 → 235,8
proc_table[p].name,
lev->flag[p] & RM_FLAG_SPORADIC ? "MinITime" : "Period ",
lev->period[p],
proc_table[p].timespec_priority.tv_sec,
proc_table[p].timespec_priority.tv_nsec/1000,
iq_query_timespec(p, &lev->ready)->tv_sec,
iq_query_timespec(p, &lev->ready)->tv_nsec/1000,
RM_status_to_a(proc_table[p].status));
}
 
274,7 → 255,7
kern_printf(") ");
}
*/
return (PID)lev->ready;
return iq_query_first(&lev->ready);
}
 
/* The on-line guarantee is enabled only if the appropriate flag is set... */
305,7 → 286,7
 
HARD_TASK_MODEL *h = (HARD_TASK_MODEL *)m;
 
proc_table[p].priority = lev->period[p] = h->mit;
*iq_query_priority(p, &lev->ready) = lev->period[p] = h->mit;
 
if (h->periodicity == APERIODIC)
lev->flag[p] = RM_FLAG_SPORADIC;
366,14 → 347,6
return 0; /* if the task p is chosen, it is always eligible */
}
 
#ifdef __TEST1__
extern int testactive;
extern struct timespec s_stime[];
extern TIME s_curr[];
extern TIME s_PID[];
extern int useds;
#endif
 
static void RM_task_dispatch(LEVEL l, PID p, int nostop)
{
RM_level_des *lev = (RM_level_des *)(level_table[l]);
383,17 → 356,7
/* the task state is set EXE by the scheduler()
we extract the task from the ready queue
NB: we can't assume that p is the first task in the queue!!! */
q_extract(p, &lev->ready);
 
#ifdef __TEST1__
if (testactive)
{
TIMESPEC_ASSIGN(&s_stime[useds], &schedule_time);
s_curr[useds] = proc_table[p].avail_time;
s_PID[useds] = p;
useds++;
}
#endif
iq_extract(p, &lev->ready);
}
 
static void RM_task_epilogue(LEVEL l, PID p)
410,7 → 373,7
}
else {
/* the task has been preempted. it returns into the ready queue... */
q_insert(p,&lev->ready);
iq_priority_insert(p,&lev->ready);
proc_table[p].status = RM_READY;
}
}
418,6 → 381,7
static void RM_task_activate(LEVEL l, PID p)
{
RM_level_des *lev = (RM_level_des *)(level_table[l]);
struct timespec *temp;
 
if (proc_table[p].status == RM_WAIT) {
kern_raise(XACTIVATION,p);
434,16 → 398,16
/* see also RM_timer_deadline */
ll_gettime(TIME_EXACT, &proc_table[p].request_time);
 
TIMESPEC_ASSIGN(&proc_table[p].timespec_priority,
&proc_table[p].request_time);
ADDUSEC2TIMESPEC(lev->period[p], &proc_table[p].timespec_priority);
temp = iq_query_timespec(p, &lev->ready);
TIMESPEC_ASSIGN(temp, &proc_table[p].request_time);
ADDUSEC2TIMESPEC(lev->period[p], temp);
 
/* Insert task in the correct position */
proc_table[p].status = RM_READY;
q_insert(p,&lev->ready);
iq_priority_insert(p,&lev->ready);
 
/* Set the deadline timer */
lev->deadline_timer[p] = kern_event_post(&proc_table[p].timespec_priority,
lev->deadline_timer[p] = kern_event_post(temp,
RM_timer_deadline,
(void *)p);
}
457,7 → 421,7
 
/* Insert task in the correct position */
proc_table[p].status = RM_READY;
q_insert(p,&lev->ready);
iq_priority_insert(p,&lev->ready);
}
 
static void RM_task_extract(LEVEL l, PID p)
516,22 → 480,7
correctly the task state to sleep... */
}
 
static void RM_task_delay(LEVEL l, PID p, TIME usdelay)
{
struct timespec wakeuptime;
// RM_level_des *lev = (RM_level_des *)(level_table[l]);
 
/* equal to RM_task_endcycle */
proc_table[p].status = RM_DELAY;
 
/* we need to delete this event if we kill the task while it is sleeping */
ll_gettime(TIME_EXACT, &wakeuptime);
ADDUSEC2TIMESPEC(usdelay, &wakeuptime);
proc_table[p].delay_timer = kern_event_post(&wakeuptime,
RM_timer_delay,
(void *)p);
}
 
/* Guest Functions
These functions manages a JOB_TASK_MODEL, that is used to put
a guest task in the RM ready queue. */
544,9 → 493,9
/* if the RM_guest_create is called, then the pclass must be a
valid pclass. */
 
 
*iq_query_timespec(p,&lev->ready) = job->deadline;
TIMESPEC_ASSIGN(&proc_table[p].timespec_priority, &job->deadline);
lev->deadline_timer[p] = -1;
 
if (job->noraiseexc)
554,7 → 503,7
else
lev->flag[p] = 0;
 
proc_table[p].priority = lev->period[p] = job->period;
*iq_query_priority(p, &lev->ready) = lev->period[p] = job->period;
 
/* there is no bandwidth guarantee at this level, it is performed
by the level that inserts guest tasks... */
576,7 → 525,7
/* the task state is set to EXE by the scheduler()
we extract the task from the ready queue
NB: we can't assume that p is the first task in the queue!!! */
q_extract(p, &lev->ready);
iq_extract(p, &lev->ready);
}
 
static void RM_guest_epilogue(LEVEL l, PID p)
584,7 → 533,7
RM_level_des *lev = (RM_level_des *)(level_table[l]);
 
/* the task has been preempted. it returns into the ready queue... */
q_insert(p,&lev->ready);
iq_priority_insert(p,&lev->ready);
proc_table[p].status = RM_READY;
}
 
593,15 → 542,14
RM_level_des *lev = (RM_level_des *)(level_table[l]);
 
/* Insert task in the correct position */
q_insert(p,&lev->ready);
iq_priority_insert(p,&lev->ready);
proc_table[p].status = RM_READY;
 
/* Set the deadline timer */
if (!(lev->flag[p] & RM_FLAG_NORAISEEXC))
lev->deadline_timer[p] = kern_event_post(&proc_table[p].timespec_priority,
lev->deadline_timer[p] = kern_event_post(iq_query_timespec(p, &lev->ready),
RM_timer_guest_deadline,
(void *)p);
 
}
 
static void RM_guest_insert(LEVEL l, PID p)
609,7 → 557,7
RM_level_des *lev = (RM_level_des *)(level_table[l]);
 
/* Insert task in the correct position */
q_insert(p,&lev->ready);
iq_priority_insert(p,&lev->ready);
proc_table[p].status = RM_READY;
}
 
634,13 → 582,9
//kern_printf("RM_guest_end: dline timer %d\n",lev->deadline_timer[p]);
if (proc_table[p].status == RM_READY)
{
q_extract(p, &lev->ready);
iq_extract(p, &lev->ready);
//kern_printf("(g_end rdy extr)");
}
else if (proc_table[p].status == RM_DELAY) {
event_delete(proc_table[p].delay_timer);
proc_table[p].delay_timer = NIL; /* paranoia */
}
 
/* we remove the deadline timer, because the slice is finished */
if (lev->deadline_timer[p] != NIL) {
654,25 → 598,9
static void RM_guest_sleep(LEVEL l, PID p)
{ kern_raise(XINVALID_GUEST,exec_shadow); }
 
static void RM_guest_delay(LEVEL l, PID p, TIME usdelay)
{
struct timespec wakeuptime;
// RM_level_des *lev = (RM_level_des *)(level_table[l]);
 
/* equal to RM_task_endcycle */
proc_table[p].status = RM_DELAY;
 
/* we need to delete this event if we kill the task while it is sleeping */
ll_gettime(TIME_EXACT, &wakeuptime);
ADDUSEC2TIMESPEC(usdelay, &wakeuptime);
proc_table[p].delay_timer = kern_event_post(&wakeuptime,
RM_timer_delay,
(void *)p);
}
 
 
 
 
/* Registration functions */
 
/*+ Registration function:
722,7 → 650,6
lev->l.task_endcycle = RM_task_endcycle;
lev->l.task_end = RM_task_end;
lev->l.task_sleep = RM_task_sleep;
lev->l.task_delay = RM_task_delay;
 
lev->l.guest_create = RM_guest_create;
lev->l.guest_detach = RM_guest_detach;
734,7 → 661,6
lev->l.guest_endcycle = RM_guest_endcycle;
lev->l.guest_end = RM_guest_end;
lev->l.guest_sleep = RM_guest_sleep;
lev->l.guest_delay = RM_guest_delay;
 
/* fill the RM descriptor part */
for(i=0; i<MAX_PROC; i++) {
743,7 → 669,7
lev->flag[i] = 0;
}
 
lev->ready = NIL;
iq_init(&lev->ready, &freedesc, 0);
lev->flags = flags & 0x07;
lev->U = 0;
}