45,8 → 45,6 |
|
#include <tracer.h> |
|
#define RMSTAR_CHANGE_LEVEL 1 |
|
/* for iqueues */ |
/* #include "iqueue.h" Now iqueues are the only queue type into the kernel */ |
|
54,8 → 52,8 |
#include "fsf_configuration_parameters.h" |
#include "fsf_core.h" |
#include "fsf_server.h" |
#include <posix/posix/comm_message.h> |
|
|
/* |
* DEBUG stuffs begin |
*/ |
66,9 → 64,9 |
|
static __inline__ fake_printf(char *fmt, ...) {} |
|
#define rmstar_printf fake_printf |
#define rmstar_printf2 fake_printf |
#define rmstar_printf3 fake_printf |
#define rmstar_printf kern_printf |
#define rmstar_printf2 kern_printf |
#define rmstar_printf3 kern_printf |
|
//#define rmstar_printf kern_printf |
//#define rmstar_printf2 kern_printf |
84,6 → 82,7 |
#define RMSTAR_IDLE MODULE_STATUS_BASE+4 /* to wait the deadline */ |
|
/* flags */ |
#define RMSTAR_CHANGE_LEVEL 8 |
#define RMSTAR_FLAG_NOPREEMPT 4 |
#define RMSTAR_FLAG_NORAISEEXC 2 |
#define RMSTAR_FLAG_SPORADIC 1 |
121,6 → 120,9 |
|
struct timespec cap_lasttime; |
|
int new_level[MAX_PROC]; |
int wcet[MAX_PROC]; /* save the wcet fields */ |
|
} RMSTAR_level_des; |
|
static void capacity_handler(void *l) |
157,6 → 159,51 |
} |
} |
|
static int RMSTAR_private_change_level(LEVEL l, PID p) |
{ |
|
RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]); |
|
/* Change task level */ |
if (lev->flag[p] & RMSTAR_CHANGE_LEVEL) { |
|
#ifdef RMSTAR_DEBUG |
rmstar_printf("(RM:clev)"); |
#endif |
|
STD_command_message msg; |
|
proc_table[p].status = SLEEP; |
lev->flag[p] &= ~ RMSTAR_CHANGE_LEVEL; |
|
level_table[lev->scheduling_level]->private_extract(lev->scheduling_level,p); |
iq_extract(p,&lev->ready); |
|
if (lev->deadline_timer[p] != -1) |
kern_event_delete(lev->deadline_timer[p]); |
|
lev->deadline_timer[p]=NIL; |
|
RMSTAR_check_preemption(lev); |
|
lev->nact[p] = 0; |
lev->budget[p] = -1; |
proc_table[p].task_level = lev->new_level[p]; |
|
/* Send change level command to local scheduler */ |
|
msg.command = STD_ACTIVATE_TASK; |
msg.param = NULL; |
|
level_table[ lev->new_level[p] ]->public_message(lev->new_level[p],p,&msg); |
|
return 1; |
|
} |
|
return 0; |
|
} |
static void RMSTAR_timer_deadline(void *par); |
|
static void RMSTAR_internal_activate(RMSTAR_level_des *lev, PID p, |
187,7 → 234,7 |
RMSTAR_level_des *lev; |
|
#ifdef RMSTAR_DEBUG |
// rmstar_printf("(E:tdl "); |
rmstar_printf("(E:tdl "); |
#endif |
|
lev = (RMSTAR_level_des *)level_table[proc_table[p].task_level]; |
196,7 → 243,7 |
switch (proc_table[p].status) { |
case RMSTAR_IDLE: |
#ifdef RMSTAR_DEBUG |
// rmstar_printf2("I%d",p); |
rmstar_printf2("I%d",p); |
#endif |
/* set the request time */ |
if (!(lev->flag[p] & RMSTAR_FLAG_SPORADIC)) |
207,7 → 254,7 |
|
default: |
#ifdef RMSTAR_DEBUG |
// rmstar_printf2("D%d",p); |
rmstar_printf2("D%d",p); |
#endif |
/* else, a deadline miss occurred!!! */ |
lev->dline_miss[p]++; |
226,7 → 273,7 |
(void *)p); |
|
#ifdef RMSTAR_DEBUG |
// rmstar_printf(")"); |
rmstar_printf(")"); |
#endif |
} |
|
260,7 → 307,9 |
/* if the RMSTAR_task_create is called, then the pclass must be a |
valid pclass. */ |
HARD_TASK_MODEL *h; |
|
#ifdef RMSTAR_DEBUG |
rmstar_printf("(RM:tcr)"); |
#endif |
if (m->pclass != HARD_PCLASS) return -1; |
if (m->level != 0 && m->level != l) return -1; |
h = (HARD_TASK_MODEL *)m; |
267,11 → 316,10 |
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)"); |
rmstar_printf("(RM:tcr)"); |
#endif |
|
lev->period[p] = h->mit; |
278,6 → 326,10 |
*iq_query_priority(p, &lev->ready) = h->mit; |
|
lev->flag[p] = 0; |
|
if (h->periodicity == APERIODIC) |
lev->flag[p] |= RMSTAR_FLAG_SPORADIC; |
|
lev->deadline_timer[p] = -1; |
lev->dline_miss[p] = 0; |
lev->wcet_miss[p] = 0; |
339,6 → 391,8 |
|
if (proc_table[exec].avail_time > 0) RMSTAR_account_capacity(lev,exec); |
|
if (RMSTAR_private_change_level(l, p)) return; |
|
/* check if the wcet is finished... */ |
if (proc_table[exec].avail_time) { |
/* wcet finished: disable wcet event and count wcet miss */ |
435,10 → 489,11 |
{ |
RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]); |
struct timespec temp; |
|
#ifdef RMSTAR_DEBUG |
rmstar_printf("(E:ecy "); |
#endif |
STD_command_message *msg; |
HARD_TASK_MODEL *h; |
|
switch ((long)(m)) |
{ |
446,6 → 501,11 |
/* Task EndCycle */ |
case (long)(NULL): |
|
if (RMSTAR_private_change_level(l,p)) return 0; |
|
if (proc_table[p].avail_time > 0) RMSTAR_account_capacity(lev,p); |
|
|
/* we call guest_end directly here because the same task may |
be reinserted in the queue before calling the preemption check! */ |
level_table[ lev->scheduling_level ]-> |
458,7 → 518,7 |
|
if (lev->nact[p] > 0) { |
#ifdef RMSTAR_DEBUG |
rmstar_printf2("E%d",p); |
rmstar_printf2("RM%d",p); |
#endif |
|
/* Pending activation: reactivate the thread!!! */ |
486,6 → 546,9 |
if (lev->flag[p] & RMSTAR_FLAG_SPORADIC && lev->deadline_timer[p] != NIL) { |
kern_event_delete(lev->deadline_timer[p]); |
lev->deadline_timer[p] = NIL; |
#ifdef RMSTAR_DEBUG |
rmstar_printf("deaddelete%d",p); |
#endif |
} |
|
/* the task has terminated his job before it consume the wcet. All OK! */ |
507,10 → 570,58 |
jet_update_endcycle(); /* Update the Jet data... */ |
break; |
default: |
msg = (STD_command_message *)m; |
|
#ifdef RMSTAR_DEBUG |
rmstar_printf("(RM:MSG %d)",msg->command); |
#endif |
|
switch(msg->command) { |
case STD_SET_NEW_MODEL: |
/* if the RMSTAR_task_create is called, then the pclass must be a |
valid pclass. */ |
h=(HARD_TASK_MODEL *)(msg->param); |
|
/* now we know that m is a valid model */ |
lev->wcet[p] = h->wcet; |
lev->period[p] = h->mit; |
|
#ifdef RMSTAR_DEBUG |
kern_printf("(RM:NM p%d w%d m%d)", p, h->wcet, h->mit); |
#endif |
lev->flag[p] = 0; |
lev->deadline_timer[p] = -1; |
lev->dline_miss[p] = 0; |
lev->wcet_miss[p] = 0; |
lev->nact[p] = 0; |
|
break; |
|
case STD_SET_NEW_LEVEL: |
|
lev->flag[p] |= RMSTAR_CHANGE_LEVEL; |
lev->new_level[p] = (int)(msg->param); |
|
break; |
|
case STD_ACTIVATE_TASK: |
#ifdef RMSTAR_DEBUG |
kern_printf("(RM:SA)"); |
#endif |
/* Enable wcet check */ |
proc_table[p].avail_time = lev->wcet[p]; |
proc_table[p].wcet = lev->wcet[p]; |
proc_table[p].control &= ~CONTROL_CAP; |
|
RMSTAR_public_activate(l, p,NULL); |
|
break; |
|
|
} |
break; |
|
} |
return 0; |
} |
|
563,9 → 674,9 |
lev->nact[p] = 0; |
|
if (job->noraiseexc) |
lev->flag[p] = RMSTAR_FLAG_NORAISEEXC; |
lev->flag[p] |= RMSTAR_FLAG_NORAISEEXC; |
else { |
lev->flag[p] = 0; |
lev->flag[p] &= ~RMSTAR_FLAG_NORAISEEXC; |
lev->deadline_timer[p] = kern_event_post(iq_query_timespec(p, &lev->ready), |
RMSTAR_timer_guest_deadline, |
(void *)p); |
610,7 → 721,7 |
RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]); |
|
#ifdef RMSTAR_DEBUG |
//kern_printf("RMSTAR_guest_end: dline timer %d\n",lev->deadline_timer[p]); |
kern_printf("RMSTAR_guest_end: dline timer %d\n",lev->deadline_timer[p]); |
#endif |
|
iq_extract(p, &lev->ready); |
618,7 → 729,7 |
/* we remove the deadline timer, because the slice is finished */ |
if (lev->deadline_timer[p] != NIL) { |
#ifdef RMSTAR_DEBUG |
// kern_printf("RMSTAR_guest_end: dline timer %d\n",lev->deadline_timer[p]); |
kern_printf("RMSTAR_guest_end: dline timer %d\n",lev->deadline_timer[p]); |
#endif |
kern_event_delete(lev->deadline_timer[p]); |
lev->deadline_timer[p] = NIL; |
672,6 → 783,7 |
lev->wcet_miss[i] = 0; |
lev->nact[i] = 0; |
lev->budget[i] = NIL; |
lev->new_level[i] = -1; |
} |
|
iq_init(&lev->ready, NULL, 0); |