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; |
} |
|