Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 1085 → Rev 1143

/demos/tags/rel_0_5/slsh/slsh.h
21,11 → 21,11
 
/**
------------
CVS : $Id: slsh.h,v 1.1.1.1 2002-09-02 09:37:41 pj Exp $
CVS : $Id: slsh.h,v 1.2 2003-01-07 17:10:18 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:18 $
------------
Author: Tomas Lennvall, Date: Feb 2000.
 
127,7 → 127,6
#include <kernel/config.h>
#include <sys/types.h>
#include <kernel/types.h>
#include <modules/codes.h>
 
#define STATIC_PCLASS 0x0500
 
196,7 → 195,7
} SLSH_interval;
 
/*+ Registration function: */
void SLSH_register_level();
LEVEL SLSH_register_level();
 
void SLSH_set_interval(LEVEL l, int start, int end, int maxt);
void SLSH_set_variables(LEVEL l, TIME length);
/demos/tags/rel_0_5/slsh/slsh.c
20,11 → 20,11
 
/**
------------
CVS : $Id: slsh.c,v 1.1.1.1 2002-09-02 09:37:41 pj Exp $
CVS : $Id: slsh.c,v 1.4 2003-01-07 17:10:18 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:18 $
------------
 
This file contains the scheduling module for Slot-Shifting.
63,6 → 63,7
#include <kernel/descr.h>
#include <kernel/var.h>
#include <kernel/func.h>
#include <kernel/trace.h>
 
//#define eslsh_printf kern_printf
#define slsh_printf printk
90,9 → 91,9
/* task lists */
SLSH_task tasks[MAX_PROC]; /* est and dl's for static and guaranteed task */
QUEUE idle_statics; /* finished static tasks */
IQUEUE idle_statics; /* finished static tasks */
QQUEUE unspecified; /* tasks with only a wcet */
IQUEUE unspecified; /* tasks with only a wcet */
/* the Intervals list */
SLSH_interval intervals[MAX_INTERVALS];
107,39 → 108,6
} SLSH_level_des;
 
 
/* Which task models the Slot-Shifting module accepts */
static int SLSH_level_accept_task_model(LEVEL l, TASK_MODEL* m)
{
HARD_TASK_MODEL* h;
SOFT_TASK_MODEL* s;
 
/* Check the models */
switch(m->pclass)
{
case STATIC_PCLASS: /* offline scheduled tasks */
return 0;
case HARD_PCLASS: /* hard aperiodic tasks */
h = (HARD_TASK_MODEL *) m;
if(h->drel != 0 && h->wcet != 0) /* must be set */
return 0;
break;
case SOFT_PCLASS: /* soft aperiodic tasks */
s = (SOFT_TASK_MODEL *) m;
if(s->wcet != 0) /* must be set */
return 0;
break;
default:
}
 
return -1; /* Not accepted model */
}
 
 
static void SLSH_level_status(LEVEL l)
{
kern_printf("Level status not implemented\n");
}
 
/* check if some tasks are ready, return 0 if ready, -1 otherwise */
static int SLSH_R(SLSH_task* tasks)
{
155,9 → 123,9
}
 
/* check if unspecified exists, return 0 if it exists, -1 otherwise */
static int SLSH_T(QQUEUE unspecified)
static int SLSH_T(IQUEUE *unspecified)
{
if(unspecified.first != NIL)
if(!iq_isempty(unspecified))
return 0;
else
return -1;
206,8 → 174,8
{
lowest_dl = lev->tasks[t].dabs;
pid = t;
}
}
}
}
}/* for all tasks */
218,7 → 186,7
static PID SLSH_candidates(SLSH_task* tasks)
{
int lowest_dl = 0;
PID pid;
PID pid = -1;
int t;
 
/* Use the EDL algorithm again to decide which task to run */
283,7 → 251,7
}
 
/* The scheduler, decides which task to run. */
static PID SLSH_level_scheduler(LEVEL l)
static PID SLSH_public_scheduler(LEVEL l)
{
SLSH_level_des* lev = (SLSH_level_des *)(level_table[l]);
PID pid;
300,10 → 268,10
else if(SLSH_R(lev->tasks) > 0 && SLSH_sc(lev->intervals, lev->current) > 0)
{
/* If unspecified exist, execute it according to FIFO order */
if(SLSH_T(lev->unspecified) == 0)
if(SLSH_T(&lev->unspecified) == 0)
{
SLSH_decSc(lev->intervals, lev->current, 1); /* decrease sc by 1 */
return (PID)qq_getfirst(&lev->unspecified);
return iq_getfirst(&lev->unspecified);
}
else /* No unspecified, execute task from candidates (statics) */
{
322,7 → 290,7
}
 
/* not used, slot-shifting handles all guarantees itself, it handles all bandwidth */
static int SLSH_level_guarantee(LEVEL l, bandwidth_t *freebandwidth)
static int SLSH_public_guarantee(LEVEL l, bandwidth_t *freebandwidth)
{
*freebandwidth = 0;
return 1;
456,7 → 424,7
}
 
/* check if task model is accepted and store nessecary parameters */
static int SLSH_task_create(LEVEL l, PID p, TASK_MODEL *m)
static int SLSH_public_create(LEVEL l, PID p, TASK_MODEL *m)
{
SLSH_level_des *lev = (SLSH_level_des *)(level_table[l]);
STATIC_TASK_MODEL* s;
463,6 → 431,27
HARD_TASK_MODEL* h;
SOFT_TASK_MODEL* u;
 
 
/* Check the models */
switch(m->pclass)
{
case STATIC_PCLASS: /* offline scheduled tasks */
break;
case HARD_PCLASS: /* hard aperiodic tasks */
h = (HARD_TASK_MODEL *) m;
if (h->drel == 0 || h->wcet == 0) /* must be set */
return -1;
break;
case SOFT_PCLASS: /* soft aperiodic tasks */
u = (SOFT_TASK_MODEL *) m;
if(u->wcet == 0) /* must be set */
return -1;
break;
default:
return -1;
}
 
 
/* if the SLSH_task_create is called, then the pclass must be a
valid pclass. Slot-shifting accepts STATIC_TASK, HARD_TASK
and SOFT_TASK models with some restrictions */
494,7 → 483,7
u = (SOFT_TASK_MODEL *) m;
proc_table[p].avail_time = u->wcet;
proc_table[p].wcet = u->wcet;
qq_insertlast(p, &lev->unspecified); /* respect FIFO order */
iq_insertlast(p, &lev->unspecified); /* respect FIFO order */
break;
default: /* a task model not supported */
return -1;
505,17 → 494,6
return 0;
}
 
static void SLSH_task_detach(LEVEL l, PID p)
{
/* do nothing */
}
 
/* check if a task chosen by scheduler is correct */
static int SLSH_task_eligible(LEVEL l, PID p)
{
return 0; /* if the task p is chosen, it is always eligible */
}
 
/************* The slot end event handler *************/
static void SLSH_slot_end(void* p)
{
543,7 → 521,7
{
lev->slot = 0;
while((pid = q_getfirst(&lev->idle_statics)) != NIL)
while((pid = iq_getfirst(&lev->idle_statics)) != NIL)
{
if(lev->tasks[pid].est <= lev->slot)
proc_table[pid].status = SLSH_READY;
559,7 → 537,7
}
 
/* when a task becomes executing (EXE status) */
static void SLSH_task_dispatch(LEVEL l, PID pid, int nostop)
static void SLSH_public_dispatch(LEVEL l, PID pid, int nostop)
{
SLSH_level_des *lev = (SLSH_level_des *)(level_table[l]);
struct timespec t;
569,7 → 547,7
NB: we can't assume that p is the first task in the queue!!! */
if(proc_table[pid].pclass == SOFT_PCLASS)
qq_extract(pid, &lev->unspecified);
iq_extract(pid, &lev->unspecified);
 
/* also start the timer for one slot length */
lev->slot_event = kern_event_post(&TIME2TIMESPEC(lev->slot_length, t),
577,7 → 555,7
}
 
/* called when task is moved from EXE status */
static void SLSH_task_epilogue(LEVEL l, PID pid)
static void SLSH_public_epilogue(LEVEL l, PID pid)
{
SLSH_level_des *lev = (SLSH_level_des *)(level_table[l]);
 
591,7 → 569,7
else /* the end of a slot. the task returns into the ready queue... */
{
if(proc_table[pid].pclass == SOFT_PCLASS)
qq_insertfirst(pid,&lev->unspecified);
iq_insertfirst(pid,&lev->unspecified);
proc_table[pid].status = SLSH_READY;
}
598,7 → 576,7
}
 
/* when task go from SLEEP to SLSH_READY or SLSH_WAIT */
static void SLSH_task_activate(LEVEL l, PID pid)
static void SLSH_public_activate(LEVEL l, PID pid)
{
SLSH_level_des *lev = (SLSH_level_des *)(level_table[l]);
WORD type = proc_table[pid].pclass;
620,13 → 598,13
/* insert unspecified tasks in QQUEUE and make it ready */
if(type == SOFT_PCLASS)
{
qq_insertlast(pid ,&lev->unspecified);
iq_insertlast(pid ,&lev->unspecified);
proc_table[pid].status = SLSH_READY;
}
}
 
/* when a task i returned to module from a semaphore, mutex ... */
static void SLSH_task_insert(LEVEL l, PID pid)
static void SLSH_public_unblock(LEVEL l, PID pid)
{
SLSH_level_des *lev = (SLSH_level_des *)(level_table[l]);
 
634,11 → 612,11
proc_table[pid].status = SLSH_READY;
if(proc_table[pid].pclass == SOFT_PCLASS)
qq_insertfirst(pid ,&lev->unspecified);
iq_insertfirst(pid ,&lev->unspecified);
}
 
/* when a semaphore, mutex ... taskes a task from module */
static void SLSH_task_extract(LEVEL l, PID pid)
static void SLSH_public_block(LEVEL l, PID pid)
{
/* Extract the running task from the level
. we have already extract it from the ready queue at the dispatch time.
651,14 → 629,8
*/
}
 
/* task has finished execution for this period */
static void SLSH_task_endcycle(LEVEL l, PID pid)
{
/* do nothing */
}
 
/* the task has finihed its wcet, kill task (dont kill static tasks) */
static void SLSH_task_end(LEVEL l, PID pid)
static void SLSH_public_end(LEVEL l, PID pid)
{
SLSH_level_des *lev = (SLSH_level_des *)(level_table[l]);
 
665,7 → 637,7
if(proc_table[pid].pclass == SOFT_PCLASS)
{
if (proc_table[pid].status == SLSH_READY)
qq_extract(pid, &lev->unspecified);
iq_extract(pid, &lev->unspecified);
}
else if(proc_table[pid].pclass == HARD_PCLASS)
{
678,7 → 650,7
{
proc_table[pid].avail_time = proc_table[pid].wcet;
proc_table[pid].status = SLSH_IDLE;
q_insert(pid, &lev->idle_statics);
iq_priority_insert(pid, &lev->idle_statics);
}
proc_table[pid].status = FREE;
685,61 → 657,25
}
 
/* called when a task should sleep but not execute for awhile, mabe a mode change */
static void SLSH_task_sleep(LEVEL l, PID pid)
{
//static void SLSH_task_sleep(LEVEL l, PID pid)
//{
//
// /* the task has terminated his job before it consume the wcet. All OK! */
// proc_table[pid].status = SLEEP;
//
// /* we reset the capacity counters... only for static tasks */
// if (proc_table[pid].pclass == STATIC_PCLASS)
// proc_table[pid].avail_time = proc_table[pid].wcet;
//
//}
 
/* the task has terminated his job before it consume the wcet. All OK! */
proc_table[pid].status = SLEEP;
/* we reset the capacity counters... only for static tasks */
if (proc_table[pid].pclass == STATIC_PCLASS)
proc_table[pid].avail_time = proc_table[pid].wcet;
}
 
static void SLSH_task_delay(LEVEL l, PID p, TIME usdelay) { }
 
/** Guest Functions, slot shifing accepts no guests, so all generates exceptions **/
 
static int SLSH_level_accept_guest_model(LEVEL l, TASK_MODEL* m) { return -1; }
 
static int SLSH_guest_create(LEVEL l, PID p, TASK_MODEL *m)
{ kern_raise(XUNVALID_GUEST,exec_shadow); return 0; }
 
static void SLSH_guest_detach(LEVEL l, PID p)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
static void SLSH_guest_dispatch(LEVEL l, PID p, int nostop)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
static void SLSH_guest_epilogue(LEVEL l, PID p)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
static void SLSH_guest_activate(LEVEL l, PID p)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
static void SLSH_guest_insert(LEVEL l, PID p)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
static void SLSH_guest_extract(LEVEL l, PID p)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
static void SLSH_guest_endcycle(LEVEL l, PID p)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
static void SLSH_guest_end(LEVEL l, PID p)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
static void SLSH_guest_sleep(LEVEL l, PID p)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
static void SLSH_guest_delay(LEVEL l, PID p, TIME usdelay)
{ kern_raise(XUNVALID_GUEST,exec_shadow); }
 
/******* Registration functions *******/
 
/*+ Registration function: */
void SLSH_register_level()
LEVEL SLSH_register_level()
{
LEVEL l; /* the level that we register */
SLSH_level_des *lev; /* for readableness only */
747,53 → 683,24
kern_printf("SLSH_register_level\n");
/* request an entry in the level_table */
l = level_alloc_descriptor();
/* request an entry in the level_table */
l = level_alloc_descriptor(sizeof(SLSH_level_des));
/* alloc the space needed for the EDF_level_des */
lev = (SLSH_level_des *)kern_alloc(sizeof(SLSH_level_des));
lev = (SLSH_level_des *)level_table[l];
/* update the level_table with the new entry */
level_table[l] = (level_des *)lev;
printk(" lev=%d\n",(int)lev);
/* fill the standard descriptor */
strncpy(lev->l.level_name, SLSH_LEVELNAME, MAX_LEVELNAME);
 
lev->l.level_code = SLSH_LEVEL_CODE;
lev->l.level_version = SLSH_LEVEL_VERSION;
 
lev->l.level_accept_task_model = SLSH_level_accept_task_model;
lev->l.level_accept_guest_model = SLSH_level_accept_guest_model;
lev->l.level_status = SLSH_level_status;
lev->l.level_scheduler = SLSH_level_scheduler;
 
lev->l.level_guarantee = SLSH_level_guarantee;
lev->l.task_create = SLSH_task_create;
lev->l.task_detach = SLSH_task_detach;
lev->l.task_eligible = SLSH_task_eligible;
lev->l.task_dispatch = SLSH_task_dispatch;
lev->l.task_epilogue = SLSH_task_epilogue;
lev->l.task_activate = SLSH_task_activate;
lev->l.task_insert = SLSH_task_insert;
lev->l.task_extract = SLSH_task_extract;
lev->l.task_endcycle = SLSH_task_endcycle;
lev->l.task_end = SLSH_task_end;
lev->l.task_sleep = SLSH_task_sleep;
lev->l.task_delay = SLSH_task_delay;
/* fill the standard descriptor */
lev->l.public_scheduler = SLSH_public_scheduler;
lev->l.public_guarantee = SLSH_public_guarantee;
lev->l.public_create = SLSH_public_create;
lev->l.public_end = SLSH_public_end;
lev->l.public_dispatch = SLSH_public_dispatch;
lev->l.public_epilogue = SLSH_public_epilogue;
lev->l.public_activate = SLSH_public_activate;
lev->l.public_unblock = SLSH_public_unblock;
lev->l.public_block = SLSH_public_block;
lev->l.guest_create = SLSH_guest_create;
lev->l.guest_detach = SLSH_guest_detach;
lev->l.guest_dispatch = SLSH_guest_dispatch;
lev->l.guest_epilogue = SLSH_guest_epilogue;
lev->l.guest_activate = SLSH_guest_activate;
lev->l.guest_insert = SLSH_guest_insert;
lev->l.guest_extract = SLSH_guest_extract;
lev->l.guest_endcycle = SLSH_guest_endcycle;
lev->l.guest_end = SLSH_guest_end;
lev->l.guest_sleep = SLSH_guest_sleep;
lev->l.guest_delay = SLSH_guest_delay;
/* fill the SLSH descriptor part */
for(i = 0; i < MAX_PROC; i++)
{
816,6 → 723,8
lev->slot = 0;
lev->slot_length = 0;
lev->slot_event = -1;
 
return l;
}