Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 1018 → Rev 1021

/shark/trunk/modules/intdrive/intdrive.c
57,25 → 57,25
 
/*+ the level redefinition for the IntDrive +*/
typedef struct {
level_des l; /*+ the standard level descriptor +*/
level_des l; /*+ the standard level descriptor +*/
 
TIME replenish_period;
TIME capacity;
TIME q_theta;
TIME replenish_period;
TIME capacity;
TIME q_theta;
 
struct timespec act_time;
struct timespec act_time;
 
int avail;
int replenish_timer;
int avail;
int replenish_timer;
 
//struct timespec replenish_expires;
//int wcet_timer;
//struct timespec replenish_expires;
//int wcet_timer;
 
int act_number; /*+ the activation number +*/
int act_number; /*+ the activation number +*/
 
int flags; /*+ the init flags... +*/
int flags; /*+ the init flags... +*/
 
bandwidth_t U; /*+ the used bandwidth +*/
bandwidth_t U; /*+ the used bandwidth +*/
 
} INTDRIVE_level_des;
 
84,163 → 84,143
/* Replenish the capacity */
static void INTDRIVE_timer(void *arg)
{
INTDRIVE_level_des *lev = (INTDRIVE_level_des *)(arg);
INTDRIVE_level_des *lev = (INTDRIVE_level_des *)(arg);
 
lev->replenish_timer = NIL;
lev->replenish_timer = NIL;
 
#ifdef INTDRIVE_DEBUG
kern_printf("(INTD:TIMER)");
#endif
#ifdef INTDRIVE_DEBUG
kern_printf("(INTD:TIMER)");
#endif
 
if (INTDRIVE_task == NIL) return;
if (INTDRIVE_task == NIL) return;
 
lev->avail = lev->q_theta;
TRACER_LOGEVENT(FTrace_EVT_user_event_0, 0, lev->avail + INT_MAX);
lev->avail = lev->q_theta;
 
switch (proc_table[INTDRIVE_task].status) {
TRACER_LOGEVENT(FTrace_EVT_user_event_0, 0, lev->avail + INT_MAX);
 
case INTDRIVE_IDLE:
if (lev->act_number) {
proc_table[INTDRIVE_task].status = INTDRIVE_READY;
event_need_reschedule();
} else {
proc_table[INTDRIVE_task].status = INTDRIVE_WAIT;
}
break;
}
switch (proc_table[INTDRIVE_task].status) {
case INTDRIVE_IDLE:
if (lev->act_number) {
proc_table[INTDRIVE_task].status = INTDRIVE_READY;
event_need_reschedule();
} else {
proc_table[INTDRIVE_task].status = INTDRIVE_WAIT;
}
break;
}
}
 
/*static void INTDRIVE_wcet_timer(void *arg)
{
INTDRIVE_level_des *lev = (INTDRIVE_level_des *)(arg);
 
INTDRIVE_level_des *lev = (INTDRIVE_level_des *)(arg);
lev->wcet_timer = NIL;
 
lev->wcet_timer = NIL;
kern_raise(XWCET_VIOLATION,INTDRIVE_task);
 
kern_raise(XWCET_VIOLATION,INTDRIVE_task);
}*/
 
static PID INTDRIVE_public_scheduler(LEVEL l)
{
if (INTDRIVE_task == NIL) return NIL;
 
if (INTDRIVE_task == NIL) return NIL;
if (proc_table[INTDRIVE_task].status == INTDRIVE_READY ||
proc_table[INTDRIVE_task].status == EXE)
return INTDRIVE_task;
else
return NIL;
 
if (proc_table[INTDRIVE_task].status == INTDRIVE_READY ||
proc_table[INTDRIVE_task].status == EXE)
return INTDRIVE_task;
else
return NIL;
}
 
static int INTDRIVE_public_create(LEVEL l, PID p, TASK_MODEL *m)
{
HARD_TASK_MODEL *h;
 
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->periodicity != INTDRIVE) return -1;
 
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->periodicity != INTDRIVE) return -1;
if (INTDRIVE_task != NIL) return -1;
 
if (INTDRIVE_task != NIL) return -1;
INTDRIVE_task = p;
 
INTDRIVE_task = p;
proc_table[INTDRIVE_task].wcet = h->wcet;
proc_table[INTDRIVE_task].avail_time = h->wcet;
proc_table[INTDRIVE_task].status = INTDRIVE_WAIT;
proc_table[INTDRIVE_task].control &= ~CONTROL_CAP;
 
proc_table[INTDRIVE_task].wcet = h->wcet;
proc_table[INTDRIVE_task].avail_time = h->wcet;
proc_table[INTDRIVE_task].status = INTDRIVE_WAIT;
proc_table[INTDRIVE_task].control &= ~CONTROL_CAP;
return 0;
 
return 0;
}
 
static void INTDRIVE_public_dispatch(LEVEL l, PID p, int nostop)
{
INTDRIVE_level_des *lev = (INTDRIVE_level_des *)(level_table[l]);
//struct timespec time;
 
INTDRIVE_level_des *lev = (INTDRIVE_level_des *)(level_table[l]);
//struct timespec time;
kern_gettime(&(lev->act_time));
 
kern_gettime(&(lev->act_time));
/*TIMESPEC_ASSIGN(&time,&(lev->act_time));
ADDUSEC2TIMESPEC(proc_table[INTDRIVE_task].wcet,&time);
/*TIMESPEC_ASSIGN(&time,&(lev->act_time));
ADDUSEC2TIMESPEC(proc_table[INTDRIVE_task].wcet,&time);
 
if (lev->flags == INTDRIVE_CHECK_WCET)
lev->wcet_timer = kern_event_post(&time,INTDRIVE_wcet_timer,(void *)lev);*/
if (lev->flags == INTDRIVE_CHECK_WCET)
lev->wcet_timer = kern_event_post(&time,INTDRIVE_wcet_timer,(void *)lev);*/
}
 
static void INTDRIVE_public_epilogue(LEVEL l, PID p)
{
struct timespec time;
 
struct timespec time;
INTDRIVE_level_des *lev = (INTDRIVE_level_des *)(level_table[l]);
 
INTDRIVE_level_des *lev = (INTDRIVE_level_des *)(level_table[l]);
/*if (lev->wcet_timer != NIL)
kern_event_delete(lev->wcet_timer);*/
 
/*if (lev->wcet_timer != NIL)
kern_event_delete(lev->wcet_timer);*/
SUBTIMESPEC(&schedule_time, &(lev->act_time), &time);
lev->avail -= TIMESPEC2USEC(&time);
TRACER_LOGEVENT(FTrace_EVT_user_event_0, 0, lev->avail + INT_MAX);
if (proc_table[INTDRIVE_task].wcet < TIMESPEC2USEC(&time)) {
kern_raise(XWCET_VIOLATION,INTDRIVE_task);
}
SUBTIMESPEC(&schedule_time, &(lev->act_time), &time);
lev->avail -= TIMESPEC2USEC(&time);
TRACER_LOGEVENT(FTrace_EVT_user_event_0, 0, lev->avail + INT_MAX);
 
if (proc_table[INTDRIVE_task].wcet < TIMESPEC2USEC(&time)) {
kern_raise(XWCET_VIOLATION,INTDRIVE_task);
}
}
 
static void INTDRIVE_public_activate(LEVEL l, PID p, struct timespec *t)
{
struct timespec acttime;
TIME time, delta_capacity;
struct timespec acttime;
TIME time, delta_capacity;
 
INTDRIVE_level_des *lev = (INTDRIVE_level_des *)(level_table[l]);
INTDRIVE_level_des *lev = (INTDRIVE_level_des *)(level_table[l]);
 
if (proc_table[INTDRIVE_task].status == INTDRIVE_WAIT) {
if (proc_table[INTDRIVE_task].status == INTDRIVE_WAIT) {
proc_table[INTDRIVE_task].status = INTDRIVE_READY;
lev->act_number++;
} else {
if (proc_table[INTDRIVE_task].status == INTDRIVE_IDLE ||
proc_table[INTDRIVE_task].status == INTDRIVE_READY ||
proc_table[INTDRIVE_task].status == EXE) {
#ifdef INTDRIVE_DEBUG
kern_printf("(INTD:WAIT_REC)");
#endif
lev->act_number++;
}
}
 
proc_table[INTDRIVE_task].status = INTDRIVE_READY;
if (lev->replenish_timer == NIL) {
delta_capacity = lev->q_theta - lev->avail;
mul32div32to32(delta_capacity, MAX_BANDWIDTH, lev->U, time);
kern_gettime(&acttime);
ADDUSEC2TIMESPEC(time,&acttime);
lev->replenish_timer = kern_event_post(&acttime,INTDRIVE_timer,(void *)lev);
 
lev->act_number++;
 
} else {
 
if (proc_table[INTDRIVE_task].status == INTDRIVE_IDLE ||
proc_table[INTDRIVE_task].status == INTDRIVE_READY ||
proc_table[INTDRIVE_task].status == EXE) {
 
#ifdef INTDRIVE_DEBUG
kern_printf("(INTD:WAIT_REC)");
#endif
lev->act_number++;
 
}
 
}
 
if (lev->replenish_timer == NIL) {
 
delta_capacity = lev->q_theta - lev->avail;
mul32div32to32(delta_capacity, MAX_BANDWIDTH, lev->U, time);
kern_gettime(&acttime);
ADDUSEC2TIMESPEC(time,&acttime);
lev->replenish_timer = kern_event_post(&acttime,INTDRIVE_timer,(void *)lev);
/*kern_gettime(&(lev->replenish_expires));
ADDUSEC2TIMESPEC(lev->replenish_period,&(lev->replenish_expires));
lev->replenish_timer = kern_event_post(&(lev->replenish_expires),INTDRIVE_timer,(void *)lev);*/
}
/*kern_gettime(&(lev->replenish_expires));
ADDUSEC2TIMESPEC(lev->replenish_period,&(lev->replenish_expires));
lev->replenish_timer = kern_event_post(&(lev->replenish_expires),INTDRIVE_timer,(void *)lev);*/
}
}
 
static void INTDRIVE_public_unblock(LEVEL l, PID p)
{
/* Insert task in the correct position */
proc_table[INTDRIVE_task].status = INTDRIVE_READY;
/* Insert task in the correct position */
proc_table[INTDRIVE_task].status = INTDRIVE_READY;
}
 
static void INTDRIVE_public_block(LEVEL l, PID p)
250,89 → 230,80
 
static int INTDRIVE_public_message(LEVEL l, PID p, void *m)
{
INTDRIVE_level_des *lev = (INTDRIVE_level_des *)(level_table[l]);
struct timespec time, acttime;
//int delta_time;
TIME delta_capacity, delta_time;
lev->act_number--;
INTDRIVE_level_des *lev = (INTDRIVE_level_des *)(level_table[l]);
struct timespec time, acttime;
//int delta_time;
TIME delta_capacity, delta_time;
 
/*if (lev->wcet_timer != NIL)
kern_event_delete(lev->wcet_timer);*/
lev->act_number--;
 
kern_gettime(&acttime);
SUBTIMESPEC(&acttime, &(lev->act_time), &time);
delta_time = TIMESPEC2USEC(&time);
mul32div32to32(delta_time, (MAX_BANDWIDTH-lev->U), MAX_BANDWIDTH, delta_capacity);
lev->avail -= delta_capacity;
//lev->avail -= TIMESPEC2USEC(&time);
/*if (lev->wcet_timer != NIL)
kern_event_delete(lev->wcet_timer);*/
 
TRACER_LOGEVENT(FTrace_EVT_user_event_0, 0, lev->avail + INT_MAX);
kern_gettime(&acttime);
SUBTIMESPEC(&acttime, &(lev->act_time), &time);
delta_time = TIMESPEC2USEC(&time);
mul32div32to32(delta_time, (MAX_BANDWIDTH-lev->U), MAX_BANDWIDTH, delta_capacity);
lev->avail -= delta_capacity;
 
#ifdef INTDRIVE_DEBUG
kern_printf("(INTD:AV:%d)",(int)(lev->avail));
#endif
//lev->avail -= TIMESPEC2USEC(&time);
 
if (lev->avail < 0) {
proc_table[INTDRIVE_task].status = INTDRIVE_IDLE;
if (lev->replenish_timer != NIL)
kern_event_delete(lev->replenish_timer);
TRACER_LOGEVENT(FTrace_EVT_user_event_0, 0, lev->avail + INT_MAX);
 
delta_capacity = lev->q_theta - lev->avail;
mul32div32to32(delta_capacity, MAX_BANDWIDTH, lev->U, delta_time);
kern_gettime(&acttime);
ADDUSEC2TIMESPEC(delta_time,&acttime);
lev->replenish_timer = kern_event_post(&acttime,INTDRIVE_timer,(void *)lev);
/*temp = -lev->avail;
mul32div32to32(temp,lev->replenish_period,lev->capacity,delta_time)
ADDUSEC2TIMESPEC(delta_time,&(lev->replenish_expires));
lev->replenish_timer = kern_event_post(&(lev->replenish_expires),INTDRIVE_timer,(void *)lev);*/
#ifdef INTDRIVE_DEBUG
kern_printf("(INTD:AV:%d)",(int)(lev->avail));
#endif
 
#ifdef INTDRIVE_DEBUG
kern_printf("(INTD:IDLE:%d)",delta_time);
#endif
if (lev->avail < 0) {
proc_table[INTDRIVE_task].status = INTDRIVE_IDLE;
 
} else {
if (lev->act_number) {
proc_table[INTDRIVE_task].status = INTDRIVE_READY;
if (lev->replenish_timer != NIL)
kern_event_delete(lev->replenish_timer);
 
#ifdef INTDRIVE_DEBUG
kern_printf("(INTD:NEXT_ACT)");
#endif
delta_capacity = lev->q_theta - lev->avail;
mul32div32to32(delta_capacity, MAX_BANDWIDTH, lev->U, delta_time);
kern_gettime(&acttime);
ADDUSEC2TIMESPEC(delta_time,&acttime);
lev->replenish_timer = kern_event_post(&acttime,INTDRIVE_timer,(void *)lev);
 
} else {
/*temp = -lev->avail;
mul32div32to32(temp,lev->replenish_period,lev->capacity,delta_time)
ADDUSEC2TIMESPEC(delta_time,&(lev->replenish_expires));
lev->replenish_timer = kern_event_post(&(lev->replenish_expires),INTDRIVE_timer,(void *)lev);*/
 
#ifdef INTDRIVE_DEBUG
kern_printf("(INTD:WAIT_ACT)");
#endif
#ifdef INTDRIVE_DEBUG
kern_printf("(INTD:IDLE:%d)",delta_time);
#endif
} else {
if (lev->act_number) {
proc_table[INTDRIVE_task].status = INTDRIVE_READY;
#ifdef INTDRIVE_DEBUG
kern_printf("(INTD:NEXT_ACT)");
#endif
} else {
#ifdef INTDRIVE_DEBUG
kern_printf("(INTD:WAIT_ACT)");
#endif
proc_table[INTDRIVE_task].status = INTDRIVE_WAIT;
}
}
 
proc_table[INTDRIVE_task].status = INTDRIVE_WAIT;
TRACER_LOGEVENT(FTrace_EVT_task_end_cycle, (unsigned short int)proc_table[INTDRIVE_task].context,(unsigned int)l);
 
}
}
 
TRACER_LOGEVENT(FTrace_EVT_task_end_cycle,
(unsigned short int)proc_table[INTDRIVE_task].context,(unsigned int)l);
 
return 0;
return 0;
}
 
static void INTDRIVE_public_end(LEVEL l, PID p)
{
INTDRIVE_level_des *lev = (INTDRIVE_level_des *)(level_table[l]);
 
INTDRIVE_level_des *lev = (INTDRIVE_level_des *)(level_table[l]);
if (lev->replenish_timer != NIL)
kern_event_delete(lev->replenish_timer);
 
if (lev->replenish_timer != NIL)
kern_event_delete(lev->replenish_timer);
/*if (lev->wcet_timer != NIL)
kern_event_delete(lev->wcet_timer);*/
 
/*if (lev->wcet_timer != NIL)
kern_event_delete(lev->wcet_timer);*/
 
proc_table[INTDRIVE_task].status = INTDRIVE_IDLE;
 
proc_table[INTDRIVE_task].status = INTDRIVE_IDLE;
}
 
/* Registration functions */
340,57 → 311,62
/*+ Registration function: +*/
LEVEL INTDRIVE_register_level(TIME capacity, TIME q_theta, int U, int flags)
{
LEVEL l; /* the level that we register */
INTDRIVE_level_des *lev;
LEVEL l; /* the level that we register */
INTDRIVE_level_des *lev;
 
printk("INTDRIVE_register_level\n");
printk("INTDRIVE_register_level\n");
 
/* request an entry in the level_table */
l = level_alloc_descriptor(sizeof(INTDRIVE_level_des));
/* request an entry in the level_table */
l = level_alloc_descriptor(sizeof(INTDRIVE_level_des));
 
lev = (INTDRIVE_level_des *)level_table[l];
lev = (INTDRIVE_level_des *)level_table[l];
 
lev->l.public_scheduler = INTDRIVE_public_scheduler;
lev->l.public_guarantee = NULL;
lev->l.public_create = INTDRIVE_public_create;
lev->l.public_end = INTDRIVE_public_end;
lev->l.public_dispatch = INTDRIVE_public_dispatch;
lev->l.public_epilogue = INTDRIVE_public_epilogue;
lev->l.public_activate = INTDRIVE_public_activate;
lev->l.public_unblock = INTDRIVE_public_unblock;
lev->l.public_block = INTDRIVE_public_block;
lev->l.public_message = INTDRIVE_public_message;
lev->l.public_scheduler = INTDRIVE_public_scheduler;
lev->l.public_guarantee = NULL;
lev->l.public_create = INTDRIVE_public_create;
lev->l.public_end = INTDRIVE_public_end;
lev->l.public_dispatch = INTDRIVE_public_dispatch;
lev->l.public_epilogue = INTDRIVE_public_epilogue;
lev->l.public_activate = INTDRIVE_public_activate;
lev->l.public_unblock = INTDRIVE_public_unblock;
lev->l.public_block = INTDRIVE_public_block;
lev->l.public_message = INTDRIVE_public_message;
 
NULL_TIMESPEC(&(lev->act_time));
NULL_TIMESPEC(&(lev->act_time));
 
lev->capacity = capacity;
lev->replenish_timer = NIL;
lev->flags = flags;
lev->act_number = 0;
lev->avail = 0;
lev->q_theta = q_theta;
mul32div32to32(MAX_BANDWIDTH,U,10000,lev->U);
lev->capacity = capacity;
lev->replenish_timer = NIL;
lev->flags = flags;
lev->act_number = 0;
lev->avail = 0;
lev->q_theta = q_theta;
lev->U = U;
//mul32div32to32(MAX_BANDWIDTH,U,10000,lev->U);
#ifdef INTDRIVE_DEBUG
printk("INTDRIVE Init: %d %d %d\n", lev->capacity, lev->q_theta, lev->U);
#endif
 
//!!!calcolare parametro
intdrive_taskinit(l, 10000);
//TODO !!! Fixing 10000 is not a clean way to work !!!
if (intdrive_taskinit(l, 10000) == -1)
printk("Error: INTDRIVE task not activated!\n");
 
return l;
return l;
}
 
bandwidth_t INTDRIVE_usedbandwidth(LEVEL l)
{
INTDRIVE_level_des *lev = (INTDRIVE_level_des *)(level_table[l]);
INTDRIVE_level_des *lev = (INTDRIVE_level_des *)(level_table[l]);
 
return lev->U;
return lev->U;
}
 
TIME INTDRIVE_set_q_theta(LEVEL l, TIME new_q_theta)
{
INTDRIVE_level_des *lev = (INTDRIVE_level_des *)(level_table[l]);
INTDRIVE_level_des *lev = (INTDRIVE_level_des *)(level_table[l]);
 
lev->q_theta = new_q_theta;
if (lev->q_theta < 0) lev->q_theta = 0;
if (lev->q_theta > lev->capacity) lev->q_theta = lev->capacity;
return lev->q_theta;
lev->q_theta = new_q_theta;
if (lev->q_theta < 0) lev->q_theta = 0;
if (lev->q_theta > lev->capacity) lev->q_theta = lev->capacity;
 
return lev->q_theta;
}
/shark/trunk/modules/intdrive/inttask.c
46,7 → 46,7
 
#include <intdrive/intdrive/inttask.h>
 
#define DEBUG_SHARK_GLUE
//#define DEBUG_SHARK_GLUE
 
PID intr_server = NIL;
void (*noint_handler)(int n);
64,6 → 64,10
{
int old_free_int = next_free_int;
 
#ifdef DEBUG_SHARK_GLUE
kern_printf("(add_interrupt_job: %d)", no);
#endif
 
if (no<16)
irq_mask(no);
 
99,6 → 103,10
 
TRACER_LOGEVENT(FTrace_EVT_user_event_2, res, 0);
 
#ifdef DEBUG_SHARK_GLUE
kern_printf("(get_interrupt_job: %d)", res);
#endif
 
return res;
}
 
114,8 → 122,16
 
no = get_interrupt_job();
 
#ifdef DEBUG_SHARK_GLUE
kern_printf("(interrupt_job: no %d)",no);
#endif
 
if (no != -1 && no < 16) {
tmp_fast = handler_get_intdrive(no);
 
/*extern void linux_intr(int irq);
linux_intr(no);*/
 
(tmp_fast)(no);
irq_unmask(no);
}
158,7 → 174,7
hard_task_def_system(ht);
hard_task_def_nokill(ht);
 
if (level >= 0)
if (level > 0)
intr_server = task_create("Interrupt Server (Protected)",Interrupt_Server_Prot,&ht,NULL);
else
intr_server = task_create("Interrupt Server",Interrupt_Server,&ht,NULL);