Blame |
Last modification |
View Log
| RSS feed
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* (see the web pages for full authors list)
*
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy)
*
* http://www.sssup.it
* http://retis.sssup.it
* http://shark.sssup.it
*/
/**
------------
CVS : $Id: static.c,v 1.1.1.1 2004-05-24 18:03:47 giacomo Exp $
File: $File$
Revision: $Revision: 1.1.1.1 $
Last update: $Date: 2004-05-24 18:03:47 $
------------
**/
/*
* Copyright (C) 2001 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
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "static.h"
#include <ll/stdio.h>
#include <ll/string.h>
#include <kernel/model.h>
#include <kernel/descr.h>
#include <kernel/var.h>
#include <kernel/func.h>
#define STATIC_printf kern_printf
//#define STATIC_printf printk
/*+ Status used in the level +*/
#define STATIC_READY MODULE_STATUS_BASE /*+ - Ready status +*/
#define STATIC_IDLE MODULE_STATUS_BASE+4 /*+ to wait the deadline +*/
/*+ flags +*/
#define STATIC_FLAG_NORAISEEXC 2
/*+ the level redefinition for the Earliest Deadline First level +*/
typedef struct {
level_des l; /*+ the standard level descriptor +*/
IQUEUE mytable;
PID currenttask;
struct timespec hp;
struct timespec ref;
} STATIC_level_des;
static void STATIC_offset_activate(void *par)
{
PID p = (PID) par;
STATIC_level_des *lev;
lev = (STATIC_level_des *)level_table[proc_table[p].task_level];
lev->currenttask = p;
event_need_reschedule();
// STATIC_printf("(o p%d t%d)", p, (int)proc_table[p].timespec_priority.tv_sec);
}
static void STATIC_activateall(STATIC_level_des *lev)
{
PID my_table_index;
struct timespec x;
STATIC_printf("(A ");
for (my_table_index = iq_query_first(&lev->mytable);
my_table_index != NIL;
my_table_index = iq_query_next(my_table_index, &lev->mytable)) {
ADDTIMESPEC(&lev->ref,iq_query_timespec(my_table_index, &lev->mytable),&x);
kern_event_post(&x, STATIC_offset_activate,(void *)my_table_index);
STATIC_printf("|p%d t%d ",
my_table_index,
(int)iq_query_timespec(my_table_index, &lev->mytable)->tv_sec);
}
STATIC_printf(")");
}
static void STATIC_hyperperiod(void *par)
{
STATIC_level_des *lev;
struct timespec x;
lev = (STATIC_level_des *)level_table[(LEVEL)par];
STATIC_printf("(hp %d)", (int)lev->ref.tv_sec);
STATIC_activateall(lev);
ADDTIMESPEC(&lev->ref, &lev->hp, &x);
lev->ref = x;
kern_event_post(&x, STATIC_hyperperiod, par);
}
/* The scheduler only gets the first task in the queue */
static PID STATIC_public_scheduler(LEVEL l)
{
STATIC_level_des *lev = (STATIC_level_des *)(level_table[l]);
return lev->currenttask;
}
static int STATIC_public_create(LEVEL l, PID p, TASK_MODEL *m)
{
STATIC_level_des *lev = (STATIC_level_des *)(level_table[l]);
/* if the STATIC_task_create is called, then the pclass must be a
valid pclass. */
STATIC_TASK_MODEL *h = (STATIC_TASK_MODEL *)m;
if (m->pclass != STATIC_PCLASS) return -1;
if (m->level != 0 && m->level != l) return -1;
iq_query_timespec(p, &lev->mytable)->tv_sec = h->offset.tv_sec;
iq_query_timespec(p, &lev->mytable)->tv_nsec = h->offset.tv_nsec;
iq_timespec_insert(p,&lev->mytable);
return 0; /* OK, also if the task cannot be guaranteed... */
}
static void STATIC_public_dispatch(LEVEL l, PID p, int nostop)
{
}
static void STATIC_public_epilogue(LEVEL l, PID p)
{
}
static void STATIC_public_activate(LEVEL l, PID p)
{
}
static void STATIC_public_unblock(LEVEL l, PID p)
{
}
static void STATIC_public_block(LEVEL l, PID p)
{
}
static int STATIC_public_message(LEVEL l, PID p, void *m)
{
STATIC_level_des *lev = (STATIC_level_des *)(level_table[l]);
lev->currenttask = NIL;
jet_update_endcycle(); /* Update the Jet data... */
return 0;
}
static void STATIC_public_end(LEVEL l, PID p)
{
STATIC_level_des *lev = (STATIC_level_des *)(level_table[l]);
lev->currenttask = NIL;
iq_extract(p,&lev->mytable);
/* we finally put the task in the ready queue */
proc_table[p].status = FREE;
iq_insertfirst(p,&freedesc);
}
/* Registration functions */
/*+ Registration function:
int flags the init flags ... see STATIC.h +*/
LEVEL STATIC_register_level()
{
LEVEL l; /* the level that we register */
STATIC_level_des *lev; /* for readableness only */
printk("STATIC_register_level\n");
/* request an entry in the level_table */
l = level_alloc_descriptor(sizeof(STATIC_level_des));
lev = (STATIC_level_des *)level_table[l];
printk(" lev=%d\n",(int)lev);
/* fill the standard descriptor */
lev->l.public_scheduler = STATIC_public_scheduler;
lev->l.public_create = STATIC_public_create;
lev->l.public_end = STATIC_public_end;
lev->l.public_dispatch = STATIC_public_dispatch;
lev->l.public_epilogue = STATIC_public_epilogue;
lev->l.public_activate = STATIC_public_activate;
lev->l.public_unblock = STATIC_public_unblock;
lev->l.public_block = STATIC_public_block;
lev->l.public_message = STATIC_public_message;
/* fill the STATIC descriptor part */
iq_init(&lev->mytable, &freedesc, 0);
lev->currenttask = NIL;
NULL_TIMESPEC(&lev->hp);
NULL_TIMESPEC(&lev->ref);
return l;
}
void STATIC_start(LEVEL l, struct timespec *h, struct timespec *o)
{
STATIC_level_des *lev = (STATIC_level_des *)(level_table[l]);
struct timespec x;
kern_cli();
kern_gettime(&x);
lev->hp = *h;
ADDTIMESPEC(&x,o,&lev->ref);
STATIC_printf("(ST: ref:%d.%d x:%d.%d)\n",
(int)lev->ref.tv_sec, (int)lev->ref.tv_nsec,
(int)x.tv_sec, (int)x.tv_nsec);
kern_event_post(&x, STATIC_hyperperiod,(void *)l);
kern_sti();
}