/shark/trunk/kernel/modules/edf.c |
---|
20,11 → 20,11 |
/** |
------------ |
CVS : $Id: edf.c,v 1.3 2002-11-11 08:32:06 pj Exp $ |
CVS : $Id: edf.c,v 1.4 2003-01-07 17:07:50 pj Exp $ |
File: $File$ |
Revision: $Revision: 1.3 $ |
Last update: $Date: 2002-11-11 08:32:06 $ |
Revision: $Revision: 1.4 $ |
Last update: $Date: 2003-01-07 17:07:50 $ |
------------ |
This file contains the scheduling module EDF (Earliest Deadline First) |
34,7 → 34,7 |
**/ |
/* |
* Copyright (C) 2000 Paolo Gai |
* Copyright (C) 2000,2002 Paolo Gai |
* |
* This program is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
62,8 → 62,8 |
#include <kernel/func.h> |
#include <kernel/trace.h> |
//#define edf_printf kern_printf |
#define edf_printf printk |
//#define EDFDEBUG |
#define edf_printf kern_printf |
/*+ Status used in the level +*/ |
#define EDF_READY MODULE_STATUS_BASE /*+ - Ready status +*/ |
98,21 → 98,6 |
} EDF_level_des; |
static char *EDF_status_to_a(WORD status) |
{ |
if (status < MODULE_STATUS_BASE) |
return status_to_a(status); |
switch (status) { |
case EDF_READY : return "EDF_Ready"; |
case EDF_WCET_VIOLATED: return "EDF_Wcet_Violated"; |
case EDF_WAIT : return "EDF_Sporadic_Wait"; |
case EDF_IDLE : return "EDF_Idle"; |
case EDF_ZOMBIE : return "EDF_Zombie"; |
default : return "EDF_Unknown"; |
} |
} |
static void EDF_timer_deadline(void *par) |
{ |
PID p = (PID) par; |
119,7 → 104,9 |
EDF_level_des *lev; |
struct timespec *temp; |
#ifdef EDFDEBUG |
edf_printf("$"); |
#endif |
lev = (EDF_level_des *)level_table[proc_table[p].task_level]; |
137,8 → 124,6 |
trc_logevent(TRC_INTACTIVATION,&p); |
/* similar to EDF_task_activate */ |
temp = iq_query_timespec(p,&lev->ready); |
TIMESPEC_ASSIGN(&proc_table[p].request_time, |
temp); |
ADDUSEC2TIMESPEC(lev->period[p], temp); |
proc_table[p].status = EDF_READY; |
iq_timespec_insert(p,&lev->ready); |
145,10 → 130,10 |
lev->deadline_timer[p] = kern_event_post(temp, |
EDF_timer_deadline, |
(void *)p); |
#ifdef EDFDEBUG |
edf_printf("(dline p%d ev%d %d.%d)",(int)p,(int)lev->deadline_timer[p],(int)temp->tv_sec,(int)temp->tv_nsec/1000); |
//printk("(d%d idle priority set to %d)",p,proc_table[p].priority ); |
#endif |
event_need_reschedule(); |
printk("el%d|",p); |
break; |
case EDF_WAIT: |
158,8 → 143,10 |
default: |
/* else, a deadline miss occurred!!! */ |
#ifdef EDFDEBUG |
edf_printf("\nstatus %d\n", (int)proc_table[p].status); |
edf_printf("timer_deadline:AAARRRGGGHHH!!!"); |
#endif |
kern_raise(XDEADLINE_MISS,p); |
} |
} |
168,99 → 155,26 |
{ |
PID p = (PID) par; |
#ifdef EDFDEBUG |
edf_printf("AAARRRGGGHHH!!!"); |
#endif |
kern_raise(XDEADLINE_MISS,p); |
} |
static int EDF_level_accept_task_model(LEVEL l, TASK_MODEL *m) |
/* The scheduler only gets the first task in the queue */ |
static PID EDF_public_scheduler(LEVEL l) |
{ |
if (m->pclass == HARD_PCLASS || m->pclass == (HARD_PCLASS | l)) { |
HARD_TASK_MODEL *h = (HARD_TASK_MODEL *)m; |
if (h->wcet && h->mit) |
return 0; |
} |
return -1; |
} |
static int EDF_level_accept_guest_model(LEVEL l, TASK_MODEL *m) |
{ |
if (m->pclass == JOB_PCLASS || m->pclass == (JOB_PCLASS | l)) |
return 0; |
else |
return -1; |
} |
static char *onoff(int i) |
{ |
if (i) |
return "On "; |
else |
return "Off"; |
} |
static void EDF_level_status(LEVEL l) |
{ |
EDF_level_des *lev = (EDF_level_des *)(level_table[l]); |
PID p = iq_query_first(&lev->ready); |
kern_printf("Wcet Check : %s\n", |
onoff(lev->flags & EDF_ENABLE_WCET_CHECK)); |
kern_printf("On-line guarantee : %s\n", |
onoff(lev->flags & EDF_ENABLE_GUARANTEE)); |
kern_printf("Used Bandwidth : %u/%u\n", |
lev->U, MAX_BANDWIDTH); |
#ifdef EDFDEBUG |
edf_printf("(s%d)", iq_query_first(&lev->ready)); |
#endif |
while (p != NIL) { |
if ((proc_table[p].pclass) == JOB_PCLASS) |
kern_printf("Pid: %2d (GUEST)\n", p); |
else |
kern_printf("Pid: %2d Name: %10s %s: %9ld Dline: %9ld.%6ld Stat: %s\n", |
p, |
proc_table[p].name, |
lev->flag[p] & EDF_FLAG_SPORADIC ? "MinITime" : "Period ", |
lev->period[p], |
iq_query_timespec(p, &lev->ready)->tv_sec, |
iq_query_timespec(p, &lev->ready)->tv_nsec/1000, |
EDF_status_to_a(proc_table[p].status)); |
p = iq_query_next(p, &lev->ready); |
} |
for (p=0; p<MAX_PROC; p++) |
if (proc_table[p].task_level == l && proc_table[p].status != EDF_READY |
&& proc_table[p].status != FREE ) |
kern_printf("Pid: %2d Name: %10s %s: %9ld Dline: %9ld.%6ld Stat: %s\n", |
p, |
proc_table[p].name, |
lev->flag[p] & EDF_FLAG_SPORADIC ? "MinITime" : "Period ", |
lev->period[p], |
iq_query_timespec(p, &lev->ready)->tv_sec, |
iq_query_timespec(p, &lev->ready)->tv_nsec/1000, |
EDF_status_to_a(proc_table[p].status)); |
} |
/* The scheduler only gets the first task in the queue */ |
static PID EDF_level_scheduler(LEVEL l) |
{ |
EDF_level_des *lev = (EDF_level_des *)(level_table[l]); |
/* { // print 4 dbg the ready queue |
PID p= lev->ready; |
kern_printf("(s"); |
while (p != NIL) { |
kern_printf("%d ",p); |
p = proc_table[p].next; |
} |
kern_printf(") "); |
} |
*/ |
return iq_query_first(&lev->ready); |
} |
/* The on-line guarantee is enabled only if the appropriate flag is set... */ |
static int EDF_level_guarantee(LEVEL l, bandwidth_t *freebandwidth) |
static int EDF_public_guarantee(LEVEL l, bandwidth_t *freebandwidth) |
{ |
EDF_level_des *lev = (EDF_level_des *)(level_table[l]); |
278,14 → 192,20 |
} |
static int EDF_task_create(LEVEL l, PID p, TASK_MODEL *m) |
static int EDF_public_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
EDF_level_des *lev = (EDF_level_des *)(level_table[l]); |
HARD_TASK_MODEL *h; |
/* if the EDF_task_create is called, then the pclass must be a |
valid pclass. */ |
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; |
/* now we know that m is a valid model */ |
HARD_TASK_MODEL *h = (HARD_TASK_MODEL *)m; |
#ifdef EDFDEBUG |
edf_printf("(cr%d)", p); |
#endif |
lev->period[p] = h->mit; |
329,7 → 249,7 |
return 0; /* OK, also if the task cannot be guaranteed... */ |
} |
static void EDF_task_detach(LEVEL l, PID p) |
static void EDF_public_detach(LEVEL l, PID p) |
{ |
/* the EDF level doesn't introduce any dinamic allocated new field. |
we have only to reset the NO_GUARANTEE FIELD and decrement the allocated |
337,6 → 257,10 |
EDF_level_des *lev = (EDF_level_des *)(level_table[l]); |
#ifdef EDFDEBUG |
edf_printf("(det%d)", p); |
#endif |
if (lev->flags & EDF_FAILED_GUARANTEE) |
lev->flags &= ~EDF_FAILED_GUARANTEE; |
else |
343,16 → 267,13 |
lev->U -= (MAX_BANDWIDTH / lev->period[p]) * proc_table[p].wcet; |
} |
static int EDF_task_eligible(LEVEL l, PID p) |
static void EDF_public_dispatch(LEVEL l, PID p, int nostop) |
{ |
return 0; /* if the task p is chosen, it is always eligible */ |
} |
static void EDF_task_dispatch(LEVEL l, PID p, int nostop) |
{ |
EDF_level_des *lev = (EDF_level_des *)(level_table[l]); |
#ifdef EDFDEBUG |
edf_printf("(disp p%d %d.%d)",(int)p,(int)schedule_time.tv_sec,(int)schedule_time.tv_nsec/1000); |
#endif |
/* the task state is set EXE by the scheduler() |
we extract the task from the ready queue |
360,11 → 281,13 |
iq_extract(p, &lev->ready); |
} |
static void EDF_task_epilogue(LEVEL l, PID p) |
static void EDF_public_epilogue(LEVEL l, PID p) |
{ |
EDF_level_des *lev = (EDF_level_des *)(level_table[l]); |
#ifdef EDFDEBUG |
edf_printf("(epil p%d %d.%d)",p,(int)schedule_time.tv_sec,(int)schedule_time.tv_nsec/1000); |
#endif |
/* check if the wcet is finished... */ |
if ((lev->flags & EDF_ENABLE_WCET_CHECK) && proc_table[p].avail_time <= 0) { |
379,11 → 302,15 |
} |
} |
static void EDF_task_activate(LEVEL l, PID p) |
static void EDF_public_activate(LEVEL l, PID p) |
{ |
EDF_level_des *lev = (EDF_level_des *)(level_table[l]); |
struct timespec *temp; |
#ifdef EDFDEBUG |
edf_printf("(act%d)", p); |
#endif |
if (proc_table[p].status == EDF_WAIT) { |
kern_raise(XACTIVATION,p); |
return; |
397,10 → 324,8 |
/* see also EDF_timer_deadline */ |
ll_gettime(TIME_EXACT, &proc_table[p].request_time); |
temp = iq_query_timespec(p, &lev->ready); |
TIMESPEC_ASSIGN(temp, &proc_table[p].request_time); |
kern_gettime(temp); |
ADDUSEC2TIMESPEC(lev->period[p], temp); |
/* Insert task in the correct position */ |
411,15 → 336,17 |
lev->deadline_timer[p] = kern_event_post(temp, |
EDF_timer_deadline, |
(void *)p); |
#ifdef EDFDEBUG |
edf_printf("(dline p%d ev%d %d.%d)",p,(int)lev->deadline_timer[p],(int)temp->tv_sec,(int)temp->tv_nsec/1000); |
#endif |
} |
static void EDF_task_insert(LEVEL l, PID p) |
static void EDF_public_unblock(LEVEL l, PID p) |
{ |
EDF_level_des *lev = (EDF_level_des *)(level_table[l]); |
/* Similar to EDF_task_activate, but we don't check in what state |
the task is and we don't set the request_time*/ |
/* Similar to EDF_task_activate, |
but we don't check in what state the task is */ |
/* Insert task in the coEDFect position */ |
proc_table[p].status = EDF_READY; |
426,7 → 353,7 |
iq_timespec_insert(p,&lev->ready); |
} |
static void EDF_task_extract(LEVEL l, PID p) |
static void EDF_public_block(LEVEL l, PID p) |
{ |
/* Extract the running task from the level |
. we have already extract it from the ready queue at the dispatch time. |
439,30 → 366,35 |
*/ |
} |
static void EDF_task_endcycle(LEVEL l, PID p) |
static int EDF_public_message(LEVEL l, PID p, void *m) |
{ |
EDF_level_des *lev = (EDF_level_des *)(level_table[l]); |
#ifdef EDFDEBUG |
edf_printf("(ecyc p%d %d.%d)",p,(int)schedule_time.tv_sec,(int)schedule_time.tv_nsec/1000); |
#endif |
/* the task has terminated his job before it consume the wcet. All OK! */ |
if (lev->flag[p] & EDF_FLAG_SPORADIC) |
if (!lev->flag[p] & EDF_FLAG_SPORADIC) |
proc_table[p].status = EDF_IDLE; |
else |
proc_table[p].status = EDF_WAIT; |
else /* pclass = sporadic_pclass */ |
proc_table[p].status = EDF_IDLE; |
/* we reset the capacity counters... */ |
if (lev->flags & EDF_ENABLE_WCET_CHECK) |
proc_table[p].avail_time = proc_table[p].wcet; |
jet_update_endcycle(); /* Update the Jet data... */ |
trc_logevent(TRC_ENDCYCLE,&exec_shadow); /* tracer stuff */ |
/* when the deadline timer fire, it recognize the situation and set |
correctly all the stuffs (like reactivation, request_time, etc... ) */ |
correctly all the stuffs (like reactivation, sleep, etc... ) */ |
return 0; |
} |
static void EDF_task_end(LEVEL l, PID p) |
static void EDF_public_end(LEVEL l, PID p) |
{ |
// EDF_level_des *lev = (EDF_level_des *)(level_table[l]); |
proc_table[p].status = EDF_ZOMBIE; |
/* When the deadline timer fire, it put the task descriptor in |
469,60 → 401,40 |
the free queue, and free the allocated bandwidth... */ |
} |
static void EDF_task_sleep(LEVEL l, PID p) |
static void EDF_private_insert(LEVEL l, PID p, TASK_MODEL *m) |
{ |
EDF_level_des *lev = (EDF_level_des *)(level_table[l]); |
JOB_TASK_MODEL *job; |
/* the task has terminated his job before it consume the wcet. All OK! */ |
proc_table[p].status = EDF_WAIT; |
if (m->pclass != JOB_PCLASS || (m->level != 0 && m->level != l) ) { |
kern_raise(XINVALID_TASK, p); |
return; |
} |
/* we reset the capacity counters... */ |
if (lev->flags & EDF_ENABLE_WCET_CHECK) |
proc_table[p].avail_time = proc_table[p].wcet; |
job = (JOB_TASK_MODEL *)m; |
/* when the deadline timer fire, it recognize the situation and set |
correctly the task state to sleep... */ |
} |
/* Guest Functions |
These functions manages a JOB_TASK_MODEL, that is used to put |
a guest task in the EDF ready queue. */ |
static int EDF_guest_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
EDF_level_des *lev = (EDF_level_des *)(level_table[l]); |
JOB_TASK_MODEL *job = (JOB_TASK_MODEL *)m; |
/* if the EDF_guest_create is called, then the pclass must be a |
valid pclass. */ |
/* Insert task in the correct position */ |
*iq_query_timespec(p, &lev->ready) = job->deadline; |
iq_timespec_insert(p,&lev->ready); |
proc_table[p].status = EDF_READY; |
lev->deadline_timer[p] = -1; |
if (job->noraiseexc) |
lev->period[p] = job->period; |
/* Set the deadline timer */ |
if (!(job->noraiseexc)) |
lev->flag[p] = EDF_FLAG_NORAISEEXC; |
else |
else { |
lev->flag[p] = 0; |
lev->period[p] = job->period; |
/* there is no bandwidth guarantee at this level, it is performed |
by the level that inserts guest tasks... */ |
return 0; /* OK, also if the task cannot be guaranteed... */ |
lev->deadline_timer[p] = kern_event_post(iq_query_timespec(p, &lev->ready), |
EDF_timer_guest_deadline, |
(void *)p); |
} |
} |
static void EDF_guest_detach(LEVEL l, PID p) |
static void EDF_private_dispatch(LEVEL l, PID p, int nostop) |
{ |
/* the EDF level doesn't introduce any dinamic allocated new field. |
No guarantee is performed on guest tasks... so we don't have to reset |
the NO_GUARANTEE FIELD */ |
} |
static void EDF_guest_dispatch(LEVEL l, PID p, int nostop) |
{ |
EDF_level_des *lev = (EDF_level_des *)(level_table[l]); |
/* the task state is set to EXE by the scheduler() |
531,7 → 443,7 |
iq_extract(p, &lev->ready); |
} |
static void EDF_guest_epilogue(LEVEL l, PID p) |
static void EDF_private_epilogue(LEVEL l, PID p) |
{ |
EDF_level_des *lev = (EDF_level_des *)(level_table[l]); |
540,75 → 452,30 |
proc_table[p].status = EDF_READY; |
} |
static void EDF_guest_activate(LEVEL l, PID p) |
static void EDF_private_extract(LEVEL l, PID p) |
{ |
EDF_level_des *lev = (EDF_level_des *)(level_table[l]); |
/* Insert task in the correct position */ |
iq_timespec_insert(p,&lev->ready); |
proc_table[p].status = EDF_READY; |
/* Set the deadline timer */ |
if (!(lev->flag[p] & EDF_FLAG_NORAISEEXC)) |
lev->deadline_timer[p] = kern_event_post(iq_query_timespec(p, &lev->ready), |
EDF_timer_guest_deadline, |
(void *)p); |
} |
static void EDF_guest_insert(LEVEL l, PID p) |
{ |
EDF_level_des *lev = (EDF_level_des *)(level_table[l]); |
/* Insert task in the correct position */ |
iq_timespec_insert(p,&lev->ready); |
proc_table[p].status = EDF_READY; |
} |
static void EDF_guest_extract(LEVEL l, PID p) |
{ |
/* Extract the running task from the level |
. we have already extract it from the ready queue at the dispatch time. |
. the state of the task is set by the calling function |
. the deadline must remain... |
So, we do nothing!!! |
*/ |
} |
static void EDF_guest_endcycle(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void EDF_guest_end(LEVEL l, PID p) |
{ |
EDF_level_des *lev = (EDF_level_des *)(level_table[l]); |
//kern_printf("EDF_guest_end: dline timer %d\n",lev->deadline_timer[p]); |
#ifdef EDFDEBUG |
edf_printf("EDF_guest_end: dline timer %d\n",lev->deadline_timer[p]); |
#endif |
if (proc_table[p].status == EDF_READY) |
{ |
iq_extract(p, &lev->ready); |
//kern_printf("(g_end rdy extr)"); |
} |
/* we remove the deadline timer, because the slice is finished */ |
if (lev->deadline_timer[p] != NIL) { |
// kern_printf("EDF_guest_end: dline timer %d\n",lev->deadline_timer[p]); |
event_delete(lev->deadline_timer[p]); |
kern_event_delete(lev->deadline_timer[p]); |
lev->deadline_timer[p] = NIL; |
} |
} |
static void EDF_guest_sleep(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
/* Registration functions */ |
/*+ Registration function: |
int flags the init flags ... see edf.h +*/ |
void EDF_register_level(int flags) |
LEVEL EDF_register_level(int flags) |
{ |
LEVEL l; /* the level that we register */ |
EDF_level_des *lev; /* for readableness only */ |
617,56 → 484,34 |
printk("EDF_register_level\n"); |
/* request an entry in the level_table */ |
l = level_alloc_descriptor(); |
l = level_alloc_descriptor(sizeof(EDF_level_des)); |
printk(" alloco descrittore %d %d\n",l,(int)sizeof(EDF_level_des)); |
lev = (EDF_level_des *)level_table[l]; |
/* alloc the space needed for the EDF_level_des */ |
lev = (EDF_level_des *)kern_alloc(sizeof(EDF_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, EDF_LEVELNAME, MAX_LEVELNAME); |
lev->l.level_code = EDF_LEVEL_CODE; |
lev->l.level_version = EDF_LEVEL_VERSION; |
lev->l.private_insert = EDF_private_insert; |
lev->l.private_extract = EDF_private_extract; |
lev->l.private_dispatch = EDF_private_dispatch; |
lev->l.private_epilogue = EDF_private_epilogue; |
lev->l.level_accept_task_model = EDF_level_accept_task_model; |
lev->l.level_accept_guest_model = EDF_level_accept_guest_model; |
lev->l.level_status = EDF_level_status; |
lev->l.level_scheduler = EDF_level_scheduler; |
lev->l.public_scheduler = EDF_public_scheduler; |
if (flags & EDF_ENABLE_GUARANTEE) |
lev->l.level_guarantee = EDF_level_guarantee; |
lev->l.public_guarantee = EDF_public_guarantee; |
else |
lev->l.level_guarantee = NULL; |
lev->l.public_guarantee = NULL; |
lev->l.task_create = EDF_task_create; |
lev->l.task_detach = EDF_task_detach; |
lev->l.task_eligible = EDF_task_eligible; |
lev->l.task_dispatch = EDF_task_dispatch; |
lev->l.task_epilogue = EDF_task_epilogue; |
lev->l.task_activate = EDF_task_activate; |
lev->l.task_insert = EDF_task_insert; |
lev->l.task_extract = EDF_task_extract; |
lev->l.task_endcycle = EDF_task_endcycle; |
lev->l.task_end = EDF_task_end; |
lev->l.task_sleep = EDF_task_sleep; |
lev->l.public_create = EDF_public_create; |
lev->l.public_detach = EDF_public_detach; |
lev->l.public_end = EDF_public_end; |
lev->l.public_dispatch = EDF_public_dispatch; |
lev->l.public_epilogue = EDF_public_epilogue; |
lev->l.public_activate = EDF_public_activate; |
lev->l.public_unblock = EDF_public_unblock; |
lev->l.public_block = EDF_public_block; |
lev->l.public_message = EDF_public_message; |
lev->l.guest_create = EDF_guest_create; |
lev->l.guest_detach = EDF_guest_detach; |
lev->l.guest_dispatch = EDF_guest_dispatch; |
lev->l.guest_epilogue = EDF_guest_epilogue; |
lev->l.guest_activate = EDF_guest_activate; |
lev->l.guest_insert = EDF_guest_insert; |
lev->l.guest_extract = EDF_guest_extract; |
lev->l.guest_endcycle = EDF_guest_endcycle; |
lev->l.guest_end = EDF_guest_end; |
lev->l.guest_sleep = EDF_guest_sleep; |
/* fill the EDF descriptor part */ |
for(i=0; i<MAX_PROC; i++) { |
lev->period[i] = 0; |
677,15 → 522,14 |
iq_init(&lev->ready, &freedesc, 0); |
lev->flags = flags & 0x07; |
lev->U = 0; |
return l; |
} |
bandwidth_t EDF_usedbandwidth(LEVEL l) |
{ |
EDF_level_des *lev = (EDF_level_des *)(level_table[l]); |
if (lev->l.level_code == EDF_LEVEL_CODE && |
lev->l.level_version == EDF_LEVEL_VERSION) |
return lev->U; |
else |
return 0; |
return lev->U; |
} |
/shark/trunk/kernel/modules/trace.c |
---|
38,11 → 38,11 |
*/ |
/* |
* CVS : $Id: trace.c,v 1.2 2002-10-21 10:13:56 pj Exp $ |
* CVS : $Id: trace.c,v 1.3 2003-01-07 17:07:51 pj Exp $ |
* |
* File: $File$ |
* Revision: $Revision: 1.2 $ |
* Last update: $Date: 2002-10-21 10:13:56 $ |
* Revision: $Revision: 1.3 $ |
* Last update: $Date: 2003-01-07 17:07:51 $ |
*/ |
#include <ll/sys/types.h> |
313,7 → 313,7 |
evt=queue->get(queue->data); |
if (evt!=NULL) { |
evt->event=event; |
evt->time=ll_gettime(TIME_EXACT,NULL); |
evt->time=kern_gettime(NULL); |
memcpy(&evt->x,ptr,sizeof(trc_allevents_t)); |
queue->post(queue->data); |
} |
/shark/trunk/kernel/modules/posix.c |
---|
20,11 → 20,11 |
/** |
------------ |
CVS : $Id: posix.c,v 1.3 2002-11-11 08:32:06 pj Exp $ |
CVS : $Id: posix.c,v 1.4 2003-01-07 17:07:50 pj Exp $ |
File: $File$ |
Revision: $Revision: 1.3 $ |
Last update: $Date: 2002-11-11 08:32:06 $ |
Revision: $Revision: 1.4 $ |
Last update: $Date: 2003-01-07 17:07:50 $ |
------------ |
This file contains the scheduling module compatible with POSIX |
63,6 → 63,7 |
#include <kernel/descr.h> |
#include <kernel/var.h> |
#include <kernel/func.h> |
#include <kernel/trace.h> |
/*+ Status used in the level +*/ |
#define POSIX_READY MODULE_STATUS_BASE |
88,53 → 89,11 |
} POSIX_level_des; |
static char *POSIX_status_to_a(WORD status) |
{ |
if (status < MODULE_STATUS_BASE) |
return status_to_a(status); |
switch (status) { |
case POSIX_READY: return "POSIX_Ready"; |
default : return "POSIX_Unknown"; |
} |
} |
static int POSIX_level_accept_task_model(LEVEL l, TASK_MODEL *m) |
{ |
if (m->pclass == NRT_PCLASS || m->pclass == (NRT_PCLASS | l)) |
return 0; |
else |
return -1; |
} |
static int POSIX_level_accept_guest_model(LEVEL l, TASK_MODEL *m) |
{ |
return -1; |
} |
static void POSIX_level_status(LEVEL l) |
{ |
POSIX_level_des *lev = (POSIX_level_des *)(level_table[l]); |
PID p; |
kern_printf("Slice: %d \n", lev->slice); |
for (p=0; p<MAX_PROC; p++) |
if (proc_table[p].task_level == l && proc_table[p].status != POSIX_READY |
&& proc_table[p].status != FREE ) |
kern_printf("Pid: %d\t Name: %20s Prio: %3d Status: %s\n", |
p,proc_table[p].name, |
lev->priority[p], |
POSIX_status_to_a(proc_table[p].status)); |
} |
/* This is not efficient but very fair :-) |
The need of all this stuff is because if a task execute a long time |
due to (shadow!) priority inheritance, then the task shall go to the |
tail of the queue many times... */ |
static PID POSIX_level_scheduler(LEVEL l) |
static PID POSIX_public_scheduler(LEVEL l) |
{ |
POSIX_level_des *lev = (POSIX_level_des *)(level_table[l]); |
166,19 → 125,15 |
} |
} |
static int POSIX_level_guarantee(LEVEL l, bandwidth_t *freebandwidth) |
static int POSIX_public_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
/* the POSIX level always guarantee... the function is defined because |
there can be an aperiodic server at a level with less priority than |
the POSIX that need guarantee (e.g., a TBS server) */ |
return 1; |
} |
POSIX_level_des *lev = (POSIX_level_des *)(level_table[l]); |
NRT_TASK_MODEL *nrt; |
if (m->pclass != NRT_PCLASS) return -1; |
if (m->level != 0 && m->level != l) return -1; |
static int POSIX_task_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
POSIX_level_des *lev = (POSIX_level_des *)(level_table[l]); |
NRT_TASK_MODEL *nrt = (NRT_TASK_MODEL *)m; |
nrt = (NRT_TASK_MODEL *)m; |
/* the task state is set at SLEEP by the general task_create */ |
223,20 → 178,8 |
return 0; /* OK */ |
} |
static void POSIX_task_detach(LEVEL l, PID p) |
static void POSIX_public_dispatch(LEVEL l, PID p, int nostop) |
{ |
/* the POSIX level doesn't introduce any new field in the TASK_MODEL |
so, all detach stuffs are done by the task_create |
The task state is set at FREE by the general task_create */ |
} |
static int POSIX_task_eligible(LEVEL l, PID p) |
{ |
return 0; /* if the task p is chosen, it is always eligible */ |
} |
static void POSIX_task_dispatch(LEVEL l, PID p, int nostop) |
{ |
POSIX_level_des *lev = (POSIX_level_des *)(level_table[l]); |
/* the task state is set EXE by the scheduler() |
245,7 → 188,7 |
iq_extract(p, &lev->ready[lev->priority[p]]); |
} |
static void POSIX_task_epilogue(LEVEL l, PID p) |
static void POSIX_public_epilogue(LEVEL l, PID p) |
{ |
POSIX_level_des *lev = (POSIX_level_des *)(level_table[l]); |
266,7 → 209,7 |
proc_table[p].status = POSIX_READY; |
} |
static void POSIX_task_activate(LEVEL l, PID p) |
static void POSIX_public_activate(LEVEL l, PID p) |
{ |
POSIX_level_des *lev = (POSIX_level_des *)(level_table[l]); |
278,19 → 221,17 |
return; |
} |
ll_gettime(TIME_EXACT, &proc_table[p].request_time); |
/* Insert task in the correct position */ |
proc_table[p].status = POSIX_READY; |
iq_insertlast(p,&lev->ready[lev->priority[p]]); |
} |
static void POSIX_task_insert(LEVEL l, PID p) |
static void POSIX_public_unblock(LEVEL l, PID p) |
{ |
POSIX_level_des *lev = (POSIX_level_des *)(level_table[l]); |
/* Similar to POSIX_task_activate, but we don't check in what state |
the task is and we don't set the request_time */ |
the task is */ |
/* Insert task in the coPOSIXect position */ |
proc_table[p].status = POSIX_READY; |
297,7 → 238,7 |
iq_insertlast(p,&lev->ready[lev->priority[p]]); |
} |
static void POSIX_task_extract(LEVEL l, PID p) |
static void POSIX_public_block(LEVEL l, PID p) |
{ |
/* Extract the running task from the level |
. we have already extract it from the ready queue at the dispatch time. |
309,13 → 250,12 |
*/ |
} |
static void POSIX_task_endcycle(LEVEL l, PID p) |
static int POSIX_public_message(LEVEL l, PID p, void *m) |
{ |
POSIX_level_des *lev = (POSIX_level_des *)(level_table[l]); |
if (lev->nact[p] > 0) { |
/* continue!!!! */ |
ll_gettime(TIME_EXACT, &proc_table[p].request_time); |
lev->nact[p]--; |
iq_insertfirst(p,&lev->ready[lev->priority[p]]); |
proc_table[p].status = POSIX_READY; |
322,9 → 262,14 |
} |
else |
proc_table[p].status = SLEEP; |
jet_update_endcycle(); /* Update the Jet data... */ |
trc_logevent(TRC_ENDCYCLE,&exec_shadow); /* tracer stuff */ |
return 0; |
} |
static void POSIX_task_end(LEVEL l, PID p) |
static void POSIX_public_end(LEVEL l, PID p) |
{ |
POSIX_level_des *lev = (POSIX_level_des *)(level_table[l]); |
335,46 → 280,6 |
iq_priority_insert(p,&freedesc); |
} |
static void POSIX_task_sleep(LEVEL l, PID p) |
{ |
POSIX_level_des *lev = (POSIX_level_des *)(level_table[l]); |
lev->nact[p] = 0; |
proc_table[p].status = SLEEP; |
} |
static int POSIX_guest_create(LEVEL l, PID p, TASK_MODEL *m) |
{ kern_raise(XINVALID_GUEST,exec_shadow); return 0; } |
static void POSIX_guest_detach(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void POSIX_guest_dispatch(LEVEL l, PID p, int nostop) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void POSIX_guest_epilogue(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void POSIX_guest_activate(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void POSIX_guest_insert(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void POSIX_guest_extract(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void POSIX_guest_endcycle(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void POSIX_guest_end(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void POSIX_guest_sleep(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
/* Registration functions */ |
/*+ This init function install the "main" task +*/ |
405,7 → 310,7 |
if (p == NIL) |
printk("\nPanic!!! can't create main task...\n"); |
POSIX_task_activate(lev,p); |
POSIX_public_activate(lev,p); |
} |
413,7 → 318,7 |
TIME slice the slice for the Round Robin queue |
int createmain 1 if the level creates the main task 0 otherwise |
struct multiboot_info *mb used if createmain specified +*/ |
void POSIX_register_level(TIME slice, |
LEVEL POSIX_register_level(TIME slice, |
int createmain, |
struct multiboot_info *mb, |
int prioritylevels) |
425,53 → 330,23 |
printk("POSIX_register_level\n"); |
/* request an entry in the level_table */ |
l = level_alloc_descriptor(); |
l = level_alloc_descriptor(sizeof(POSIX_level_des)); |
printk(" alloco descrittore %d %d\n",l,(int)sizeof(POSIX_level_des)); |
lev = (POSIX_level_des *)level_table[l]; |
/* alloc the space needed for the POSIX_level_des */ |
lev = (POSIX_level_des *)kern_alloc(sizeof(POSIX_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, POSIX_LEVELNAME, MAX_LEVELNAME); |
lev->l.level_code = POSIX_LEVEL_CODE; |
lev->l.level_version = POSIX_LEVEL_VERSION; |
lev->l.public_scheduler = POSIX_public_scheduler; |
lev->l.public_create = POSIX_public_create; |
lev->l.public_end = POSIX_public_end; |
lev->l.public_dispatch = POSIX_public_dispatch; |
lev->l.public_epilogue = POSIX_public_epilogue; |
lev->l.public_activate = POSIX_public_activate; |
lev->l.public_unblock = POSIX_public_unblock; |
lev->l.public_block = POSIX_public_block; |
lev->l.public_message = POSIX_public_message; |
lev->l.level_accept_task_model = POSIX_level_accept_task_model; |
lev->l.level_accept_guest_model = POSIX_level_accept_guest_model; |
lev->l.level_status = POSIX_level_status; |
lev->l.level_scheduler = POSIX_level_scheduler; |
lev->l.level_guarantee = POSIX_level_guarantee; |
lev->l.task_create = POSIX_task_create; |
lev->l.task_detach = POSIX_task_detach; |
lev->l.task_eligible = POSIX_task_eligible; |
lev->l.task_dispatch = POSIX_task_dispatch; |
lev->l.task_epilogue = POSIX_task_epilogue; |
lev->l.task_activate = POSIX_task_activate; |
lev->l.task_insert = POSIX_task_insert; |
lev->l.task_extract = POSIX_task_extract; |
lev->l.task_endcycle = POSIX_task_endcycle; |
lev->l.task_end = POSIX_task_end; |
lev->l.task_sleep = POSIX_task_sleep; |
lev->l.guest_create = POSIX_guest_create; |
lev->l.guest_detach = POSIX_guest_detach; |
lev->l.guest_dispatch = POSIX_guest_dispatch; |
lev->l.guest_epilogue = POSIX_guest_epilogue; |
lev->l.guest_activate = POSIX_guest_activate; |
lev->l.guest_insert = POSIX_guest_insert; |
lev->l.guest_extract = POSIX_guest_extract; |
lev->l.guest_endcycle = POSIX_guest_endcycle; |
lev->l.guest_end = POSIX_guest_end; |
lev->l.guest_sleep = POSIX_guest_sleep; |
/* fill the POSIX descriptor part */ |
for (i = 0; i < MAX_PROC; i++) |
lev->nact[i] = -1; |
491,6 → 366,8 |
if (createmain) |
sys_atrunlevel(POSIX_call_main,(void *) l, RUNLEVEL_INIT); |
return l; |
} |
/*+ this function forces the running task to go to his queue tail; |
499,13 → 376,6 |
{ |
POSIX_level_des *lev = (POSIX_level_des *)(level_table[l]); |
if (l < 0 || l >= sched_levels) |
return -1; |
if (level_table[l]->level_code != POSIX_LEVEL_CODE || |
level_table[l]->level_version != POSIX_LEVEL_VERSION ) |
return -1; |
if (proc_table[exec_shadow].task_level != l) |
return -1; |
536,13 → 406,6 |
returns ENOSYS or ESRCH if there are problems +*/ |
int POSIX_getschedparam(LEVEL l, PID p, int *policy, int *priority) |
{ |
if (l < 0 || l >= sched_levels) |
return ENOSYS; |
if (level_table[l]->level_code != POSIX_LEVEL_CODE || |
level_table[l]->level_version != POSIX_LEVEL_VERSION ) |
return ENOSYS; |
if (p<0 || p>= MAX_PROC || proc_table[p].status == FREE) |
return ESRCH; |
564,13 → 427,6 |
{ |
POSIX_level_des *lev = (POSIX_level_des *)(level_table[l]); |
if (l < 0 || l >= sched_levels) |
return ENOSYS; |
if (level_table[l]->level_code != POSIX_LEVEL_CODE || |
level_table[l]->level_version != POSIX_LEVEL_VERSION ) |
return ENOSYS; |
if (p<0 || p>= MAX_PROC || proc_table[p].status == FREE) |
return ESRCH; |
/shark/trunk/kernel/modules/pc.c |
---|
20,11 → 20,11 |
/** |
------------ |
CVS : $Id: pc.c,v 1.1.1.1 2002-03-29 14:12:52 pj Exp $ |
CVS : $Id: pc.c,v 1.2 2003-01-07 17:07:50 pj Exp $ |
File: $File$ |
Revision: $Revision: 1.1.1.1 $ |
Last update: $Date: 2002-03-29 14:12:52 $ |
Revision: $Revision: 1.2 $ |
Last update: $Date: 2003-01-07 17:07:50 $ |
------------ |
Priority Ceiling protocol. see pc.h for more details... |
57,7 → 57,6 |
#include <ll/string.h> |
#include <ll/stdio.h> |
#include <kernel/const.h> |
#include <modules/codes.h> |
#include <sys/types.h> |
#include <kernel/var.h> |
#include <kernel/func.h> |
153,7 → 152,7 |
} |
#if 0 |
/*+ print resource protocol statistics...+*/ |
static void PC_resource_status(RLEVEL r) |
{ |
172,23 → 171,24 |
// in the future: print the status of the blocked semaphores! |
} |
#endif |
static int PC_res_register(RLEVEL l, PID p, RES_MODEL *r) |
{ |
PC_mutex_resource_des *m = (PC_mutex_resource_des *)(resource_table[l]); |
PC_RES_MODEL *pc; |
static int PC_level_accept_resource_model(RLEVEL l, RES_MODEL *r) |
{ |
if (r->rclass == PC_RCLASS || r->rclass == (PC_RCLASS | l) ) |
return 0; |
else |
if (r->rclass != PC_RCLASS) |
return -1; |
} |
if (r->level && r->level !=l) |
return -1; |
static void PC_res_register(RLEVEL l, PID p, RES_MODEL *r) |
{ |
PC_mutex_resource_des *m = (PC_mutex_resource_des *)(resource_table[l]); |
PC_RES_MODEL *pc = (PC_RES_MODEL *)r; |
pc = (PC_RES_MODEL *)r; |
m->priority[p] = pc->priority; |
m->nlocked[p] = 0; |
return 0; |
} |
static void PC_res_detach(RLEVEL l, PID p) |
203,18 → 203,13 |
m->priority[p] = MAX_DWORD; |
} |
static int PC_level_accept_mutexattr(RLEVEL l, const mutexattr_t *a) |
{ |
if (a->mclass == PC_MCLASS || a->mclass == (PC_MCLASS | l) ) |
return 0; |
else |
return -1; |
} |
static int PC_init(RLEVEL l, mutex_t *m, const mutexattr_t *a) |
{ |
PC_mutex_t *p; |
if (a->mclass != PC_MCLASS) |
return -1; |
p = (PC_mutex_t *) kern_alloc(sizeof(PC_mutex_t)); |
/* control if there is enough memory; no control on init on a |
403,7 → 398,7 |
return 0; |
} |
void PC_register_module(void) |
RLEVEL PC_register_module(void) |
{ |
RLEVEL l; /* the level that we register */ |
PC_mutex_resource_des *m; /* for readableness only */ |
421,20 → 416,11 |
resource_table[l] = (resource_des *)m; |
/* fill the resource_des descriptor */ |
strncpy(m->m.r.res_name, PC_MODULENAME, MAX_MODULENAME); |
m->m.r.res_code = PC_MODULE_CODE; |
m->m.r.res_version = PC_MODULE_VERSION; |
m->m.r.rtype = MUTEX_RTYPE; |
m->m.r.resource_status = PC_resource_status; |
m->m.r.level_accept_resource_model = PC_level_accept_resource_model; |
m->m.r.res_register = PC_res_register; |
m->m.r.res_detach = PC_res_detach; |
/* fill the mutex_resource_des descriptor */ |
m->m.level_accept_mutexattr = PC_level_accept_mutexattr; |
m->m.init = PC_init; |
m->m.destroy = PC_destroy; |
m->m.lock = PC_lock; |
447,6 → 433,8 |
m->mlist = NULL; |
return l; |
} |
/*+ This function gets the ceiling of a PC mutex, and it have to be called |
461,11 → 449,6 |
r = resource_table[mutex->mutexlevel]; |
if (r->rtype != MUTEX_RTYPE || |
r->res_code != PC_MODULE_CODE || |
r->res_version != PC_MODULE_VERSION) |
return -1; |
if (ceiling) |
*ceiling = ((PC_mutex_t *)mutex->opt)->ceiling; |
else |
486,11 → 469,6 |
r = resource_table[mutex->mutexlevel]; |
if (r->rtype != MUTEX_RTYPE || |
r->res_code != PC_MODULE_CODE || |
r->res_version != PC_MODULE_VERSION) |
return -1; |
if (old_ceiling) |
*old_ceiling = ((PC_mutex_t *)mutex->opt)->ceiling; |
/shark/trunk/kernel/modules/bd_edf.c |
---|
38,11 → 38,11 |
*/ |
/* |
* CVS : $Id: bd_edf.c,v 1.1.1.1 2002-03-29 14:12:52 pj Exp $ |
* CVS : $Id: bd_edf.c,v 1.2 2003-01-07 17:07:50 pj Exp $ |
* |
* File: $File$ |
* Revision: $Revision: 1.1.1.1 $ |
* Last update: $Date: 2002-03-29 14:12:52 $ |
* Revision: $Revision: 1.2 $ |
* Last update: $Date: 2003-01-07 17:07:50 $ |
*/ |
#include <modules/bd_edf.h> |
51,7 → 51,6 |
#include <ll/string.h> |
#include <ll/stdio.h> |
#include <kernel/const.h> |
#include <modules/codes.h> |
#include <sys/types.h> |
#include <kernel/var.h> |
#include <kernel/func.h> |
74,12 → 73,21 |
return -1; |
} |
static void res_register(RLEVEL l, PID p, RES_MODEL *r) |
static int res_register(RLEVEL l, PID p, RES_MODEL *r) |
{ |
bd_edf_resource_des *m=(bd_edf_resource_des*)(resource_table[l]); |
BDEDF_RES_MODEL *rm=(BDEDF_RES_MODEL*)r; |
BDEDF_RES_MODEL *rm; |
if (r->rclass!=BDEDF_RCLASS) |
return -1; |
if (r->level && r->level !=l) |
return -1; |
rm=(BDEDF_RES_MODEL*)r; |
assertk(mylevel==l); |
m->dl[p]=rm->dl; |
return 0; |
} |
static void res_detach(RLEVEL l, PID p) |
89,10 → 97,7 |
m->dl[p]=0; |
} |
static void res_resource_status(void) |
{} |
void BD_EDF_register_module(void) |
RLEVEL BD_EDF_register_module(void) |
{ |
RLEVEL l; |
bd_edf_resource_des *m; |
108,12 → 113,7 |
resource_table[l]=(resource_des*)m; |
/* fill the resource_des descriptor */ |
strcpy(m->rd.res_name,BDEDF_MODULENAME); |
m->rd.res_code=BDEDF_MODULE_CODE; |
m->rd.res_version=BDEDF_MODULE_VERSION; |
m->rd.rtype=DEFAULT_RTYPE; |
m->rd.resource_status=res_resource_status; |
m->rd.level_accept_resource_model=res_level_accept_resource_model; |
m->rd.res_register=res_register; |
m->rd.res_detach=res_detach; |
121,6 → 121,8 |
assertk(mylevel==-1); |
mylevel=l; |
return l; |
} |
TIME bd_edf_getdl(void) |
/shark/trunk/kernel/modules/srp.c |
---|
20,11 → 20,11 |
/** |
------------ |
CVS : $Id: srp.c,v 1.2 2002-10-28 07:55:55 pj Exp $ |
CVS : $Id: srp.c,v 1.3 2003-01-07 17:07:51 pj Exp $ |
File: $File$ |
Revision: $Revision: 1.2 $ |
Last update: $Date: 2002-10-28 07:55:55 $ |
Revision: $Revision: 1.3 $ |
Last update: $Date: 2003-01-07 17:07:51 $ |
------------ |
Stack Resource Policy. see srp.h for general details... |
141,7 → 141,6 |
#include <ll/string.h> |
#include <ll/stdio.h> |
#include <kernel/const.h> |
#include <modules/codes.h> |
#include <sys/types.h> |
#include <kernel/descr.h> |
#include <kernel/var.h> |
385,27 → 384,14 |
} |
/*+ print resource protocol statistics...+*/ |
static void SRP_resource_status(RLEVEL r) |
static int SRP_res_register(RLEVEL l, PID p, RES_MODEL *r) |
{ |
kern_printf("SRP status not implemented yet"); |
} |
SRP_mutex_resource_des *m = (SRP_mutex_resource_des *)(resource_table[l]); |
static int SRP_level_accept_resource_model(RLEVEL l, RES_MODEL *r) |
{ |
if (r->rclass == SRP_RCLASS || r->rclass == (SRP_RCLASS | l) || |
r->rclass == SRP2_RCLASS || r->rclass == (SRP2_RCLASS | l)) |
return 0; |
else |
if (r->level && r->level !=l) |
return -1; |
} |
static void SRP_res_register(RLEVEL l, PID p, RES_MODEL *r) |
{ |
SRP_mutex_resource_des *m = (SRP_mutex_resource_des *)(resource_table[l]); |
if (r->rclass == SRP_RCLASS || r->rclass == (SRP_RCLASS | l)) { |
if (r->rclass == SRP_RCLASS) { |
/* SRP_RES_MODEL resource model */ |
// kern_printf("!%d %d",((SRP_RES_MODEL *)r)->preempt,p); |
429,14 → 415,15 |
} |
m->nlocked[p] = 0; |
return 0; |
} |
else { |
else if (r->rclass == SRP2_RCLASS) { |
/* a mutex passed via SRP_useres() */ |
SRP_mutex_t *mut = (SRP_mutex_t *)r; |
if (mut->use[p]) |
/* the mutex is already registered, do nothing! */ |
return; |
return -1; |
/* register the mutex for the task */ |
mut->use[p] = 1; |
449,7 → 436,10 |
mut->ceiling = m->proc_preempt[p].preempt; |
} |
return 0; |
} |
else |
return -1; |
} |
static void SRP_res_detach(RLEVEL l, PID p) |
488,14 → 478,6 |
SRP_extract_tasklist(m, p); |
} |
static int SRP_level_accept_mutexattr(RLEVEL l, const mutexattr_t *a) |
{ |
if (a->mclass == SRP_MCLASS || a->mclass == (SRP_MCLASS | l) ) |
return 0; |
else |
return -1; |
} |
static int SRP_init(RLEVEL l, mutex_t *m, const mutexattr_t *a) |
{ |
SRP_mutex_resource_des *lev = (SRP_mutex_resource_des *)(resource_table[l]); |
502,6 → 484,9 |
SRP_mutex_t *p; |
PID x; |
if (a->mclass != SRP_MCLASS) |
return -1; |
p = (SRP_mutex_t *) kern_alloc(sizeof(SRP_mutex_t)); |
/* control if there is enough memory; no control on init on a |
719,7 → 704,7 |
/* activate the task if it was activated while in lobby list! */ |
if (task_unblock_activation(x)) { |
LEVEL sl = proc_table[x].task_level; |
level_table[sl]->task_activate(sl,x); |
level_table[sl]->public_activate(sl,x); |
// kern_printf("activate it!!!"); |
} |
} |
736,7 → 721,7 |
return 0; |
} |
void SRP_register_module(void) |
RLEVEL SRP_register_module(void) |
{ |
RLEVEL l; /* the level that we register */ |
SRP_mutex_resource_des *m; /* for readableness only */ |
754,20 → 739,11 |
resource_table[l] = (resource_des *)m; |
/* fill the resource_des descriptor */ |
strncpy(m->m.r.res_name, SRP_MODULENAME, MAX_MODULENAME); |
m->m.r.res_code = SRP_MODULE_CODE; |
m->m.r.res_version = SRP_MODULE_VERSION; |
m->m.r.rtype = MUTEX_RTYPE; |
m->m.r.resource_status = SRP_resource_status; |
m->m.r.level_accept_resource_model = SRP_level_accept_resource_model; |
m->m.r.res_register = SRP_res_register; |
m->m.r.res_detach = SRP_res_detach; |
/* fill the mutex_resource_des descriptor */ |
m->m.level_accept_mutexattr = SRP_level_accept_mutexattr; |
m->m.init = SRP_init; |
m->m.destroy = SRP_destroy; |
m->m.lock = SRP_lock; |
789,5 → 765,7 |
m->srpstack = NULL; |
m->srprecalc = NULL; |
m->srplist = NULL; |
return l; |
} |
/shark/trunk/kernel/modules/rr2.c |
---|
20,11 → 20,11 |
/** |
------------ |
CVS : $Id: rr2.c,v 1.3 2002-11-11 08:32:06 pj Exp $ |
CVS : $Id: rr2.c,v 1.4 2003-01-07 17:07:50 pj Exp $ |
File: $File$ |
Revision: $Revision: 1.3 $ |
Last update: $Date: 2002-11-11 08:32:06 $ |
Revision: $Revision: 1.4 $ |
Last update: $Date: 2003-01-07 17:07:50 $ |
------------ |
This file contains the scheduling module RR2 (Round Robin) version 2 |
60,6 → 60,7 |
#include <kernel/descr.h> |
#include <kernel/var.h> |
#include <kernel/func.h> |
#include <kernel/trace.h> |
/*+ Status used in the level +*/ |
#define RR2_READY MODULE_STATUS_BASE |
79,57 → 80,11 |
} RR2_level_des; |
static char *RR2_status_to_a(WORD status) |
{ |
if (status < MODULE_STATUS_BASE) |
return status_to_a(status); |
switch (status) { |
case RR2_READY: return "RR2_Ready"; |
default : return "RR2_Unknown"; |
} |
} |
static int RR2_level_accept_task_model(LEVEL l, TASK_MODEL *m) |
{ |
if (m->pclass == NRT_PCLASS || m->pclass == (NRT_PCLASS | l)) |
return 0; |
else |
return -1; |
} |
static int RR2_level_accept_guest_model(LEVEL l, TASK_MODEL *m) |
{ |
return -1; |
} |
static void RR2_level_status(LEVEL l) |
{ |
RR2_level_des *lev = (RR2_level_des *)(level_table[l]); |
PID p = iq_query_first(&lev->ready); |
kern_printf("Slice: %d \n", lev->slice); |
while (p != NIL) { |
kern_printf("Pid: %d\t Name: %20s Status: %s\n",p,proc_table[p].name, |
RR2_status_to_a(proc_table[p].status)); |
p = iq_query_next(p, &lev->ready); |
} |
for (p=0; p<MAX_PROC; p++) |
if (proc_table[p].task_level == l && proc_table[p].status != RR2_READY |
&& proc_table[p].status != FREE ) |
kern_printf("Pid: %d\t Name: %20s Status: %s\n",p,proc_table[p].name, |
RR2_status_to_a(proc_table[p].status)); |
} |
/* This is not efficient but very fair :-) |
The need of all this stuff is because if a task execute a long time |
due to (shadow!) priority inheritance, then the task shall go to the |
tail of the queue many times... */ |
static PID RR2_level_scheduler(LEVEL l) |
static PID RR2_public_scheduler(LEVEL l) |
{ |
RR2_level_des *lev = (RR2_level_des *)(level_table[l]); |
150,20 → 105,15 |
} |
} |
static int RR2_level_guarantee(LEVEL l, bandwidth_t *freebandwidth) |
static int RR2_public_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
/* the RR2 level always guarantee... the function is defined because |
there can be an aperiodic server at a level with less priority than |
the RR2 that need guarantee (e.g., a TBS server) */ |
return 1; |
} |
RR2_level_des *lev = (RR2_level_des *)(level_table[l]); |
NRT_TASK_MODEL *nrt; |
if (m->pclass != NRT_PCLASS) return -1; |
if (m->level != 0 && m->level != l) return -1; |
nrt = (NRT_TASK_MODEL *)m; |
static int RR2_task_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
RR2_level_des *lev = (RR2_level_des *)(level_table[l]); |
NRT_TASK_MODEL *nrt = (NRT_TASK_MODEL *)m; |
/* the task state is set at SLEEP by the general task_create |
the only thing to set remains the capacity stuffs that are set |
to the values passed in the model... */ |
189,20 → 139,8 |
return 0; /* OK */ |
} |
static void RR2_task_detach(LEVEL l, PID p) |
static void RR2_public_dispatch(LEVEL l, PID p, int nostop) |
{ |
/* the RR2 level doesn't introduce any new field in the TASK_MODEL |
so, all detach stuffs are done by the task_create |
The task state is set at FREE by the general task_create */ |
} |
static int RR2_task_eligible(LEVEL l, PID p) |
{ |
return 0; /* if the task p is chosen, it is always eligible */ |
} |
static void RR2_task_dispatch(LEVEL l, PID p, int nostop) |
{ |
RR2_level_des *lev = (RR2_level_des *)(level_table[l]); |
/* the task state is set EXE by the scheduler() |
211,7 → 149,7 |
iq_extract(p, &lev->ready); |
} |
static void RR2_task_epilogue(LEVEL l, PID p) |
static void RR2_public_epilogue(LEVEL l, PID p) |
{ |
RR2_level_des *lev = (RR2_level_des *)(level_table[l]); |
228,7 → 166,7 |
proc_table[p].status = RR2_READY; |
} |
static void RR2_task_activate(LEVEL l, PID p) |
static void RR2_public_activate(LEVEL l, PID p) |
{ |
RR2_level_des *lev = (RR2_level_des *)(level_table[l]); |
240,19 → 178,17 |
return; |
} |
ll_gettime(TIME_EXACT, &proc_table[p].request_time); |
/* Insert task in the coRR2ect position */ |
proc_table[p].status = RR2_READY; |
iq_insertlast(p,&lev->ready); |
} |
static void RR2_task_insert(LEVEL l, PID p) |
static void RR2_public_unblock(LEVEL l, PID p) |
{ |
RR2_level_des *lev = (RR2_level_des *)(level_table[l]); |
/* Similar to RR2_task_activate, but we don't check in what state |
the task is and we don't set the request_time */ |
/* Similar to RR2_task_activate, |
but we don't check in what state the task is */ |
/* Insert task in the coRR2ect position */ |
proc_table[p].status = RR2_READY; |
259,7 → 195,7 |
iq_insertlast(p,&lev->ready); |
} |
static void RR2_task_extract(LEVEL l, PID p) |
static void RR2_public_block(LEVEL l, PID p) |
{ |
/* Extract the running task from the level |
. we have already extract it from the ready queue at the dispatch time. |
271,13 → 207,12 |
*/ |
} |
static void RR2_task_endcycle(LEVEL l, PID p) |
static int RR2_public_message(LEVEL l, PID p, void *m) |
{ |
RR2_level_des *lev = (RR2_level_des *)(level_table[l]); |
if (lev->nact[p] > 0) { |
/* continue!!!! */ |
ll_gettime(TIME_EXACT, &proc_table[p].request_time); |
lev->nact[p]--; |
iq_insertfirst(p,&lev->ready); |
proc_table[p].status = RR2_READY; |
284,9 → 219,14 |
} |
else |
proc_table[p].status = SLEEP; |
jet_update_endcycle(); /* Update the Jet data... */ |
trc_logevent(TRC_ENDCYCLE,&exec_shadow); /* tracer stuff */ |
return 0; |
} |
static void RR2_task_end(LEVEL l, PID p) |
static void RR2_public_end(LEVEL l, PID p) |
{ |
RR2_level_des *lev = (RR2_level_des *)(level_table[l]); |
297,46 → 237,6 |
iq_insertlast(p,&freedesc); |
} |
static void RR2_task_sleep(LEVEL l, PID p) |
{ |
RR2_level_des *lev = (RR2_level_des *)(level_table[l]); |
if (lev->nact[p] >= 0) lev->nact[p] = 0; |
proc_table[p].status = SLEEP; |
} |
static int RR2_guest_create(LEVEL l, PID p, TASK_MODEL *m) |
{ kern_raise(XINVALID_GUEST,exec_shadow); return 0; } |
static void RR2_guest_detach(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RR2_guest_dispatch(LEVEL l, PID p, int nostop) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RR2_guest_epilogue(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RR2_guest_activate(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RR2_guest_insert(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RR2_guest_extract(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RR2_guest_endcycle(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RR2_guest_end(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RR2_guest_sleep(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
/* Registration functions */ |
/*+ This init function install the "main" task +*/ |
364,7 → 264,7 |
if (p == NIL) |
printk("\nPanic!!! can't create main task...\n"); |
RR2_task_activate(lev,p); |
RR2_public_activate(lev,p); |
} |
372,11 → 272,11 |
TIME slice the slice for the Round Robin queue |
int createmain 1 if the level creates the main task 0 otherwise |
struct multiboot_info *mb used if createmain specified +*/ |
void RR2_register_level(TIME slice, |
LEVEL RR2_register_level(TIME slice, |
int createmain, |
struct multiboot_info *mb) |
{ |
LEVEL l; /* the level that we register */ |
LEVEL l; /* the level that we register */ |
RR2_level_des *lev; /* for readableness only */ |
PID i; |
383,50 → 283,23 |
printk("RR2_register_level\n"); |
/* request an entry in the level_table */ |
l = level_alloc_descriptor(); |
l = level_alloc_descriptor(sizeof(RR2_level_des)); |
/* alloc the space needed for the RR2_level_des */ |
lev = (RR2_level_des *)kern_alloc(sizeof(RR2_level_des)); |
lev = (RR2_level_des *)level_table[l]; |
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, RR2_LEVELNAME, MAX_LEVELNAME); |
lev->l.level_code = RR2_LEVEL_CODE; |
lev->l.level_version = RR2_LEVEL_VERSION; |
lev->l.public_scheduler = RR2_public_scheduler; |
lev->l.public_create = RR2_public_create; |
lev->l.public_end = RR2_public_end; |
lev->l.public_dispatch = RR2_public_dispatch; |
lev->l.public_epilogue = RR2_public_epilogue; |
lev->l.public_activate = RR2_public_activate; |
lev->l.public_unblock = RR2_public_unblock; |
lev->l.public_block = RR2_public_block; |
lev->l.public_message = RR2_public_message; |
lev->l.level_accept_task_model = RR2_level_accept_task_model; |
lev->l.level_accept_guest_model = RR2_level_accept_guest_model; |
lev->l.level_status = RR2_level_status; |
lev->l.level_scheduler = RR2_level_scheduler; |
lev->l.level_guarantee = RR2_level_guarantee; |
lev->l.task_create = RR2_task_create; |
lev->l.task_detach = RR2_task_detach; |
lev->l.task_eligible = RR2_task_eligible; |
lev->l.task_dispatch = RR2_task_dispatch; |
lev->l.task_epilogue = RR2_task_epilogue; |
lev->l.task_activate = RR2_task_activate; |
lev->l.task_insert = RR2_task_insert; |
lev->l.task_extract = RR2_task_extract; |
lev->l.task_endcycle = RR2_task_endcycle; |
lev->l.task_end = RR2_task_end; |
lev->l.task_sleep = RR2_task_sleep; |
lev->l.guest_create = RR2_guest_create; |
lev->l.guest_detach = RR2_guest_detach; |
lev->l.guest_dispatch = RR2_guest_dispatch; |
lev->l.guest_epilogue = RR2_guest_epilogue; |
lev->l.guest_activate = RR2_guest_activate; |
lev->l.guest_insert = RR2_guest_insert; |
lev->l.guest_extract = RR2_guest_extract; |
lev->l.guest_endcycle = RR2_guest_endcycle; |
lev->l.guest_end = RR2_guest_end; |
lev->l.guest_sleep = RR2_guest_sleep; |
/* fill the RR2 descriptor part */ |
for (i = 0; i < MAX_PROC; i++) |
lev->nact[i] = -1; |
441,6 → 314,8 |
if (createmain) |
sys_atrunlevel(RR2_call_main,(void *) l, RUNLEVEL_INIT); |
return l; |
} |
/shark/trunk/kernel/modules/ds.c |
---|
20,11 → 20,11 |
/** |
------------ |
CVS : $Id: ds.c,v 1.3 2002-11-11 08:32:06 pj Exp $ |
CVS : $Id: ds.c,v 1.4 2003-01-07 17:07:50 pj Exp $ |
File: $File$ |
Revision: $Revision: 1.3 $ |
Last update: $Date: 2002-11-11 08:32:06 $ |
Revision: $Revision: 1.4 $ |
Last update: $Date: 2003-01-07 17:07:50 $ |
------------ |
This file contains the aperiodic server DS (Deferrable Server) |
64,6 → 64,7 |
#include <kernel/descr.h> |
#include <kernel/var.h> |
#include <kernel/func.h> |
#include <kernel/trace.h> |
/*+ Status used in the level +*/ |
#define DS_WAIT APER_STATUS_BASE /*+ waiting the service +*/ |
106,8 → 107,7 |
m = lev->scheduling_level; |
job_task_default_model(j,lev->lastdline); |
job_task_def_period(j,lev->period); |
level_table[m]->guest_create(m,p,(TASK_MODEL *)&j); |
level_table[m]->guest_activate(m,p); |
level_table[m]->private_insert(m,p,(TASK_MODEL *)&j); |
// kern_printf("(%d %d)",lev->lastdline.tv_sec,lev->lastdline.tv_nsec); |
} |
139,80 → 139,8 |
// kern_printf("!"); |
} |
static char *DS_status_to_a(WORD status) |
static PID DS_public_schedulerbackground(LEVEL l) |
{ |
if (status < MODULE_STATUS_BASE) |
return status_to_a(status); |
switch (status) { |
case DS_WAIT : return "DS_Wait"; |
default : return "DS_Unknown"; |
} |
} |
static int DS_level_accept_task_model(LEVEL l, TASK_MODEL *m) |
{ |
if (m->pclass == SOFT_PCLASS || m->pclass == (SOFT_PCLASS | l) ) { |
SOFT_TASK_MODEL *s = (SOFT_TASK_MODEL *)m; |
if (s->periodicity == APERIODIC) |
return 0; |
} |
return -1; |
} |
static int DS_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 DS_level_status(LEVEL l) |
{ |
DS_level_des *lev = (DS_level_des *)(level_table[l]); |
PID p = iq_query_first(&lev->wait); |
kern_printf("On-line guarantee : %s\n", |
onoff(lev->flags & DS_ENABLE_GUARANTEE_EDF || |
lev->flags & DS_ENABLE_GUARANTEE_RM )); |
kern_printf("Used Bandwidth : %u/%u\n", |
lev->U, MAX_BANDWIDTH); |
if (lev->activated != -1) |
kern_printf("Activated: Pid: %2d Name: %10s Dl: %ld.%ld Nact: %d Stat: %s\n", |
lev->activated, |
proc_table[lev->activated].name, |
iq_query_timespec(lev->activated,&lev->wait)->tv_sec, |
iq_query_timespec(lev->activated,&lev->wait)->tv_nsec, |
lev->nact[lev->activated], |
DS_status_to_a(proc_table[lev->activated].status)); |
while (p != NIL) { |
kern_printf("Pid: %2d Name: %10s Stat: %s\n", |
p, |
proc_table[p].name, |
DS_status_to_a(proc_table[p].status)); |
p = iq_query_next(p, &lev->wait); |
} |
} |
static PID DS_level_scheduler(LEVEL l) |
{ |
/* the DS don't schedule anything... |
it's an EDF level or similar that do it! */ |
return NIL; |
} |
static PID DS_level_schedulerbackground(LEVEL l) |
{ |
/* the DS catch the background time to exec aperiodic activities */ |
DS_level_des *lev = (DS_level_des *)(level_table[l]); |
225,7 → 153,7 |
} |
/* The on-line guarantee is enabled only if the appropriate flag is set... */ |
static int DS_level_guaranteeEDF(LEVEL l, bandwidth_t *freebandwidth) |
static int DS_public_guaranteeEDF(LEVEL l, bandwidth_t *freebandwidth) |
{ |
DS_level_des *lev = (DS_level_des *)(level_table[l]); |
237,7 → 165,7 |
return 0; |
} |
static int DS_level_guaranteeRM(LEVEL l, bandwidth_t *freebandwidth) |
static int DS_public_guaranteeRM(LEVEL l, bandwidth_t *freebandwidth) |
{ |
DS_level_des *lev = (DS_level_des *)(level_table[l]); |
249,14 → 177,19 |
return 0; |
} |
static int DS_task_create(LEVEL l, PID p, TASK_MODEL *m) |
static int DS_public_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
DS_level_des *lev = (DS_level_des *)(level_table[l]); |
/* if the DS_task_create is called, then the pclass must be a |
valid pclass. */ |
SOFT_TASK_MODEL *s = (SOFT_TASK_MODEL *)m; |
SOFT_TASK_MODEL *s; |
if (m->pclass != SOFT_PCLASS) return -1; |
if (m->level != 0 && m->level != l) return -1; |
s = (SOFT_TASK_MODEL *)m; |
if (s->periodicity != APERIODIC) return -1; |
s = (SOFT_TASK_MODEL *)m; |
if (s->arrivals == SAVE_ARRIVALS) |
lev->nact[p] = 0; |
else |
265,18 → 198,8 |
return 0; /* OK, also if the task cannot be guaranteed... */ |
} |
static void DS_task_detach(LEVEL l, PID p) |
static void DS_public_dispatch(LEVEL l, PID p, int nostop) |
{ |
/* the DS level doesn't introduce any dinamic allocated new field. */ |
} |
static int DS_task_eligible(LEVEL l, PID p) |
{ |
return 0; /* if the task p is chosen, it is always eligible */ |
} |
static void DS_task_dispatch(LEVEL l, PID p, int nostop) |
{ |
DS_level_des *lev = (DS_level_des *)(level_table[l]); |
struct timespec ty; |
292,7 → 215,7 |
else { |
//if (nostop) kern_printf("(gd status=%d)",proc_table[p].status); |
level_table[ lev->scheduling_level ]-> |
guest_dispatch(lev->scheduling_level,p,nostop); |
private_dispatch(lev->scheduling_level,p,nostop); |
} |
/* set the capacity timer */ |
305,7 → 228,7 |
// kern_printf("(disp %d %d)",ty.tv_sec, ty.tv_nsec); |
} |
static void DS_task_epilogue(LEVEL l, PID p) |
static void DS_public_epilogue(LEVEL l, PID p) |
{ |
DS_level_des *lev = (DS_level_des *)(level_table[l]); |
struct timespec ty; |
337,7 → 260,7 |
task point the shadow to it!!!*/ |
if (lev->activated == p) |
level_table[ lev->scheduling_level ]-> |
guest_end(lev->scheduling_level,p); |
private_extract(lev->scheduling_level,p); |
iq_insertfirst(p, &lev->wait); |
proc_table[p].status = DS_WAIT; |
lev->activated = NIL; |
347,7 → 270,7 |
wait queue by calling the guest_epilogue... */ |
if (lev->activated == p) {//kern_printf("Û1"); |
level_table[ lev->scheduling_level ]-> |
guest_epilogue(lev->scheduling_level,p); |
private_epilogue(lev->scheduling_level,p); |
} else { //kern_printf("Û2"); |
iq_insertfirst(p, &lev->wait); |
proc_table[p].status = DS_WAIT; |
354,7 → 277,7 |
} |
} |
static void DS_task_activate(LEVEL l, PID p) |
static void DS_public_activate(LEVEL l, PID p) |
{ |
DS_level_des *lev = (DS_level_des *)(level_table[l]); |
363,7 → 286,6 |
lev->nact[p]++; |
} |
else if (proc_table[p].status == SLEEP) { |
ll_gettime(TIME_EXACT, &proc_table[p].request_time); |
if (lev->activated == NIL && lev->availCs > 0) { |
lev->activated = p; |
380,7 → 302,7 |
} |
static void DS_task_insert(LEVEL l, PID p) |
static void DS_public_unblock(LEVEL l, PID p) |
{ |
DS_level_des *lev = (DS_level_des *)(level_table[l]); |
394,7 → 316,7 |
proc_table[p].status = DS_WAIT; |
} |
static void DS_task_extract(LEVEL l, PID p) |
static void DS_public_block(LEVEL l, PID p) |
{ |
DS_level_des *lev = (DS_level_des *)(level_table[l]); |
405,10 → 327,10 |
if (lev->activated == p) |
level_table[ lev->scheduling_level ]-> |
guest_end(lev->scheduling_level,p); |
private_extract(lev->scheduling_level,p); |
} |
static void DS_task_endcycle(LEVEL l, PID p) |
static int DS_public_message(LEVEL l, PID p, void *m) |
{ |
DS_level_des *lev = (DS_level_des *)(level_table[l]); |
struct timespec ty; |
425,7 → 347,7 |
if (lev->activated == p) |
level_table[ lev->scheduling_level ]-> |
guest_end(lev->scheduling_level,p); |
private_extract(lev->scheduling_level,p); |
else |
iq_extract(p, &lev->wait); |
441,9 → 363,14 |
lev->activated = iq_getfirst(&lev->wait); |
if (lev->activated != NIL) |
DS_activation(lev); |
jet_update_endcycle(); /* Update the Jet data... */ |
trc_logevent(TRC_ENDCYCLE,&exec_shadow); /* tracer stuff */ |
return 0; |
} |
static void DS_task_end(LEVEL l, PID p) |
static void DS_public_end(LEVEL l, PID p) |
{ |
DS_level_des *lev = (DS_level_des *)(level_table[l]); |
struct timespec ty; |
460,7 → 387,7 |
if (lev->activated == p) |
level_table[ lev->scheduling_level ]-> |
guest_end(lev->scheduling_level,p); |
private_extract(lev->scheduling_level,p); |
proc_table[p].status = FREE; |
iq_insertfirst(p,&freedesc); |
470,70 → 397,6 |
DS_activation(lev); |
} |
static void DS_task_sleep(LEVEL l, PID p) |
{ |
DS_level_des *lev = (DS_level_des *)(level_table[l]); |
struct timespec ty; |
TIME tx; |
/* update the server capacity */ |
if (lev->flags & DS_BACKGROUND) |
lev->flags &= ~DS_BACKGROUND; |
else { |
SUBTIMESPEC(&schedule_time, &cap_lasttime, &ty); |
tx = TIMESPEC2USEC(&ty); |
lev->availCs -= tx; |
} |
if (lev->nact[p] >= 0) lev->nact[p] = 0; |
if (lev->activated == p) |
level_table[ lev->scheduling_level ]-> |
guest_end(lev->scheduling_level,p); |
else |
iq_extract(p, &lev->wait); |
proc_table[p].status = SLEEP; |
lev->activated = iq_getfirst(&lev->wait); |
if (lev->activated != NIL) |
DS_activation(lev); |
} |
static int DS_guest_create(LEVEL l, PID p, TASK_MODEL *m) |
{ kern_raise(XINVALID_GUEST,exec_shadow); return 0; } |
static void DS_guest_detach(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void DS_guest_dispatch(LEVEL l, PID p, int nostop) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void DS_guest_epilogue(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void DS_guest_activate(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void DS_guest_insert(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void DS_guest_extract(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void DS_guest_endcycle(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void DS_guest_end(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void DS_guest_sleep(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
/* Registration functions */ |
543,7 → 406,7 |
{ |
DS_level_des *lev = (DS_level_des *)(level_table[(LEVEL)l]); |
ll_gettime(TIME_EXACT,&lev->lastdline); |
kern_gettime(&lev->lastdline); |
ADDUSEC2TIMESPEC(lev->period, &lev->lastdline); |
kern_event_post(&lev->lastdline, DS_deadline_timer, l); |
553,7 → 416,7 |
/*+ Registration function: |
int flags the init flags ... see DS.h +*/ |
void DS_register_level(int flags, LEVEL master, int Cs, int per) |
LEVEL DS_register_level(int flags, LEVEL master, int Cs, int per) |
{ |
LEVEL l; /* the level that we register */ |
DS_level_des *lev; /* for readableness only */ |
562,62 → 425,33 |
printk("DS_register_level\n"); |
/* request an entry in the level_table */ |
l = level_alloc_descriptor(); |
l = level_alloc_descriptor(sizeof(DS_level_des)); |
printk(" alloco descrittore %d %d\n",l,(int)sizeof(DS_level_des)); |
lev = (DS_level_des *)level_table[l]; |
/* alloc the space needed for the DS_level_des */ |
lev = (DS_level_des *)kern_alloc(sizeof(DS_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, DS_LEVELNAME, MAX_LEVELNAME); |
lev->l.level_code = DS_LEVEL_CODE; |
lev->l.level_version = DS_LEVEL_VERSION; |
lev->l.level_accept_task_model = DS_level_accept_task_model; |
lev->l.level_accept_guest_model = DS_level_accept_guest_model; |
lev->l.level_status = DS_level_status; |
if (flags & DS_ENABLE_BACKGROUND) |
lev->l.level_scheduler = DS_level_schedulerbackground; |
else |
lev->l.level_scheduler = DS_level_scheduler; |
lev->l.public_scheduler = DS_public_schedulerbackground; |
if (flags & DS_ENABLE_GUARANTEE_EDF) |
lev->l.level_guarantee = DS_level_guaranteeEDF; |
lev->l.public_guarantee = DS_public_guaranteeEDF; |
else if (flags & DS_ENABLE_GUARANTEE_RM) |
lev->l.level_guarantee = DS_level_guaranteeRM; |
lev->l.public_guarantee = DS_public_guaranteeRM; |
else |
lev->l.level_guarantee = NULL; |
lev->l.public_guarantee = NULL; |
lev->l.task_create = DS_task_create; |
lev->l.task_detach = DS_task_detach; |
lev->l.task_eligible = DS_task_eligible; |
lev->l.task_dispatch = DS_task_dispatch; |
lev->l.task_epilogue = DS_task_epilogue; |
lev->l.task_activate = DS_task_activate; |
lev->l.task_insert = DS_task_insert; |
lev->l.task_extract = DS_task_extract; |
lev->l.task_endcycle = DS_task_endcycle; |
lev->l.task_end = DS_task_end; |
lev->l.task_sleep = DS_task_sleep; |
lev->l.public_create = DS_public_create; |
lev->l.public_end = DS_public_end; |
lev->l.public_dispatch = DS_public_dispatch; |
lev->l.public_epilogue = DS_public_epilogue; |
lev->l.public_activate = DS_public_activate; |
lev->l.public_unblock = DS_public_unblock; |
lev->l.public_block = DS_public_block; |
lev->l.public_message = DS_public_message; |
lev->l.guest_create = DS_guest_create; |
lev->l.guest_detach = DS_guest_detach; |
lev->l.guest_dispatch = DS_guest_dispatch; |
lev->l.guest_epilogue = DS_guest_epilogue; |
lev->l.guest_activate = DS_guest_activate; |
lev->l.guest_insert = DS_guest_insert; |
lev->l.guest_extract = DS_guest_extract; |
lev->l.guest_endcycle = DS_guest_endcycle; |
lev->l.guest_end = DS_guest_end; |
lev->l.guest_sleep = DS_guest_sleep; |
/* fill the DS descriptor part */ |
for (i=0; i<MAX_PROC; i++) |
638,15 → 472,13 |
lev->flags = flags & 0x07; |
sys_atrunlevel(DS_dline_install,(void *) l, RUNLEVEL_INIT); |
return l; |
} |
bandwidth_t DS_usedbandwidth(LEVEL l) |
{ |
DS_level_des *lev = (DS_level_des *)(level_table[l]); |
if (lev->l.level_code == DS_LEVEL_CODE && |
lev->l.level_version == DS_LEVEL_VERSION) |
return lev->U; |
else |
return 0; |
return lev->U; |
} |
/shark/trunk/kernel/modules/cbs.c |
---|
20,11 → 20,11 |
/** |
------------ |
CVS : $Id: cbs.c,v 1.3 2002-11-11 08:32:06 pj Exp $ |
CVS : $Id: cbs.c,v 1.4 2003-01-07 17:07:50 pj Exp $ |
File: $File$ |
Revision: $Revision: 1.3 $ |
Last update: $Date: 2002-11-11 08:32:06 $ |
Revision: $Revision: 1.4 $ |
Last update: $Date: 2003-01-07 17:07:50 $ |
------------ |
This file contains the aperiodic server CBS (Total Bandwidth Server) |
172,25 → 172,9 |
job_task_default_model(job, lev->cbs_dline[p]); |
job_task_def_noexc(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 *CBS_status_to_a(WORD status) |
{ |
if (status < MODULE_STATUS_BASE) |
return status_to_a(status); |
switch (status) { |
case CBS_IDLE : return "CBS_Idle"; |
case CBS_ZOMBIE : return "CBS_Zombie"; |
default : return "CBS_Unknown"; |
} |
} |
static void CBS_avail_time_check(CBS_level_des *lev, PID p) |
{ |
/* there is a while because if the wcet is << than the system tick |
270,60 → 254,8 |
} |
static int CBS_level_accept_task_model(LEVEL l, TASK_MODEL *m) |
{ |
if (m->pclass == SOFT_PCLASS || m->pclass == (SOFT_PCLASS | l)) { |
SOFT_TASK_MODEL *s = (SOFT_TASK_MODEL *)m; |
if (s->met && s->period) |
return 0; |
} |
return -1; |
} |
static int CBS_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 CBS_level_status(LEVEL l) |
{ |
CBS_level_des *lev = (CBS_level_des *)(level_table[l]); |
PID p; |
kern_printf("On-line guarantee : %s\n", |
onoff(lev->flags & CBS_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->cbs_dline[p].tv_sec, |
lev->cbs_dline[p].tv_nsec/1000, |
CBS_status_to_a(proc_table[p].status)); |
} |
static PID CBS_level_scheduler(LEVEL l) |
{ |
/* the CBS don't schedule anything... |
it's an EDF level or similar that do it! */ |
return NIL; |
} |
/* The on-line guarantee is enabled only if the appropriate flag is set... */ |
static int CBS_level_guarantee(LEVEL l, bandwidth_t *freebandwidth) |
static int CBS_public_guarantee(LEVEL l, bandwidth_t *freebandwidth) |
{ |
CBS_level_des *lev = (CBS_level_des *)(level_table[l]); |
340,14 → 272,18 |
return 0; |
} |
static int CBS_task_create(LEVEL l, PID p, TASK_MODEL *m) |
static int CBS_public_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
CBS_level_des *lev = (CBS_level_des *)(level_table[l]); |
SOFT_TASK_MODEL *soft; |
/* if the CBS_task_create is called, then the pclass must be a |
valid pclass. */ |
SOFT_TASK_MODEL *soft = (SOFT_TASK_MODEL *)m; |
if (m->pclass != SOFT_PCLASS) return -1; |
if (m->level != 0 && m->level != l) return -1; |
soft = (SOFT_TASK_MODEL *)m; |
if (!(soft->met && soft->period)) return -1; |
soft = (SOFT_TASK_MODEL *)m; |
/* Enable wcet check */ |
proc_table[p].avail_time = soft->met; |
proc_table[p].wcet = soft->met; |
383,7 → 319,7 |
return 0; /* OK, also if the task cannot be guaranteed... */ |
} |
static void CBS_task_detach(LEVEL l, PID p) |
static void CBS_public_detach(LEVEL l, PID p) |
{ |
/* the CBS level doesn't introduce any dinamic allocated new field. |
we have only to reset the NO_GUARANTEE FIELD and decrement the allocated |
397,7 → 333,7 |
lev->U -= (MAX_BANDWIDTH / lev->period[p]) * proc_table[p].wcet; |
} |
static int CBS_task_eligible(LEVEL l, PID p) |
static int CBS_public_eligible(LEVEL l, PID p) |
{ |
CBS_level_des *lev = (CBS_level_des *)(level_table[l]); |
JOB_TASK_MODEL job; |
412,7 → 348,7 |
if ( TIMESPEC_A_LT_B(&lev->cbs_dline[p], &schedule_time) ) { |
/* 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 ... */ |
TIMESPEC_ASSIGN(&lev->cbs_dline[p], &schedule_time); |
425,9 → 361,7 |
job_task_default_model(job, lev->cbs_dline[p]); |
job_task_def_noexc(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); |
return -1; |
} |
435,14 → 369,14 |
return 0; |
} |
static void CBS_task_dispatch(LEVEL l, PID p, int nostop) |
static void CBS_public_dispatch(LEVEL l, PID p, int nostop) |
{ |
CBS_level_des *lev = (CBS_level_des *)(level_table[l]); |
level_table[ lev->scheduling_level ]-> |
guest_dispatch(lev->scheduling_level,p,nostop); |
private_dispatch(lev->scheduling_level,p,nostop); |
} |
static void CBS_task_epilogue(LEVEL l, PID p) |
static void CBS_public_epilogue(LEVEL l, PID p) |
{ |
CBS_level_des *lev = (CBS_level_des *)(level_table[l]); |
JOB_TASK_MODEL job; |
451,7 → 385,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 according to rule 4 ... */ |
CBS_avail_time_check(lev, p); |
460,9 → 394,7 |
job_task_default_model(job, lev->cbs_dline[p]); |
job_task_def_noexc(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->cbs_dline[p].tv_nsec/1000,lev->period[p],p); |
471,12 → 403,13 |
/* 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 CBS_task_activate(LEVEL l, PID p) |
static void CBS_public_activate(LEVEL l, PID p) |
{ |
CBS_level_des *lev = (CBS_level_des *)(level_table[l]); |
struct timespec t; |
/* save activation (only if needed... */ |
if (proc_table[p].status != SLEEP) { |
485,9 → 418,9 |
return; |
} |
ll_gettime(TIME_EXACT, &proc_table[p].request_time); |
kern_gettime(&t); |
CBS_activation(lev, p, &proc_table[p].request_time); |
CBS_activation(lev, p, &t); |
/* Set the reactivation timer */ |
if (!(lev->flag[p] & CBS_APERIODIC)) |
496,7 → 429,7 |
the deadline may be != from actual_time + period |
(if we call the task_activate after a task_sleep, and the |
deadline was postponed a lot...) */ |
TIMESPEC_ASSIGN(&lev->reactivation_time[p], &proc_table[p].request_time); |
TIMESPEC_ASSIGN(&lev->reactivation_time[p], &t); |
ADDUSEC2TIMESPEC(lev->period[p], &lev->reactivation_time[p]); |
// TIMESPEC_ASSIGN(&lev->reactivation_time[p], &lev->cbs_dline[p]); |
lev->reactivation_timer[p] = kern_event_post(&lev->reactivation_time[p], |
509,17 → 442,17 |
// kern_printf("act : %d %d |",lev->cbs_dline[p].tv_nsec/1000,p); |
} |
static void CBS_task_insert(LEVEL l, PID p) |
static void CBS_public_unblock(LEVEL l, PID p) |
{ |
CBS_level_des *lev = (CBS_level_des *)(level_table[l]); |
struct timespec acttime; |
ll_gettime(TIME_EXACT, &acttime); |
kern_gettime(&acttime); |
CBS_activation(lev,p,&acttime); |
} |
static void CBS_task_extract(LEVEL l, PID p) |
static void CBS_public_block(LEVEL l, PID p) |
{ |
CBS_level_des *lev = (CBS_level_des *)(level_table[l]); |
527,10 → 460,10 |
CBS_avail_time_check(lev, p); |
level_table[ lev->scheduling_level ]-> |
guest_end(lev->scheduling_level,p); |
private_extract(lev->scheduling_level,p); |
} |
static void CBS_task_endcycle(LEVEL l, PID p) |
static int CBS_public_message(LEVEL l, PID p, void *m) |
{ |
CBS_level_des *lev = (CBS_level_des *)(level_table[l]); |
539,24 → 472,27 |
if (lev->nact[p]) { |
/* continue!!!! */ |
ll_gettime(TIME_EXACT, &proc_table[p].request_time); |
lev->nact[p]--; |
level_table[ lev->scheduling_level ]-> |
guest_epilogue(lev->scheduling_level,p); |
private_epilogue(lev->scheduling_level,p); |
} |
else { |
level_table[ lev->scheduling_level ]-> |
guest_end(lev->scheduling_level,p); |
private_extract(lev->scheduling_level,p); |
if (lev->flag[p] & CBS_APERIODIC) |
proc_table[p].status = SLEEP; |
else /* the task is soft_periodic */ |
proc_table[p].status = CBS_IDLE; |
} |
} |
jet_update_endcycle(); /* Update the Jet data... */ |
trc_logevent(TRC_ENDCYCLE,&exec_shadow); /* tracer stuff */ |
return 0; |
} |
static void CBS_task_end(LEVEL l, PID p) |
static void CBS_public_end(LEVEL l, PID p) |
{ |
CBS_level_des *lev = (CBS_level_des *)(level_table[l]); |
564,11 → 500,11 |
CBS_avail_time_check(lev, p); |
level_table[ lev->scheduling_level ]-> |
guest_end(lev->scheduling_level,p); |
private_extract(lev->scheduling_level,p); |
/* we delete the reactivation timer */ |
if (!(lev->flag[p] & CBS_APERIODIC)) { |
event_delete(lev->reactivation_timer[p]); |
kern_event_delete(lev->reactivation_timer[p]); |
lev->reactivation_timer[p] = -1; |
} |
580,67 → 516,11 |
(void *)p); |
} |
static void CBS_task_sleep(LEVEL l, PID p) |
{ |
CBS_level_des *lev = (CBS_level_des *)(level_table[l]); |
/* check if the wcet is finished... */ |
CBS_avail_time_check(lev, p); |
/* a task activation is finished, but we are using a JOB_TASK_MODEL |
that implements a single activation, so we have to call |
the guest_end, that representsa single activation... */ |
level_table[ lev->scheduling_level ]-> |
guest_end(lev->scheduling_level,p); |
/* we delete the reactivation timer */ |
if (!(lev->flag[p] & CBS_APERIODIC)) { |
event_delete(lev->reactivation_timer[p]); |
lev->reactivation_timer[p] = -1; |
} |
proc_table[p].status = SLEEP; |
/* the sleep forgets pending activations... */ |
lev->nact[p] = 0; |
} |
static int CBS_guest_create(LEVEL l, PID p, TASK_MODEL *m) |
{ kern_raise(XINVALID_GUEST,exec_shadow); return 0; } |
static void CBS_guest_detach(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void CBS_guest_dispatch(LEVEL l, PID p, int nostop) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void CBS_guest_epilogue(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void CBS_guest_activate(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void CBS_guest_insert(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void CBS_guest_extract(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void CBS_guest_endcycle(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void CBS_guest_end(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void CBS_guest_sleep(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
/* Registration functions */ |
/*+ Registration function: |
int flags the init flags ... see CBS.h +*/ |
void CBS_register_level(int flags, LEVEL master) |
LEVEL CBS_register_level(int flags, LEVEL master) |
{ |
LEVEL l; /* the level that we register */ |
CBS_level_des *lev; /* for readableness only */ |
649,56 → 529,28 |
printk("CBS_register_level\n"); |
/* request an entry in the level_table */ |
l = level_alloc_descriptor(); |
l = level_alloc_descriptor(sizeof(CBS_level_des)); |
printk(" alloco descrittore %d %d\n",l,(int)sizeof(CBS_level_des)); |
lev = (CBS_level_des *)level_table[l]; |
/* alloc the space needed for the CBS_level_des */ |
lev = (CBS_level_des *)kern_alloc(sizeof(CBS_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, CBS_LEVELNAME, MAX_LEVELNAME); |
lev->l.level_code = CBS_LEVEL_CODE; |
lev->l.level_version = CBS_LEVEL_VERSION; |
lev->l.level_accept_task_model = CBS_level_accept_task_model; |
lev->l.level_accept_guest_model = CBS_level_accept_guest_model; |
lev->l.level_status = CBS_level_status; |
lev->l.level_scheduler = CBS_level_scheduler; |
if (flags & CBS_ENABLE_GUARANTEE) |
lev->l.level_guarantee = CBS_level_guarantee; |
lev->l.public_guarantee = CBS_public_guarantee; |
else |
lev->l.level_guarantee = NULL; |
lev->l.public_guarantee = NULL; |
lev->l.public_create = CBS_public_create; |
lev->l.public_detach = CBS_public_detach; |
lev->l.public_end = CBS_public_end; |
lev->l.public_eligible = CBS_public_eligible; |
lev->l.public_dispatch = CBS_public_dispatch; |
lev->l.public_epilogue = CBS_public_epilogue; |
lev->l.public_activate = CBS_public_activate; |
lev->l.public_unblock = CBS_public_unblock; |
lev->l.public_block = CBS_public_block; |
lev->l.public_message = CBS_public_message; |
lev->l.task_create = CBS_task_create; |
lev->l.task_detach = CBS_task_detach; |
lev->l.task_eligible = CBS_task_eligible; |
lev->l.task_dispatch = CBS_task_dispatch; |
lev->l.task_epilogue = CBS_task_epilogue; |
lev->l.task_activate = CBS_task_activate; |
lev->l.task_insert = CBS_task_insert; |
lev->l.task_extract = CBS_task_extract; |
lev->l.task_endcycle = CBS_task_endcycle; |
lev->l.task_end = CBS_task_end; |
lev->l.task_sleep = CBS_task_sleep; |
lev->l.guest_create = CBS_guest_create; |
lev->l.guest_detach = CBS_guest_detach; |
lev->l.guest_dispatch = CBS_guest_dispatch; |
lev->l.guest_epilogue = CBS_guest_epilogue; |
lev->l.guest_activate = CBS_guest_activate; |
lev->l.guest_insert = CBS_guest_insert; |
lev->l.guest_extract = CBS_guest_extract; |
lev->l.guest_endcycle = CBS_guest_endcycle; |
lev->l.guest_end = CBS_guest_end; |
lev->l.guest_sleep = CBS_guest_sleep; |
/* fill the CBS descriptor part */ |
for (i=0; i<MAX_PROC; i++) { |
NULL_TIMESPEC(&lev->cbs_dline[i]); |
715,16 → 567,15 |
lev->scheduling_level = master; |
lev->flags = flags & 0x01; |
return l; |
} |
bandwidth_t CBS_usedbandwidth(LEVEL l) |
{ |
CBS_level_des *lev = (CBS_level_des *)(level_table[l]); |
if (lev->l.level_code == CBS_LEVEL_CODE && |
lev->l.level_version == CBS_LEVEL_VERSION) |
return lev->U; |
else |
return 0; |
return lev->U; |
} |
int CBS_get_nact(LEVEL l, PID p) |
/shark/trunk/kernel/modules/pi.c |
---|
20,11 → 20,11 |
/** |
------------ |
CVS : $Id: pi.c,v 1.1.1.1 2002-03-29 14:12:52 pj Exp $ |
CVS : $Id: pi.c,v 1.2 2003-01-07 17:07:50 pj Exp $ |
File: $File$ |
Revision: $Revision: 1.1.1.1 $ |
Last update: $Date: 2002-03-29 14:12:52 $ |
Revision: $Revision: 1.2 $ |
Last update: $Date: 2003-01-07 17:07:50 $ |
------------ |
Priority Inhertitance protocol. see pi.h for more details... |
56,7 → 56,6 |
#include <ll/ll.h> |
#include <ll/string.h> |
#include <ll/stdio.h> |
#include <modules/codes.h> |
#include <kernel/const.h> |
#include <sys/types.h> |
#include <kernel/descr.h> |
83,6 → 82,7 |
#if 0 |
/*+ print resource protocol statistics...+*/ |
static void PI_resource_status(RLEVEL r) |
{ |
94,19 → 94,14 |
kern_printf("%-4d", m->nlocked[i]); |
} |
} |
#endif |
static int PI_level_accept_resource_model(RLEVEL l, RES_MODEL *r) |
static int PI_res_register(RLEVEL l, PID p, RES_MODEL *r) |
{ |
/* priority inheritance works with all tasks without Resource parameters */ |
return -1; |
} |
static void PI_res_register(RLEVEL l, PID p, RES_MODEL *r) |
{ |
/* never called!!! */ |
} |
static void PI_res_detach(RLEVEL l, PID p) |
{ |
PI_mutex_resource_des *m = (PI_mutex_resource_des *)(resource_table[l]); |
115,18 → 110,13 |
kern_raise(XMUTEX_OWNER_KILLED, p); |
} |
static int PI_level_accept_mutexattr(RLEVEL l, const mutexattr_t *a) |
{ |
if (a->mclass == PI_MCLASS || a->mclass == (PI_MCLASS | l) ) |
return 0; |
else |
return -1; |
} |
static int PI_init(RLEVEL l, mutex_t *m, const mutexattr_t *a) |
{ |
PI_mutex_t *p; |
if (a->mclass != PI_MCLASS) |
return -1; |
p = (PI_mutex_t *) kern_alloc(sizeof(PI_mutex_t)); |
/* control if there is enough memory; no control on init on a |
299,7 → 289,7 |
return 0; |
} |
void PI_register_module(void) |
RLEVEL PI_register_module(void) |
{ |
RLEVEL l; /* the level that we register */ |
PI_mutex_resource_des *m; /* for readableness only */ |
317,20 → 307,11 |
resource_table[l] = (resource_des *)m; |
/* fill the resource_des descriptor */ |
strncpy(m->m.r.res_name, PI_MODULENAME, MAX_MODULENAME); |
m->m.r.res_code = PI_MODULE_CODE; |
m->m.r.res_version = PI_MODULE_VERSION; |
m->m.r.rtype = MUTEX_RTYPE; |
m->m.r.resource_status = PI_resource_status; |
m->m.r.level_accept_resource_model = PI_level_accept_resource_model; |
m->m.r.res_register = PI_res_register; |
m->m.r.res_detach = PI_res_detach; |
/* fill the mutex_resource_des descriptor */ |
m->m.level_accept_mutexattr = PI_level_accept_mutexattr; |
m->m.init = PI_init; |
m->m.destroy = PI_destroy; |
m->m.lock = PI_lock; |
342,5 → 323,7 |
m->nlocked[i] = 0; |
m->blocked[i] = NIL; |
} |
return l; |
} |
/shark/trunk/kernel/modules/trcfixed.c |
---|
107,9 → 107,6 |
if (queue->filename==NULL) trc_create_name("fix",queue->uniq,pathname); |
else trc_create_name(queue->filename,0,pathname); |
//sys_status(SCHED_STATUS); |
//task_delay(250000); |
h=open("/TEMP/FIX1",O_CREAT|O_TRUNC|O_WRONLY); |
if (h!=-1) { |
write(h,queue->table,queue->index*sizeof(trc_event_t)); |
/shark/trunk/kernel/modules/nopm.c |
---|
20,11 → 20,11 |
/** |
------------ |
CVS : $Id: nopm.c,v 1.2 2002-11-11 08:32:06 pj Exp $ |
CVS : $Id: nopm.c,v 1.3 2003-01-07 17:07:50 pj Exp $ |
File: $File$ |
Revision: $Revision: 1.2 $ |
Last update: $Date: 2002-11-11 08:32:06 $ |
Revision: $Revision: 1.3 $ |
Last update: $Date: 2003-01-07 17:07:50 $ |
------------ |
See modules/nopm.h. |
58,7 → 58,6 |
#include <ll/string.h> |
#include <kernel/const.h> |
#include <sys/types.h> |
#include <modules/codes.h> |
#include <kernel/descr.h> |
#include <kernel/var.h> |
#include <kernel/func.h> |
138,40 → 137,23 |
#define NOPM_WAIT LIB_STATUS_BASE |
/*+ print resource protocol statistics...+*/ |
static void NOPM_resource_status(RLEVEL r) |
{ |
kern_printf("No status for NOPM module\n"); |
} |
static int NOPM_level_accept_resource_model(RLEVEL l, RES_MODEL *r) |
static int NOPM_res_register(RLEVEL l, PID p, RES_MODEL *r) |
{ |
/* priority inheritance works with all tasks without Resource parameters */ |
return -1; |
} |
static void NOPM_res_register(RLEVEL l, PID p, RES_MODEL *r) |
{ |
/* never called!!! */ |
} |
static void NOPM_res_detach(RLEVEL l, PID p) |
{ |
} |
static int NOPM_level_accept_mutexattr(RLEVEL l, const mutexattr_t *a) |
{ |
if (a->mclass == NOPM_MCLASS || a->mclass == (NOPM_MCLASS | l) ) |
return 0; |
else |
return -1; |
} |
static int NOPM_init(RLEVEL l, mutex_t *m, const mutexattr_t *a) |
{ |
NOPM_mutex_t *p; |
if (a->mclass != NOPM_MCLASS) |
return -1; |
p = (NOPM_mutex_t *) kern_alloc(sizeof(NOPM_mutex_t)); |
/* control if there is enough memory; no control on init on a |
234,23 → 216,12 |
if (p->owner != NIL) { /* We must block exec task */ |
LEVEL l; /* for readableness only */ |
TIME tx; /* a dummy TIME for timespec operations */ |
struct timespec ty; /* a dummy timespec for timespec operations */ |
proc_table[exec_shadow].context = kern_context_save(); |
/* SAME AS SCHEDULER... manage the capacity event and the load_info */ |
ll_gettime(TIME_EXACT, &schedule_time); |
SUBTIMESPEC(&schedule_time, &cap_lasttime, &ty); |
tx = TIMESPEC2USEC(&ty); |
proc_table[exec_shadow].avail_time -= tx; |
jet_update_slice(tx); |
if (cap_timer != NIL) { |
event_delete(cap_timer); |
cap_timer = NIL; |
} |
kern_epilogue_macro(); |
l = proc_table[exec_shadow].task_level; |
level_table[l]->task_extract(l,exec_shadow); |
level_table[l]->public_block(l,exec_shadow); |
/* we insert the task in the semaphore queue */ |
proc_table[exec_shadow].status = NOPM_WAIT; |
333,7 → 304,7 |
break; |
} else if (proc_table[e].status == NOPM_WAIT) { |
l = proc_table[e].task_level; |
level_table[l]->task_insert(l,e); |
level_table[l]->public_unblock(l,e); |
p->counter++; |
break; |
} |
348,7 → 319,7 |
return 0; |
} |
void NOPM_register_module(void) |
RLEVEL NOPM_register_module(void) |
{ |
RLEVEL l; /* the level that we register */ |
NOPM_mutex_resource_des *m; /* for readableness only */ |
365,20 → 336,11 |
resource_table[l] = (resource_des *)m; |
/* fill the resource_des descriptor */ |
strncpy(m->m.r.res_name, NOPM_MODULENAME, MAX_MODULENAME); |
m->m.r.res_code = NOPM_MODULE_CODE; |
m->m.r.res_version = NOPM_MODULE_VERSION; |
m->m.r.rtype = MUTEX_RTYPE; |
m->m.r.resource_status = NOPM_resource_status; |
m->m.r.level_accept_resource_model = NOPM_level_accept_resource_model; |
m->m.r.res_register = NOPM_res_register; |
m->m.r.res_detach = NOPM_res_detach; |
/* fill the mutex_resource_des descriptor */ |
m->m.level_accept_mutexattr = NOPM_level_accept_mutexattr; |
m->m.init = NOPM_init; |
m->m.destroy = NOPM_destroy; |
m->m.lock = NOPM_lock; |
385,5 → 347,6 |
m->m.trylock = NOPM_trylock; |
m->m.unlock = NOPM_unlock; |
return l; |
} |
/shark/trunk/kernel/modules/bd_pscan.c |
---|
38,11 → 38,11 |
*/ |
/* |
* CVS : $Id: bd_pscan.c,v 1.1.1.1 2002-03-29 14:12:52 pj Exp $ |
* CVS : $Id: bd_pscan.c,v 1.2 2003-01-07 17:07:50 pj Exp $ |
* |
* File: $File$ |
* Revision: $Revision: 1.1.1.1 $ |
* Last update: $Date: 2002-03-29 14:12:52 $ |
* Revision: $Revision: 1.2 $ |
* Last update: $Date: 2003-01-07 17:07:50 $ |
*/ |
#include <modules/bd_pscan.h> |
51,7 → 51,6 |
#include <ll/string.h> |
#include <ll/stdio.h> |
#include <kernel/const.h> |
#include <modules/codes.h> |
#include <sys/types.h> |
#include <kernel/var.h> |
#include <kernel/func.h> |
68,21 → 67,21 |
int priority[MAX_PROC]; |
} bd_pscan_resource_des; |
static int res_level_accept_resource_model(RLEVEL l, RES_MODEL *r) |
static int res_register(RLEVEL l, PID p, RES_MODEL *r) |
{ |
assertk(mylevel==l); |
if (r->rclass==BDPSCAN_RCLASS||r->rclass==(BDPSCAN_RCLASS|l)) |
return 0; |
else |
bd_pscan_resource_des *m=(bd_pscan_resource_des*)(resource_table[l]); |
BDPSCAN_RES_MODEL *rm; |
if (r->rclass!=BDEDF_RCLASS) |
return -1; |
} |
static void res_register(RLEVEL l, PID p, RES_MODEL *r) |
{ |
bd_pscan_resource_des *m=(bd_pscan_resource_des*)(resource_table[l]); |
BDPSCAN_RES_MODEL *rm=(BDPSCAN_RES_MODEL*)r; |
if (r->level && r->level !=l) |
return -1; |
rm=(BDPSCAN_RES_MODEL*)r; |
assertk(mylevel==l); |
m->priority[p]=rm->priority; |
return 0; |
} |
static void res_detach(RLEVEL l, PID p) |
92,10 → 91,7 |
m->priority[p]=LOWESTPRIORITY; |
} |
static void res_resource_status(void) |
{} |
void BD_PSCAN_register_module(void) |
RLEVEL BD_PSCAN_register_module(void) |
{ |
RLEVEL l; |
bd_pscan_resource_des *m; |
111,12 → 107,7 |
resource_table[l]=(resource_des*)m; |
/* fill the resource_des descriptor */ |
strcpy(m->rd.res_name,BDPSCAN_MODULENAME); |
m->rd.res_code=BDPSCAN_MODULE_CODE; |
m->rd.res_version=BDPSCAN_MODULE_VERSION; |
m->rd.rtype=DEFAULT_RTYPE; |
m->rd.resource_status=res_resource_status; |
m->rd.level_accept_resource_model=res_level_accept_resource_model; |
m->rd.res_register=res_register; |
m->rd.res_detach=res_detach; |
124,6 → 115,8 |
assertk(mylevel==-1); |
mylevel=l; |
return l; |
} |
int bd_pscan_getpriority(void) |
/shark/trunk/kernel/modules/rm.c |
---|
20,11 → 20,11 |
/** |
------------ |
CVS : $Id: rm.c,v 1.3 2002-11-11 08:32:06 pj Exp $ |
CVS : $Id: rm.c,v 1.4 2003-01-07 17:07:50 pj Exp $ |
File: $File$ |
Revision: $Revision: 1.3 $ |
Last update: $Date: 2002-11-11 08:32:06 $ |
Revision: $Revision: 1.4 $ |
Last update: $Date: 2003-01-07 17:07:50 $ |
------------ |
This file contains the scheduling module RM (Rate Monotonic) |
41,7 → 41,7 |
**/ |
/* |
* Copyright (C) 2000 Paolo Gai |
* Copyright (C) 2000,2002 Paolo Gai |
* |
* This program is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
102,21 → 102,6 |
} RM_level_des; |
static char *RM_status_to_a(WORD status) |
{ |
if (status < MODULE_STATUS_BASE) |
return status_to_a(status); |
switch (status) { |
case RM_READY : return "RM_Ready"; |
case RM_WCET_VIOLATED: return "RM_Wcet_Violated"; |
case RM_WAIT : return "RM_Sporadic_Wait"; |
case RM_IDLE : return "RM_Idle"; |
case RM_ZOMBIE : return "RM_Zombie"; |
default : return "RM_Unknown"; |
} |
} |
static void RM_timer_deadline(void *par) |
{ |
PID p = (PID) par; |
139,7 → 124,6 |
trc_logevent(TRC_INTACTIVATION,&p); |
/* similar to RM_task_activate */ |
temp = iq_query_timespec(p, &lev->ready); |
TIMESPEC_ASSIGN(&proc_table[p].request_time, temp); |
ADDUSEC2TIMESPEC(lev->period[p], temp); |
proc_table[p].status = RM_READY; |
iq_priority_insert(p,&lev->ready); |
171,95 → 155,16 |
kern_raise(XDEADLINE_MISS,p); |
} |
static int RM_level_accept_task_model(LEVEL l, TASK_MODEL *m) |
{ |
if (m->pclass == HARD_PCLASS || m->pclass == (HARD_PCLASS | l)) { |
HARD_TASK_MODEL *h = (HARD_TASK_MODEL *)m; |
if (h->wcet && h->mit) |
return 0; |
} |
return -1; |
} |
static int RM_level_accept_guest_model(LEVEL l, TASK_MODEL *m) |
{ |
if (m->pclass == JOB_PCLASS || m->pclass == (JOB_PCLASS | l)) |
return 0; |
else |
return -1; |
} |
static char *onoff(int i) |
{ |
if (i) |
return "On "; |
else |
return "Off"; |
} |
static void RM_level_status(LEVEL l) |
{ |
RM_level_des *lev = (RM_level_des *)(level_table[l]); |
PID p = iq_query_first(&lev->ready); |
kern_printf("Wcet Check : %s\n", |
onoff(lev->flags & RM_ENABLE_WCET_CHECK)); |
kern_printf("On-line guarantee : %s\n", |
onoff(lev->flags & RM_ENABLE_GUARANTEE)); |
kern_printf("Used Bandwidth : %u/%u\n", |
lev->U, MAX_BANDWIDTH); |
while (p != NIL) { |
if ((proc_table[p].pclass) == JOB_PCLASS) |
kern_printf("Pid: %2d (GUEST)\n", p); |
else |
kern_printf("Pid: %2d Name: %10s %s: %9ld Dline: %9ld.%6ld Stat: %s\n", |
p, |
proc_table[p].name, |
lev->flag[p] & RM_FLAG_SPORADIC ? "MinITime" : "Period ", |
lev->period[p], |
iq_query_timespec(p, &lev->ready)->tv_sec, |
iq_query_timespec(p, &lev->ready)->tv_nsec/1000, |
RM_status_to_a(proc_table[p].status)); |
p = iq_query_next(p, &lev->ready); |
} |
for (p=0; p<MAX_PROC; p++) |
if (proc_table[p].task_level == l && proc_table[p].status != RM_READY |
&& proc_table[p].status != FREE ) |
kern_printf("Pid: %2d Name: %10s %s: %9ld Dline: %9ld.%6ld Stat: %s\n", |
p, |
proc_table[p].name, |
lev->flag[p] & RM_FLAG_SPORADIC ? "MinITime" : "Period ", |
lev->period[p], |
iq_query_timespec(p, &lev->ready)->tv_sec, |
iq_query_timespec(p, &lev->ready)->tv_nsec/1000, |
RM_status_to_a(proc_table[p].status)); |
} |
/* The scheduler only gets the first task in the queue */ |
static PID RM_level_scheduler(LEVEL l) |
static PID RM_public_scheduler(LEVEL l) |
{ |
RM_level_des *lev = (RM_level_des *)(level_table[l]); |
/* { // print 4 dbg the ready queue |
PID p= lev->ready; |
kern_printf("(s"); |
while (p != NIL) { |
kern_printf("%d ",p); |
p = proc_table[p].next; |
} |
kern_printf(") "); |
} |
*/ |
return iq_query_first(&lev->ready); |
} |
/* The on-line guarantee is enabled only if the appropriate flag is set... */ |
static int RM_level_guarantee(LEVEL l, bandwidth_t *freebandwidth) |
static int RM_public_guarantee(LEVEL l, bandwidth_t *freebandwidth) |
{ |
RM_level_des *lev = (RM_level_des *)(level_table[l]); |
277,14 → 182,17 |
} |
static int RM_task_create(LEVEL l, PID p, TASK_MODEL *m) |
static int RM_public_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
RM_level_des *lev = (RM_level_des *)(level_table[l]); |
/* if the RM_task_create is called, then the pclass must be a |
valid pclass. */ |
HARD_TASK_MODEL *h; |
HARD_TASK_MODEL *h = (HARD_TASK_MODEL *)m; |
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; |
/* now we know that m is a valid model */ |
*iq_query_priority(p, &lev->ready) = lev->period[p] = h->mit; |
328,7 → 236,7 |
return 0; /* OK, also if the task cannot be guaranteed... */ |
} |
static void RM_task_detach(LEVEL l, PID p) |
static void RM_public_detach(LEVEL l, PID p) |
{ |
/* the RM level doesn't introduce any dinamic allocated new field. |
we have only to reset the NO_GUARANTEE FIELD and decrement the allocated |
342,13 → 250,8 |
lev->U -= (MAX_BANDWIDTH / lev->period[p]) * proc_table[p].wcet; |
} |
static int RM_task_eligible(LEVEL l, PID p) |
static void RM_public_dispatch(LEVEL l, PID p, int nostop) |
{ |
return 0; /* if the task p is chosen, it is always eligible */ |
} |
static void RM_task_dispatch(LEVEL l, PID p, int nostop) |
{ |
RM_level_des *lev = (RM_level_des *)(level_table[l]); |
// kern_printf("(disp %d)",p); |
359,7 → 262,7 |
iq_extract(p, &lev->ready); |
} |
static void RM_task_epilogue(LEVEL l, PID p) |
static void RM_public_epilogue(LEVEL l, PID p) |
{ |
RM_level_des *lev = (RM_level_des *)(level_table[l]); |
378,7 → 281,7 |
} |
} |
static void RM_task_activate(LEVEL l, PID p) |
static void RM_public_activate(LEVEL l, PID p) |
{ |
RM_level_des *lev = (RM_level_des *)(level_table[l]); |
struct timespec *temp; |
396,10 → 299,8 |
/* see also RM_timer_deadline */ |
ll_gettime(TIME_EXACT, &proc_table[p].request_time); |
temp = iq_query_timespec(p, &lev->ready); |
TIMESPEC_ASSIGN(temp, &proc_table[p].request_time); |
kern_gettime(temp); |
ADDUSEC2TIMESPEC(lev->period[p], temp); |
/* Insert task in the correct position */ |
412,12 → 313,12 |
(void *)p); |
} |
static void RM_task_insert(LEVEL l, PID p) |
static void RM_public_unblock(LEVEL l, PID p) |
{ |
RM_level_des *lev = (RM_level_des *)(level_table[l]); |
/* Similar to RM_task_activate, but we don't check in what state |
the task is and we don't set the request_time*/ |
/* Similar to RM_task_activate, |
but we don't check in what state the task is */ |
/* Insert task in the correct position */ |
proc_table[p].status = RM_READY; |
424,7 → 325,7 |
iq_priority_insert(p,&lev->ready); |
} |
static void RM_task_extract(LEVEL l, PID p) |
static void RM_public_block(LEVEL l, PID p) |
{ |
/* Extract the running task from the level |
. we have already extract it from the ready queue at the dispatch time. |
437,7 → 338,7 |
*/ |
} |
static void RM_task_endcycle(LEVEL l, PID p) |
static int RM_public_message(LEVEL l, PID p, void *m) |
{ |
RM_level_des *lev = (RM_level_des *)(level_table[l]); |
451,14 → 352,17 |
if (lev->flags & RM_ENABLE_WCET_CHECK) |
proc_table[p].avail_time = proc_table[p].wcet; |
jet_update_endcycle(); /* Update the Jet data... */ |
trc_logevent(TRC_ENDCYCLE,&exec_shadow); /* tracer stuff */ |
/* when the deadline timer fire, it recognize the situation and set |
correctly all the stuffs (like reactivation, request_time, etc... ) */ |
correctly all the stuffs (like reactivation, sleep, etc... ) */ |
return 0; |
} |
static void RM_task_end(LEVEL l, PID p) |
static void RM_public_end(LEVEL l, PID p) |
{ |
// RM_level_des *lev = (RM_level_des *)(level_table[l]); |
proc_table[p].status = RM_ZOMBIE; |
/* When the deadline timer fire, it put the task descriptor in |
465,61 → 369,39 |
the free queue, and free the allocated bandwidth... */ |
} |
static void RM_task_sleep(LEVEL l, PID p) |
static void RM_private_insert(LEVEL l, PID p, TASK_MODEL *m) |
{ |
RM_level_des *lev = (RM_level_des *)(level_table[l]); |
JOB_TASK_MODEL *job; |
/* the task has terminated his job before it consume the wcet. All OK! */ |
proc_table[p].status = RM_WAIT; |
if (m->pclass != JOB_PCLASS || (m->level != 0 && m->level != l) ) { |
kern_raise(XINVALID_TASK, p); |
return; |
} |
/* we reset the capacity counters... */ |
if (lev->flags & RM_ENABLE_WCET_CHECK) |
proc_table[p].avail_time = proc_table[p].wcet; |
job = (JOB_TASK_MODEL *)m; |
/* when the deadline timer fire, it recognize the situation and set |
correctly the task state to sleep... */ |
} |
/* Guest Functions |
These functions manages a JOB_TASK_MODEL, that is used to put |
a guest task in the RM ready queue. */ |
static int RM_guest_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
RM_level_des *lev = (RM_level_des *)(level_table[l]); |
JOB_TASK_MODEL *job = (JOB_TASK_MODEL *)m; |
/* if the RM_guest_create is called, then the pclass must be a |
valid pclass. */ |
*iq_query_timespec(p,&lev->ready) = job->deadline; |
*iq_query_priority(p, &lev->ready) = lev->period[p] = job->period; |
lev->deadline_timer[p] = -1; |
/* Insert task in the correct position */ |
iq_priority_insert(p,&lev->ready); |
proc_table[p].status = RM_READY; |
if (job->noraiseexc) |
lev->flag[p] = RM_FLAG_NORAISEEXC; |
else |
else { |
lev->flag[p] = 0; |
*iq_query_priority(p, &lev->ready) = lev->period[p] = job->period; |
/* there is no bandwidth guarantee at this level, it is performed |
by the level that inserts guest tasks... */ |
return 0; /* OK, also if the task cannot be guaranteed... */ |
lev->deadline_timer[p] = kern_event_post(iq_query_timespec(p, &lev->ready), |
RM_timer_guest_deadline, |
(void *)p); |
} |
} |
static void RM_guest_detach(LEVEL l, PID p) |
static void RM_private_dispatch(LEVEL l, PID p, int nostop) |
{ |
/* the RM level doesn't introduce any dinamic allocated new field. |
No guarantee is performed on guest tasks... so we don't have to reset |
the NO_GUARANTEE FIELD */ |
} |
static void RM_guest_dispatch(LEVEL l, PID p, int nostop) |
{ |
RM_level_des *lev = (RM_level_des *)(level_table[l]); |
/* the task state is set to EXE by the scheduler() |
528,7 → 410,7 |
iq_extract(p, &lev->ready); |
} |
static void RM_guest_epilogue(LEVEL l, PID p) |
static void RM_private_epilogue(LEVEL l, PID p) |
{ |
RM_level_des *lev = (RM_level_des *)(level_table[l]); |
537,48 → 419,10 |
proc_table[p].status = RM_READY; |
} |
static void RM_guest_activate(LEVEL l, PID p) |
static void RM_private_extract(LEVEL l, PID p) |
{ |
RM_level_des *lev = (RM_level_des *)(level_table[l]); |
/* Insert task in the correct position */ |
iq_priority_insert(p,&lev->ready); |
proc_table[p].status = RM_READY; |
/* Set the deadline timer */ |
if (!(lev->flag[p] & RM_FLAG_NORAISEEXC)) |
lev->deadline_timer[p] = kern_event_post(iq_query_timespec(p, &lev->ready), |
RM_timer_guest_deadline, |
(void *)p); |
} |
static void RM_guest_insert(LEVEL l, PID p) |
{ |
RM_level_des *lev = (RM_level_des *)(level_table[l]); |
/* Insert task in the correct position */ |
iq_priority_insert(p,&lev->ready); |
proc_table[p].status = RM_READY; |
} |
static void RM_guest_extract(LEVEL l, PID p) |
{ |
/* Extract the running task from the level |
. we have already extract it from the ready queue at the dispatch time. |
. the state of the task is set by the calling function |
. the deadline must remain... |
So, we do nothing!!! |
*/ |
} |
static void RM_guest_endcycle(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RM_guest_end(LEVEL l, PID p) |
{ |
RM_level_des *lev = (RM_level_des *)(level_table[l]); |
//kern_printf("RM_guest_end: dline timer %d\n",lev->deadline_timer[p]); |
if (proc_table[p].status == RM_READY) |
{ |
589,23 → 433,17 |
/* we remove the deadline timer, because the slice is finished */ |
if (lev->deadline_timer[p] != NIL) { |
// kern_printf("RM_guest_end: dline timer %d\n",lev->deadline_timer[p]); |
event_delete(lev->deadline_timer[p]); |
kern_event_delete(lev->deadline_timer[p]); |
lev->deadline_timer[p] = NIL; |
} |
} |
static void RM_guest_sleep(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
/* Registration functions */ |
/*+ Registration function: |
int flags the init flags ... see rm.h +*/ |
void RM_register_level(int flags) |
LEVEL RM_register_level(int flags) |
{ |
LEVEL l; /* the level that we register */ |
RM_level_des *lev; /* for readableness only */ |
614,54 → 452,34 |
printk("RM_register_level\n"); |
/* request an entry in the level_table */ |
l = level_alloc_descriptor(); |
l = level_alloc_descriptor(sizeof(RM_level_des)); |
/* alloc the space needed for the RM_level_des */ |
lev = (RM_level_des *)kern_alloc(sizeof(RM_level_des)); |
lev = (RM_level_des *)level_table[l]; |
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, RM_LEVELNAME, MAX_LEVELNAME); |
lev->l.level_code = RM_LEVEL_CODE; |
lev->l.level_version = RM_LEVEL_VERSION; |
lev->l.private_insert = RM_private_insert; |
lev->l.private_extract = RM_private_extract; |
lev->l.private_dispatch = RM_private_dispatch; |
lev->l.private_epilogue = RM_private_epilogue; |
lev->l.level_accept_task_model = RM_level_accept_task_model; |
lev->l.level_accept_guest_model = RM_level_accept_guest_model; |
lev->l.level_status = RM_level_status; |
lev->l.level_scheduler = RM_level_scheduler; |
lev->l.public_scheduler = RM_public_scheduler; |
if (flags & RM_ENABLE_GUARANTEE) |
lev->l.level_guarantee = RM_level_guarantee; |
lev->l.public_guarantee = RM_public_guarantee; |
else |
lev->l.level_guarantee = NULL; |
lev->l.public_guarantee = NULL; |
lev->l.task_create = RM_task_create; |
lev->l.task_detach = RM_task_detach; |
lev->l.task_eligible = RM_task_eligible; |
lev->l.task_dispatch = RM_task_dispatch; |
lev->l.task_epilogue = RM_task_epilogue; |
lev->l.task_activate = RM_task_activate; |
lev->l.task_insert = RM_task_insert; |
lev->l.task_extract = RM_task_extract; |
lev->l.task_endcycle = RM_task_endcycle; |
lev->l.task_end = RM_task_end; |
lev->l.task_sleep = RM_task_sleep; |
lev->l.public_create = RM_public_create; |
lev->l.public_detach = RM_public_detach; |
lev->l.public_end = RM_public_end; |
lev->l.public_dispatch = RM_public_dispatch; |
lev->l.public_epilogue = RM_public_epilogue; |
lev->l.public_activate = RM_public_activate; |
lev->l.public_unblock = RM_public_unblock; |
lev->l.public_block = RM_public_block; |
lev->l.public_message = RM_public_message; |
lev->l.guest_create = RM_guest_create; |
lev->l.guest_detach = RM_guest_detach; |
lev->l.guest_dispatch = RM_guest_dispatch; |
lev->l.guest_epilogue = RM_guest_epilogue; |
lev->l.guest_activate = RM_guest_activate; |
lev->l.guest_insert = RM_guest_insert; |
lev->l.guest_extract = RM_guest_extract; |
lev->l.guest_endcycle = RM_guest_endcycle; |
lev->l.guest_end = RM_guest_end; |
lev->l.guest_sleep = RM_guest_sleep; |
/* fill the RM descriptor part */ |
for(i=0; i<MAX_PROC; i++) { |
lev->period[i] = 0; |
672,15 → 490,14 |
iq_init(&lev->ready, &freedesc, 0); |
lev->flags = flags & 0x07; |
lev->U = 0; |
return l; |
} |
bandwidth_t RM_usedbandwidth(LEVEL l) |
{ |
RM_level_des *lev = (RM_level_des *)(level_table[l]); |
if (lev->l.level_code == RM_LEVEL_CODE && |
lev->l.level_version == RM_LEVEL_VERSION) |
return lev->U; |
else |
return 0; |
return lev->U; |
} |
/shark/trunk/kernel/modules/rrsoft.c |
---|
20,11 → 20,11 |
/** |
------------ |
CVS : $Id: rrsoft.c,v 1.3 2002-11-11 08:32:07 pj Exp $ |
CVS : $Id: rrsoft.c,v 1.4 2003-01-07 17:07:51 pj Exp $ |
File: $File$ |
Revision: $Revision: 1.3 $ |
Last update: $Date: 2002-11-11 08:32:07 $ |
Revision: $Revision: 1.4 $ |
Last update: $Date: 2003-01-07 17:07:51 $ |
------------ |
This file contains the scheduling module RRSOFT (Round Robin) |
60,6 → 60,7 |
#include <kernel/descr.h> |
#include <kernel/var.h> |
#include <kernel/func.h> |
#include <kernel/trace.h> |
/*+ Status used in the level +*/ |
#define RRSOFT_READY MODULE_STATUS_BASE |
92,19 → 93,6 |
} RRSOFT_level_des; |
static char *RRSOFT_status_to_a(WORD status) |
{ |
if (status < MODULE_STATUS_BASE) |
return status_to_a(status); |
switch (status) { |
case RRSOFT_READY: return "RRSOFT_Ready"; |
case RRSOFT_IDLE : return "RRSOFT_Idle"; |
default : return "RRSOFT_Unknown"; |
} |
} |
/* this is the periodic reactivation of the task... it is posted only |
if the task is a periodic task */ |
static void RRSOFT_timer_reactivate(void *par) |
137,53 → 125,11 |
// trc_logevent(TRC_INTACTIVATION,&p); |
} |
static int RRSOFT_level_accept_task_model(LEVEL l, TASK_MODEL *m) |
{ |
RRSOFT_level_des *lev = (RRSOFT_level_des *)(level_table[l]); |
if ((m->pclass == NRT_PCLASS || m->pclass == (NRT_PCLASS | l)) && lev->models & RRSOFT_ONLY_NRT) |
return 0; |
else if ((m->pclass == SOFT_PCLASS || m->pclass == (SOFT_PCLASS | l)) && lev->models & RRSOFT_ONLY_SOFT) |
return 0; |
else if ((m->pclass == HARD_PCLASS || m->pclass == (HARD_PCLASS | l)) && lev->models & RRSOFT_ONLY_HARD) |
return 0; |
else |
return -1; |
} |
static int RRSOFT_level_accept_guest_model(LEVEL l, TASK_MODEL *m) |
{ |
return -1; |
} |
static void RRSOFT_level_status(LEVEL l) |
{ |
RRSOFT_level_des *lev = (RRSOFT_level_des *)(level_table[l]); |
PID p = iq_query_first(&lev->ready); |
kern_printf("Slice: %d \n", lev->slice); |
while (p != NIL) { |
kern_printf("Pid: %d\t Name: %20s Status: %s\n",p,proc_table[p].name, |
RRSOFT_status_to_a(proc_table[p].status)); |
p = iq_query_next(p, &lev->ready); |
} |
for (p=0; p<MAX_PROC; p++) |
if (proc_table[p].task_level == l && proc_table[p].status != RRSOFT_READY |
&& proc_table[p].status != FREE ) |
kern_printf("Pid: %d\t Name: %20s Status: %s\n",p,proc_table[p].name, |
RRSOFT_status_to_a(proc_table[p].status)); |
} |
/* This is not efficient but very fair :-) |
The need of all this stuff is because if a task execute a long time |
due to (shadow!) priority inheritance, then the task shall go to the |
tail of the queue many times... */ |
static PID RRSOFT_level_scheduler(LEVEL l) |
static PID RRSOFT_public_scheduler(LEVEL l) |
{ |
RRSOFT_level_des *lev = (RRSOFT_level_des *)(level_table[l]); |
208,17 → 154,8 |
} |
} |
static int RRSOFT_level_guarantee(LEVEL l, bandwidth_t *freebandwidth) |
static int RRSOFT_public_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
/* the RRSOFT level always guarantee... the function is defined because |
there can be an aperiodic server at a level with less priority than |
the RRSOFT that need guarantee (e.g., a TBS server) */ |
return 1; |
} |
static int RRSOFT_task_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
RRSOFT_level_des *lev = (RRSOFT_level_des *)(level_table[l]); |
// kern_printf("create %d mod %d\n",p,m->pclass); |
226,6 → 163,11 |
the only thing to set remains the capacity stuffs that are set |
to the values passed in the model... */ |
if ( !(m->pclass==NRT_PCLASS && lev->models & RRSOFT_ONLY_NRT ) ) return -1; |
if ( !(m->pclass==SOFT_PCLASS && lev->models & RRSOFT_ONLY_SOFT) ) return -1; |
if ( !(m->pclass==HARD_PCLASS && lev->models & RRSOFT_ONLY_HARD) ) return -1; |
if (m->level != 0 && m->level != l) return -1; |
/* I used the wcet field because using wcet can account if a task |
consume more than the timeslice... */ |
289,22 → 231,9 |
return 0; /* OK */ |
} |
static void RRSOFT_task_detach(LEVEL l, PID p) |
static void RRSOFT_public_dispatch(LEVEL l, PID p, int nostop) |
{ |
/* the RRSOFT level doesn't introduce any new field in the TASK_MODEL |
so, all detach stuffs are done by the task_create |
The task state is set at FREE by the general task_create */ |
} |
static int RRSOFT_task_eligible(LEVEL l, PID p) |
{ |
return 0; /* if the task p is chosen, it is always eligible */ |
} |
static void RRSOFT_task_dispatch(LEVEL l, PID p, int nostop) |
{ |
RRSOFT_level_des *lev = (RRSOFT_level_des *)(level_table[l]); |
//static int p2count=0; |
/* the task state is set EXE by the scheduler() |
we extract the task from the ready queue |
312,7 → 241,7 |
iq_extract(p, &lev->ready); |
} |
static void RRSOFT_task_epilogue(LEVEL l, PID p) |
static void RRSOFT_public_epilogue(LEVEL l, PID p) |
{ |
RRSOFT_level_des *lev = (RRSOFT_level_des *)(level_table[l]); |
329,7 → 258,7 |
proc_table[p].status = RRSOFT_READY; |
} |
static void RRSOFT_task_activate(LEVEL l, PID p) |
static void RRSOFT_public_activate(LEVEL l, PID p) |
{ |
RRSOFT_level_des *lev = (RRSOFT_level_des *)(level_table[l]); |
341,9 → 270,7 |
return; |
} |
ll_gettime(TIME_EXACT, &proc_table[p].request_time); |
/* Insert task in the coRRSOFTect position */ |
/* Insert task in the correct position */ |
proc_table[p].status = RRSOFT_READY; |
iq_insertlast(p,&lev->ready); |
350,9 → 277,8 |
/* Set the reactivation timer */ |
if (lev->periodic[p]) |
{ |
TIMESPEC_ASSIGN(&lev->reactivation_time[p], &proc_table[p].request_time); |
kern_gettime(&lev->reactivation_time[p]); |
ADDUSEC2TIMESPEC(lev->period[p], &lev->reactivation_time[p]); |
// TIMESPEC_ASSIGN(&lev->reactivation_time[p], &lev->cbs_dline[p]); |
lev->reactivation_timer[p] = kern_event_post(&lev->reactivation_time[p], |
RRSOFT_timer_reactivate, |
(void *)p); |
359,12 → 285,12 |
} |
} |
static void RRSOFT_task_insert(LEVEL l, PID p) |
static void RRSOFT_public_unblock(LEVEL l, PID p) |
{ |
RRSOFT_level_des *lev = (RRSOFT_level_des *)(level_table[l]); |
/* Similar to RRSOFT_task_activate, but we don't check in what state |
the task is and we don't set the request_time */ |
the task is */ |
/* Insert task in the coRRSOFTect position */ |
proc_table[p].status = RRSOFT_READY; |
371,7 → 297,7 |
iq_insertlast(p,&lev->ready); |
} |
static void RRSOFT_task_extract(LEVEL l, PID p) |
static void RRSOFT_public_block(LEVEL l, PID p) |
{ |
/* Extract the running task from the level |
. we have already extract it from the ready queue at the dispatch time. |
383,13 → 309,12 |
*/ |
} |
static void RRSOFT_task_endcycle(LEVEL l, PID p) |
static int RRSOFT_public_message(LEVEL l, PID p, void *m) |
{ |
RRSOFT_level_des *lev = (RRSOFT_level_des *)(level_table[l]); |
if (lev->nact[p] > 0) { |
/* continue!!!! */ |
ll_gettime(TIME_EXACT, &proc_table[p].request_time); |
lev->nact[p]--; |
// qq_insertlast(p,&lev->ready); |
iq_insertfirst(p,&lev->ready); |
397,9 → 322,14 |
} |
else |
proc_table[p].status = RRSOFT_IDLE; |
jet_update_endcycle(); /* Update the Jet data... */ |
trc_logevent(TRC_ENDCYCLE,&exec_shadow); /* tracer stuff */ |
return 0; |
} |
static void RRSOFT_task_end(LEVEL l, PID p) |
static void RRSOFT_public_end(LEVEL l, PID p) |
{ |
RRSOFT_level_des *lev = (RRSOFT_level_des *)(level_table[l]); |
407,7 → 337,7 |
/* we delete the reactivation timer */ |
if (lev->periodic[p]) { |
event_delete(lev->reactivation_timer[p]); |
kern_event_delete(lev->reactivation_timer[p]); |
lev->reactivation_timer[p] = -1; |
} |
416,53 → 346,6 |
iq_insertlast(p,&freedesc); |
} |
static void RRSOFT_task_sleep(LEVEL l, PID p) |
{ |
RRSOFT_level_des *lev = (RRSOFT_level_des *)(level_table[l]); |
if (lev->nact[p] >= 0) lev->nact[p] = 0; |
/* we delete the reactivation timer */ |
if (lev->periodic[p]) { |
event_delete(lev->reactivation_timer[p]); |
lev->reactivation_timer[p] = -1; |
} |
proc_table[p].status = SLEEP; |
} |
static int RRSOFT_guest_create(LEVEL l, PID p, TASK_MODEL *m) |
{ kern_raise(XINVALID_GUEST,exec_shadow); return 0; } |
static void RRSOFT_guest_detach(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RRSOFT_guest_dispatch(LEVEL l, PID p, int nostop) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RRSOFT_guest_epilogue(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RRSOFT_guest_activate(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RRSOFT_guest_insert(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RRSOFT_guest_extract(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RRSOFT_guest_endcycle(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RRSOFT_guest_end(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RRSOFT_guest_sleep(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
/* Registration functions */ |
/*+ This init function install the "main" task +*/ |
490,7 → 373,7 |
if (p == NIL) |
printk("\nPanic!!! can't create main task...\n"); |
RRSOFT_task_activate(lev,p); |
RRSOFT_public_activate(lev,p); |
} |
498,7 → 381,7 |
TIME slice the slice for the Round Robin queue |
int createmain 1 if the level creates the main task 0 otherwise |
struct multiboot_info *mb used if createmain specified +*/ |
void RRSOFT_register_level(TIME slice, |
LEVEL RRSOFT_register_level(TIME slice, |
int createmain, |
struct multiboot_info *mb, |
BYTE models) |
510,50 → 393,23 |
printk("RRSOFT_register_level\n"); |
/* request an entry in the level_table */ |
l = level_alloc_descriptor(); |
l = level_alloc_descriptor(sizeof(RRSOFT_level_des)); |
/* alloc the space needed for the RRSOFT_level_des */ |
lev = (RRSOFT_level_des *)kern_alloc(sizeof(RRSOFT_level_des)); |
lev = (RRSOFT_level_des *)level_table[l]; |
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, RRSOFT_LEVELNAME, MAX_LEVELNAME); |
lev->l.level_code = RRSOFT_LEVEL_CODE; |
lev->l.level_version = RRSOFT_LEVEL_VERSION; |
lev->l.public_scheduler = RRSOFT_public_scheduler; |
lev->l.public_create = RRSOFT_public_create; |
lev->l.public_end = RRSOFT_public_end; |
lev->l.public_dispatch = RRSOFT_public_dispatch; |
lev->l.public_epilogue = RRSOFT_public_epilogue; |
lev->l.public_activate = RRSOFT_public_activate; |
lev->l.public_unblock = RRSOFT_public_unblock; |
lev->l.public_block = RRSOFT_public_block; |
lev->l.public_message = RRSOFT_public_message; |
lev->l.level_accept_task_model = RRSOFT_level_accept_task_model; |
lev->l.level_accept_guest_model = RRSOFT_level_accept_guest_model; |
lev->l.level_status = RRSOFT_level_status; |
lev->l.level_scheduler = RRSOFT_level_scheduler; |
lev->l.level_guarantee = RRSOFT_level_guarantee; |
lev->l.task_create = RRSOFT_task_create; |
lev->l.task_detach = RRSOFT_task_detach; |
lev->l.task_eligible = RRSOFT_task_eligible; |
lev->l.task_dispatch = RRSOFT_task_dispatch; |
lev->l.task_epilogue = RRSOFT_task_epilogue; |
lev->l.task_activate = RRSOFT_task_activate; |
lev->l.task_insert = RRSOFT_task_insert; |
lev->l.task_extract = RRSOFT_task_extract; |
lev->l.task_endcycle = RRSOFT_task_endcycle; |
lev->l.task_end = RRSOFT_task_end; |
lev->l.task_sleep = RRSOFT_task_sleep; |
lev->l.guest_create = RRSOFT_guest_create; |
lev->l.guest_detach = RRSOFT_guest_detach; |
lev->l.guest_dispatch = RRSOFT_guest_dispatch; |
lev->l.guest_epilogue = RRSOFT_guest_epilogue; |
lev->l.guest_activate = RRSOFT_guest_activate; |
lev->l.guest_insert = RRSOFT_guest_insert; |
lev->l.guest_extract = RRSOFT_guest_extract; |
lev->l.guest_endcycle = RRSOFT_guest_endcycle; |
lev->l.guest_end = RRSOFT_guest_end; |
lev->l.guest_sleep = RRSOFT_guest_sleep; |
/* fill the RRSOFT descriptor part */ |
for (i = 0; i < MAX_PROC; i++) { |
lev->nact[i] = -1; |
575,6 → 431,8 |
if (createmain) |
sys_atrunlevel(RRSOFT_call_main,(void *) l, RUNLEVEL_INIT); |
return l; |
} |
/shark/trunk/kernel/modules/ps.c |
---|
20,11 → 20,11 |
/** |
------------ |
CVS : $Id: ps.c,v 1.3 2002-11-11 08:32:06 pj Exp $ |
CVS : $Id: ps.c,v 1.4 2003-01-07 17:07:50 pj Exp $ |
File: $File$ |
Revision: $Revision: 1.3 $ |
Last update: $Date: 2002-11-11 08:32:06 $ |
Revision: $Revision: 1.4 $ |
Last update: $Date: 2003-01-07 17:07:50 $ |
------------ |
This file contains the aperiodic server PS (Polling Server) |
103,6 → 103,7 |
#include <kernel/descr.h> |
#include <kernel/var.h> |
#include <kernel/func.h> |
#include <kernel/trace.h> |
/*+ Status used in the level +*/ |
#define PS_WAIT APER_STATUS_BASE /*+ waiting the service +*/ |
145,8 → 146,7 |
m = lev->scheduling_level; |
job_task_default_model(j,lev->lastdline); |
job_task_def_period(j,lev->period); |
level_table[m]->guest_create(m,p,(TASK_MODEL *)&j); |
level_table[m]->guest_activate(m,p); |
level_table[m]->private_insert(m,p,(TASK_MODEL *)&j); |
// kern_printf("(%d %d)",lev->lastdline.tv_sec,lev->lastdline.tv_nsec); |
} |
180,80 → 180,8 |
// kern_printf("!"); |
} |
static char *PS_status_to_a(WORD status) |
static PID PS_public_schedulerbackground(LEVEL l) |
{ |
if (status < MODULE_STATUS_BASE) |
return status_to_a(status); |
switch (status) { |
case PS_WAIT : return "PS_Wait"; |
default : return "PS_Unknown"; |
} |
} |
static int PS_level_accept_task_model(LEVEL l, TASK_MODEL *m) |
{ |
if (m->pclass == SOFT_PCLASS || m->pclass == (SOFT_PCLASS | l) ) { |
SOFT_TASK_MODEL *s = (SOFT_TASK_MODEL *)m; |
if (s->periodicity == APERIODIC) |
return 0; |
} |
return -1; |
} |
static int PS_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 PS_level_status(LEVEL l) |
{ |
PS_level_des *lev = (PS_level_des *)(level_table[l]); |
PID p = iq_query_first(&lev->wait); |
kern_printf("On-line guarantee : %s\n", |
onoff(lev->flags & PS_ENABLE_GUARANTEE_EDF || |
lev->flags & PS_ENABLE_GUARANTEE_RM )); |
kern_printf("Used Bandwidth : %u/%u\n", |
lev->U, MAX_BANDWIDTH); |
if (lev->activated != -1) |
kern_printf("Activated: Pid: %2d Name: %10s Dl: %ld.%ld Nact: %d Stat: %s\n", |
lev->activated, |
proc_table[lev->activated].name, |
iq_query_timespec(lev->activated,&lev->wait)->tv_sec, |
iq_query_timespec(lev->activated,&lev->wait)->tv_nsec, |
lev->nact[lev->activated], |
PS_status_to_a(proc_table[lev->activated].status)); |
while (p != NIL) { |
kern_printf("Pid: %2d Name: %10s Stat: %s\n", |
p, |
proc_table[p].name, |
PS_status_to_a(proc_table[p].status)); |
p = iq_query_next(p, &lev->wait); |
} |
} |
static PID PS_level_scheduler(LEVEL l) |
{ |
/* the PS don't schedule anything... |
it's an EDF level or similar that do it! */ |
return NIL; |
} |
static PID PS_level_schedulerbackground(LEVEL l) |
{ |
/* the PS catch the background time to exec aperiodic activities */ |
PS_level_des *lev = (PS_level_des *)(level_table[l]); |
266,7 → 194,7 |
} |
/* The on-line guarantee is enabled only if the appropriate flag is set... */ |
static int PS_level_guaranteeEDF(LEVEL l, bandwidth_t *freebandwidth) |
static int PS_public_guaranteeEDF(LEVEL l, bandwidth_t *freebandwidth) |
{ |
PS_level_des *lev = (PS_level_des *)(level_table[l]); |
278,7 → 206,7 |
return 0; |
} |
static int PS_level_guaranteeRM(LEVEL l, bandwidth_t *freebandwidth) |
static int PS_public_guaranteeRM(LEVEL l, bandwidth_t *freebandwidth) |
{ |
PS_level_des *lev = (PS_level_des *)(level_table[l]); |
290,13 → 218,17 |
return 0; |
} |
static int PS_task_create(LEVEL l, PID p, TASK_MODEL *m) |
static int PS_public_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
PS_level_des *lev = (PS_level_des *)(level_table[l]); |
SOFT_TASK_MODEL *s; |
/* if the PS_task_create is called, then the pclass must be a |
valid pclass. */ |
SOFT_TASK_MODEL *s = (SOFT_TASK_MODEL *)m; |
if (m->pclass != SOFT_PCLASS) return -1; |
if (m->level != 0 && m->level != l) return -1; |
s = (SOFT_TASK_MODEL *)m; |
if (s->periodicity != APERIODIC) return -1; |
s = (SOFT_TASK_MODEL *)m; |
if (s->arrivals == SAVE_ARRIVALS) |
lev->nact[p] = 0; |
306,18 → 238,8 |
return 0; /* OK, also if the task cannot be guaranteed... */ |
} |
static void PS_task_detach(LEVEL l, PID p) |
static void PS_public_dispatch(LEVEL l, PID p, int nostop) |
{ |
/* the PS level doesn't introduce any dinamic allocated new field. */ |
} |
static int PS_task_eligible(LEVEL l, PID p) |
{ |
return 0; /* if the task p is chosen, it is always eligible */ |
} |
static void PS_task_dispatch(LEVEL l, PID p, int nostop) |
{ |
PS_level_des *lev = (PS_level_des *)(level_table[l]); |
struct timespec ty; |
333,7 → 255,7 |
else { |
//if (nostop) kern_printf("(gd status=%d)",proc_table[p].status); |
level_table[ lev->scheduling_level ]-> |
guest_dispatch(lev->scheduling_level,p,nostop); |
private_dispatch(lev->scheduling_level,p,nostop); |
} |
/* set the capacity timer */ |
346,7 → 268,7 |
// kern_printf("(disp %d %d)",ty.tv_sec, ty.tv_nsec); |
} |
static void PS_task_epilogue(LEVEL l, PID p) |
static void PS_public_epilogue(LEVEL l, PID p) |
{ |
PS_level_des *lev = (PS_level_des *)(level_table[l]); |
struct timespec ty; |
378,7 → 300,7 |
task point the shadow to it!!!*/ |
if (lev->activated == p) |
level_table[ lev->scheduling_level ]-> |
guest_end(lev->scheduling_level,p); |
private_extract(lev->scheduling_level,p); |
iq_insertfirst(p, &lev->wait); |
proc_table[p].status = PS_WAIT; |
lev->activated = NIL; |
388,7 → 310,7 |
wait queue by calling the guest_epilogue... */ |
if (lev->activated == p) {//kern_printf("Û1"); |
level_table[ lev->scheduling_level ]-> |
guest_epilogue(lev->scheduling_level,p); |
private_epilogue(lev->scheduling_level,p); |
} else { //kern_printf("Û2"); |
iq_insertfirst(p, &lev->wait); |
proc_table[p].status = PS_WAIT; |
395,7 → 317,7 |
} |
} |
static void PS_task_activate(LEVEL l, PID p) |
static void PS_public_activate(LEVEL l, PID p) |
{ |
PS_level_des *lev = (PS_level_des *)(level_table[l]); |
404,7 → 326,6 |
lev->nact[p]++; |
} |
else if (proc_table[p].status == SLEEP) { |
ll_gettime(TIME_EXACT, &proc_table[p].request_time); |
if (lev->activated == NIL && lev->availCs > 0) { |
lev->activated = p; |
421,7 → 342,7 |
} |
static void PS_task_insert(LEVEL l, PID p) |
static void PS_public_unblock(LEVEL l, PID p) |
{ |
PS_level_des *lev = (PS_level_des *)(level_table[l]); |
435,7 → 356,7 |
proc_table[p].status = PS_WAIT; |
} |
static void PS_task_extract(LEVEL l, PID p) |
static void PS_public_block(LEVEL l, PID p) |
{ |
PS_level_des *lev = (PS_level_des *)(level_table[l]); |
446,10 → 367,10 |
if (lev->activated == p) |
level_table[ lev->scheduling_level ]-> |
guest_end(lev->scheduling_level,p); |
private_extract(lev->scheduling_level,p); |
} |
static void PS_task_endcycle(LEVEL l, PID p) |
static int PS_public_message(LEVEL l, PID p, void *m) |
{ |
PS_level_des *lev = (PS_level_des *)(level_table[l]); |
struct timespec ty; |
466,7 → 387,7 |
if (lev->activated == p) |
level_table[ lev->scheduling_level ]-> |
guest_end(lev->scheduling_level,p); |
private_extract(lev->scheduling_level,p); |
else |
iq_extract(p, &lev->wait); |
484,9 → 405,14 |
lev->availCs = 0; /* see note (*) at the begin of the file */ |
else |
PS_activation(lev); |
jet_update_endcycle(); /* Update the Jet data... */ |
trc_logevent(TRC_ENDCYCLE,&exec_shadow); /* tracer stuff */ |
return 0; |
} |
static void PS_task_end(LEVEL l, PID p) |
static void PS_public_end(LEVEL l, PID p) |
{ |
PS_level_des *lev = (PS_level_des *)(level_table[l]); |
struct timespec ty; |
503,7 → 429,7 |
if (lev->activated == p) |
level_table[ lev->scheduling_level ]-> |
guest_end(lev->scheduling_level,p); |
private_extract(lev->scheduling_level,p); |
proc_table[p].status = FREE; |
iq_insertfirst(p,&freedesc); |
515,72 → 441,6 |
PS_activation(lev); |
} |
static void PS_task_sleep(LEVEL l, PID p) |
{ |
PS_level_des *lev = (PS_level_des *)(level_table[l]); |
struct timespec ty; |
TIME tx; |
/* update the server capacity */ |
if (lev->flags & PS_BACKGROUND) |
lev->flags &= ~PS_BACKGROUND; |
else { |
SUBTIMESPEC(&schedule_time, &cap_lasttime, &ty); |
tx = TIMESPEC2USEC(&ty); |
lev->availCs -= tx; |
} |
if (lev->nact[p] >= 0) lev->nact[p] = 0; |
if (lev->activated == p) |
level_table[ lev->scheduling_level ]-> |
guest_end(lev->scheduling_level,p); |
else |
iq_extract(p, &lev->wait); |
proc_table[p].status = SLEEP; |
lev->activated = iq_getfirst(&lev->wait); |
if (lev->activated == NIL) |
lev->availCs = 0; /* see note (*) at the begin of the file */ |
else |
PS_activation(lev); |
} |
static int PS_guest_create(LEVEL l, PID p, TASK_MODEL *m) |
{ kern_raise(XINVALID_GUEST,exec_shadow); return 0; } |
static void PS_guest_detach(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void PS_guest_dispatch(LEVEL l, PID p, int nostop) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void PS_guest_epilogue(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void PS_guest_activate(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void PS_guest_insert(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void PS_guest_extract(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void PS_guest_endcycle(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void PS_guest_end(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void PS_guest_sleep(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
/* Registration functions */ |
590,7 → 450,7 |
{ |
PS_level_des *lev = (PS_level_des *)(level_table[(LEVEL)l]); |
ll_gettime(TIME_EXACT,&lev->lastdline); |
kern_gettime(&lev->lastdline); |
ADDUSEC2TIMESPEC(lev->period, &lev->lastdline); |
kern_event_post(&lev->lastdline, PS_deadline_timer, l); |
600,7 → 460,7 |
/*+ Registration function: |
int flags the init flags ... see PS.h +*/ |
void PS_register_level(int flags, LEVEL master, int Cs, int per) |
LEVEL PS_register_level(int flags, LEVEL master, int Cs, int per) |
{ |
LEVEL l; /* the level that we register */ |
PS_level_des *lev; /* for readableness only */ |
609,62 → 469,33 |
printk("PS_register_level\n"); |
/* request an entry in the level_table */ |
l = level_alloc_descriptor(); |
l = level_alloc_descriptor(sizeof(PS_level_des)); |
printk(" alloco descrittore %d %d\n",l,(int)sizeof(PS_level_des)); |
lev = (PS_level_des *)level_table[l]; |
/* alloc the space needed for the PS_level_des */ |
lev = (PS_level_des *)kern_alloc(sizeof(PS_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, PS_LEVELNAME, MAX_LEVELNAME); |
lev->l.level_code = PS_LEVEL_CODE; |
lev->l.level_version = PS_LEVEL_VERSION; |
lev->l.level_accept_task_model = PS_level_accept_task_model; |
lev->l.level_accept_guest_model = PS_level_accept_guest_model; |
lev->l.level_status = PS_level_status; |
if (flags & PS_ENABLE_BACKGROUND) |
lev->l.level_scheduler = PS_level_schedulerbackground; |
else |
lev->l.level_scheduler = PS_level_scheduler; |
lev->l.public_scheduler = PS_public_schedulerbackground; |
if (flags & PS_ENABLE_GUARANTEE_EDF) |
lev->l.level_guarantee = PS_level_guaranteeEDF; |
lev->l.public_guarantee = PS_public_guaranteeEDF; |
else if (flags & PS_ENABLE_GUARANTEE_RM) |
lev->l.level_guarantee = PS_level_guaranteeRM; |
lev->l.public_guarantee = PS_public_guaranteeRM; |
else |
lev->l.level_guarantee = NULL; |
lev->l.public_guarantee = NULL; |
lev->l.task_create = PS_task_create; |
lev->l.task_detach = PS_task_detach; |
lev->l.task_eligible = PS_task_eligible; |
lev->l.task_dispatch = PS_task_dispatch; |
lev->l.task_epilogue = PS_task_epilogue; |
lev->l.task_activate = PS_task_activate; |
lev->l.task_insert = PS_task_insert; |
lev->l.task_extract = PS_task_extract; |
lev->l.task_endcycle = PS_task_endcycle; |
lev->l.task_end = PS_task_end; |
lev->l.task_sleep = PS_task_sleep; |
lev->l.public_create = PS_public_create; |
lev->l.public_end = PS_public_end; |
lev->l.public_dispatch = PS_public_dispatch; |
lev->l.public_epilogue = PS_public_epilogue; |
lev->l.public_activate = PS_public_activate; |
lev->l.public_unblock = PS_public_unblock; |
lev->l.public_block = PS_public_block; |
lev->l.public_message = PS_public_message; |
lev->l.guest_create = PS_guest_create; |
lev->l.guest_detach = PS_guest_detach; |
lev->l.guest_dispatch = PS_guest_dispatch; |
lev->l.guest_epilogue = PS_guest_epilogue; |
lev->l.guest_activate = PS_guest_activate; |
lev->l.guest_insert = PS_guest_insert; |
lev->l.guest_extract = PS_guest_extract; |
lev->l.guest_endcycle = PS_guest_endcycle; |
lev->l.guest_end = PS_guest_end; |
lev->l.guest_sleep = PS_guest_sleep; |
/* fill the PS descriptor part */ |
for (i=0; i<MAX_PROC; i++) |
685,15 → 516,14 |
lev->flags = flags & 0x07; |
sys_atrunlevel(PS_dline_install,(void *) l, RUNLEVEL_INIT); |
return l; |
} |
bandwidth_t PS_usedbandwidth(LEVEL l) |
{ |
PS_level_des *lev = (PS_level_des *)(level_table[l]); |
if (lev->l.level_code == PS_LEVEL_CODE && |
lev->l.level_version == PS_LEVEL_VERSION) |
return lev->U; |
else |
return 0; |
return lev->U; |
} |
/shark/trunk/kernel/modules/rr.c |
---|
20,11 → 20,11 |
/** |
------------ |
CVS : $Id: rr.c,v 1.3 2002-11-11 08:32:06 pj Exp $ |
CVS : $Id: rr.c,v 1.4 2003-01-07 17:07:50 pj Exp $ |
File: $File$ |
Revision: $Revision: 1.3 $ |
Last update: $Date: 2002-11-11 08:32:06 $ |
Revision: $Revision: 1.4 $ |
Last update: $Date: 2003-01-07 17:07:50 $ |
------------ |
This file contains the scheduling module RR (Round Robin) |
60,7 → 60,12 |
#include <kernel/descr.h> |
#include <kernel/var.h> |
#include <kernel/func.h> |
#include <kernel/trace.h> |
//#define RRDEBUG |
#define rr_printf kern_printf |
/*+ Status used in the level +*/ |
#define RR_READY MODULE_STATUS_BASE |
76,67 → 81,29 |
the main task +*/ |
} RR_level_des; |
static char *RR_status_to_a(WORD status) |
{ |
if (status < MODULE_STATUS_BASE) |
return status_to_a(status); |
switch (status) { |
case RR_READY: return "RR_Ready"; |
default : return "RR_Unknown"; |
} |
} |
static int RR_level_accept_task_model(LEVEL l, TASK_MODEL *m) |
{ |
if (m->pclass == NRT_PCLASS || m->pclass == (NRT_PCLASS | l)) |
return 0; |
else |
return -1; |
} |
static int RR_level_accept_guest_model(LEVEL l, TASK_MODEL *m) |
{ |
return -1; |
} |
static void RR_level_status(LEVEL l) |
{ |
RR_level_des *lev = (RR_level_des *)(level_table[l]); |
PID p = iq_query_first(&lev->ready); |
kern_printf("Slice: %d \n", lev->slice); |
while (p != NIL) { |
kern_printf("Pid: %d\t Name: %20s Status: %s\n",p,proc_table[p].name, |
RR_status_to_a(proc_table[p].status)); |
p = iq_query_next(p,&lev->ready); |
} |
for (p=0; p<MAX_PROC; p++) |
if (proc_table[p].task_level == l && proc_table[p].status != RR_READY |
&& proc_table[p].status != FREE ) |
kern_printf("Pid: %d\t Name: %20s Status: %s\n",p,proc_table[p].name, |
RR_status_to_a(proc_table[p].status)); |
} |
/* This is not efficient but very fair :-) |
The need of all this stuff is because if a task execute a long time |
due to (shadow!) priority inheritance, then the task shall go to the |
tail of the queue many times... */ |
static PID RR_level_scheduler(LEVEL l) |
static PID RR_public_scheduler(LEVEL l) |
{ |
RR_level_des *lev = (RR_level_des *)(level_table[l]); |
PID p; |
#ifdef RRDEBUG |
rr_printf("(RRs",p); |
#endif |
for (;;) { |
p = iq_query_first(&lev->ready); |
if (p == -1) |
if (p == -1) { |
#ifdef RRDEBUG |
rr_printf(" %d)",p); |
#endif |
return p; |
} |
if (proc_table[p].avail_time <= 0) { |
proc_table[p].avail_time += proc_table[p].wcet; |
143,25 → 110,28 |
iq_extract(p,&lev->ready); |
iq_insertlast(p,&lev->ready); |
} |
else |
else { |
#ifdef RRDEBUG |
rr_printf(" %d)",p); |
#endif |
return p; |
} |
} |
} |
static int RR_level_guarantee(LEVEL l, bandwidth_t *freebandwidth) |
static int RR_public_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
/* the RR level always guarantee... the function is defined because |
there can be an aperiodic server at a level with less priority than |
the RR that need guarantee (e.g., a TBS server) */ |
return 1; |
} |
RR_level_des *lev = (RR_level_des *)(level_table[l]); |
NRT_TASK_MODEL *nrt; |
#ifdef RRDEBUG |
rr_printf("(create %d!!!!)",p); |
#endif |
static int RR_task_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
RR_level_des *lev = (RR_level_des *)(level_table[l]); |
NRT_TASK_MODEL *nrt = (NRT_TASK_MODEL *)m; |
if (m->pclass != NRT_PCLASS) return -1; |
if (m->level != 0 && m->level != l) return -1; |
nrt = (NRT_TASK_MODEL *)m; |
/* the task state is set at SLEEP by the general task_create |
the only thing to set remains the capacity stuffs that are set |
to the values passed in the model... */ |
179,23 → 149,14 |
} |
proc_table[p].control |= CONTROL_CAP; |
#ifdef RRDEBUG |
rr_printf("(c%d av%d w%d )",p,proc_table[p].avail_time,proc_table[p].wcet); |
#endif |
return 0; /* OK */ |
} |
static void RR_task_detach(LEVEL l, PID p) |
static void RR_public_dispatch(LEVEL l, PID p, int nostop) |
{ |
/* the RR level doesn't introduce any new field in the TASK_MODEL |
so, all detach stuffs are done by the task_create |
The task state is set at FREE by the general task_create */ |
} |
static int RR_task_eligible(LEVEL l, PID p) |
{ |
return 0; /* if the task p is chosen, it is always eligible */ |
} |
static void RR_task_dispatch(LEVEL l, PID p, int nostop) |
{ |
RR_level_des *lev = (RR_level_des *)(level_table[l]); |
/* the task state is set EXE by the scheduler() |
202,9 → 163,13 |
we extract the task from the ready queue |
NB: we can't assume that p is the first task in the queue!!! */ |
iq_extract(p, &lev->ready); |
#ifdef RRDEBUG |
rr_printf("(dis%d)",p); |
#endif |
} |
static void RR_task_epilogue(LEVEL l, PID p) |
static void RR_public_epilogue(LEVEL l, PID p) |
{ |
RR_level_des *lev = (RR_level_des *)(level_table[l]); |
219,9 → 184,13 |
iq_insertfirst(p,&lev->ready); |
proc_table[p].status = RR_READY; |
#ifdef RRDEBUG |
rr_printf("(epi%d)",p); |
#endif |
} |
static void RR_task_activate(LEVEL l, PID p) |
static void RR_public_activate(LEVEL l, PID p) |
{ |
RR_level_des *lev = (RR_level_des *)(level_table[l]); |
230,26 → 199,33 |
if (proc_table[p].status != SLEEP) |
return; |
ll_gettime(TIME_EXACT, &proc_table[p].request_time); |
/* Insert task in the correct position */ |
proc_table[p].status = RR_READY; |
iq_insertlast(p,&lev->ready); |
#ifdef RRDEBUG |
rr_printf("(act%d)",p); |
#endif |
} |
static void RR_task_insert(LEVEL l, PID p) |
static void RR_public_unblock(LEVEL l, PID p) |
{ |
RR_level_des *lev = (RR_level_des *)(level_table[l]); |
/* Similar to RR_task_activate, but we don't check in what state |
the task is and we don't set the request_time */ |
/* Similar to RR_task_activate, |
but we don't check in what state the task is */ |
/* Insert task in the correct position */ |
proc_table[p].status = RR_READY; |
iq_insertlast(p,&lev->ready); |
#ifdef RRDEBUG |
rr_printf("(ubl%d)",p); |
#endif |
} |
static void RR_task_extract(LEVEL l, PID p) |
static void RR_public_block(LEVEL l, PID p) |
{ |
/* Extract the running task from the level |
. we have already extract it from the ready queue at the dispatch time. |
259,64 → 235,36 |
So, we do nothing!!! |
*/ |
#ifdef RRDEBUG |
rr_printf("(bl%d)",p); |
#endif |
} |
static void RR_task_endcycle(LEVEL l, PID p) |
static int RR_public_message(LEVEL l, PID p, void *m) |
{ |
// RR_level_des *lev = (RR_level_des *)(level_table[l]); |
proc_table[p].status = SLEEP; |
/* this function is equal to the RR_task_extract, except that |
the task fall asleep... */ |
proc_table[p].status = SLEEP; |
jet_update_endcycle(); /* Update the Jet data... */ |
trc_logevent(TRC_ENDCYCLE,&exec_shadow); /* tracer stuff */ |
#ifdef RRDEBUG |
rr_printf("(msg%d)",p); |
#endif |
return 0; |
} |
static void RR_task_end(LEVEL l, PID p) |
static void RR_public_end(LEVEL l, PID p) |
{ |
// RR_level_des *lev = (RR_level_des *)(level_table[l]); |
/* we insert the task in the free queue */ |
proc_table[p].status = FREE; |
iq_insertlast(p,&freedesc); |
} |
static void RR_task_sleep(LEVEL l, PID p) |
{ |
proc_table[p].status = SLEEP; |
#ifdef RRDEBUG |
rr_printf("(end%d)",p); |
#endif |
} |
static int RR_guest_create(LEVEL l, PID p, TASK_MODEL *m) |
{ kern_raise(XINVALID_GUEST,exec_shadow); return 0; } |
static void RR_guest_detach(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RR_guest_dispatch(LEVEL l, PID p, int nostop) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RR_guest_epilogue(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RR_guest_activate(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RR_guest_insert(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RR_guest_extract(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RR_guest_endcycle(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RR_guest_end(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void RR_guest_sleep(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
/* Registration functions */ |
/*+ This init function install the "main" task +*/ |
342,9 → 290,13 |
p = task_create("Main", __init__, (TASK_MODEL *)&m, NULL); |
if (p == NIL) |
kern_printf("\nPanic!!! can't create main task... errno =%d\n",errno); |
printk(KERN_EMERG "Panic!!! can't create main task... errno =%d\n",errno); |
RR_task_activate(lev,p); |
RR_public_activate(lev,p); |
#ifdef RRDEBUG |
rr_printf("(main created %d)",p); |
#endif |
} |
352,7 → 304,7 |
TIME slice the slice for the Round Robin queue |
int createmain 1 if the level creates the main task 0 otherwise |
struct multiboot_info *mb used if createmain specified +*/ |
void RR_register_level(TIME slice, |
LEVEL RR_register_level(TIME slice, |
int createmain, |
struct multiboot_info *mb) |
{ |
362,50 → 314,23 |
printk("RR_register_level\n"); |
/* request an entry in the level_table */ |
l = level_alloc_descriptor(); |
l = level_alloc_descriptor(sizeof(RR_level_des)); |
/* alloc the space needed for the RR_level_des */ |
lev = (RR_level_des *)kern_alloc(sizeof(RR_level_des)); |
lev = (RR_level_des *)level_table[l]; |
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, RR_LEVELNAME, MAX_LEVELNAME); |
lev->l.level_code = RR_LEVEL_CODE; |
lev->l.level_version = RR_LEVEL_VERSION; |
lev->l.public_scheduler = RR_public_scheduler; |
lev->l.public_create = RR_public_create; |
lev->l.public_end = RR_public_end; |
lev->l.public_dispatch = RR_public_dispatch; |
lev->l.public_epilogue = RR_public_epilogue; |
lev->l.public_activate = RR_public_activate; |
lev->l.public_unblock = RR_public_unblock; |
lev->l.public_block = RR_public_block; |
lev->l.public_message = RR_public_message; |
lev->l.level_accept_task_model = RR_level_accept_task_model; |
lev->l.level_accept_guest_model = RR_level_accept_guest_model; |
lev->l.level_status = RR_level_status; |
lev->l.level_scheduler = RR_level_scheduler; |
lev->l.level_guarantee = RR_level_guarantee; |
lev->l.task_create = RR_task_create; |
lev->l.task_detach = RR_task_detach; |
lev->l.task_eligible = RR_task_eligible; |
lev->l.task_dispatch = RR_task_dispatch; |
lev->l.task_epilogue = RR_task_epilogue; |
lev->l.task_activate = RR_task_activate; |
lev->l.task_insert = RR_task_insert; |
lev->l.task_extract = RR_task_extract; |
lev->l.task_endcycle = RR_task_endcycle; |
lev->l.task_end = RR_task_end; |
lev->l.task_sleep = RR_task_sleep; |
lev->l.guest_create = RR_guest_create; |
lev->l.guest_detach = RR_guest_detach; |
lev->l.guest_dispatch = RR_guest_dispatch; |
lev->l.guest_epilogue = RR_guest_epilogue; |
lev->l.guest_activate = RR_guest_activate; |
lev->l.guest_insert = RR_guest_insert; |
lev->l.guest_extract = RR_guest_extract; |
lev->l.guest_endcycle = RR_guest_endcycle; |
lev->l.guest_end = RR_guest_end; |
lev->l.guest_sleep = RR_guest_sleep; |
/* fill the RR descriptor part */ |
iq_init(&lev->ready, &freedesc, 0); |
417,6 → 342,6 |
if (createmain) |
sys_atrunlevel(RR_call_main,(void *) l, RUNLEVEL_INIT); |
return l; |
} |
/shark/trunk/kernel/modules/sem.c |
---|
20,11 → 20,11 |
/** |
------------ |
CVS : $Id: sem.c,v 1.2 2002-11-11 08:32:07 pj Exp $ |
CVS : $Id: sem.c,v 1.3 2003-01-07 17:07:51 pj Exp $ |
File: $File$ |
Revision: $Revision: 1.2 $ |
Last update: $Date: 2002-11-11 08:32:07 $ |
Revision: $Revision: 1.3 $ |
Last update: $Date: 2003-01-07 17:07:51 $ |
------------ |
This file contains the Hartik 3.3.1 Semaphore functions |
115,7 → 115,7 |
iq_extract(i,&sem_table[ sp_table[i].sem ].blocked); |
l = proc_table[i].task_level; |
level_table[l]->task_insert(l,i); |
level_table[l]->public_unblock(l,i); |
return 1; |
} |
350,25 → 350,14 |
if (s1->blocked.first != NIL || s1->count == 0) { |
/* We must block exec task */ |
LEVEL l; /* for readableness only */ |
TIME tx; /* a dummy TIME for timespec operations */ |
struct timespec ty; /* a dummy timespec for timespec operations */ |
/* tracer stuff */ |
trc_logevent(TRC_SEM_WAIT,s); |
/* SAME AS SCHEDULER... manage the capacity event and the load_info */ |
ll_gettime(TIME_EXACT, &schedule_time); |
SUBTIMESPEC(&schedule_time, &cap_lasttime, &ty); |
tx = TIMESPEC2USEC(&ty); |
proc_table[exec_shadow].avail_time -= tx; |
jet_update_slice(tx); |
if (cap_timer != NIL) { |
event_delete(cap_timer); |
cap_timer = NIL; |
} |
kern_epilogue_macro(); |
l = proc_table[exec_shadow].task_level; |
level_table[l]->task_extract(l,exec_shadow); |
level_table[l]->public_block(l,exec_shadow); |
/* we insert the task in the semaphore queue */ |
proc_table[exec_shadow].status = WAIT_SEM; |
476,25 → 465,14 |
if (s1->blocked.first != NIL || s1->count < n) { |
/* We must block exec task */ |
LEVEL l; /* for readableness only */ |
TIME tx; /* a dummy TIME for timespec operations */ |
struct timespec ty; /* a dummy timespec for timespec operations */ |
/* tracer */ |
trc_logevent(TRC_SEM_WAIT,s); |
/* SAME AS SCHEDULER... manage the capacity event and the load_info */ |
ll_gettime(TIME_EXACT, &schedule_time); |
SUBTIMESPEC(&schedule_time, &cap_lasttime, &ty); |
tx = TIMESPEC2USEC(&ty); |
proc_table[exec_shadow].avail_time -= tx; |
jet_update_slice(tx); |
if (cap_timer != NIL) { |
event_delete(cap_timer); |
cap_timer = NIL; |
} |
kern_epilogue_macro(); |
l = proc_table[exec_shadow].task_level; |
level_table[l]->task_extract(l,exec_shadow); |
level_table[l]->public_block(l,exec_shadow); |
/* we insert the task in the semaphore queue */ |
proc_table[exec_shadow].status = WAIT_SEM; |
557,7 → 535,7 |
iq_extract(p,&s1->blocked); |
l = proc_table[p].task_level; |
level_table[l]->task_insert(l,p); |
level_table[l]->public_unblock(l,p); |
/* only a task can be awaken */ |
/* Preempt if necessary */ |
event_need_reschedule(); |
582,7 → 560,7 |
iq_extract(p,&s1->blocked); |
l = proc_table[p].task_level; |
level_table[l]->task_insert(l,p); |
level_table[l]->public_unblock(l,p); |
/* only a task can be awaken */ |
/* Preempt if necessary */ |
scheduler(); |
630,7 → 608,7 |
iq_extract(p,&s1->blocked); |
l = proc_table[p].task_level; |
level_table[l]->task_insert(l,p); |
level_table[l]->public_unblock(l,p); |
/* Next task to wake */ |
p = s1->blocked.first; |
660,7 → 638,7 |
iq_extract(p,&s1->blocked); |
l = proc_table[p].task_level; |
level_table[l]->task_insert(l,p); |
level_table[l]->public_unblock(l,p); |
/* Next task to wake */ |
p = s1->blocked.first; |
/shark/trunk/kernel/modules/ss.c |
---|
20,11 → 20,11 |
/** |
------------ |
CVS : $Id: ss.c,v 1.3 2002-11-11 08:32:07 pj Exp $ |
CVS : $Id: ss.c,v 1.4 2003-01-07 17:07:51 pj Exp $ |
File: $File$ |
Revision: $Revision: 1.3 $ |
Last update: $Date: 2002-11-11 08:32:07 $ |
Revision: $Revision: 1.4 $ |
Last update: $Date: 2003-01-07 17:07:51 $ |
------------ |
This file contains the aperiodic Sporadic Server (SS). |
125,6 → 125,7 |
#include <kernel/descr.h> |
#include <kernel/var.h> |
#include <kernel/func.h> |
#include <kernel/trace.h> |
/* For debugging purpose */ |
//#define DEBUG 1 |
174,7 → 175,7 |
} SS_level_des; |
/*+ function prototypes +*/ |
void SS_level_status(LEVEL l); |
void SS_internal_status(LEVEL l); |
static void SS_replenish_timer(void *arg); |
/*-------------------------------------------------------------------*/ |
313,7 → 314,7 |
if(ssq_inslast(l, lev->replenish_amount) == NIL) { |
kern_printf("SS: no more space to post replenishment\n"); |
kern_printf("You should recompile setting higher SS_MAX_REPLENISH into include/modules/ss.h\n"); |
SS_level_status(l); |
SS_internal_status(l); |
kern_raise(XINVALID_SS_REPLENISH,exec_shadow); |
#ifdef DEBUG |
sys_abort(-1); |
324,7 → 325,7 |
} |
else { |
kern_printf("SS not active when posting R.A.\n"); |
SS_level_status(l); |
SS_internal_status(l); |
kern_raise(XINVALID_SS_REPLENISH,exec_shadow); |
#ifdef DEBUG |
sys_abort(-1); |
368,8 → 369,7 |
job_task_default_model(j,lev->lastdline); |
job_task_def_period(j,lev->period); |
level_table[m]->guest_create(m,p,(TASK_MODEL *)&j); |
level_table[m]->guest_activate(m,p); |
level_table[m]->private_insert(m,p,(TASK_MODEL *)&j); |
#ifdef DEBUG |
kern_printf("PID:%p lastdl:%d.%d ",p,lev->lastdline.tv_sec,lev->lastdline.tv_nsec); |
400,7 → 400,7 |
if(ssq_inslast(l, tx+lev->replenish_amount) == NIL) { |
kern_printf("SS: no more space to post replenishment\n"); |
kern_printf(" You should recompile setting higher SS_MAX_REPLENISH into include/modules/ss.h\n"); |
SS_level_status(l); |
SS_internal_status(l); |
kern_raise(XINVALID_SS_REPLENISH,exec_shadow); |
#ifdef DEBUG |
sys_abort(-1); |
456,7 → 456,7 |
else { |
/* replenish queue is empty */ |
kern_printf("Replenish Timer fires but no Replenish Amount defined\n"); |
SS_level_status(l); |
SS_internal_status(l); |
kern_raise(XINVALID_SS_REPLENISH,exec_shadow); |
#ifdef DEBUG |
sys_abort(-1); |
471,7 → 471,7 |
if (lev->server_active == SS_SERVER_NOTACTIVE) { |
lev->server_active = SS_SERVER_ACTIVE; |
/* set replenish time */ |
ll_gettime(TIME_EXACT, &ty); |
kern_gettime(&ty); |
ADDUSEC2TIMESPEC(lev->period, &ty); |
TIMESPEC_ASSIGN(&lev->lastdline, &ty); |
#ifdef DEBUG |
488,7 → 488,7 |
static char *SS_status_to_a(WORD status) |
{ |
if (status < MODULE_STATUS_BASE) |
return status_to_a(status); |
return "Unavailable"; //status_to_a(status); |
switch (status) { |
case SS_WAIT : return "SS_Wait"; |
501,40 → 501,8 |
/*** Level functions ***/ |
static int SS_level_accept_task_model(LEVEL l, TASK_MODEL *m) |
void SS_internal_status(LEVEL l) |
{ |
#ifdef DEBUG |
kern_printf("SS_levacctm cl=%d ",m->pclass); |
#endif |
if (m->pclass == SOFT_PCLASS || m->pclass == (SOFT_PCLASS | l) ) { |
SOFT_TASK_MODEL *s = (SOFT_TASK_MODEL *)m; |
if (s->periodicity == APERIODIC) { |
#ifdef DEBUG |
kern_printf("AcceptApe "); |
#endif |
return 0; |
} |
#ifdef DEBUG |
kern_printf("NAcceptApe "); |
#endif |
} |
#ifdef DEBUG |
kern_printf("NAccept "); |
#endif |
return -1; |
} |
static int SS_level_accept_guest_model(LEVEL l, TASK_MODEL *m) |
{ |
/* SS doesn't handles guest tasks */ |
return -1; |
} |
void SS_level_status(LEVEL l) |
{ |
SS_level_des *lev = (SS_level_des *)(level_table[l]); |
PID p = iq_query_first(&lev->wait); |
568,19 → 536,8 |
} |
} |
static PID SS_level_scheduler(LEVEL l) |
static PID SS_public_schedulerbackground(LEVEL l) |
{ |
#ifdef DEBUG |
kern_printf("SS_levsch "); |
#endif |
/* the SS don't schedule anything... |
it's an RM level or similar that do it! */ |
return NIL; |
} |
static PID SS_level_schedulerbackground(LEVEL l) |
{ |
/* the SS catch the background time to exec aperiodic activities */ |
SS_level_des *lev = (SS_level_des *)(level_table[l]); |
597,7 → 554,7 |
} |
/* The on-line guarantee is enabled only if the appropriate flag is set... */ |
static int SS_level_guaranteeEDF(LEVEL l, bandwidth_t *freebandwidth) |
static int SS_public_guaranteeEDF(LEVEL l, bandwidth_t *freebandwidth) |
{ |
SS_level_des *lev = (SS_level_des *)(level_table[l]); |
613,7 → 570,7 |
return 0; |
} |
static int SS_level_guaranteeRM(LEVEL l, bandwidth_t *freebandwidth) |
static int SS_public_guaranteeRM(LEVEL l, bandwidth_t *freebandwidth) |
{ |
SS_level_des *lev = (SS_level_des *)(level_table[l]); |
634,17 → 591,22 |
/*** Task functions ***/ |
static int SS_task_create(LEVEL l, PID p, TASK_MODEL *m) |
static int SS_public_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
SS_level_des *lev = (SS_level_des *)(level_table[l]); |
SOFT_TASK_MODEL *s = (SOFT_TASK_MODEL *)m; /* if the SS_task_create is |
called, the pclass must |
be a valid pclass. */ |
SOFT_TASK_MODEL *s; |
#ifdef DEBUG |
kern_printf("SS_taskcre "); |
#endif |
if (m->pclass != SOFT_PCLASS) return -1; |
if (m->level != 0 && m->level != l) return -1; |
s = (SOFT_TASK_MODEL *)m; |
if (s->periodicity != APERIODIC) return -1; |
s = (SOFT_TASK_MODEL *)m; |
if (s->arrivals == SAVE_ARRIVALS) |
lev->nact[p] = 0; |
else |
653,19 → 615,8 |
return 0; /* OK, also if the task cannot be guaranteed */ |
} |
static void SS_task_detach(LEVEL l, PID p) |
static void SS_public_dispatch(LEVEL l, PID p, int nostop) |
{ |
/* No cleanups to do here. |
SS level doesn't introduce any dynamic allocated field. */ |
} |
static int SS_task_eligible(LEVEL l, PID p) |
{ |
return 0; /* If the task p is chosen, it is always eligible */ |
} |
static void SS_task_dispatch(LEVEL l, PID p, int nostop) |
{ |
SS_level_des *lev = (SS_level_des *)(level_table[l]); |
struct timespec ty; |
706,7 → 657,7 |
if (nostop) kern_printf("(gd status=%d)",proc_table[p].status); |
#endif |
level_table[lev->scheduling_level]-> |
guest_dispatch(lev->scheduling_level,p,nostop); |
private_dispatch(lev->scheduling_level,p,nostop); |
} |
/* set capacity timer */ |
723,7 → 674,7 |
} |
} |
static void SS_task_epilogue(LEVEL l, PID p) { |
static void SS_public_epilogue(LEVEL l, PID p) { |
SS_level_des *lev = (SS_level_des *)(level_table[l]); |
struct timespec ty; |
765,7 → 716,7 |
if(ssq_inslast(l, lev->replenish_amount) == NIL) { |
kern_printf("SS: no more space to post replenishment\n"); |
kern_printf("You should recompile setting higher SS_MAX_REPLENISH into include/modules/ss.h\n"); |
SS_level_status(l); |
SS_internal_status(l); |
kern_raise(XINVALID_SS_REPLENISH,exec_shadow); |
#ifdef DEBUG |
sys_abort(-1); |
777,7 → 728,7 |
} |
if (lev->activated == p) |
level_table[lev->scheduling_level]->guest_end(lev->scheduling_level,p); |
level_table[lev->scheduling_level]->private_extract(lev->scheduling_level,p); |
iq_insertfirst(p, &lev->wait); |
proc_table[p].status = SS_WAIT; |
786,11 → 737,11 |
else { |
/* The task has been preempted. |
It returns into the ready queue or to the |
wait queue by calling the guest_epilogue... */ |
wait queue by calling the private_epilogue... */ |
if (lev->activated == p) { /* goes into ready queue */ |
level_table[ lev->scheduling_level ]-> |
guest_epilogue(lev->scheduling_level,p); |
private_epilogue(lev->scheduling_level,p); |
} |
else { /* goes into wait queue */ |
iq_insertfirst(p, &lev->wait); |
799,7 → 750,7 |
} |
} |
static void SS_task_activate(LEVEL l, PID p) |
static void SS_public_activate(LEVEL l, PID p) |
{ |
SS_level_des *lev = (SS_level_des *)(level_table[l]); |
struct timespec ty; |
812,8 → 763,6 |
if (lev->nact[p] != -1) lev->nact[p]++; |
} |
else if (proc_table[p].status == SLEEP) { |
ll_gettime(TIME_EXACT, &proc_table[p].request_time); |
// kern_printf("-%d.%d- ",proc_table[p].request_time.tv_sec,proc_table[p].request_time.tv_nsec); |
if (lev->activated == NIL && lev->availCs > 0) { |
if(!BACKGROUND_ON) { |
/* if server is active, replenish time already set */ |
820,7 → 769,7 |
if (lev->server_active == SS_SERVER_NOTACTIVE) { |
lev->server_active = SS_SERVER_ACTIVE; |
/* set replenish time */ |
TIMESPEC_ASSIGN(&ty, &proc_table[p].request_time); |
kern_gettime(&ty); |
ADDUSEC2TIMESPEC(lev->period, &ty); |
TIMESPEC_ASSIGN(&lev->lastdline, &ty); |
#ifdef DEBUG |
847,7 → 796,7 |
} |
} |
static void SS_task_insert(LEVEL l, PID p) |
static void SS_public_unblock(LEVEL l, PID p) |
{ |
SS_level_des *lev = (SS_level_des *)(level_table[l]); |
864,7 → 813,7 |
proc_table[p].status = SS_WAIT; |
} |
static void SS_task_extract(LEVEL l, PID p) |
static void SS_public_block(LEVEL l, PID p) |
{ |
SS_level_des *lev = (SS_level_des *)(level_table[l]); |
883,10 → 832,10 |
lev->flags |= SS_BACKGROUND_BLOCK; |
if (lev->activated == p) |
level_table[lev->scheduling_level]->guest_end(lev->scheduling_level,p); |
level_table[lev->scheduling_level]->private_extract(lev->scheduling_level,p); |
} |
static void SS_task_endcycle(LEVEL l, PID p) |
static int SS_public_message(LEVEL l, PID p, void *m) |
{ |
SS_level_des *lev = (SS_level_des *)(level_table[l]); |
struct timespec ty; |
910,7 → 859,7 |
} |
if (lev->activated == p) |
level_table[lev->scheduling_level]->guest_end(lev->scheduling_level,p); |
level_table[lev->scheduling_level]->private_extract(lev->scheduling_level,p); |
else |
iq_extract(p, &lev->wait); |
933,9 → 882,14 |
SS_set_ra(l); |
} |
} |
jet_update_endcycle(); /* Update the Jet data... */ |
trc_logevent(TRC_ENDCYCLE,&exec_shadow); /* tracer stuff */ |
return 0; |
} |
static void SS_task_end(LEVEL l, PID p) |
static void SS_public_end(LEVEL l, PID p) |
{ |
SS_level_des *lev = (SS_level_des *)(level_table[l]); |
struct timespec ty; |
959,7 → 913,7 |
} |
if (lev->activated == p) |
level_table[lev->scheduling_level]->guest_end(lev->scheduling_level,p); |
level_table[lev->scheduling_level]->private_extract(lev->scheduling_level,p); |
proc_table[p].status = FREE; |
iq_insertfirst(p,&freedesc); |
976,97 → 930,14 |
} |
} |
static void SS_task_sleep(LEVEL l, PID p) |
{ |
SS_level_des *lev = (SS_level_des *)(level_table[l]); |
struct timespec ty; |
int tx; |
#ifdef DEBUG |
kern_printf("SS_tasksle "); |
#endif |
/* update the server capacity */ |
if (BACKGROUND_ON) |
lev->flags &= ~SS_BACKGROUND; |
else { |
SUBTIMESPEC(&schedule_time, &cap_lasttime, &ty); |
tx = TIMESPEC2USEC(&ty); |
lev->availCs -= tx; |
lev->replenish_amount += tx; |
#ifdef DEBUG |
kern_printf("PID:%d RA=%d ",p,lev->replenish_amount); |
#endif |
} |
lev->nact[p] = 0; |
if (lev->activated == p) |
level_table[lev->scheduling_level]->guest_end(lev->scheduling_level,p); |
else |
iq_extract(p, &lev->wait); |
proc_table[p].status = SLEEP; |
lev->activated = iq_getfirst(&lev->wait); |
if (lev->activated != NIL) { |
SS_activation(lev); |
} |
else { |
if(!(BACKGROUND_ON)){ |
/* No more task to schedule; set replenish amount */ |
SS_set_ra(l); |
} |
} |
} |
/*-------------------------------------------------------------------*/ |
/*** Guest functions ***/ |
/* SS doesn't handles guest tasks */ |
static int SS_guest_create(LEVEL l, PID p, TASK_MODEL *m) |
{ kern_raise(XINVALID_GUEST,exec_shadow); return 0; } |
static void SS_guest_detach(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void SS_guest_dispatch(LEVEL l, PID p, int nostop) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void SS_guest_epilogue(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void SS_guest_activate(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void SS_guest_insert(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void SS_guest_extract(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void SS_guest_endcycle(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void SS_guest_end(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void SS_guest_sleep(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
/*-------------------------------------------------------------------*/ |
/*** Registration functions ***/ |
/*+ Registration function: |
int flags the init flags ... see SS.h +*/ |
void SS_register_level(int flags, LEVEL master, int Cs, int per) |
LEVEL SS_register_level(int flags, LEVEL master, int Cs, int per) |
{ |
LEVEL l; /* the level that we register */ |
SS_level_des *lev; /* for readableness only */ |
1073,61 → 944,33 |
PID i; /* a counter */ |
/* request an entry in the level_table */ |
l = level_alloc_descriptor(); |
#ifdef DEBUG |
kern_printf("Alloc des %d ",l); |
#endif |
l = level_alloc_descriptor(sizeof(SS_level_des)); |
/* alloc the space needed for the SS_level_des */ |
lev = (SS_level_des *)kern_alloc(sizeof(SS_level_des)); |
lev = (SS_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, SS_LEVELNAME, MAX_LEVELNAME); |
lev->l.level_code = SS_LEVEL_CODE; |
lev->l.level_version = SS_LEVEL_VERSION; |
lev->l.level_accept_task_model = SS_level_accept_task_model; |
lev->l.level_accept_guest_model = SS_level_accept_guest_model; |
lev->l.level_status = SS_level_status; |
if (flags & SS_ENABLE_BACKGROUND) |
lev->l.level_scheduler = SS_level_schedulerbackground; |
else |
lev->l.level_scheduler = SS_level_scheduler; |
lev->l.public_scheduler = SS_public_schedulerbackground; |
if (flags & SS_ENABLE_GUARANTEE_EDF) |
lev->l.level_guarantee = SS_level_guaranteeEDF; |
lev->l.public_guarantee = SS_public_guaranteeEDF; |
else if (flags & SS_ENABLE_GUARANTEE_RM) |
lev->l.level_guarantee = SS_level_guaranteeRM; |
lev->l.public_guarantee = SS_public_guaranteeRM; |
else |
lev->l.level_guarantee = NULL; |
lev->l.public_guarantee = NULL; |
lev->l.task_create = SS_task_create; |
lev->l.task_detach = SS_task_detach; |
lev->l.task_eligible = SS_task_eligible; |
lev->l.task_dispatch = SS_task_dispatch; |
lev->l.task_epilogue = SS_task_epilogue; |
lev->l.task_activate = SS_task_activate; |
lev->l.task_insert = SS_task_insert; |
lev->l.task_extract = SS_task_extract; |
lev->l.task_endcycle = SS_task_endcycle; |
lev->l.task_end = SS_task_end; |
lev->l.task_sleep = SS_task_sleep; |
lev->l.public_create = SS_public_create; |
lev->l.public_end = SS_public_end; |
lev->l.public_dispatch = SS_public_dispatch; |
lev->l.public_epilogue = SS_public_epilogue; |
lev->l.public_activate = SS_public_activate; |
lev->l.public_unblock = SS_public_unblock; |
lev->l.public_block = SS_public_block; |
lev->l.public_message = SS_public_message; |
lev->l.guest_create = SS_guest_create; |
lev->l.guest_detach = SS_guest_detach; |
lev->l.guest_dispatch = SS_guest_dispatch; |
lev->l.guest_epilogue = SS_guest_epilogue; |
lev->l.guest_activate = SS_guest_activate; |
lev->l.guest_insert = SS_guest_insert; |
lev->l.guest_extract = SS_guest_extract; |
lev->l.guest_endcycle = SS_guest_endcycle; |
lev->l.guest_end = SS_guest_end; |
lev->l.guest_sleep = SS_guest_sleep; |
/* fill the SS descriptor part */ |
for (i=0; i<MAX_PROC; i++) |
1156,23 → 999,19 |
lev->rcount=0; |
lev->replenish_amount=0; |
lev->server_active=SS_SERVER_NOTACTIVE; |
return l; |
} |
bandwidth_t SS_usedbandwidth(LEVEL l) |
{ |
SS_level_des *lev = (SS_level_des *)(level_table[l]); |
if (lev->l.level_code == SS_LEVEL_CODE && |
lev->l.level_version == SS_LEVEL_VERSION) |
return lev->U; |
else |
return 0; |
return lev->U; |
} |
int SS_availCs(LEVEL l) { |
SS_level_des *lev = (SS_level_des *)(level_table[l]); |
if (lev->l.level_code == SS_LEVEL_CODE && |
lev->l.level_version == SS_LEVEL_VERSION) |
return lev->availCs; |
else |
return 0; |
return lev->availCs; |
} |
/shark/trunk/kernel/modules/tbs.c |
---|
20,11 → 20,11 |
/** |
------------ |
CVS : $Id: tbs.c,v 1.3 2002-11-11 08:32:07 pj Exp $ |
CVS : $Id: tbs.c,v 1.4 2003-01-07 17:07:51 pj Exp $ |
File: $File$ |
Revision: $Revision: 1.3 $ |
Last update: $Date: 2002-11-11 08:32:07 $ |
Revision: $Revision: 1.4 $ |
Last update: $Date: 2003-01-07 17:07:51 $ |
------------ |
This file contains the aperiodic server TBS (Total Bandwidth Server) |
60,6 → 60,7 |
#include <kernel/descr.h> |
#include <kernel/var.h> |
#include <kernel/func.h> |
#include <kernel/trace.h> |
/*+ 4 debug purposes +*/ |
#undef TBS_TEST |
97,19 → 98,6 |
} TBS_level_des; |
static char *TBS_status_to_a(WORD status) |
{ |
if (status < MODULE_STATUS_BASE) |
return status_to_a(status); |
switch (status) { |
case TBS_WCET_VIOLATED: return "TBS_Wcet_Violated"; |
case TBS_WAIT : return "TBS_Wait"; |
default : return "TBS_Unknown"; |
} |
} |
#ifdef TESTG |
#include "drivers/glib.h" |
#endif |
131,9 → 119,6 |
/* we compute a suitable deadline for the task */ |
drel = (proc_table[p].wcet * lev->band_den) / lev->band_num; |
if (TIMESPEC_A_GT_B(&proc_table[p].request_time, &lev->lastdline)) |
TIMESPEC_ASSIGN(&lev->lastdline, &proc_table[p].request_time ); |
ADDUSEC2TIMESPEC(drel, &lev->lastdline); |
#ifdef TESTG |
147,8 → 132,7 |
/* and we insert the task in another level */ |
m = lev->scheduling_level; |
job_task_default_model(j,lev->lastdline); |
level_table[m]->guest_create(m,p,(TASK_MODEL *)&j); |
level_table[m]->guest_activate(m,p); |
level_table[m]->private_insert(m,p,(TASK_MODEL *)&j); |
#ifdef TBS_TEST |
kern_printf("TBS_activation: lastdline %ds %dns\n",lev->lastdline.tv_sec,lev->lastdline.tv_nsec); |
176,74 → 160,8 |
#endif |
} |
static int TBS_level_accept_task_model(LEVEL l, TASK_MODEL *m) |
{ |
if (m->pclass == SOFT_PCLASS || m->pclass == (SOFT_PCLASS | l) ) { |
SOFT_TASK_MODEL *s = (SOFT_TASK_MODEL *)m; |
if (s->wcet && s->periodicity == APERIODIC) |
return 0; |
} |
return -1; |
} |
static int TBS_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 TBS_level_status(LEVEL l) |
{ |
TBS_level_des *lev = (TBS_level_des *)(level_table[l]); |
PID p = iq_query_first(&lev->wait); |
kern_printf("Wcet Check : %s\n", |
onoff(lev->flags & TBS_ENABLE_WCET_CHECK)); |
kern_printf("On-line guarantee : %s\n", |
onoff(lev->flags & TBS_ENABLE_GUARANTEE)); |
kern_printf("Used Bandwidth : %u/%u\n", |
lev->U, MAX_BANDWIDTH); |
kern_printf("Last deadline : %lds %ldns\n",lev->lastdline.tv_sec, |
lev->lastdline.tv_nsec); |
if (lev->activated != -1) |
kern_printf("Activated: Pid: %2d Name: %10s Dl: %ld.%9ld nact: %d Stat: %s\n", |
lev->activated, |
proc_table[lev->activated].name, |
iq_query_timespec(lev->activated, &lev->wait)->tv_sec, |
iq_query_timespec(lev->activated, &lev->wait)->tv_nsec, |
lev->nact[lev->activated], |
TBS_status_to_a(proc_table[lev->activated].status)); |
while (p != NIL) { |
kern_printf("Pid: %2d Name: %10s Stat: %s\n", |
p, |
proc_table[p].name, |
TBS_status_to_a(proc_table[p].status)); |
p = iq_query_next(p, &lev->wait); |
} |
} |
static PID TBS_level_scheduler(LEVEL l) |
{ |
/* the TBS don't schedule anything... |
it's an EDF level or similar that do it! */ |
return NIL; |
} |
/* The on-line guarantee is enabled only if the appropriate flag is set... */ |
static int TBS_level_guarantee(LEVEL l, bandwidth_t *freebandwidth) |
static int TBS_public_guarantee(LEVEL l, bandwidth_t *freebandwidth) |
{ |
TBS_level_des *lev = (TBS_level_des *)(level_table[l]); |
255,14 → 173,19 |
return 0; |
} |
static int TBS_task_create(LEVEL l, PID p, TASK_MODEL *m) |
static int TBS_public_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
TBS_level_des *lev = (TBS_level_des *)(level_table[l]); |
/* if the TBS_task_create is called, then the pclass must be a |
valid pclass. */ |
SOFT_TASK_MODEL *s = (SOFT_TASK_MODEL *)m; |
SOFT_TASK_MODEL *s; |
if (m->pclass != SOFT_PCLASS) return -1; |
if (m->level != 0 && m->level != l) return -1; |
s = (SOFT_TASK_MODEL *)m; |
if (!(s->wcet && s->periodicity == APERIODIC)) return -1; |
proc_table[p].wcet = s->wcet; |
/* Enable wcet check */ |
278,18 → 201,8 |
return 0; /* OK, also if the task cannot be guaranteed... */ |
} |
static void TBS_task_detach(LEVEL l, PID p) |
static void TBS_public_dispatch(LEVEL l, PID p, int nostop) |
{ |
/* the TBS level doesn't introduce any dinamic allocated new field. */ |
} |
static int TBS_task_eligible(LEVEL l, PID p) |
{ |
return 0; /* if the task p is chosen, it is always eligible */ |
} |
static void TBS_task_dispatch(LEVEL l, PID p, int nostop) |
{ |
TBS_level_des *lev = (TBS_level_des *)(level_table[l]); |
/* there is at least one task ready inserted in an EDF or similar |
296,10 → 209,10 |
level */ |
level_table[ lev->scheduling_level ]-> |
guest_dispatch(lev->scheduling_level,p,nostop); |
private_dispatch(lev->scheduling_level,p,nostop); |
} |
static void TBS_task_epilogue(LEVEL l, PID p) |
static void TBS_public_epilogue(LEVEL l, PID p) |
{ |
TBS_level_des *lev = (TBS_level_des *)(level_table[l]); |
313,7 → 226,7 |
have to be put in place... this code is identical to the |
TBS_task_end */ |
level_table[ lev->scheduling_level ]-> |
guest_end(lev->scheduling_level,p); |
private_extract(lev->scheduling_level,p); |
/* we reclaim an avail time that can be <0 due to the timer |
approximations -> we have to postpone the deadline a little! |
335,18 → 248,22 |
/* 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 TBS_task_activate(LEVEL l, PID p) |
static void TBS_public_activate(LEVEL l, PID p) |
{ |
TBS_level_des *lev = (TBS_level_des *)(level_table[l]); |
struct timespec t; |
if (proc_table[p].status == SLEEP || |
proc_table[p].status == TBS_WCET_VIOLATED) { |
ll_gettime(TIME_EXACT, &proc_table[p].request_time); |
kern_gettime(&t); |
if (TIMESPEC_A_GT_B(&t, &lev->lastdline)) |
TIMESPEC_ASSIGN(&lev->lastdline, &t ); |
if (lev->activated == NIL) { |
/* This is the first task in the level, so we activate it immediately */ |
lev->activated = p; |
363,23 → 280,25 |
kern_printf("TBSREJ!!!");*/ |
} |
static void TBS_task_insert(LEVEL l, PID p) |
static void TBS_public_unblock(LEVEL l, PID p) |
{ |
TBS_level_des *lev = (TBS_level_des *)(level_table[l]); |
JOB_TASK_MODEL j; |
level_table[ lev->scheduling_level ]-> |
guest_insert(lev->scheduling_level,p); |
job_task_default_model(j,lev->lastdline); |
level_table[lev->scheduling_level]-> |
private_insert(lev->scheduling_level,p,(TASK_MODEL *)&j); |
} |
static void TBS_task_extract(LEVEL l, PID p) |
static void TBS_public_block(LEVEL l, PID p) |
{ |
TBS_level_des *lev = (TBS_level_des *)(level_table[l]); |
level_table[ lev->scheduling_level ]-> |
guest_extract(lev->scheduling_level,p); |
private_extract(lev->scheduling_level,p); |
} |
static void TBS_task_endcycle(LEVEL l, PID p) |
static int TBS_public_message(LEVEL l, PID p, void *m) |
{ |
TBS_level_des *lev = (TBS_level_des *)(level_table[l]); |
387,7 → 306,7 |
that implements a single activation, so we have to call |
the guest_end, that representsa single activation... */ |
level_table[ lev->scheduling_level ]-> |
guest_end(lev->scheduling_level,p); |
private_extract(lev->scheduling_level,p); |
TBS_bandwidth_reclaiming(lev,p); |
408,14 → 327,18 |
if (lev->activated != NIL) |
TBS_activation(lev); |
jet_update_endcycle(); /* Update the Jet data... */ |
trc_logevent(TRC_ENDCYCLE,&exec_shadow); /* tracer stuff */ |
return 0; |
} |
static void TBS_task_end(LEVEL l, PID p) |
static void TBS_public_end(LEVEL l, PID p) |
{ |
TBS_level_des *lev = (TBS_level_des *)(level_table[l]); |
level_table[ lev->scheduling_level ]-> |
guest_end(lev->scheduling_level,p); |
private_extract(lev->scheduling_level,p); |
TBS_bandwidth_reclaiming(lev,p); |
427,65 → 350,6 |
TBS_activation(lev); |
} |
static void TBS_task_sleep(LEVEL l, PID p) |
{ |
TBS_level_des *lev = (TBS_level_des *)(level_table[l]); |
/* a task activation is finished, but we are using a JOB_TASK_MODEL |
that implements a single activation, so we have to call |
the guest_end, that representsa single activation... */ |
level_table[ lev->scheduling_level ]-> |
guest_end(lev->scheduling_level,p); |
TBS_bandwidth_reclaiming(lev,p); |
/* we reset the capacity counters... */ |
if (lev->flags & TBS_ENABLE_WCET_CHECK) |
proc_table[p].avail_time = proc_table[p].wcet; |
proc_table[p].status = SLEEP; |
lev->nact[p] = 0; |
lev->activated = iq_getfirst(&lev->wait); |
if (lev->activated != NIL) |
TBS_activation(lev); |
} |
static int TBS_guest_create(LEVEL l, PID p, TASK_MODEL *m) |
{ kern_raise(XINVALID_GUEST,exec_shadow); return 0; } |
static void TBS_guest_detach(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void TBS_guest_dispatch(LEVEL l, PID p, int nostop) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void TBS_guest_epilogue(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void TBS_guest_activate(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void TBS_guest_insert(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void TBS_guest_extract(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void TBS_guest_endcycle(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void TBS_guest_end(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
static void TBS_guest_sleep(LEVEL l, PID p) |
{ kern_raise(XINVALID_GUEST,exec_shadow); } |
/* Registration functions */ |
/*+ Registration function: |
499,56 → 363,28 |
printk("TBS_register_level\n"); |
/* request an entry in the level_table */ |
l = level_alloc_descriptor(); |
l = level_alloc_descriptor(sizeof(TBS_level_des)); |
printk(" alloco descrittore %d %d\n",l,(int)sizeof(TBS_level_des)); |
lev = (TBS_level_des *)level_table[l]; |
/* alloc the space needed for the TBS_level_des */ |
lev = (TBS_level_des *)kern_alloc(sizeof(TBS_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, TBS_LEVELNAME, MAX_LEVELNAME); |
lev->l.level_code = TBS_LEVEL_CODE; |
lev->l.level_version = TBS_LEVEL_VERSION; |
lev->l.level_accept_task_model = TBS_level_accept_task_model; |
lev->l.level_accept_guest_model = TBS_level_accept_guest_model; |
lev->l.level_status = TBS_level_status; |
lev->l.level_scheduler = TBS_level_scheduler; |
if (flags & TBS_ENABLE_GUARANTEE) |
lev->l.level_guarantee = TBS_level_guarantee; |
lev->l.public_guarantee = TBS_public_guarantee; |
else |
lev->l.level_guarantee = NULL; |
lev->l.public_guarantee = NULL; |
lev->l.task_create = TBS_task_create; |
lev->l.task_detach = TBS_task_detach; |
lev->l.task_eligible = TBS_task_eligible; |
lev->l.task_dispatch = TBS_task_dispatch; |
lev->l.task_epilogue = TBS_task_epilogue; |
lev->l.task_activate = TBS_task_activate; |
lev->l.task_insert = TBS_task_insert; |
lev->l.task_extract = TBS_task_extract; |
lev->l.task_endcycle = TBS_task_endcycle; |
lev->l.task_end = TBS_task_end; |
lev->l.task_sleep = TBS_task_sleep; |
lev->l.public_guarantee = TBS_public_guarantee; |
lev->l.public_create = TBS_public_create; |
lev->l.public_end = TBS_public_end; |
lev->l.public_dispatch = TBS_public_dispatch; |
lev->l.public_epilogue = TBS_public_epilogue; |
lev->l.public_activate = TBS_public_activate; |
lev->l.public_unblock = TBS_public_unblock; |
lev->l.public_block = TBS_public_block; |
lev->l.public_message = TBS_public_message; |
lev->l.guest_create = TBS_guest_create; |
lev->l.guest_detach = TBS_guest_detach; |
lev->l.guest_dispatch = TBS_guest_dispatch; |
lev->l.guest_epilogue = TBS_guest_epilogue; |
lev->l.guest_activate = TBS_guest_activate; |
lev->l.guest_insert = TBS_guest_insert; |
lev->l.guest_extract = TBS_guest_extract; |
lev->l.guest_endcycle = TBS_guest_endcycle; |
lev->l.guest_end = TBS_guest_end; |
lev->l.guest_sleep = TBS_guest_sleep; |
/* fill the TBS descriptor part */ |
for (i = 0; i < MAX_PROC; i++) { |
573,20 → 409,14 |
bandwidth_t TBS_usedbandwidth(LEVEL l) |
{ |
TBS_level_des *lev = (TBS_level_des *)(level_table[l]); |
if (lev->l.level_code == TBS_LEVEL_CODE && |
lev->l.level_version == TBS_LEVEL_VERSION) |
return lev->U; |
else |
return 0; |
return lev->U; |
} |
int TBS_get_nact(LEVEL l, PID p) |
{ |
TBS_level_des *lev = (TBS_level_des *)(level_table[l]); |
if (lev->l.level_code == TBS_LEVEL_CODE && |
lev->l.level_version == TBS_LEVEL_VERSION) |
return lev->nact[p]; |
else |
return -1; |
return lev->nact[p]; |
} |
/shark/trunk/kernel/modules/dummy.c |
---|
20,11 → 20,11 |
/** |
------------ |
CVS : $Id: dummy.c,v 1.3 2002-11-11 08:32:06 pj Exp $ |
CVS : $Id: dummy.c,v 1.4 2003-01-07 17:07:50 pj Exp $ |
File: $File$ |
Revision: $Revision: 1.3 $ |
Last update: $Date: 2002-11-11 08:32:06 $ |
Revision: $Revision: 1.4 $ |
Last update: $Date: 2003-01-07 17:07:50 $ |
------------ |
This file contains the Dummy scheduling module |
58,7 → 58,6 |
#include <ll/string.h> |
#include <kernel/config.h> |
#include <sys/types.h> |
#include <modules/codes.h> |
#include <kernel/model.h> |
#include <kernel/descr.h> |
#include <kernel/var.h> |
74,42 → 73,21 |
} dummy_level_des; |
static int dummy_level_accept_task_model(LEVEL l, TASK_MODEL *m) |
static PID dummy_public_scheduler(LEVEL l) |
{ |
dummy_level_des *lev = (dummy_level_des *)(level_table[l]); |
if ((m->pclass == DUMMY_PCLASS || m->pclass == (DUMMY_PCLASS | l)) |
&& lev->dummy == -1) |
return 0; |
else |
return -1; |
//kern_printf("DUMMYsched!!! %d", lev->dummy); |
return lev->dummy; |
} |
static int dummy_level_accept_guest_model(LEVEL l, TASK_MODEL *m) |
static int dummy_public_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
return -1; |
} |
static void dummy_level_status(LEVEL l) |
{ |
dummy_level_des *lev = (dummy_level_des *)(level_table[l]); |
kern_printf("dummy PID: %d\n", lev->dummy); |
}; |
if (m->pclass != DUMMY_PCLASS) return -1; |
if (m->level != 0 && m->level != l) return -1; |
if (lev->dummy != -1) return -1; |
static PID dummy_level_scheduler(LEVEL l) |
{ |
dummy_level_des *lev = (dummy_level_des *)(level_table[l]); |
//kern_printf("DUMMYsched!!! %d", lev->dummy); |
return lev->dummy; |
} |
/* There is not guarantee on this level!!! -> the entry must be null |
int (*level_guarantee)(LEVEL l, DWORD *freebandwidth); */ |
static int dummy_task_create(LEVEL l, PID p, TASK_MODEL *m) |
{ |
/* the dummy level doesn't introduce any new field in the TASK_MODEL |
so, all initialization stuffs are done by the task_create. |
the task state is set at SLEEP by the general task_create */ |
116,92 → 94,16 |
return 0; /* OK */ |
} |
static void dummy_task_detach(LEVEL l, PID p) |
static void dummy_public_dispatch(LEVEL l, PID p, int nostop) |
{ |
/* the dummy level doesn't introduce any new field in the TASK_MODEL |
so, all detach stuffs are done by the task_create |
The task state is set at FREE by the general task_create */ |
} |
static int dummy_task_eligible(LEVEL l, PID p) |
{ |
return 0; /* if the task p is chosen, it is always eligible */ |
} |
extern int testactive; |
extern struct timespec s_stime[]; |
extern TIME s_curr[]; |
extern TIME s_PID[]; |
extern int useds; |
static void dummy_task_dispatch(LEVEL l, PID p, int nostop) |
{ |
/* nothing... the dummy hangs the cpu waiting for interrupts... */ |
if (0)//testactive) |
{ |
s_stime[useds]= schedule_time; |
s_curr[useds] = -1; |
s_PID[useds] = p; |
useds++; |
} |
//kern_printf("ÛDUMMYÛ"); |
} |
static void dummy_task_epilogue(LEVEL l, PID p) |
static void dummy_public_epilogue(LEVEL l, PID p) |
{ |
proc_table[p].status = SLEEP; /* Paranoia */ |
} |
static void dummy_task_activate(LEVEL l, PID p) |
{ kern_printf("Dummy1"); kern_raise(XINVALID_DUMMY_OP,exec_shadow); } |
static void dummy_task_insert(LEVEL l, PID p) |
{ kern_printf("Dummy2"); kern_raise(XINVALID_DUMMY_OP,exec_shadow); } |
static void dummy_task_extract(LEVEL l, PID p) |
{ kern_printf("Dummy3"); kern_raise(XINVALID_DUMMY_OP,exec_shadow); } |
static void dummy_task_endcycle(LEVEL l, PID p) |
{ kern_printf("Dummy4"); kern_raise(XINVALID_DUMMY_OP,exec_shadow); } |
static void dummy_task_end(LEVEL l, PID p) |
{ kern_printf("Dummy5"); kern_raise(XINVALID_DUMMY_OP,exec_shadow); } |
static void dummy_task_sleep(LEVEL l, PID p) |
{ kern_printf("Dummy6"); kern_raise(XINVALID_DUMMY_OP,exec_shadow); } |
static int dummy_guest_create(LEVEL l, PID p, TASK_MODEL *m) |
{ kern_printf("Dummy8"); kern_raise(XINVALID_GUEST,exec_shadow); return 0; } |
static void dummy_guest_detach(LEVEL l, PID p) |
{ kern_printf("Dummy9"); kern_raise(XINVALID_GUEST,exec_shadow); } |
static void dummy_guest_dispatch(LEVEL l, PID p, int nostop) |
{ kern_printf("Dummy0"); kern_raise(XINVALID_GUEST,exec_shadow); } |
static void dummy_guest_epilogue(LEVEL l, PID p) |
{ kern_printf("Dummya"); kern_raise(XINVALID_GUEST,exec_shadow); } |
static void dummy_guest_activate(LEVEL l, PID p) |
{ kern_printf("Dummyb"); kern_raise(XINVALID_GUEST,exec_shadow); } |
static void dummy_guest_insert(LEVEL l, PID p) |
{ kern_printf("Dummyc"); kern_raise(XINVALID_GUEST,exec_shadow); } |
static void dummy_guest_extract(LEVEL l, PID p) |
{ kern_printf("Dummyd"); kern_raise(XINVALID_GUEST,exec_shadow); } |
static void dummy_guest_endcycle(LEVEL l, PID p) |
{ kern_printf("Dummye"); kern_raise(XINVALID_GUEST,exec_shadow); } |
static void dummy_guest_end(LEVEL l, PID p) |
{ kern_printf("Dummyf"); kern_raise(XINVALID_GUEST,exec_shadow); } |
static void dummy_guest_sleep(LEVEL l, PID p) |
{ kern_printf("Dummyg"); kern_raise(XINVALID_GUEST,exec_shadow); } |
/*+ Dummy task must be present & cannot be killed; +*/ |
static TASK dummy() |
{ |
244,7 → 146,7 |
if (p == NIL) |
printk("\nPanic!!! can't create dummy task...\n"); |
/* dummy must block all tasks... */ |
/* dummy must block all signals... */ |
proc_table[p].sigmask = 0xFFFFFFFF; |
} |
253,55 → 155,27 |
TIME slice the slice for the Round Robin queue |
int createmain 1 if the level creates the main task 0 otherwise |
struct multiboot_info *mb used if createmain specified +*/ |
void dummy_register_level() |
LEVEL dummy_register_level() |
{ |
LEVEL l; /* the level that we register */ |
dummy_level_des *lev; /* for readableness only */ |
printk("Entro in dummy_register_level\n"); |
printk("Inside dummy_register_level\n"); |
/* request an entry in the level_table */ |
l = level_alloc_descriptor(); |
l = level_alloc_descriptor(sizeof(dummy_level_des)); |
/* alloc the space needed for the dummy_level_des */ |
lev = (dummy_level_des *)kern_alloc(sizeof(dummy_level_des)); |
lev = (dummy_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, DUMMY_LEVELNAME, MAX_LEVELNAME); |
lev->l.level_code = DUMMY_LEVEL_CODE; |
lev->l.level_version = DUMMY_LEVEL_VERSION; |
lev->l.public_scheduler = dummy_public_scheduler; |
lev->l.public_guarantee = NULL; |
lev->l.public_create = dummy_public_create; |
lev->l.public_dispatch = dummy_public_dispatch; |
lev->l.public_epilogue = dummy_public_epilogue; |
lev->l.level_accept_task_model = dummy_level_accept_task_model; |
lev->l.level_accept_guest_model = dummy_level_accept_guest_model; |
lev->l.level_status = dummy_level_status; |
lev->l.level_scheduler = dummy_level_scheduler; |
lev->l.level_guarantee = NULL; /* No guarantee! */ |
lev->l.task_create = dummy_task_create; |
lev->l.task_detach = dummy_task_detach; |
lev->l.task_eligible = dummy_task_eligible; |
lev->l.task_dispatch = dummy_task_dispatch; |
lev->l.task_epilogue = dummy_task_epilogue; |
lev->l.task_activate = dummy_task_activate; |
lev->l.task_insert = dummy_task_insert; |
lev->l.task_extract = dummy_task_extract; |
lev->l.task_endcycle = dummy_task_endcycle; |
lev->l.task_end = dummy_task_end; |
lev->l.task_sleep = dummy_task_sleep; |
lev->l.guest_create = dummy_guest_create; |
lev->l.guest_detach = dummy_guest_detach; |
lev->l.guest_dispatch = dummy_guest_dispatch; |
lev->l.guest_epilogue = dummy_guest_epilogue; |
lev->l.guest_activate = dummy_guest_activate; |
lev->l.guest_insert = dummy_guest_insert; |
lev->l.guest_extract = dummy_guest_extract; |
lev->l.guest_endcycle = dummy_guest_endcycle; |
lev->l.guest_end = dummy_guest_end; |
lev->l.guest_sleep = dummy_guest_sleep; |
/* the dummy process will be created at init_time. |
see also dummy_level_accept_model,dummy_create */ |
lev->dummy = -1; |
309,4 → 183,6 |
printk("\tPosto dummy_create\n"); |
sys_atrunlevel(dummy_create,(void *) l, RUNLEVEL_INIT); |
return l; |
} |
/shark/trunk/kernel/modules/nop.c |
---|
20,11 → 20,11 |
/** |
------------ |
CVS : $Id: nop.c,v 1.2 2002-11-11 08:32:06 pj Exp $ |
CVS : $Id: nop.c,v 1.3 2003-01-07 17:07:50 pj Exp $ |
File: $File$ |
Revision: $Revision: 1.2 $ |
Last update: $Date: 2002-11-11 08:32:06 $ |
Revision: $Revision: 1.3 $ |
Last update: $Date: 2003-01-07 17:07:50 $ |
------------ |
Binary Semaphores. see nop.h for more details... |
58,7 → 58,6 |
#include <ll/string.h> |
#include <kernel/const.h> |
#include <sys/types.h> |
#include <modules/codes.h> |
#include <kernel/descr.h> |
#include <kernel/var.h> |
#include <kernel/func.h> |
80,40 → 79,21 |
/* Wait status for this library */ |
#define NOP_WAIT LIB_STATUS_BASE |
/*+ print resource protocol statistics...+*/ |
static void NOP_resource_status(RLEVEL r) |
static int NOP_res_register(RLEVEL l, PID p, RES_MODEL *r) |
{ |
kern_printf("No status for NOP module\n"); |
} |
static int NOP_level_accept_resource_model(RLEVEL l, RES_MODEL *r) |
{ |
/* priority inheritance works with all tasks without Resource parameters */ |
return -1; |
} |
static void NOP_res_register(RLEVEL l, PID p, RES_MODEL *r) |
{ |
/* never called!!! */ |
} |
static void NOP_res_detach(RLEVEL l, PID p) |
{ |
} |
static int NOP_level_accept_mutexattr(RLEVEL l, const mutexattr_t *a) |
{ |
if (a->mclass == NOP_MCLASS || a->mclass == (NOP_MCLASS | l) ) |
return 0; |
else |
return -1; |
} |
static int NOP_init(RLEVEL l, mutex_t *m, const mutexattr_t *a) |
{ |
NOP_mutex_t *p; |
if (a->mclass != NOP_MCLASS) |
return -1; |
p = (NOP_mutex_t *) kern_alloc(sizeof(NOP_mutex_t)); |
172,23 → 152,12 |
if (p->owner != NIL) { /* We must block exec task */ |
LEVEL l; /* for readableness only */ |
TIME tx; /* a dummy TIME for timespec operations */ |
struct timespec ty; /* a dummy timespec for timespec operations */ |
proc_table[exec_shadow].context = kern_context_save(); |
/* SAME AS SCHEDULER... manage the capacity event and the load_info */ |
ll_gettime(TIME_EXACT, &schedule_time); |
SUBTIMESPEC(&schedule_time, &cap_lasttime, &ty); |
tx = TIMESPEC2USEC(&ty); |
proc_table[exec_shadow].avail_time -= tx; |
jet_update_slice(tx); |
if (cap_timer != NIL) { |
event_delete(cap_timer); |
cap_timer = NIL; |
} |
kern_epilogue_macro(); |
l = proc_table[exec_shadow].task_level; |
level_table[l]->task_extract(l,exec_shadow); |
level_table[l]->public_block(l,exec_shadow); |
/* we insert the task in the semaphore queue */ |
proc_table[exec_shadow].status = NOP_WAIT; |
256,7 → 225,7 |
p->owner = iq_getfirst(&p->blocked); |
if (p->owner != NIL) { |
l = proc_table[p->owner].task_level; |
level_table[l]->task_insert(l,p->owner); |
level_table[l]->public_unblock(l,p->owner); |
} |
scheduler(); |
265,7 → 234,7 |
return 0; |
} |
void NOP_register_module(void) |
RLEVEL NOP_register_module(void) |
{ |
RLEVEL l; /* the level that we register */ |
NOP_mutex_resource_des *m; /* for readableness only */ |
282,20 → 251,11 |
resource_table[l] = (resource_des *)m; |
/* fill the resource_des descriptor */ |
strncpy(m->m.r.res_name, NOP_MODULENAME, MAX_MODULENAME); |
m->m.r.res_code = NOP_MODULE_CODE; |
m->m.r.res_version = NOP_MODULE_VERSION; |
m->m.r.rtype = MUTEX_RTYPE; |
m->m.r.resource_status = NOP_resource_status; |
m->m.r.level_accept_resource_model = NOP_level_accept_resource_model; |
m->m.r.res_register = NOP_res_register; |
m->m.r.res_detach = NOP_res_detach; |
/* fill the mutex_resource_des descriptor */ |
m->m.level_accept_mutexattr = NOP_level_accept_mutexattr; |
m->m.init = NOP_init; |
m->m.destroy = NOP_destroy; |
m->m.lock = NOP_lock; |
302,5 → 262,6 |
m->m.trylock = NOP_trylock; |
m->m.unlock = NOP_unlock; |
return l; |
} |
/shark/trunk/kernel/modules/npp.c |
---|
20,11 → 20,11 |
/** |
------------ |
CVS : $Id: npp.c,v 1.1.1.1 2002-03-29 14:12:52 pj Exp $ |
CVS : $Id: npp.c,v 1.2 2003-01-07 17:07:50 pj Exp $ |
File: $File$ |
Revision: $Revision: 1.1.1.1 $ |
Last update: $Date: 2002-03-29 14:12:52 $ |
Revision: $Revision: 1.2 $ |
Last update: $Date: 2003-01-07 17:07:50 $ |
------------ |
Non Preemptive Protocol. see npp.h for more details... |
56,7 → 56,6 |
#include <ll/ll.h> |
#include <ll/string.h> |
#include <ll/stdio.h> |
#include <modules/codes.h> |
#include <kernel/const.h> |
#include <sys/types.h> |
#include <kernel/descr.h> |
71,6 → 70,7 |
} NPP_mutex_resource_des; |
#if 0 |
/*+ print resource protocol statistics...+*/ |
static void NPP_resource_status(RLEVEL r) |
{ |
78,18 → 78,14 |
kern_printf("%d Resources owned by the tasks %d\n", m->nlocked, exec_shadow); |
} |
#endif |
static int NPP_level_accept_resource_model(RLEVEL l, RES_MODEL *r) |
static int NPP_res_register(RLEVEL l, PID p, RES_MODEL *r) |
{ |
/* NPP works with all tasks without Resource parameters */ |
return -1; |
} |
static void NPP_res_register(RLEVEL l, PID p, RES_MODEL *r) |
{ |
/* never called!!! */ |
} |
static void NPP_res_detach(RLEVEL l, PID p) |
{ |
NPP_mutex_resource_des *m = (NPP_mutex_resource_des *)(resource_table[l]); |
98,16 → 94,11 |
kern_raise(XMUTEX_OWNER_KILLED, p); |
} |
static int NPP_level_accept_mutexattr(RLEVEL l, const mutexattr_t *a) |
static int NPP_init(RLEVEL l, mutex_t *m, const mutexattr_t *a) |
{ |
if (a->mclass == NPP_MCLASS || a->mclass == (NPP_MCLASS | l) ) |
return 0; |
else |
if (a->mclass != NPP_MCLASS) |
return -1; |
} |
static int NPP_init(RLEVEL l, mutex_t *m, const mutexattr_t *a) |
{ |
m->mutexlevel = l; |
m->opt = (void *)NIL; |
187,20 → 178,11 |
resource_table[l] = (resource_des *)m; |
/* fill the resource_des descriptor */ |
strncpy(m->m.r.res_name, NPP_MODULENAME, MAX_MODULENAME); |
m->m.r.res_code = NPP_MODULE_CODE; |
m->m.r.res_version = NPP_MODULE_VERSION; |
m->m.r.rtype = MUTEX_RTYPE; |
m->m.r.resource_status = NPP_resource_status; |
m->m.r.level_accept_resource_model = NPP_level_accept_resource_model; |
m->m.r.res_register = NPP_res_register; |
m->m.r.res_detach = NPP_res_detach; |
/* fill the mutex_resource_des descriptor */ |
m->m.level_accept_mutexattr = NPP_level_accept_mutexattr; |
m->m.init = NPP_init; |
m->m.destroy = NPP_destroy; |
m->m.lock = NPP_lock; |