Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 1085 → Rev 1329

/demos/tags/rel_0_5/cash/cash.c
20,11 → 20,11
 
/**
------------
CVS : $Id: cash.c,v 1.1.1.1 2002-09-02 09:37:41 pj Exp $
CVS : $Id: cash.c,v 1.4 2003-01-07 17:10:16 pj Exp $
 
File: $File$
Revision: $Revision: 1.1.1.1 $
Last update: $Date: 2002-09-02 09:37:41 $
Revision: $Revision: 1.4 $
Last update: $Date: 2003-01-07 17:10:16 $
------------
 
This file contains the aperiodic server CBS (Total Bandwidth Server)
60,25 → 60,12
#include <kernel/descr.h>
#include <kernel/var.h>
#include <kernel/func.h>
#include <kernel/trace.h>
 
/*+ 4 debug purposes +*/
#undef CBS_TEST
 
#ifdef TESTG
#include "drivers/glib.h"
TIME x,oldx;
extern TIME starttime;
#endif
 
 
 
 
 
/*+ Status used in the level +*/
#define CBSGHD_IDLE APER_STATUS_BASE /*+ waiting the activation +*/
#define CBSGHD_ZOMBIE APER_STATUS_BASE+1 /*+ waiting the period end +*/
#define CBSGHD_DELAY APER_STATUS_BASE+2 /*+ waiting the delay end +*/
 
/* structure of an element of the capacity queue */
struct cap_queue {
108,6 → 95,7
TIME act_period[MAX_PROC]; /*+ actual period of each elastic task: it
must be less than maxperiod!!! +*/
 
struct timespec request_time[MAX_PROC]; /* used for the response time */
TIME last_response_time[MAX_PROC]; /* response time of the last instance */
TIME cnormal[MAX_PROC]; /*+ CBSGHD normal computation time +*/
152,7 → 140,7
new = (struct cap_queue *)kern_alloc(sizeof(struct cap_queue));
if (new == NULL) {
kern_printf("\nNew cash_queue element failed\n");
kern_raise(XUNVALID_TASK, p);
kern_raise(XINVALID_TASK, p);
return -1;
}
new->next = NULL;
274,28 → 262,10
job_task_default_model(job, lev->cbsghd_dline[p]);
job_task_def_yesexc(job);
level_table[ lev->scheduling_level ]->
guest_create(lev->scheduling_level, p, (TASK_MODEL *)&job);
level_table[ lev->scheduling_level ]->
guest_activate(lev->scheduling_level, p);
private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
}
 
 
static char *CBSGHD_status_to_a(WORD status)
{
if (status < MODULE_STATUS_BASE)
return status_to_a(status);
 
switch (status) {
case CBSGHD_IDLE : return "CBSGHD_Idle";
case CBSGHD_ZOMBIE : return "CBSGHD_Zombie";
case CBSGHD_DELAY : return "CBSGHD_Delay";
default : return "CBSGHD_Unknown";
}
}
 
 
 
 
/* this is the periodic reactivation of the task... */
static void CBSGHD_timer_reactivate(void *par)
{
309,7 → 279,7
reactivated */
/* request_time represents the time of the last instance release!! */
TIMESPEC_ASSIGN(&proc_table[p].request_time, &lev->reactivation_time[p]);
TIMESPEC_ASSIGN(&lev->request_time[p], &lev->reactivation_time[p]);
/* If idle=1, then we have to discharge the capacities stored in
the capacity queue up to the length of the idle interval */
317,7 → 287,7
TIME interval;
struct timespec delta;
lev->idle = 0;
SUBTIMESPEC(&proc_table[p].request_time, &lev->start_idle, &delta);
SUBTIMESPEC(&lev->request_time[p], &lev->start_idle, &delta);
/* length of the idle interval expressed in usec! */
interval = TIMESPEC2NANOSEC(&delta) / 1000;
 
357,7 → 327,7
else {
/* this situation cannot occur */
kern_printf("Trying to reactivate a task which is not IDLE!!!/n");
kern_raise(XUNVALID_TASK,p);
kern_raise(XINVALID_TASK,p);
}
}
 
463,7 → 433,7
if (TIMESPEC_A_LT_B(&lev->reactivation_time[p], &lev->cbsghd_dline[p])) {
/* we delete the reactivation timer */
event_delete(lev->reactivation_timer[p]);
kern_event_delete(lev->reactivation_timer[p]);
/* repost the event at the next instance deadline... */
lev->reactivation_time[p] = lev->cbsghd_dline[p];
lev->reactivation_timer[p] = kern_event_post(&lev->reactivation_time[p],
498,7 → 468,7
 
/* we finally put the task in the FREE status */
proc_table[p].status = FREE;
q_insertfirst(p,&freedesc);
iq_insertfirst(p,&freedesc);
 
/* and free the allocated bandwidth */
lev->U -= (MAX_BANDWIDTH/lev->period[p]) * lev->cnormal[p];
505,69 → 475,14
 
}
 
 
static int CBSGHD_level_accept_task_model(LEVEL l, TASK_MODEL *m)
static PID CBSGHD_public_scheduler(LEVEL l)
{
 
if (m->pclass == ELASTIC_HARD_PCLASS || m->pclass ==
(ELASTIC_HARD_PCLASS | l)) {
ELASTIC_HARD_TASK_MODEL *s = (ELASTIC_HARD_TASK_MODEL *)m;
bandwidth_t b1, b2;
/* kern_printf("accept :ELASTIC TASK found!!!!!!\n"); */
b1 = (MAX_BANDWIDTH / s->period) * s->cnormal;
b2 = (MAX_BANDWIDTH / s->maxperiod) * s->wcet;
if (s->wcet && s->cnormal && s->period && s->maxperiod &&
s->wcet >= s->cnormal && b1 >= b2)
return 0;
/* kern_printf("period: %d maxperiod: %d cnormal: %d wcet: %d, b1: %d b2:
%d\n", s->period, s->maxperiod, s->cnormal, s->wcet, b1, b2); */
}
return -1;
}
 
static int CBSGHD_level_accept_guest_model(LEVEL l, TASK_MODEL *m)
{
return -1;
}
 
static char *onoff(int i)
{
if (i)
return "On ";
else
return "Off";
}
 
static void CBSGHD_level_status(LEVEL l)
{
CBSGHD_level_des *lev = (CBSGHD_level_des *)(level_table[l]);
PID p;
 
kern_printf("On-line guarantee : %s\n",
onoff(lev->flags & CBSGHD_ENABLE_GUARANTEE));
kern_printf("Used Bandwidth : %u/%u\n",
lev->U, MAX_BANDWIDTH);
 
for (p=0; p<MAX_PROC; p++)
if (proc_table[p].task_level == l && proc_table[p].status != FREE )
kern_printf("Pid: %2d Name: %10s Period: %9ld Dline: %9ld.%6ld Stat: %s\n",
p,
proc_table[p].name,
lev->period[p],
lev->cbsghd_dline[p].tv_sec,
lev->cbsghd_dline[p].tv_nsec/1000,
CBSGHD_status_to_a(proc_table[p].status));
}
 
static PID CBSGHD_level_scheduler(LEVEL l)
{
CBSGHD_level_des *lev = (CBSGHD_level_des *)(level_table[l]);
/* it stores the actual time and set the IDLE flag in order to handle
the capacity queue discharging!!! */
lev->idle = 1;
ll_gettime(TIME_EXACT, &lev->start_idle);
kern_gettime(&lev->start_idle);
 
/* the CBSGHD don't schedule anything...
576,7 → 491,7
}
 
/* The on-line guarantee is enabled only if the appropriate flag is set... */
static int CBSGHD_level_guarantee(LEVEL l, bandwidth_t *freebandwidth)
static int CBSGHD_public_guarantee(LEVEL l, bandwidth_t *freebandwidth)
{
CBSGHD_level_des *lev = (CBSGHD_level_des *)(level_table[l]);
 
596,14 → 511,28
}
}
 
static int CBSGHD_task_create(LEVEL l, PID p, TASK_MODEL *m)
static int CBSGHD_public_create(LEVEL l, PID p, TASK_MODEL *m)
{
CBSGHD_level_des *lev = (CBSGHD_level_des *)(level_table[l]);
ELASTIC_HARD_TASK_MODEL *s;
bandwidth_t b1, b2;
 
/* if the CBSGHD_task_create is called, then the pclass must be a
valid pclass. */
ELASTIC_HARD_TASK_MODEL *s = (ELASTIC_HARD_TASK_MODEL *)m;
if (m->pclass != ELASTIC_HARD_PCLASS) return -1;
if (m->level != 0 && m->level != l) return -1;
s = (ELASTIC_HARD_TASK_MODEL *)m;
 
/* kern_printf("accept :ELASTIC TASK found!!!!!!\n"); */
b1 = (MAX_BANDWIDTH / s->period) * s->cnormal;
b2 = (MAX_BANDWIDTH / s->maxperiod) * s->wcet;
if (!(s->wcet && s->cnormal && s->period && s->maxperiod &&
s->wcet >= s->cnormal && b1 >= b2) )
return -1;
/* kern_printf("period: %d maxperiod: %d cnormal: %d wcet: %d, b1: %d b2:
%d\n", s->period, s->maxperiod, s->cnormal, s->wcet, b1, b2); */
 
/* now we know that m is a valid model */
 
 
/* Enable wcet check */
proc_table[p].avail_time = 0;
proc_table[p].wcet = s->wcet;
613,8 → 542,9
lev->maxperiod[p] = s->maxperiod;
lev->cnormal[p] = s->cnormal;
NULL_TIMESPEC(&lev->cbsghd_dline[p]);
NULL_TIMESPEC(&lev->request_time[p]);
 
 
/* update the bandwidth... */
if (lev->flags & CBSGHD_ENABLE_GUARANTEE) {
bandwidth_t b;
634,7 → 564,7
return 0; /* OK, also if the task cannot be guaranteed... */
}
 
static void CBSGHD_task_detach(LEVEL l, PID p)
static void CBSGHD_public_detach(LEVEL l, PID p)
{
/* the CBSGHD level doesn't introduce any dinamic allocated new field.
we have only to reset the NO_GUARANTEE FIELD and decrement the allocated
650,37 → 580,15
}
 
static int CBSGHD_task_eligible(LEVEL l, PID p)
static void CBSGHD_public_dispatch(LEVEL l, PID p, int nostop)
{
return 0; /* if the task p is chosen, it is always eligible */
}
 
#ifdef __TEST1__
extern int testactive;
extern struct timespec s_stime[];
extern TIME s_curr[];
extern TIME s_PID[];
extern int useds;
#endif
 
static void CBSGHD_task_dispatch(LEVEL l, PID p, int nostop)
{
CBSGHD_level_des *lev = (CBSGHD_level_des *)(level_table[l]);
level_table[ lev->scheduling_level ]->
guest_dispatch(lev->scheduling_level,p,nostop);
private_dispatch(lev->scheduling_level,p,nostop);
 
#ifdef __TEST1__
if (testactive)
{
TIMESPEC_ASSIGN(&s_stime[useds], &schedule_time);
s_curr[useds] = proc_table[p].avail_time;
s_PID[useds] = p;
useds++;
}
#endif
}
 
static void CBSGHD_task_epilogue(LEVEL l, PID p)
static void CBSGHD_public_epilogue(LEVEL l, PID p)
{
CBSGHD_level_des *lev = (CBSGHD_level_des *)(level_table[l]);
JOB_TASK_MODEL job;
689,7 → 597,7
if ( proc_table[p].avail_time <= 0) {
/* we kill the current activation */
level_table[ lev->scheduling_level ]->
guest_end(lev->scheduling_level, p);
private_extract(lev->scheduling_level, p);
 
/* we modify the deadline */
CBSGHD_avail_time_check(lev, p);
698,9 → 606,7
job_task_default_model(job, lev->cbsghd_dline[p]);
job_task_def_yesexc(job);
level_table[ lev->scheduling_level ]->
guest_create(lev->scheduling_level, p, (TASK_MODEL *)&job);
level_table[ lev->scheduling_level ]->
guest_activate(lev->scheduling_level, p);
private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
// kern_printf("epil : dl %d per %d p %d |\n",
// lev->cbsghd_dline[p].tv_nsec/1000,lev->period[p],p);
 
709,14 → 615,14
/* the task has been preempted. it returns into the ready queue by
calling the guest_epilogue... */
level_table[ lev->scheduling_level ]->
guest_epilogue(lev->scheduling_level,p);
private_epilogue(lev->scheduling_level,p);
}
 
static void CBSGHD_task_activate(LEVEL l, PID p)
static void CBSGHD_public_activate(LEVEL l, PID p)
{
CBSGHD_level_des *lev = (CBSGHD_level_des *)(level_table[l]);
 
ll_gettime(TIME_EXACT, &proc_table[p].request_time);
kern_gettime(&lev->request_time[p]);
/* If idle=1, then we have to discharge the capacities stored in
the capacity queue up to the length of the idle interval */
724,7 → 630,7
TIME interval;
struct timespec delta;
lev->idle = 0;
SUBTIMESPEC(&proc_table[p].request_time, &lev->start_idle, &delta);
SUBTIMESPEC(&lev->request_time[p], &lev->start_idle, &delta);
/* length of the idle interval expressed in usec! */
interval = TIMESPEC2NANOSEC(&delta) / 1000;
 
744,7 → 650,7
}
}
CBSGHD_activation(lev, p, &proc_table[p].request_time);
CBSGHD_activation(lev, p, &lev->request_time[p]);
 
 
/* check the constraint on the maximum period permitted... */
763,31 → 669,31
// kern_printf("act : %d %d |",lev->cbsghd_dline[p].tv_nsec/1000,p);
}
 
static void CBSGHD_task_insert(LEVEL l, PID p)
static void CBSGHD_public_unblock(LEVEL l, PID p)
{
printk("CBSGHD_task_insert\n");
kern_raise(XUNVALID_TASK,p);
kern_raise(XINVALID_TASK,p);
}
 
static void CBSGHD_task_extract(LEVEL l, PID p)
static void CBSGHD_public_block(LEVEL l, PID p)
{
printk("CBSGHD_task_extract\n");
kern_raise(XUNVALID_TASK,p);
kern_raise(XINVALID_TASK,p);
}
 
static void CBSGHD_task_endcycle(LEVEL l, PID p)
static int CBSGHD_public_message(LEVEL l, PID p, void *m)
{
CBSGHD_level_des *lev = (CBSGHD_level_des *)(level_table[l]);
struct timespec act_time, res;
 
/* It computes the response time of the current instance... */
ll_gettime(TIME_EXACT, &act_time);
SUBTIMESPEC(&act_time, &proc_table[p].request_time, &res);
kern_gettime(&act_time);
SUBTIMESPEC(&act_time, &lev->request_time[p], &res);
/* response time expressed in usec! */
lev->last_response_time[p] = TIMESPEC2NANOSEC(&res) / 1000;
level_table[ lev->scheduling_level ]->
guest_end(lev->scheduling_level,p);
private_extract(lev->scheduling_level,p);
 
/* A spare capacity is inserted in the capacity queue!! */
798,9 → 704,14
 
proc_table[p].status = CBSGHD_IDLE;
 
jet_update_endcycle(); /* Update the Jet data... */
trc_logevent(TRC_ENDCYCLE,&exec_shadow); /* tracer stuff */
 
return 0;
}
 
static void CBSGHD_task_end(LEVEL l, PID p)
static void CBSGHD_public_end(LEVEL l, PID p)
{
CBSGHD_level_des *lev = (CBSGHD_level_des *)(level_table[l]);
 
814,10 → 725,10
}
level_table[ lev->scheduling_level ]->
guest_end(lev->scheduling_level,p);
private_extract(lev->scheduling_level,p);
 
/* we delete the reactivation timer */
event_delete(lev->reactivation_timer[p]);
kern_event_delete(lev->reactivation_timer[p]);
lev->reactivation_timer[p] = -1;
 
829,60 → 740,11
(void *)p);
}
 
static void CBSGHD_task_sleep(LEVEL l, PID p)
{
printk("CBSGHD_task_sleep\n");
kern_raise(XUNVALID_TASK,p);
}
 
static void CBSGHD_task_delay(LEVEL l, PID p, TIME usdelay)
{
printk("CBSGHD_task_delay\n");
kern_raise(XUNVALID_TASK,p);
}
 
 
static int CBSGHD_guest_create(LEVEL l, PID p, TASK_MODEL *m)
{ kern_raise(XUNVALID_GUEST,exec_shadow); return 0; }
 
static void CBSGHD_guest_detach(LEVEL l, PID p)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
static void CBSGHD_guest_dispatch(LEVEL l, PID p, int nostop)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
static void CBSGHD_guest_epilogue(LEVEL l, PID p)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
static void CBSGHD_guest_activate(LEVEL l, PID p)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
static void CBSGHD_guest_insert(LEVEL l, PID p)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
static void CBSGHD_guest_extract(LEVEL l, PID p)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
static void CBSGHD_guest_endcycle(LEVEL l, PID p)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
static void CBSGHD_guest_end(LEVEL l, PID p)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
static void CBSGHD_guest_sleep(LEVEL l, PID p)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
static void CBSGHD_guest_delay(LEVEL l, PID p,DWORD tickdelay)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
 
 
 
/* Registration functions */
 
/*+ Registration function:
int flags the init flags ... see CBS.h +*/
void CBSGHD_register_level(int flags, LEVEL master)
LEVEL CBSGHD_register_level(int flags, LEVEL master)
{
LEVEL l; /* the level that we register */
CBSGHD_level_des *lev; /* for readableness only */
891,62 → 753,35
printk("CBSGHD_register_level\n");
 
/* request an entry in the level_table */
l = level_alloc_descriptor();
l = level_alloc_descriptor(sizeof(CBSGHD_level_des));
 
printk(" alloco descrittore %d %d\n",l,sizeof(CBSGHD_level_des));
lev = (CBSGHD_level_des *)level_table[l];
 
/* alloc the space needed for the CBSGHD_level_des */
lev = (CBSGHD_level_des *)kern_alloc(sizeof(CBSGHD_level_des));
 
printk(" lev=%d\n",(int)lev);
 
/* update the level_table with the new entry */
level_table[l] = (level_des *)lev;
 
/* fill the standard descriptor */
strncpy(lev->l.level_name, CBSGHD_LEVELNAME, MAX_LEVELNAME);
lev->l.level_code = CBSGHD_LEVEL_CODE;
lev->l.level_version = CBSGHD_LEVEL_VERSION;
lev->l.public_scheduler = CBSGHD_public_scheduler;
 
lev->l.level_accept_task_model = CBSGHD_level_accept_task_model;
lev->l.level_accept_guest_model = CBSGHD_level_accept_guest_model;
lev->l.level_status = CBSGHD_level_status;
lev->l.level_scheduler = CBSGHD_level_scheduler;
 
if (flags & CBSGHD_ENABLE_GUARANTEE)
lev->l.level_guarantee = CBSGHD_level_guarantee;
lev->l.public_guarantee = CBSGHD_public_guarantee;
else
lev->l.level_guarantee = NULL;
lev->l.public_guarantee = NULL;
 
lev->l.task_create = CBSGHD_task_create;
lev->l.task_detach = CBSGHD_task_detach;
lev->l.task_eligible = CBSGHD_task_eligible;
lev->l.task_dispatch = CBSGHD_task_dispatch;
lev->l.task_epilogue = CBSGHD_task_epilogue;
lev->l.task_activate = CBSGHD_task_activate;
lev->l.task_insert = CBSGHD_task_insert;
lev->l.task_extract = CBSGHD_task_extract;
lev->l.task_endcycle = CBSGHD_task_endcycle;
lev->l.task_end = CBSGHD_task_end;
lev->l.task_sleep = CBSGHD_task_sleep;
lev->l.task_delay = CBSGHD_task_delay;
lev->l.public_create = CBSGHD_public_create;
lev->l.public_detach = CBSGHD_public_detach;
lev->l.public_end = CBSGHD_public_end;
lev->l.public_dispatch = CBSGHD_public_dispatch;
lev->l.public_epilogue = CBSGHD_public_epilogue;
lev->l.public_activate = CBSGHD_public_activate;
lev->l.public_unblock = CBSGHD_public_unblock;
lev->l.public_block = CBSGHD_public_block;
lev->l.public_message = CBSGHD_public_message;
 
lev->l.guest_create = CBSGHD_guest_create;
lev->l.guest_detach = CBSGHD_guest_detach;
lev->l.guest_dispatch = CBSGHD_guest_dispatch;
lev->l.guest_epilogue = CBSGHD_guest_epilogue;
lev->l.guest_activate = CBSGHD_guest_activate;
lev->l.guest_insert = CBSGHD_guest_insert;
lev->l.guest_extract = CBSGHD_guest_extract;
lev->l.guest_endcycle = CBSGHD_guest_endcycle;
lev->l.guest_end = CBSGHD_guest_end;
lev->l.guest_sleep = CBSGHD_guest_sleep;
lev->l.guest_delay = CBSGHD_guest_delay;
 
/* fill the CBSGHD descriptor part */
for (i=0; i<MAX_PROC; i++) {
NULL_TIMESPEC(&lev->cbsghd_dline[i]);
lev->period[i] = 0;
NULL_TIMESPEC(&lev->request_time[i]);
lev->last_response_time[i] = 0;
NULL_TIMESPEC(&lev->reactivation_time[i]);
lev->reactivation_timer[i] = -1;
960,6 → 795,8
lev->scheduling_level = master;
 
lev->flags = flags & 0x07;
 
return l;
}
 
 
966,6 → 803,7
int CBSGHD_get_response_time(LEVEL l, PID p)
{
CBSGHD_level_des *lev = (CBSGHD_level_des *)(level_table[l]);
 
return lev->last_response_time[p];
}
 
973,10 → 811,7
bandwidth_t CBSGHD_usedbandwidth(LEVEL l)
{
CBSGHD_level_des *lev = (CBSGHD_level_des *)(level_table[l]);
if (lev->l.level_code == CBSGHD_LEVEL_CODE &&
lev->l.level_version == CBSGHD_LEVEL_VERSION)
return lev->U;
else
return 0;
 
return lev->U;
}
 
/demos/tags/rel_0_5/cash/cash.h
20,11 → 20,11
 
/**
------------
CVS : $Id: cash.h,v 1.1.1.1 2002-09-02 09:37:41 pj Exp $
CVS : $Id: cash.h,v 1.2 2003-01-07 17:10:16 pj Exp $
 
File: $File$
Revision: $Revision: 1.1.1.1 $
Last update: $Date: 2002-09-02 09:37:41 $
Revision: $Revision: 1.2 $
Last update: $Date: 2003-01-07 17:10:16 $
------------
 
This file contains the server CBSHD (CASH Algorithm)
97,7 → 97,6
#include <kernel/config.h>
#include <sys/types.h>
#include <kernel/types.h>
#include <modules/codes.h>
 
 
 
166,8 → 165,10
int flags Options to be used in this level instance...
LEVEL master the level that must be used as master level for the
CBSGHD tasks
 
returns the level number at which the module has been registered.
+*/
void CBSGHD_register_level(int flags, LEVEL master);
LEVEL CBSGHD_register_level(int flags, LEVEL master);
 
/*+ Returns the used bandwidth of a level +*/
bandwidth_t CBSGHD_usedbandwidth(LEVEL l);