/shark/trunk/ports/first/modules/edfstar.c |
---|
114,8 → 114,22 |
int scheduling_level; |
int cap_lev; |
struct timespec cap_lasttime; |
} EDFSTAR_level_des; |
static void capacity_handler(void *l) |
{ |
EDFSTAR_level_des *lev = l; |
lev->cap_lev = NIL; |
//kern_printf("(/)"); |
event_need_reschedule(); |
} |
static void EDFSTAR_check_preemption(EDFSTAR_level_des *lev) |
{ |
PID first; |
158,9 → 172,10 |
/* Insert task in the correct position */ |
proc_table[p].status = EDFSTAR_READY; |
iq_timespec_insert(p,&lev->ready); |
proc_table[p].control &= ~CONTROL_CAP; |
/* 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 */ |
EDFSTAR_check_preemption(lev); |
253,11 → 268,24 |
/* 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... */ |
} |
static void EDFSTAR_account_capacity(EDFSTAR_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; |
//kern_printf("avail time pid %d , %d", p, proc_table[p].avail_time); |
} |
static int EDFSTAR_public_eligible(LEVEL l, PID p) |
{ |
EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]); |
273,6 → 301,7 |
static void EDFSTAR_public_dispatch(LEVEL l, PID p, int nostop) |
{ |
EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]); |
struct timespec ty; |
#ifdef EDFSTAR_DEBUG |
edfstar_printf("(E:dis)"); |
281,9 → 310,19 |
iq_query_timespec(p, &lev->ready)->tv_nsec/1000000, |
schedule_time.tv_nsec/1000000); |
#endif |
if (!nostop || proc_table[exec].task_level==l) { |
TIMESPEC_ASSIGN(&ty, &schedule_time); |
TIMESPEC_ASSIGN(&lev->cap_lasttime, &schedule_time); |
level_table[ lev->scheduling_level ]-> |
private_dispatch(lev->scheduling_level,p,nostop); |
/* ...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 EDFSTAR_public_epilogue(LEVEL l, PID p) |
294,15 → 333,25 |
edfstar_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 ) { |
EDFSTAR_account_capacity(lev,exec); |
/* check if the wcet is finished... */ |
if (proc_table[exec].avail_time <= 0) { |
/* wcet finished: disable wcet event and count wcet miss */ |
#ifdef EDFSTAR_DEBUG |
edfstar_printf2("W%d",p); |
#endif |
proc_table[p].control &= ~CONTROL_CAP; |
lev->wcet_miss[p]++; |
} |
//proc_table[p].control &= ~CONTROL_CAP; |
lev->wcet_miss[exec]++; |
} |
#ifdef EDFSTAR_DEBUG |
edfstar_printf(")"); |
#endif |
310,7 → 359,10 |
level_table[ lev->scheduling_level ]-> |
private_epilogue(lev->scheduling_level,p); |
proc_table[p].status = EDFSTAR_READY; |
proc_table[exec].status = EDFSTAR_READY; |
} else |
level_table[proc_table[exec].task_level]->public_epilogue(proc_table[exec].task_level,p); |
} |
static void EDFSTAR_public_activate(LEVEL l, PID p) |
618,6 → 670,8 |
lev->activated = NIL; |
lev->scheduling_level = master; |
lev->cap_lev=NIL; |
NULL_TIMESPEC(&lev->cap_lasttime); |
return l; |
} |
/shark/trunk/ports/first/modules/grubstar.c |
---|
154,7 → 154,7 |
GRUBSTAR_level_des *lev=(GRUBSTAR_level_des *)level_table[b->l]; |
#ifdef GRUBSTAR_DEBUG |
kern_printf("(GS:Rec:"); |
//kern_printf("(GS:Rec:"); |
#endif |
b->vtimer = NIL; |
223,7 → 223,7 |
if (b->vtimer!=NIL) kern_event_delete(b->vtimer); |
b->vtimer=NIL; |
if (lev->cap_lev != NIL && b->current == p) { |
if (lev->cap_lev != NIL) { |
kern_event_delete(lev->cap_lev); |
lev->cap_lev = NIL; |
} |
236,7 → 236,7 |
b->avail -= tx - b->last_reclaiming; |
#ifdef GRUBSTAR_DEBUG |
kern_printf("(GS:Cap p%d av=%d Uf=%u U=%u, tx=%d)", p, b->avail, lev->Uf, lev->U,(int)tx); |
//kern_printf("(GS:Cap p%d av=%d Uf=%u U=%u, tx=%d)", p, b->avail, lev->Uf, lev->U,(int)tx); |
#endif |
if (b->avail <= 0) b->flags = GRUBSTAR_NOACTIVE; |
281,7 → 281,9 |
GRUBSTAR_level_des *lev = l; |
lev->cap_lev = NIL; |
#ifdef GRUBSTAR_DEBUG |
kern_printf("(*)"); |
#endif |
event_need_reschedule(); |
} |
289,15 → 291,12 |
static int GRUBSTAR_private_eligible(LEVEL l, PID p) |
{ |
GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]); |
struct budget_struct *b = &lev->b[lev->tb[p]]; |
struct budget_struct *b=&lev->b[lev->tb[p]]; |
JOB_TASK_MODEL job; |
if (b->current == p) { |
if ( TIMESPEC_A_LT_B(&b->dline, &schedule_time)) { |
if ( TIMESPEC_A_LT_B(&b->dline, &schedule_time)) { |
#ifdef GRUBSTAR_DEBUG |
kern_printf("(GS:Eli:%d)",p); |
#endif |
if (lev->cap_lev!=NIL) { |
kern_event_delete(lev->cap_lev); |
339,8 → 338,7 |
return -1; |
} |
} |
} |
return 0; |
444,16 → 442,18 |
be extracted! */ |
/* ... then, we dispatch it to the master level */ |
level_table[ lev->scheduling_level ]-> |
private_dispatch(lev->scheduling_level,p,nostop); |
if (!nostop) |
level_table[ lev->scheduling_level ]-> |
private_dispatch(lev->scheduling_level,p,nostop); |
TIMESPEC_ASSIGN(&ty, &schedule_time); |
TIMESPEC_ASSIGN(&lev->cap_lasttime, &schedule_time); |
/* ...and finally, we have to post a capacity event */ |
if (!nostop) { |
TIMESPEC_ASSIGN(&ty, &schedule_time); |
TIMESPEC_ASSIGN(&lev->cap_lasttime, &schedule_time); |
ADDUSEC2TIMESPEC(lev->b[lev->tb[p]].avail,&ty); |
lev->cap_lev = kern_event_post(&ty,capacity_handler, lev); |
} |
ADDUSEC2TIMESPEC(lev->b[lev->tb[exec]].avail,&ty); |
lev->cap_lev = kern_event_post(&ty,capacity_handler, lev); |
} |
460,16 → 460,27 |
static void GRUBSTAR_private_epilogue(LEVEL l, PID p) |
{ |
GRUBSTAR_level_des *lev = (GRUBSTAR_level_des *)(level_table[l]); |
struct budget_struct *b = &lev->b[lev->tb[p]]; |
struct budget_struct *b; |
int skip_epilog; |
skip_epilog=0; |
#ifdef GRUBSTAR_DEBUG |
kern_printf("(GS:Epi:%d)",p); |
kern_printf("(GS:Epi:%d)",p); |
#endif |
if (p==b->current) { |
if (p==exec) b = &lev->b[lev->tb[p]]; |
else if (lev->tb[exec]!=NIL) { |
b = &lev->b[lev->tb[exec]]; |
#ifdef GRUBSTAR_DEBUG |
kern_printf("(ex%d, c%d)***************************", exec, p); |
#endif |
p=exec; |
skip_epilog=1; |
} |
else return; |
GRUBSTAR_account_capacity(lev,p); |
GRUBSTAR_account_capacity(lev,p); |
// L'evento di capacità va cancellato perchè sarà ripristinato nella successiva dispatch |
/* we have to check if the capacity is still available */ |
if (b->flags) { |
476,13 → 487,17 |
/* there is capacity available, maybe it is simply a preemption; |
the task have to return to the ready queue */ |
level_table[ lev->scheduling_level ]-> |
private_epilogue(lev->scheduling_level,p); |
if (!skip_epilog) |
level_table[ lev->scheduling_level ]-> |
private_epilogue(lev->scheduling_level,p); //else kern_printf("(SP)"); |
} else { |
/* we kill the current activation */ |
#ifdef GRUBSTAR_DEBUG |
kern_printf("(GS:HRExt:%d",p); |
#endif |
level_table[ lev->scheduling_level ]-> |
private_extract(lev->scheduling_level, p); |
private_extract(lev->scheduling_level, p); |
iq_insertfirst(p, &b->tasks); |
b->current = NIL; |
489,8 → 504,6 |
} |
} |
} |
static int GRUBSTAR_public_message(LEVEL l, PID p, void *m) |
/shark/trunk/ports/first/modules/posixstar.c |
---|
78,9 → 78,20 |
PID activated; |
int scheduling_level; |
int cap_lev; |
struct timespec cap_lasttime; |
} POSIXSTAR_level_des; |
static void capacity_handler(void *l) |
{ |
POSIXSTAR_level_des *lev = l; |
lev->cap_lev = NIL; |
//kern_printf("(/)"); |
event_need_reschedule(); |
} |
/* the private scheduler choice a task and insert in cbsstar module */ |
/* This is not efficient but very fair :-) |
The need of all this stuff is because if a task execute a long time |
109,7 → 120,7 |
} |
} |
if ((proc_table[p].control & CONTROL_CAP) && |
if ((proc_table[p].control /* & CONTROL_CAP */) && |
(proc_table[p].avail_time <= 0)) { |
if (proc_table[p].avail_time<=0) |
proc_table[p].avail_time += proc_table[p].wcet; |
143,14 → 154,27 |
static int POSIXSTAR_public_eligible(LEVEL l, PID p) |
{ |
POSIXSTAR_level_des *lev = (POSIXSTAR_level_des *)(level_table[l]); |
if (p==lev->activated) { |
return level_table[ lev->scheduling_level ]-> |
return level_table[ lev->scheduling_level ]-> |
private_eligible(lev->scheduling_level,p); |
} |
return 0; |
} |
static void POSIXSTAR_account_capacity(POSIXSTAR_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; |
//kern_printf("avail time pid %d , %d", p, proc_table[p].avail_time); |
} |
static int POSIXSTAR_public_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
POSIXSTAR_level_des *lev = (POSIXSTAR_level_des *)(level_table[l]); |
180,8 → 204,8 |
proc_table[p].avail_time = proc_table[exec_shadow].avail_time; |
proc_table[p].wcet = proc_table[exec_shadow].wcet; |
proc_table[p].control = (proc_table[p].control & ~CONTROL_CAP) | |
(proc_table[exec_shadow].control & CONTROL_CAP); |
proc_table[p].control = (proc_table[p].control & ~CONTROL_CAP); //| |
//(proc_table[exec_shadow].control & CONTROL_CAP); |
lev->nact[p] = (lev->nact[exec_shadow] == -1) ? -1 : 0; |
} |
198,11 → 222,11 |
proc_table[p].avail_time = lev->slice; |
proc_table[p].wcet = lev->slice; |
} |
/* |
if (nrt->policy == NRT_RR_POLICY) { |
proc_table[p].control |= CONTROL_CAP; |
} |
*/ |
if (nrt->arrivals == SAVE_ARRIVALS) |
lev->nact[p] = 0; |
else |
216,17 → 240,27 |
static void POSIXSTAR_public_dispatch(LEVEL l, PID p, int nostop) |
{ |
POSIXSTAR_level_des *lev = (POSIXSTAR_level_des *)(level_table[l]); |
struct timespec ty; |
/* 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!!! */ |
#ifdef POSIXSTAR_DEBUG |
kern_printf("(PS:Dsp:%d)",p); |
if( !nostop) kern_printf("(PS:Dsp:%d)",p); else |
kern_printf("(PS:Dsp_shad:%d)",p); |
#endif |
if (p==lev->activated) |
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); |
} |
238,22 → 272,29 |
kern_printf("(PS:Epi:%d)",p); |
#endif |
if (p==lev->activated) { |
if (lev->cap_lev!=NIL) { |
kern_event_delete(lev->cap_lev); |
lev->cap_lev=NIL; |
} |
if (/* p==exec && lev->activated==p */ |
proc_table[exec].task_level==l ) { |
POSIXSTAR_account_capacity(lev,exec); |
if (lev->yielding) { |
lev->yielding = 0; |
iq_extract(p,&lev->ready[lev->priority[p]]); |
iq_insertlast(p,&lev->ready[lev->priority[p]]); |
iq_extract(p,&lev->ready[lev->priority[exec]]); |
iq_insertlast(p,&lev->ready[lev->priority[exec]]); |
} |
/* check if the slice is finished and insert the task in the coPOSIXect |
qqueue position */ |
else if (proc_table[p].control & CONTROL_CAP && |
proc_table[p].avail_time <= 0) { |
else if (/* proc_table[p].control & CONTROL_CAP && */ |
proc_table[exec].avail_time <= 0) { |
iq_extract(p,&lev->ready[lev->priority[p]]); |
iq_insertlast(p,&lev->ready[lev->priority[p]]); |
iq_extract(exec,&lev->ready[lev->priority[exec]]); |
iq_insertlast(exec,&lev->ready[lev->priority[exec]]); |
POSIXSTAR_private_scheduler(lev); |
if (p==lev->activated) |
if (exec==lev->activated) |
level_table[lev->scheduling_level]->private_epilogue(lev->scheduling_level,p); |
} |
267,7 → 308,9 |
proc_table[p].status = POSIXSTAR_READY; |
} |
} else |
level_table[proc_table[exec].task_level]->public_epilogue(proc_table[exec].task_level,p); |
} |
339,7 → 382,7 |
#endif |
iq_extract(p,&lev->ready[lev->priority[p]]); |
if (p==lev->activated) lev->activated = NIL; |
//if (p==lev->activated) lev->activated = NIL; |
POSIXSTAR_private_scheduler(lev); |
} |
456,7 → 499,9 |
lev->slice = slice; |
lev->activated = NIL; |
lev->scheduling_level = master; |
lev->cap_lev=NIL; |
NULL_TIMESPEC(&lev->cap_lasttime); |
return l; |
} |
536,10 → 581,10 |
if (proc_table[p].task_level != l) |
return ENOSYS; |
if (proc_table[p].control & CONTROL_CAP) |
//if (proc_table[p].control & CONTROL_CAP) |
*policy = NRT_RR_POLICY; |
else |
*policy = NRT_FIFO_POLICY; |
//else |
// *policy = NRT_FIFO_POLICY; |
*priority = ((POSIXSTAR_level_des *)(level_table[l]))->priority[p]; |
556,7 → 601,7 |
if (proc_table[p].task_level != l) |
return ENOSYS; |
/* |
if (policy == SCHED_RR) |
proc_table[p].control |= CONTROL_CAP; |
else if (policy == SCHED_FIFO) |
563,7 → 608,7 |
proc_table[p].control &= ~CONTROL_CAP; |
else |
return EINVAL; |
*/ |
if (lev->priority[p] != priority) { |
if (proc_table[p].status == POSIXSTAR_READY) { |
iq_extract(p,&lev->ready[lev->priority[p]]); |