34,7 → 34,7 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
* |
*/ |
|
#include "fsf.h" |
#include "tdstar.h" |
#include <ll/stdio.h> |
#include <ll/string.h> |
56,7 → 56,6 |
#include "fsf_server.h" |
#include <modules/comm_message.h> |
|
|
/* |
* DEBUG stuffs begin |
*/ |
91,12 → 90,13 |
#define TDSTAR_FLAG_SPORADIC 1 |
|
|
typedef struct offline_table { |
PID pid; |
struct timespec start; |
struct timespec end; |
struct timespec comp_time; |
} offline_table; |
typedef struct offline_element { |
PID pid; |
struct timespec start; |
struct timespec end; |
struct timespec comp_time; |
struct offline_element *next; |
} offline_element; |
|
|
/* the level redefinition for the Earliest Deadline First level */ |
130,9 → 130,10 |
|
int cap_lev; |
struct timespec cap_lasttime; |
int td_table_act_current; |
int td_table_act_number; |
struct offline_table tdtable[FSF_MAX_N_TARGET_WINDOWS]; |
struct offline_element *td_table_act_current; |
struct offline_element *td_table_act_head; |
struct offline_element *td_table_act_free; |
struct offline_element tdtable[FSF_MAX_N_TARGET_WINDOWS]; |
|
int new_level[MAX_PROC]; |
int wcet[MAX_PROC]; /* save the wcet fields */ |
153,7 → 154,7 |
PID first; |
|
#ifdef TDSTAR_DEBUG |
tdstar_printf("(E:chk)"); |
tdstar_printf("(TD:chk)"); |
#endif |
/* check if the task is preempteble or not */ |
if (lev->activated != NIL && lev->flag[lev->activated] & TDSTAR_FLAG_NOPREEMPT) return; |
183,10 → 184,10 |
TIME tx; |
|
#ifdef TDSTAR_DEBUG |
tdstar_printf("(E:iact)"); |
tdstar_printf("(TD:iact:%ds %dus )", t->tv_sec, t->tv_nsec/1000); |
#endif |
|
tx = TIMESPEC2USEC(&lev->tdtable[lev->td_table_act_current].end); |
tx = TIMESPEC2USEC(&lev->td_table_act_current->end); |
|
ADDUSEC2TIMESPEC(tx, t); |
|
221,7 → 222,7 |
|
default: |
#ifdef TDSTAR_DEBUG |
kern_printf("(E:Dl:%d)",p); |
kern_printf("(TD:Dl:%d)",p); |
#endif |
/* else, a deadline miss occurred!!! */ |
lev->dline_miss[p]++; |
251,7 → 252,7 |
if (lev->flag[p] & TDSTAR_CHANGE_LEVEL) { |
|
#ifdef TDSTAR_DEBUG |
tdstar_printf("(E:clev)"); |
tdstar_printf("(TD:clev)"); |
#endif |
|
STD_command_message msg; |
292,7 → 293,7 |
PID p = (PID) par; |
|
#ifdef TDSTAR_DEBUG |
tdstar_printf("(E:gdl)"); |
tdstar_printf("(TD:gdl)"); |
#endif |
|
kern_raise(XDEADLINE_MISS,p); |
309,19 → 310,20 |
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) return -1; |
if (h->wcet || h->mit) return -1; |
/* now we know that m is a valid model */ |
|
#ifdef TDSTAR_DEBUG |
tdstar_printf("(E:Crt)"); |
tdstar_printf("(TD:Crt)"); |
#endif |
|
lev->period[p] = h->mit; |
lev->period[p] = 0; |
|
lev->flag[p] = 0; |
|
if (h->periodicity == APERIODIC) |
lev->flag[p] |= TDSTAR_FLAG_SPORADIC; |
else return 0; |
|
lev->deadline_timer[p] = -1; |
lev->dline_miss[p] = 0; |
331,6 → 333,7 |
/* Enable wcet check */ |
proc_table[p].avail_time = h->wcet; |
proc_table[p].wcet = h->wcet; |
proc_table[p].status = SLEEP; |
|
return 0; /* OK, also if the task cannot be guaranteed... */ |
} |
352,7 → 355,7 |
TDSTAR_level_des *lev = (TDSTAR_level_des *)(level_table[l]); |
|
#ifdef TDSTAR_DEBUG |
tdstar_printf2("(E:eli:%d)",p); |
tdstar_printf2("(TD:eli:%d)",p); |
#endif |
|
return level_table[ lev->scheduling_level ]-> |
366,7 → 369,7 |
struct timespec ty; |
|
#ifdef TDSTAR_DEBUG |
tdstar_printf("(E:dis)"); |
tdstar_printf("(TD:dis)"); |
#endif |
|
if (!nostop || proc_table[exec].task_level==l) { |
391,7 → 394,7 |
TDSTAR_level_des *lev = (TDSTAR_level_des *)(level_table[l]); |
|
#ifdef TDSTAR_DEBUG |
tdstar_printf("(E:epi "); |
tdstar_printf("(TD:epi "); |
#endif |
|
if (lev->cap_lev!=NIL) { |
435,9 → 438,9 |
static void TDSTAR_public_activate(LEVEL l, PID p, struct timespec *o) |
{ |
TDSTAR_level_des *lev = (TDSTAR_level_des *)(level_table[l]); |
|
struct timespec t; |
#ifdef TDSTAR_DEBUG |
tdstar_printf("(E:act:%d)",p); |
tdstar_printf("(TD:act:%d)",p); |
#endif |
|
/* Test if we are trying to activate a non sleeping task */ |
448,6 → 451,7 |
if (lev->flag[p] & TDSTAR_FLAG_SPORADIC) { |
if (proc_table[p].status != TDSTAR_IDLE) { |
lev->nact[p]++; |
kern_printf("err***"); |
return; |
} |
} else { |
456,12 → 460,12 |
} |
|
/* Set the new wcet and avail time check */ |
proc_table[p].avail_time = TIMESPEC2USEC(&(lev->tdtable[lev->td_table_act_current].comp_time)); |
proc_table[p].wcet = TIMESPEC2USEC(&(lev->tdtable[lev->td_table_act_current].comp_time)); |
proc_table[p].avail_time = TIMESPEC2USEC(&(lev->td_table_act_current->comp_time)); |
proc_table[p].wcet = TIMESPEC2USEC(&(lev->td_table_act_current->comp_time)); |
|
//kern_gettime(&t); |
kern_gettime(&t); |
|
TDSTAR_internal_activate(lev,p, &lev->zero_time); |
TDSTAR_internal_activate(lev,p, &t); |
|
/* Set the deadline timer */ |
lev->deadline_timer[p] = kern_event_post(&lev->deadline_timespec[p], |
475,7 → 479,7 |
TDSTAR_level_des *lev = (TDSTAR_level_des *)(level_table[l]); |
|
#ifdef TDSTAR_DEBUG |
tdstar_printf("(E:ins)"); |
tdstar_printf("(TD:ins)"); |
#endif |
|
/* Insert task in the correct position */ |
493,7 → 497,7 |
TDSTAR_level_des *lev = (TDSTAR_level_des *)(level_table[l]); |
|
#ifdef TDSTAR_DEBUG |
tdstar_printf("(E:ext)"); |
tdstar_printf("(TD:ext)"); |
#endif |
|
/* the task is blocked on a synchronization primitive. we have to |
513,7 → 517,7 |
HARD_TASK_MODEL *h; |
|
#ifdef TDSTAR_DEBUG |
tdstar_printf("(E:ecy "); |
tdstar_printf("(TD:ecy "); |
#endif |
|
switch ((long)(m)) { |
593,7 → 597,7 |
msg = (STD_command_message *)m; |
|
#ifdef TDSTAR_DEBUG |
tdstar_printf("(E:MSG %d)",msg->command); |
tdstar_printf("(TD:MSG %d)",msg->command); |
#endif |
|
switch(msg->command) { |
651,7 → 655,7 |
TDSTAR_level_des *lev = (TDSTAR_level_des *)(level_table[l]); |
|
#ifdef TDSTAR_DEBUG |
tdstar_printf("(E:end)"); |
tdstar_printf("(TD:end)"); |
#endif |
|
iq_extract(p,&lev->ready); |
810,15 → 814,26 |
lev->new_level[i] = -1; |
} |
/// struct offline_table tdtable[FSF_MAX_N_TARGET_WINDOWS]; |
for (i=0; i<FSF_MAX_N_TARGET_WINDOWS; i++) |
for (i=0; i<FSF_MAX_N_TARGET_WINDOWS; i++) { |
lev->tdtable[i].pid=NIL; |
lev->tdtable[i].next=&lev->tdtable[(i+1)%FSF_MAX_N_TARGET_WINDOWS]; |
NULL_TIMESPEC(&lev->tdtable[i].comp_time); |
NULL_TIMESPEC(&lev->tdtable[i].end); |
NULL_TIMESPEC(&lev->tdtable[i].start); |
} |
lev->tdtable[FSF_MAX_N_TARGET_WINDOWS-1].next=NULL; |
lev->td_table_act_current=NULL; |
lev->td_table_act_head=NULL; |
lev->td_table_act_free=&lev->tdtable[0]; |
|
iq_init(&lev->ready, NULL, IQUEUE_NO_PRIORITY); |
lev->activated = NIL; |
|
|
lev->scheduling_level = master; |
lev->cap_lev = NIL; |
NULL_TIMESPEC(&lev->cap_lasttime); |
NULL_TIMESPEC(&lev->zero_time); |
|
return l; |
} |
917,16 → 932,22 |
|
struct timespec end_time; |
|
task_activate(lev->tdtable[lev->td_table_act_current].pid); |
#ifdef TDSTAR_DEBUG |
kern_printf("Pid %d",lev->td_table_act_current->pid); |
#endif |
|
if (lev->td_table_act_number > lev->td_table_act_current) { |
task_activate(lev->td_table_act_current->pid); |
lev->td_table_act_current=lev->td_table_act_current->next; |
|
ADDTIMESPEC(&lev->zero_time, &lev->tdtable[lev->td_table_act_current].start, &end_time); |
|
lev->td_table_act_current++; |
if (lev->td_table_act_current!=NULL) { |
|
ADDTIMESPEC(&lev->zero_time, &lev->td_table_act_current->start, &end_time); |
#ifdef TDSTAR_DEBUG |
tdstar_printf("(NEXT:iact:%ds %dus )", end_time.tv_sec, end_time.tv_nsec/1000); |
#endif |
kern_event_post(&end_time,(void *)((void *)(tdstar_task_activate)),lev); |
|
} |
} else exit(0); |
|
} |
|
934,11 → 955,18 |
{ |
TDSTAR_level_des *lev = (TDSTAR_level_des *)(level_table[l]); |
struct timespec end_time; |
//kern_printf("(Start simulation)"); |
kern_gettime(&lev->zero_time); |
#ifdef TDSTAR_DEBUG |
tdstar_printf("(START:iact:%ds %dus )", lev->zero_time.tv_sec, lev->zero_time.tv_nsec/1000); |
#endif |
if (lev->td_table_act_head != NULL) { |
lev->td_table_act_current=lev->td_table_act_head; |
ADDTIMESPEC(&lev->zero_time, &lev->td_table_act_head->start, &end_time); |
#ifdef TDSTAR_DEBUG |
tdstar_printf("(NEXT:iact:%ds %dus )", end_time.tv_sec, end_time.tv_nsec/1000); |
#endif |
|
kern_gettime(&lev->zero_time); |
if (lev->td_table_act_number > 0) { |
ADDTIMESPEC(&lev->zero_time, &lev->tdtable[0].start, &end_time); |
lev->td_table_act_current++; |
kern_event_post(&end_time,(void *)((void *)(tdstar_task_activate)),lev); |
} |
|
949,8 → 977,50 |
/// struct fsf_target_window table[FSF_MAX_N_TARGET_WINDOWS]; |
///} fsf_table_driven_params_t; |
|
void TDSTAR_settable(LEVEL l, fsf_table_driven_params_t *param) { |
void TDSTAR_settable(LEVEL l, fsf_table_driven_params_t *param, PID pd) { |
TDSTAR_level_des *lev = (TDSTAR_level_des *)(level_table[l]); |
int i; |
struct offline_element *elem,*p,*newelem; |
//kern_printf("Set table dim=%d", param->size); |
|
for (i=0; i<param->size; i++) { |
elem = NULL; |
//kern_printf("(E=%d)", i); |
newelem=lev->td_table_act_free; |
newelem->pid=pd; |
TIMESPEC_ASSIGN(&newelem->start,¶m->table[i].start); |
TIMESPEC_ASSIGN(&newelem->end, ¶m->table[i].end); |
TIMESPEC_ASSIGN(&newelem->comp_time, ¶m->table[i].comp_time); |
|
lev->td_table_act_free=lev->td_table_act_free->next; |
|
for (p = lev->td_table_act_head; p; p = elem->next) { |
if (TIMESPEC_A_GT_B(&(param->table[i].start), &p->start)) { |
elem=p; |
} |
else |
break; |
} |
if (elem) { |
//kern_printf("(New elem)"); |
elem->next = newelem; |
} else { |
//kern_printf("(Head)"); |
lev->td_table_act_head = newelem; |
} |
newelem->next = p; |
|
} |
} |
|
void TDSTAR_debugtable(LEVEL l) { |
TDSTAR_level_des *lev = (TDSTAR_level_des *)(level_table[l]); |
struct offline_element *p; |
int i; |
|
for (p = lev->td_table_act_head, i=0; p; p = p->next, i++) { |
|
kern_printf("(ev %d, start=%ds %dus)", i, p->start.tv_sec, (p->start.tv_nsec)/1000); |
} |
|
} |