Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 393 → Rev 394

/shark/trunk/ports/first/modules/rmstar.c
80,6 → 80,7
 
/* flags */
#define RMSTAR_FLAG_NORAISEEXC 2
#define RMSTAR_FLAG_SPORADIC 1
 
/* the level redefinition for the Earliest Deadline First level */
typedef struct {
110,8 → 111,19
 
int scheduling_level;
 
int cap_lev;
 
struct timespec cap_lasttime;
 
} RMSTAR_level_des;
 
static void capacity_handler(void *l)
{
RMSTAR_level_des *lev = l;
lev->cap_lev = NIL;
event_need_reschedule();
}
 
static void RMSTAR_check_preemption(RMSTAR_level_des *lev)
{
PID first;
155,8 → 167,7
proc_table[p].status = RMSTAR_READY;
iq_priority_insert(p,&lev->ready);
 
/* needed because when there is a wcet miss I disable CONTROL_CAP */
proc_table[p].control |= CONTROL_CAP;
proc_table[p].control &= ~CONTROL_CAP;
 
/* check for preemption */
RMSTAR_check_preemption(lev);
179,7 → 190,8
// rmstar_printf2("I%d",p);
#endif
/* set the request time */
RMSTAR_internal_activate(lev,p,iq_query_timespec(p, &lev->ready));
if (!(lev->flag[p] & RMSTAR_FLAG_SPORADIC))
RMSTAR_internal_activate(lev,p,iq_query_timespec(p, &lev->ready));
 
event_need_reschedule();
break;
190,18 → 202,17
#endif
/* else, a deadline miss occurred!!! */
lev->dline_miss[p]++;
 
/* the task is into another state */
lev->nact[p]++;
 
/* Set the deadline timer */
ADDUSEC2TIMESPEC(lev->period[p], &lev->deadline_timespec[p]);
if (!(lev->flag[p] & RMSTAR_FLAG_SPORADIC)) {
lev->nact[p]++;
ADDUSEC2TIMESPEC(lev->period[p], &lev->deadline_timespec[p]);
}
}
 
/* Set the deadline timer */
lev->deadline_timer[p] = kern_event_post(&lev->deadline_timespec[p],
RMSTAR_timer_deadline,
(void *)p);
if (!(lev->flag[p] & RMSTAR_FLAG_SPORADIC))
lev->deadline_timer[p] = kern_event_post(&lev->deadline_timespec[p],
RMSTAR_timer_deadline,
(void *)p);
 
#ifdef RMSTAR_DEBUG
// rmstar_printf(")");
219,20 → 230,35
kern_raise(XDEADLINE_MISS,p);
}
 
static void RMSTAR_account_capacity(RMSTAR_level_des *lev, PID p)
{
struct timespec ty;
TIME tx;
 
SUBTIMESPEC(&schedule_time, &lev->cap_lasttime, &ty);
tx = TIMESPEC2USEC(&ty);
 
proc_table[p].avail_time -= tx;
}
 
 
static int RMSTAR_public_create(LEVEL l, PID p, TASK_MODEL *m)
{
RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
 
/* if the RMSTAR_task_create is called, then the pclass must be a
valid pclass. */
HARD_TASK_MODEL *h;
 
if (m->pclass != HARD_PCLASS) return -1;
if (m->level != 0 && m->level != l) return -1;
h = (HARD_TASK_MODEL *)m;
if (!h->wcet || !h->mit || h->periodicity != PERIODIC) return -1;
if (!h->wcet || !h->mit) return -1;
/* now we know that m is a valid model */
 
if (h->periodicity == APERIODIC)
lev->flag[p] |= RMSTAR_FLAG_SPORADIC;
 
#ifdef RMSTAR_DEBUG
rmstar_printf("(E:tcr)");
#endif
249,7 → 275,7
/* Enable wcet check */
proc_table[p].avail_time = h->wcet;
proc_table[p].wcet = h->wcet;
proc_table[p].control |= CONTROL_CAP;
//proc_table[p].control |= CONTROL_CAP;
 
return 0; /* OK, also if the task cannot be guaranteed... */
}
257,6 → 283,7
static void RMSTAR_public_dispatch(LEVEL l, PID p, int nostop)
{
RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
struct timespec ty;
 
#ifdef RMSTAR_DEBUG
rmstar_printf("(E:dis)");
266,8 → 293,19
schedule_time.tv_nsec/1000000);
#endif
 
level_table[ lev->scheduling_level ]->
private_dispatch(lev->scheduling_level,p,nostop);
if (!nostop || proc_table[exec].task_level==l) {
TIMESPEC_ASSIGN(&ty, &schedule_time);
TIMESPEC_ASSIGN(&lev->cap_lasttime, &schedule_time);
 
/* ...and finally, we have to post a capacity event on exec task because the shadow_task consume
* * capacity on exe task always */
ADDUSEC2TIMESPEC(proc_table[exec].avail_time ,&ty);
lev->cap_lev = kern_event_post(&ty,capacity_handler, lev);
level_table[lev->scheduling_level]->private_dispatch(lev->scheduling_level, p, nostop);
}
else
level_table[proc_table[exec].task_level]->public_dispatch(proc_table[exec].task_level, p, nostop);
 
}
 
static void RMSTAR_public_epilogue(LEVEL l, PID p)
278,23 → 316,35
rmstar_printf("(E:epi ");
#endif
 
/* check if the wcet is finished... */
if (proc_table[p].avail_time <= 0 && proc_table[p].control&CONTROL_CAP) {
/* wcet finished: disable wcet event and count wcet miss */
if (lev->cap_lev!=NIL) {
kern_event_delete(lev->cap_lev);
lev->cap_lev=NIL;
}
 
 
if ( proc_table[exec].task_level==l ) {
RMSTAR_account_capacity(lev,exec);
/* check if the wcet is finished... */
if (proc_table[p].avail_time) {
/* wcet finished: disable wcet event and count wcet miss */
#ifdef RMSTAR_DEBUG
rmstar_printf2("W%d",p);
rmstar_printf2("W%d",p);
#endif
proc_table[p].control &= ~CONTROL_CAP;
lev->wcet_miss[p]++;
}
//proc_table[p].control &= ~CONTROL_CAP;
lev->wcet_miss[p]++;
}
#ifdef RMSTAR_DEBUG
rmstar_printf(")");
rmstar_printf(")");
#endif
 
level_table[ lev->scheduling_level ]->
private_epilogue(lev->scheduling_level,p);
 
proc_table[p].status = RMSTAR_READY;
level_table[ lev->scheduling_level ]->
private_epilogue(lev->scheduling_level,p);
proc_table[p].status = RMSTAR_READY;
} else
level_table[proc_table[exec].task_level]->public_epilogue(proc_table[exec].task_level,p);
}
 
static void RMSTAR_public_activate(LEVEL l, PID p)
305,14 → 355,24
#ifdef RMSTAR_DEBUG
rmstar_printf("(E:act)");
#endif
/* Test if we are trying to activate a non sleeping task */
/* save activation (only if needed... */
 
if (proc_table[p].status != SLEEP) {
/* a periodic task cannot be activated when it is already active */
/* but aperiodic task can be reactivate before */
if (lev->flag[p] & RMSTAR_FLAG_SPORADIC) {
if (proc_table[p].status != RMSTAR_IDLE) {
lev->nact[p]++;
return;
}
} else {
kern_raise(XACTIVATION,p);
}
}
 
/* Test if we are trying to activate a non sleeping task */
/* save activation (only if needed... */
if (proc_table[p].status != SLEEP) {
/* a periodic task cannot be activated when it is already active */
kern_raise(XACTIVATION,p);
return;
}
 
kern_gettime(&t);
 
408,7 → 468,9
#ifdef RMSTAR_DEBUG
rmstar_printf("e%d",p);
#endif
if (lev->flag[p] & RMSTAR_FLAG_SPORADIC && lev->deadline_timer[p] != NIL)
kern_event_delete(lev->deadline_timer[p]);
/* the task has terminated his job before it consume the wcet. All OK! */
proc_table[p].status = RMSTAR_IDLE;
596,6 → 658,9
 
lev->scheduling_level = master;
 
lev->cap_lev = NIL;
NULL_TIMESPEC(&lev->cap_lasttime);
 
return l;
}