Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 29 → Rev 38

/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;