20,11 → 20,11 |
|
/** |
------------ |
CVS : $Id: slsh.c,v 1.3 2002-11-11 07:54:33 pj Exp $ |
CVS : $Id: slsh.c,v 1.4 2003-01-07 17:10:18 pj Exp $ |
|
File: $File$ |
Revision: $Revision: 1.3 $ |
Last update: $Date: 2002-11-11 07:54:33 $ |
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 |
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) |
{ |
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; |
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 */ |
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) |
{ |
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; |
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]); |
|
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; |
626,7 → 604,7 |
} |
|
/* 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]); |
|
638,7 → 616,7 |
} |
|
/* 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]); |
|
685,57 → 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; |
|
} |
|
|
/** 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(XINVALID_GUEST,exec_shadow); return 0; } |
|
static void SLSH_guest_detach(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
|
static void SLSH_guest_dispatch(LEVEL l, PID p, int nostop) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
|
static void SLSH_guest_epilogue(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
|
static void SLSH_guest_activate(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
|
static void SLSH_guest_insert(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
|
static void SLSH_guest_extract(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
|
static void SLSH_guest_endcycle(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
|
static void SLSH_guest_end(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
|
static void SLSH_guest_sleep(LEVEL l, PID p) |
{ kern_raise(XINVALID_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 */ |
743,51 → 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; |
/* 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; |
|
/* fill the SLSH descriptor part */ |
for(i = 0; i < MAX_PROC; i++) |
{ |
810,6 → 723,8 |
lev->slot = 0; |
lev->slot_length = 0; |
lev->slot_event = -1; |
|
return l; |
} |
|
|