Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 240 → Rev 241

/shark/trunk/ports/first/first-sync.c
12,8 → 12,9
//=====================================================================
 
#include "fsf_contract.h"
#include "fsf_server.h"
 
extern int fsf_cbsstar_level;
extern int fsf_server_level;
 
//#define FSF_DEBUG
 
71,8 → 72,8
TIME T,Q;
int budget, local_scheduler_level, scheduler_id;
 
local_scheduler_level = CBSSTAR_get_local_scheduler_level_from_pid(fsf_cbsstar_level, exec_shadow);
scheduler_id = CBSSTAR_get_local_scheduler_id_from_pid(fsf_cbsstar_level, exec_shadow);
local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level, exec_shadow);
scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, exec_shadow);
 
if (proc_table[exec_shadow].task_level != local_scheduler_level) return 0;
 
93,7 → 94,7
 
if (next_budget != NULL && next_period != NULL) {
 
CBSSTAR_getbudgetinfo(fsf_cbsstar_level, &Q, &T, budget);
SERVER_getbudgetinfo(fsf_server_level, &Q, &T, budget);
#ifdef FSF_DEBUG
kern_printf("(budget %d Q=%d T=%d)",budget,(int)Q,(int)T);
139,8 → 140,8
TIME T,Q;
int budget, local_scheduler_level, scheduler_id;
 
local_scheduler_level = CBSSTAR_get_local_scheduler_level_from_pid(fsf_cbsstar_level, exec_shadow);
scheduler_id = CBSSTAR_get_local_scheduler_id_from_pid(fsf_cbsstar_level, exec_shadow);
local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level, exec_shadow);
scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, exec_shadow);
 
if (proc_table[exec_shadow].task_level != local_scheduler_level) return 0;
161,7 → 162,7
 
if (next_budget != NULL && next_period != NULL) {
 
CBSSTAR_getbudgetinfo(fsf_cbsstar_level, &Q, &T, budget);
SERVER_getbudgetinfo(fsf_server_level, &Q, &T, budget);
#ifdef FSF_DEBUG
kern_printf("(budget %d Q=%d T=%d)",budget,(int)Q,(int)T);
/shark/trunk/ports/first/include/comm_message.h
File deleted
/shark/trunk/ports/first/include/posix.h
File deleted
/shark/trunk/ports/first/include/grubstar.h
0,0 → 1,182
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@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: grubstar.h,v 1.1 2003-09-30 09:26:57 giacomo Exp $
 
File: $File$
Revision: $Revision: 1.1 $
Last update: $Date: 2003-09-30 09:26:57 $
------------
 
This file contains the budget support for the multiapplication
scheduling algorithm proposed in the framework of the FIRST Project
 
Title:
CBSSTAR
 
Task Models Accepted:
None!
 
Guest Models Accepted:
BUDGET_TASK_MODEL - A task that is attached to a budget
int b; --> the number of the budget which the task is attached to
 
Description:
This module schedule its tasks following the CBS scheme.
Every task is inserted using the guest calls.
The module defines a limited set of budgets that the application
can use. Every guest task will use a particular budget; FIFO
scheduling is used inside a budget to schedule more than one ready
task attached to the same budget.
 
The tasks are inserted in an EDF level (or similar) with a JOB_TASK_MODEL,
and the CBS level expects that the task is scheduled with the absolute
deadline passed in the model.
 
This module tries to implement a simplified version of the guest
task interface:
- To insert a guest task, use guest_create
- When a task is dispatched, use guest_dispatch
- When a task have to be suspended, you have to use:
-> preemption: use guest_epilogue
-> synchronization, end: use guest_end
Remember: no check is done on the budget number passed with the model!!!
 
Exceptions raised:
XUNVALID_TASK
This level doesn't support normal tasks, but just guest tasks.
When a task operation is called, an exception is raised.
 
Restrictions & special features:
- This level doesn't manage the main task.
- At init time we have to specify:
. guarantee check
(when all task are created the system will check that the task_set
will not use more than the available bandwidth)
- A function to return the used bandwidth of the level is provided.
 
- A function is provided to allocate a buffer.
*/
 
/*
* Copyright (C) 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
* 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
*
*/
 
 
#ifndef __CBSSTAR_H__
#define __CBSSTAR_H__
 
#include <kernel/kern.h>
 
//#include <ll/ll.h>
//#include <kernel/config.h>
//#include <sys/types.h>
//#include <kernel/types.h>
//#include <modules/codes.h>
 
/* -----------------------------------------------------------------------
BUDGET_TASK_MODEL: a model for guest tasks
----------------------------------------------------------------------- */
 
#define BUDGET_PCLASS 0x0600
typedef struct {
TASK_MODEL t;
int b;
} BUDGET_TASK_MODEL;
 
#define budget_task_default_model(m,buf) \
task_default_model((m).t, BUDGET_PCLASS), \
(m).b = (buf);
 
 
 
/* some constants for registering the Module in the right place */
#define CBSSTAR_LEVELNAME "CBSSTAR"
#define CBSSTAR_LEVEL_CODE 106
#define CBSSTAR_LEVEL_VERSION 1
 
typedef struct {
int command;
void *param;
} CBSSTAR_command_message;
 
typedef struct {
int budget;
TIME T,Q;
} CBSSTAR_mod_budget;
 
/* Registration function:
int N Maximum number of budgets allocated for the applications
LEVEL master the level that must be used as master level for the
CBS tasks
*/
LEVEL CBSSTAR_register_level(int n, LEVEL master);
 
/* Allocates a budget to be used for an application.
Input parameters:
Q The budget
T The period of the budget
Return value:
0..N The ID of the budget
-1 no more free budgets
-2 The budgets allocated locally to this module have bandwidth > 1
-3 wrong LEVEL id
*/
int CBSSTAR_setbudget(LEVEL l, TIME Q, TIME T, LEVEL local_scheduler_level, int scheduler_id);
 
int CBSSTAR_removebudget(LEVEL l, int budget);
 
int CBSSTAR_adjust_budget(LEVEL l, TIME Q, TIME T, int budget);
 
int CBSSTAR_getbudgetinfo(LEVEL l, TIME *Q, TIME *T, int budget);
 
int CBSSTAR_was_budget_overran(LEVEL l, int budget);
 
int CBSSTAR_is_active(LEVEL l, int budget);
 
int CBSSTAR_get_local_scheduler_level_from_budget(LEVEL l, int budget);
 
int CBSSTAR_get_local_scheduler_level_from_pid(LEVEL l, PID p);
 
int CBSSTAR_get_local_scheduler_id_from_budget(LEVEL l, int budget);
 
int CBSSTAR_get_local_scheduler_id_from_pid(LEVEL l, PID p);
 
#endif
/shark/trunk/ports/first/include/fsf_contract.h
18,8 → 18,6
#include "fsf_configuration_parameters.h"
#include "fsf_opaque_types.h"
 
#include "posix.h"
#include "cbsstar.h"
#include "edfstar.h"
#include "rmstar.h"
#include "posixstar.h"
28,7 → 26,7
#define _FSF_CONTRACT_H_
 
/* S.Ha.R.K. Init */
int FSF_register_module(int posix_level, int cbsstar_level);
int FSF_register_module(int server_level);
 
//////////////////////////////////////////////////////////////////
// BASIC TYPES AND CONSTANTS
92,12 → 90,10
#define FSF_ERR_NO_RENEGOTIATION_REQUESTED 2003006
#define FSF_ERR_CONTRACT_REJECTED 2003007
#define FSF_ERR_TOO_MANY_SERVERS 2003008
#define FSF_ERR_BIND_THREAD 2003009
#define FSF_ERR_UNBIND_THREAD 2003010
#define FSF_ERR_CREATE_THREAD 2003011
#define FSF_ERR_SERVER_USED 2003012
#define FSF_ERR_INVALID_SERVER 2003013
#define FSF_ERR_CREATE_SERVER 2003014
#define FSF_ERR_CREATE_THREAD 2003009
#define FSF_ERR_SERVER_USED 2003010
#define FSF_ERR_INVALID_SERVER 2003011
#define FSF_ERR_CREATE_SERVER 2003012
 
//////////////////////////////////////////////////////////////
// CONTRACT PARAMETERS
246,11 → 242,15
(fsf_contract_parameters_t *contract,
fsf_scheduler_id_t local_scheduler_id);
 
//Description: Set the local scheduler
 
int
fsf_get_local_scheduler_parameter
(const fsf_contract_parameters_t *contract,
fsf_scheduler_id_t *local_scheduler_id);
 
//Description: Get the local scheduler
 
//////////////////////////////////////////////////////////////
// SYNCHRONIZATION OBJECTS
//////////////////////////////////////////////////////////////
334,84 → 334,20
//are being scheduled by the fsf scheduler.
 
int
fsf_negotiate_contract_for_new_thread
(const fsf_contract_parameters_t *contract,
fsf_server_id_t *server,
pthread_t *thread,
pthread_attr_t *attr,
fsf_thread_code_t thread_code,
void *arg,
void *rt_arg);
fsf_create_thread
(fsf_server_id_t server,
pthread_t *thread,
pthread_attr_t *attr,
fsf_thread_code_t thread_code,
void *arg,
void *local_scheduler_arg);
 
//Description: This operation negotiates a contract for a new server,
//creates a thread and binds it to the server. If the contract is
//accepted, the operation creates a thread with the arguments thread,
//attr, thread_code and arg as they are defined for the
//pthread_create() POSIX function call, and attaches it to the fsf
//scheduler. Then, it binds the created thread to the new server. It
//returns zero and puts the server identification number in the
//location pointed to by the server input parameter. The attr
//parameter is overwritten as necessary to introduce the adequate
//scheduling policy and priority, according to the preemption level
//given in the contract and the fsf_priority_map() function defined by
//the user. If the contract is rejected, the thread is not created and
//the corresponding error is returned.
//Description: This operation creates a new thread inside a specific
//server. The local_scheduler_arg parameter is used to pass specific
//parameters to local scheduler. These parameters are application
//depented.
 
int
fsf_negotiate_contract_for_myself
(const fsf_contract_parameters_t *contract,
fsf_server_id_t *server,
void *rt_arg);
 
//Description: This operation negotiates a contract for a new
//server, and binds the calling thread to it. If the contract is
//accepted it returns zero and copies the server identification
//number in the location pointed to by the server input parameter.
//If it is rejected, an error is returned.
 
//Implementation dependent issue: In order to allow the usage of
//application defined schedulers, the calling thread must not have the
//SCHED_APP scheduling policy and at the same time be attached to an
//application scheduler different than the fsf scheduler; in such case,
//an error is returned. After a successful call the calling thread
//will have the SCHED_APP scheduling policy and will be attached to
//the fsf scheduler.
 
int
fsf_bind_thread_to_server
(fsf_server_id_t server,
pthread_t thread,
void *rt_arg);
 
//Description: This operation associates a thread with a server, which
//means that it starts consuming the server's budget and is executed
//according to the contract established for that server. If the thread
//is already bound to another server, it is effectively unbound from
//it and bound to the specified one.
 
//Implementation dependent issue: In order to allow the usage of
//application defined schedulers, the given thread must not have the
//scheduling policy SCHED_APP and at the same time be attached to an
//application scheduler different than the fsf scheduler.
 
//FIRST project development issue: In this phase of the project, only
//one thread is allowed to be bound to a server, sharing a server by
//multiple threads is planned to be allowed in the next phase of
//the project.
 
int
fsf_unbind_thread_from_server (pthread_t thread);
 
//Description: This operation unbinds a thread from a server.
//Since threads with no server associated are not allow to execute,
//they remain in a dormant state until they are either eliminated or
//bound again.
 
//Implementation dependent issue: in the implementation with an
//application scheduler, the thread is still attached to the fsf
//scheduler, but suspended.
 
int
fsf_get_server
(fsf_server_id_t *server,
pthread_t thread);
/shark/trunk/ports/first/include/fsf_server.h
0,0 → 1,33
#ifndef _FSF_SERVER_H_
#define _FSF_SERVER_H_
 
#define FSF_CBSSTAR
 
#ifdef FSF_CBSSTAR
 
#include "cbsstar.h"
#define SERVER_setbudget CBSSTAR_setbudget
#define SERVER_adjust_budget CBSSTAR_adjust_budget
#define SERVER_removebudget CBSSTAR_removebudget
#define SERVER_get_local_scheduler_id_from_budget CBSSTAR_get_local_scheduler_id_from_budget
#define SERVER_get_local_scheduler_id_from_pid CBSSTAR_get_local_scheduler_id_from_pid
#define SERVER_get_local_scheduler_level_from_budget CBSSTAR_get_local_scheduler_level_from_budget
#define SERVER_get_local_scheduler_level_from_pid CBSSTAR_get_local_scheduler_level_from_pid
#define SERVER_getbudgetinfo CBSSTAR_getbudgetinfo
 
#endif
 
#ifdef FSF_GRUBSTAR
 
#include "grubstar.h"
#define SERVER_setbudget GRUBSTAR_setbudget
#define SERVER_adjust_budget GRUBSTAR_adjust_budget
#define SERVER_removebudget GRUBSTAR_removebudget
#define SERVER_get_local_scheduler_id_from_server GRUBSTAR_get_local_scheduler_id_from_server
#define SERVER_get_local_scheduler_id_from_pid GRUBSTAR_get_local_scheduler_id_from_pid
#define SERVER_get_local_scheduler_level_from_server GRUBSTAR_get_local_scheduler_level_from_server
#define SERVER_get_local_scheduler_level_from_pid GRUBSTAR_get_local_scheduler_level_from_pid
 
#endif
 
#endif
/shark/trunk/ports/first/modules/posix.c
File deleted
/shark/trunk/ports/first/modules/cbsstar.c
67,6 → 67,7
 
struct timespec dline; /* deadline */
int dline_timer; /* oslib event for budget reactivation*/
int vtimer;
int avail; /* current budget */
LEVEL l; /* Current CBSSTAR level */
81,9 → 82,9
 
};
 
#define CBSSTAR_NOACTIVE 0
#define CBSSTAR_ACTIVE 1
#define CBSSTAR_INIT 2
#define CBSSTAR_NOACTIVE 0
#define CBSSTAR_ACTIVE 1
#define CBSSTAR_RECLAIMING 2
 
typedef struct {
level_des l; /* the standard level descriptor */
95,6 → 96,7
int tb[MAX_PROC]; /* link task->budget (used in guest_end) */
 
bandwidth_t U; /*+ the used bandwidth by the server +*/
bandwidth_t Uf; /*+ the actual used bandwidth by the server +*/
 
int cap_lev;
 
154,20 → 156,56
 
}
}
 
kern_gettime(&b->dline);
ADDUSEC2TIMESPEC(b->T, &b->dline);
if (b->flags == CBSSTAR_NOACTIVE) {
kern_gettime(&b->dline);
ADDUSEC2TIMESPEC(b->T, &b->dline);
b->dline_timer=kern_event_post(&b->dline, CBSSTAR_deadline_timer_hardreservation, b);
}
 
#ifdef CBSSTAR_DEBUG
cbsstar_printf(")");
#endif
 
}
 
void CBSSTAR_ANC(void *arg)
{
struct budget_struct *b = arg;
CBSSTAR_level_des *lev=(CBSSTAR_level_des *)level_table[b->l];
#ifdef CBSSTAR_DEBUG
cbsstar_printf("(CS:Rec:");
#endif
 
b->vtimer = NIL;
if (b->current != NIL && iq_query_first(&(b->tasks)) != NIL) {
bandwidth_t bw;
 
b->flags=CBSSTAR_RECLAIMING;
 
bw = (MAX_BANDWIDTH / b->T) * b->Q;
 
lev->Uf -= bw;
#ifdef CBSSTAR_DEBUG
cbsstar_printf("%ld",(long)bw);
#endif
 
}
 
#ifdef CBSSTAR_DEBUG
cbsstar_printf(")");
#endif
 
 
}
 
static void CBSSTAR_activation(CBSSTAR_level_des *lev,
PID p)
PID p,
struct timespec *acttime)
{
JOB_TASK_MODEL job;
struct budget_struct *b = &lev->b[lev->tb[p]];
174,11 → 212,46
/* we have to check if the deadline and the wcet are correct before
activating a new task or an old task... */
 
/* and the capacity */
if (b->flags == CBSSTAR_INIT) {
b->avail = b->Q;
b->flags = CBSSTAR_ACTIVE;
/* we have to check if the deadline and the wcet are correct before
* activating a new task or an old task... */
 
/* check 1: if the deadline is before than the actual scheduling time */
 
/* check 2: if ( avail_time >= (cbs_dline - acttime)* (wcet/period) )
* (rule 7 in the CBS article!) */
TIME t;
struct timespec t2,t3;
 
t = (b->T * b->avail) / b->Q;
t3.tv_sec = t / 1000000;
t3.tv_nsec = (t % 1000000) * 1000;
 
SUBTIMESPEC(&b->dline, acttime, &t2);
if (/* 1 */ TIMESPEC_A_LT_B(&b->dline, acttime) ||
/* 2 */ TIMESPEC_A_GT_B(&t3, &t2) ) {
TIMESPEC_ASSIGN(&b->dline, acttime);
ADDUSEC2TIMESPEC(b->T, &b->dline);
b->avail=b->Q;
if (b->flags==CBSSTAR_RECLAIMING) {
bandwidth_t bw;
bw = (MAX_BANDWIDTH / b->T) * b->Q;
 
lev->Uf += bw;
#ifdef CBSSTAR_DEBUG
cbsstar_printf("BW=%ld",(long)bw);
#endif
}
 
 
b->flags=CBSSTAR_ACTIVE;
 
}
else {
SUBTIMESPEC(&b->dline, &t3, &t2);
b->vtimer = kern_event_post(&t2, CBSSTAR_ANC, (void *)&b);
}
 
 
/* record the current task inserted in the master module */
212,7 → 285,16
 
if (b->avail <= 0) b->flags = CBSSTAR_NOACTIVE;
 
if (TIMESPEC_A_LT_B(&b->dline, &schedule_time)) {
/* we modify the deadline ... */
TIMESPEC_ASSIGN(&b->dline, &schedule_time);
ADDUSEC2TIMESPEC(b->T, &b->dline);
}
 
if (b->flags == CBSSTAR_NOACTIVE && b->dline_timer == NIL) {
b->dline_timer=kern_event_post(&b->dline, CBSSTAR_deadline_timer_hardreservation, b);
}
}
 
 
317,14 → 399,12
 
lev->tb[p] = budget->b;
 
 
kern_gettime(&lev->b[budget->b].dline);
ADDUSEC2TIMESPEC(lev->b[budget->b].T,&lev->b[budget->b].dline);
 
if (lev->b[budget->b].current == NIL && lev->b[budget->b].flags ) {
/* This is the first task in the budget,
the task have to be inserted into the master module */
CBSSTAR_activation(lev,p);
struct timespec t;
kern_gettime(&t);
CBSSTAR_activation(lev,p,&t);
} else {
/* The budget is not empty, another task is already into the
master module, so the task is inserted at the end of the budget
332,11 → 412,6
iq_insertlast(p,&lev->b[budget->b].tasks);
}
 
if (lev->b[budget->b].dline_timer == NIL) {
lev->b[budget->b].dline_timer = kern_event_post(&lev->b[budget->b].dline, CBSSTAR_deadline_timer_hardreservation, &lev->b[budget->b]);
}
 
 
#ifdef CBSSTAR_DEBUG
cbsstar_printf(")");
#endif
358,8 → 433,7
/* remove the task from execution (or from the ready queue) */
if (lev->b[lev->tb[p]].current == p) {
 
CBSSTAR_account_capacity(lev,p);
 
CBSSTAR_account_capacity(lev,p);
/* remove the task from the master module */
level_table[ lev->scheduling_level ]->
private_extract(lev->scheduling_level, p);
372,10 → 446,11
else if (lev->b[lev->tb[p]].flags) {
/* if so, insert the new task into the master module */
PID n;
 
struct timespec t;
kern_gettime(&t);
n = iq_getfirst(&lev->b[lev->tb[p]].tasks);
CBSSTAR_activation(lev,n);
CBSSTAR_activation(lev,n,&t); // it modifies b[lev->tb[p]].current
}
else
lev->b[lev->tb[p]].current=NIL;
484,9 → 559,9
lev->b[i].dline_timer = NIL;
lev->b[i].avail = 0;
lev->b[i].current = -1;
lev->b[i].flags = CBSSTAR_INIT;
lev->b[i].flags = CBSSTAR_ACTIVE;
lev->b[i].l=l;
iq_init(&lev->b[i].tasks, &freedesc, 0);
iq_init(&lev->b[i].tasks, /* &freedesc */NULL, 0);
}
 
lev->n = n;
496,6 → 571,7
lev->tb[i] = NIL;
 
lev->U = 0;
lev->Uf = 0;
lev->cap_lev = NIL;
lev->scheduling_level = master;
 
523,11 → 599,13
if (Q< T && MAX_BANDWIDTH - lev->U > b) {
lev->U += b;
lev->Uf += b;
lev->freebudgets++;
lev->b[r].Q = Q;
lev->b[r].T = T;
 
lev->b[r].avail = Q;
lev->b[r].flags = CBSSTAR_ACTIVE;
lev->b[r].loc_sched_id = scheduler_id;
lev->b[r].loc_sched_level = local_scheduler_level;
557,8 → 635,7
lev->b[budget].dline_timer = NIL;
lev->b[budget].avail = 0;
lev->b[budget].current = -1;
lev->b[budget].flags = CBSSTAR_INIT;
iq_init(&lev->b[budget].tasks, &freedesc, 0);
lev->b[budget].flags = CBSSTAR_ACTIVE;
 
return 0;
 
/shark/trunk/ports/first/modules/edfstar.c
16,16 → 16,6
* http://shark.sssup.it
*/
 
/**
------------
CVS : $Id: edfstar.c,v 1.4 2003-09-17 09:43:47 giacomo Exp $
 
File: $File$
Revision: $Revision: 1.4 $
Last update: $Date: 2003-09-17 09:43:47 $
------------
**/
 
/*
* Copyright (C) 2001 Paolo Gai
*
63,8 → 53,7
#include <kernel/iqueue.h>
 
/* for BUDGET_TASK_MODEL */
#include "cbsstar.h"
#include <comm_message.h>
#include "fsf_server.h"
 
/*
* DEBUG stuffs begin
300,45 → 289,6
private_dispatch(lev->scheduling_level,p,nostop);
}
 
static int EDFSTAR_private_change_level(LEVEL l, PID p)
{
 
EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
 
/* Change task level */
if (lev->flag[p] & EDFSTAR_CHANGE_LEVEL) {
STD_command_message msg;
proc_table[p].status = SLEEP;
level_table[lev->scheduling_level]->private_extract(lev->scheduling_level,p);
iq_extract(p,&lev->ready);
if (lev->deadline_timer[p] != -1)
kern_event_delete(lev->deadline_timer[p]);
EDFSTAR_check_preemption(lev);
lev->nact[p] = 0;
lev->budget[p] = -1;
proc_table[p].task_level = lev->new_level[p];
/* Send change level command to local scheduler */
 
msg.command = STD_ACTIVATE_TASK;
msg.param = NULL;
 
level_table[ lev->new_level[p] ]->public_message(lev->new_level[p],p,&msg);
return 1;
 
}
 
return 0;
 
}
 
static void EDFSTAR_public_epilogue(LEVEL l, PID p)
{
EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
347,8 → 297,6
edfstar_printf("(E:epi ");
#endif
 
if (EDFSTAR_private_change_level(l, p)) return;
 
/* check if the wcet is finished... */
if (proc_table[p].avail_time <= 0 && proc_table[p].control&CONTROL_CAP) {
/* wcet finished: disable wcet event and count wcet miss */
432,8 → 380,6
{
EDFSTAR_level_des *lev = (EDFSTAR_level_des *)(level_table[l]);
struct timespec temp;
STD_command_message *msg;
HARD_TASK_MODEL *h;
 
#ifdef EDFSTAR_DEBUG
edfstar_printf("(E:ecy ");
444,8 → 390,6
/* Task EndCycle */
case (long)(NULL):
 
if (EDFSTAR_private_change_level(l,p)) return 0;
 
/* we call guest_end directly here because the same task may
be reinserted in the queue before calling the preemption check! */
level_table[ lev->scheduling_level ]->
504,50 → 448,8
 
default:
 
msg = (STD_command_message *)m;
#ifdef EDFSTAR_DEBUG
edfstar_printf("(E:MSG %d)",msg->command);
#endif
switch(msg->command) {
case STD_SET_NEW_MODEL:
/* if the EDFSTAR_task_create is called, then the pclass must be a
valid pclass. */
h=(HARD_TASK_MODEL *)(msg->param);
break;
/* now we know that m is a valid model */
lev->wcet[p] = h->wcet;
lev->period[p] = h->mit;
lev->flag[p] = 0;
lev->deadline_timer[p] = -1;
lev->dline_miss[p] = 0;
lev->wcet_miss[p] = 0;
lev->nact[p] = 0;
 
break;
 
case STD_SET_NEW_LEVEL:
lev->flag[p] |= EDFSTAR_CHANGE_LEVEL;
lev->new_level[p] = (int)(msg->param);
 
break;
 
case STD_ACTIVATE_TASK:
/* Enable wcet check */
proc_table[p].avail_time = lev->wcet[p];
proc_table[p].wcet = lev->wcet[p];
proc_table[p].control |= CONTROL_CAP;
EDFSTAR_public_activate(l, p);
break;
 
}
}
return 0;
}
/shark/trunk/ports/first/modules/rmstar.c
16,16 → 16,6
* http://shark.sssup.it
*/
 
/**
------------
CVS : $Id: rmstar.c,v 1.1 2003-09-17 09:13:50 giacomo Exp $
 
File: $File$
Revision: $Revision: 1.1 $
Last update: $Date: 2003-09-17 09:13:50 $
------------
**/
 
/*
* Copyright (C) 2001 Paolo Gai
*
61,8 → 51,7
/* #include "iqueue.h" Now iqueues are the only queue type into the kernel */
 
/* for BUDGET_TASK_MODEL */
#include "cbsstar.h"
#include <comm_message.h>
#include "fsf_server.h"
 
/*
* DEBUG stuffs begin
224,44 → 213,6
#endif
}
 
static int RMSTAR_private_change_level(LEVEL l, PID p)
{
 
RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
 
/* Change task level */
if (lev->flag[p] & RMSTAR_CHANGE_LEVEL) {
STD_command_message msg;
proc_table[p].status = SLEEP;
level_table[lev->scheduling_level]->private_extract(lev->scheduling_level,p);
iq_extract(p,&lev->ready);
if (lev->deadline_timer[p] != -1)
kern_event_delete(lev->deadline_timer[p]);
RMSTAR_check_preemption(lev);
lev->nact[p] = 0;
lev->budget[p] = -1;
proc_table[p].task_level = lev->new_level[p];
/* Send change level command to local scheduler */
 
msg.command = STD_ACTIVATE_TASK;
msg.param = NULL;
 
level_table[ lev->new_level[p] ]->public_message(lev->new_level[p],p,&msg);
return 1;
 
}
 
return 0;
 
}
static void RMSTAR_timer_guest_deadline(void *par)
{
PID p = (PID) par;
332,8 → 283,6
rmstar_printf("(E:epi ");
#endif
 
if (RMSTAR_private_change_level(l, p)) return;
 
/* check if the wcet is finished... */
if (proc_table[p].avail_time <= 0 && proc_table[p].control&CONTROL_CAP) {
/* wcet finished: disable wcet event and count wcet miss */
417,8 → 366,6
{
RMSTAR_level_des *lev = (RMSTAR_level_des *)(level_table[l]);
struct timespec temp;
STD_command_message *msg;
HARD_TASK_MODEL *h;
 
#ifdef RMSTAR_DEBUG
rmstar_printf("(E:ecy ");
430,7 → 377,6
/* Task EndCycle */
case (long)(NULL):
 
if (RMSTAR_private_change_level(l,p)) return 0;
/* we call guest_end directly here because the same task may
be reinserted in the queue before calling the preemption check! */
level_table[ lev->scheduling_level ]->
486,48 → 432,7
break;
default:
 
msg = (STD_command_message *)m;
#ifdef RMSTAR_DEBUG
rmstar_printf("(E:MSG %d)",msg->command);
#endif
switch(msg->command) {
case STD_SET_NEW_MODEL:
/* if the RMSTAR_task_create is called, then the pclass must be a
valid pclass. */
h=(HARD_TASK_MODEL *)(msg->param);
/* now we know that m is a valid model */
lev->wcet[p] = h->wcet;
lev->period[p] = h->mit;
lev->flag[p] = 0;
lev->deadline_timer[p] = -1;
lev->dline_miss[p] = 0;
lev->wcet_miss[p] = 0;
lev->nact[p] = 0;
break;
 
case STD_SET_NEW_LEVEL:
lev->flag[p] |= RMSTAR_CHANGE_LEVEL;
lev->new_level[p] = (int)(msg->param);
break;
case STD_ACTIVATE_TASK:
/* Enable wcet check */
proc_table[p].avail_time = lev->wcet[p];
proc_table[p].wcet = lev->wcet[p];
proc_table[p].control |= CONTROL_CAP;
RMSTAR_public_activate(l, p);
break;
}
}
return 0;
/shark/trunk/ports/first/modules/grubstar.c
0,0 → 1,707
/*
* Project: S.Ha.R.K.
*
* Coordinators:
* Giorgio Buttazzo <giorgio@sssup.it>
* Paolo Gai <pj@gandalf.sssup.it>
*
* Authors :
* Paolo Gai <pj@gandalf.sssup.it>
* Massimiliano Giorgi <massy@gandalf.sssup.it>
* Luca Abeni <luca@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
*/
 
/*
* Copyright (C) 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
* 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 "cbsstar.h"
 
/*
* DEBUG stuffs begin
*/
//#define CBSSTAR_DEBUG
#ifdef CBSSTAR_DEBUG
 
static __inline__ void fake_printf(char *fmt, ...) {}
 
#define cbsstar_printf kern_printf
#define cbsstar_printf2 kern_printf
#define cbsstar_printf3 kern_printf
 
//#define cbsstar_printf fake_printf
//#define cbsstar_printf2 fake_printf
//#define cbsstar_printf3 fake_printf
 
#endif
/*
* DEBUG stuffs end
*/
 
/* this structure contains the status for a single budget */
struct budget_struct {
TIME Q; /* budget */
TIME T; /* period */
 
struct timespec dline; /* deadline */
int dline_timer; /* oslib event for budget reactivation*/
int vtimer;
int avail; /* current budget */
LEVEL l; /* Current CBSSTAR level */
int loc_sched_id; /* Local scheduler id */
LEVEL loc_sched_level; /* Local scheduler level */
PID current; /* the task currently put in execution */
int flags;
 
IQUEUE tasks; /* a FIFO queue for the tasks handled
using the budget */
 
};
 
#define CBSSTAR_NOACTIVE 0
#define CBSSTAR_ACTIVE 1
#define CBSSTAR_RECLAIMING 2
 
typedef struct {
level_des l; /* the standard level descriptor */
 
struct budget_struct *b; /* the budgets! */
int n; /* the maximum index for the budgets */
int freebudgets; /* number of free budgets; starts from n */
 
int tb[MAX_PROC]; /* link task->budget (used in guest_end) */
 
bandwidth_t U; /*+ the used bandwidth by the server +*/
bandwidth_t Uf; /*+ the actual used bandwidth by the server +*/
 
int cap_lev;
 
LEVEL scheduling_level;
 
} CBSSTAR_level_des;
 
 
static void CBSSTAR_deadline_timer_hardreservation(void *a)
{
struct budget_struct *b = a;
PID p;
#ifdef CBSSTAR_DEBUG
cbsstar_printf("(CS:HrdRes:");
#endif
 
b->dline_timer = NIL;
 
/* we modify the deadline according to rule 4 ... */
/* there is a while because if the wcet is << than the system tick
we need to postpone the deadline many times */
b->avail += b->Q;
if (b->avail > b->Q) b->avail = b->Q;
if (b->avail > 0) b->flags = CBSSTAR_ACTIVE;
 
/* avail may be <0 because a task executed via a shadow fo many time
b->current == NIL only if the prec task was finished and there
was not any other task to be put in the ready queue
... we are now activating the next task */
if (b->current == NIL && b->flags) {
if (iq_query_first(&(b->tasks)) != NIL) {
CBSSTAR_level_des *lev;
JOB_TASK_MODEL job;
p = iq_getfirst(&b->tasks);
#ifdef CBSSTAR_DEBUG
cbsstar_printf("%d",p);
#endif
 
kern_gettime(&b->dline);
ADDUSEC2TIMESPEC(b->T, &b->dline);
 
b->current = p;
 
lev = (CBSSTAR_level_des *)(level_table[b->l]);
job_task_default_model(job, b->dline);
job_task_def_noexc(job);
level_table[ lev->scheduling_level ]->
private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
event_need_reschedule();
 
}
}
if (b->flags == CBSSTAR_NOACTIVE) {
kern_gettime(&b->dline);
ADDUSEC2TIMESPEC(b->T, &b->dline);
b->dline_timer=kern_event_post(&b->dline, CBSSTAR_deadline_timer_hardreservation, b);
}
 
#ifdef CBSSTAR_DEBUG
cbsstar_printf(")");
#endif
 
}
 
void CBSSTAR_ANC(void *arg)
{
struct budget_struct *b = arg;
CBSSTAR_level_des *lev=(CBSSTAR_level_des *)level_table[b->l];
#ifdef CBSSTAR_DEBUG
cbsstar_printf("(CS:Rec:");
#endif
 
b->vtimer = NIL;
if (b->current != NIL && iq_query_first(&(b->tasks)) != NIL) {
bandwidth_t bw;
 
b->flags=CBSSTAR_RECLAIMING;
 
bw = (MAX_BANDWIDTH / b->T) * b->Q;
 
lev->Uf -= bw;
#ifdef CBSSTAR_DEBUG
cbsstar_printf("%ld",(long)bw);
#endif
 
}
 
#ifdef CBSSTAR_DEBUG
cbsstar_printf(")");
#endif
 
 
}
 
static void CBSSTAR_activation(CBSSTAR_level_des *lev,
PID p,
struct timespec *acttime)
{
JOB_TASK_MODEL job;
struct budget_struct *b = &lev->b[lev->tb[p]];
/* we have to check if the deadline and the wcet are correct before
activating a new task or an old task... */
 
/* we have to check if the deadline and the wcet are correct before
* activating a new task or an old task... */
 
/* check 1: if the deadline is before than the actual scheduling time */
 
/* check 2: if ( avail_time >= (cbs_dline - acttime)* (wcet/period) )
* (rule 7 in the CBS article!) */
TIME t;
struct timespec t2,t3;
 
t = (b->T * b->avail) / b->Q;
t3.tv_sec = t / 1000000;
t3.tv_nsec = (t % 1000000) * 1000;
 
SUBTIMESPEC(&b->dline, acttime, &t2);
if (/* 1 */ TIMESPEC_A_LT_B(&b->dline, acttime) ||
/* 2 */ TIMESPEC_A_GT_B(&t3, &t2) ) {
TIMESPEC_ASSIGN(&b->dline, acttime);
ADDUSEC2TIMESPEC(b->T, &b->dline);
b->avail=b->Q;
if (b->flags==CBSSTAR_RECLAIMING) {
bandwidth_t bw;
bw = (MAX_BANDWIDTH / b->T) * b->Q;
 
lev->Uf += bw;
#ifdef CBSSTAR_DEBUG
cbsstar_printf("BW=%ld",(long)bw);
#endif
}
 
 
b->flags=CBSSTAR_ACTIVE;
 
}
else {
SUBTIMESPEC(&b->dline, &t3, &t2);
b->vtimer = kern_event_post(&t2, CBSSTAR_ANC, (void *)&b);
}
 
 
/* record the current task inserted in the master module */
b->current = p;
 
job_task_default_model(job, b->dline);
job_task_def_noexc(job);
level_table[ lev->scheduling_level ]->
private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
 
}
 
static void CBSSTAR_account_capacity(CBSSTAR_level_des *lev, PID p)
{
struct timespec ty;
TIME tx;
struct budget_struct *b = &lev->b[lev->tb[p]];
 
if (lev->cap_lev != NIL && b->current == p) {
kern_event_delete(lev->cap_lev);
lev->cap_lev = NIL;
}
 
SUBTIMESPEC(&schedule_time, &cap_lasttime, &ty);
tx = TIMESPEC2USEC(&ty);
b->avail -= tx;
 
#ifdef CBSSTAR_DEBUG
kern_printf("(CS:Cap p%d av=%d)", p, b->avail);
#endif
 
if (b->avail <= 0) b->flags = CBSSTAR_NOACTIVE;
 
if (TIMESPEC_A_LT_B(&b->dline, &schedule_time)) {
/* we modify the deadline ... */
TIMESPEC_ASSIGN(&b->dline, &schedule_time);
ADDUSEC2TIMESPEC(b->T, &b->dline);
}
 
if (b->flags == CBSSTAR_NOACTIVE && b->dline_timer == NIL) {
b->dline_timer=kern_event_post(&b->dline, CBSSTAR_deadline_timer_hardreservation, b);
}
}
 
 
/* The on-line guarantee is enabled only if the appropriate flag is set... */
static int CBSSTAR_public_guarantee(LEVEL l, bandwidth_t *freebandwidth)
{
CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
 
#ifdef CBSSTAR_DEBUG
cbsstar_printf("(CS:Gua)");
#endif
 
if (*freebandwidth >= lev->U) {
*freebandwidth -= lev->U;
return 1;
}
else
return 0;
}
 
static void capacity_handler(void *l)
{
CBSSTAR_level_des *lev = l;
lev->cap_lev = NIL;
event_need_reschedule();
}
 
static int CBSSTAR_private_eligible(LEVEL l, PID p)
{
CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
struct budget_struct *b = &lev->b[lev->tb[p]];
JOB_TASK_MODEL job;
 
/* we have to check if the deadline and the wcet are correct...
if the CBSSTAR level schedules in background with respect to others
levels, there can be the case in witch a task is scheduled by
schedule_time > CBSSTAR_deadline; in this case (not covered in the
article because if there is only the standard scheduling policy
this never apply) we reassign the deadline */
if (b->current == p) {
if ( TIMESPEC_A_LT_B(&b->dline, &schedule_time)) {
if (lev->cap_lev!=NIL) {
kern_event_delete(lev->cap_lev);
lev->cap_lev=NIL;
}
/* we kill the current activation */
level_table[ lev->scheduling_level ]->
private_extract(lev->scheduling_level, p);
/* we modify the deadline ... */
TIMESPEC_ASSIGN(&b->dline, &schedule_time);
ADDUSEC2TIMESPEC(b->T, &b->dline);
 
/* and the capacity */
b->avail = b->Q;
b->flags = CBSSTAR_ACTIVE;
 
if (b->dline_timer!=NIL) {
kern_event_delete(b->dline_timer);
b->dline_timer=NIL;
}
/* and, finally, we reinsert the task in the master level */
job_task_default_model(job, b->dline);
job_task_def_noexc(job);
level_table[ lev->scheduling_level ]->
private_insert(lev->scheduling_level, p, (TASK_MODEL *)&job);
return -1;
}
}
 
return 0;
 
}
 
static void CBSSTAR_private_insert(LEVEL l, PID p, TASK_MODEL *m)
{
/* A task has been activated for some reason. Basically, the task is
inserted in the queue if the queue is empty, otherwise the task is
inserted into the master module, and an oslib event is posted. */
 
CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
BUDGET_TASK_MODEL *budget;
 
if (m->pclass != BUDGET_PCLASS ||
(m->level != 0 && m->level != l)) {
kern_raise(XINVALID_TASK, p);
return;
}
budget = (BUDGET_TASK_MODEL *)m;
 
#ifdef CBSSTAR_DEBUG
cbsstar_printf("(CS:PriIns:%d:%d", p, budget->b);
#endif
if (budget->b == -1)
return;
 
lev->tb[p] = budget->b;
 
if (lev->b[budget->b].current == NIL && lev->b[budget->b].flags ) {
/* This is the first task in the budget,
the task have to be inserted into the master module */
struct timespec t;
kern_gettime(&t);
CBSSTAR_activation(lev,p,&t);
} else {
/* The budget is not empty, another task is already into the
master module, so the task is inserted at the end of the budget
queue */
iq_insertlast(p,&lev->b[budget->b].tasks);
}
 
#ifdef CBSSTAR_DEBUG
cbsstar_printf(")");
#endif
 
}
 
static void CBSSTAR_private_extract(LEVEL l, PID p)
{
CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
 
#ifdef CBSSTAR_DEBUG
kern_printf("(CS:Ext:%d)", p);
#endif
 
/* a task is removed from execution for some reasons. It must be
that it is the first in its budget queue (only the first task in
a budget queue is put into execution!) */
 
/* remove the task from execution (or from the ready queue) */
if (lev->b[lev->tb[p]].current == p) {
 
CBSSTAR_account_capacity(lev,p);
/* remove the task from the master module */
level_table[ lev->scheduling_level ]->
private_extract(lev->scheduling_level, p);
 
/* check if the buffer has someone else to schedule */
if (iq_query_first(&lev->b[lev->tb[p]].tasks) == NIL) {
/* the buffer has no tasks! */
lev->b[lev->tb[p]].current = NIL;
}
else if (lev->b[lev->tb[p]].flags) {
/* if so, insert the new task into the master module */
PID n;
struct timespec t;
kern_gettime(&t);
n = iq_getfirst(&lev->b[lev->tb[p]].tasks);
CBSSTAR_activation(lev,n,&t); // it modifies b[lev->tb[p]].current
}
else
lev->b[lev->tb[p]].current=NIL;
 
}
else {
iq_extract(p, &lev->b[lev->tb[p]].tasks);
}
}
 
static void CBSSTAR_private_dispatch(LEVEL l, PID p, int nostop)
{
CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
struct timespec ty;
 
#ifdef CBSSTAR_DEBUG
kern_printf("(CS:Dsp:%d)", p);
#endif
 
/* the current task (that is the only one inserted in the master module
for the corresponding budget) is dispatched. Note that the current
task is not inserted in any FIFO queue, so the task does not have to
be extracted! */
 
/* ... then, we dispatch it to the master level */
level_table[ lev->scheduling_level ]->
private_dispatch(lev->scheduling_level,p,nostop);
 
/* ...and finally, we have to post a capacity event */
if (!nostop) {
TIMESPEC_ASSIGN(&ty, &schedule_time);
ADDUSEC2TIMESPEC(lev->b[lev->tb[p]].avail,&ty);
lev->cap_lev = kern_event_post(&ty,capacity_handler, lev);
}
}
 
static void CBSSTAR_private_epilogue(LEVEL l, PID p)
{
CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
struct budget_struct *b = &lev->b[lev->tb[p]];
 
#ifdef CBSSTAR_DEBUG
kern_printf("(CS:Epi:%d)",p);
#endif
 
if (p==b->current) {
CBSSTAR_account_capacity(lev,p);
 
// L'evento di capacità va cancellato perchè sarà ripristinato nella successiva dispatch
/* we have to check if the capacity is still available */
if (b->flags) {
/* there is capacity available, maybe it is simply a preemption;
the task have to return to the ready queue */
level_table[ lev->scheduling_level ]->
private_epilogue(lev->scheduling_level,p);
} else {
/* we kill the current activation */
level_table[ lev->scheduling_level ]->
private_extract(lev->scheduling_level, p);
 
iq_insertfirst(p, &b->tasks);
b->current = NIL;
}
}
 
}
 
/* Registration functions }*/
 
/*+ Registration function:
int flags the init flags ... see CBSSTAR.h +*/
LEVEL CBSSTAR_register_level(int n, LEVEL master)
{
LEVEL l; /* the level that we register */
CBSSTAR_level_des *lev; /* for readableness only */
PID i; /* a counter */
 
kern_printf("CBSSTAR_register_level\n");
 
/* request an entry in the level_table */
l = level_alloc_descriptor(sizeof(CBSSTAR_level_des));
 
lev = (CBSSTAR_level_des *)level_table[l];
 
/* fill the standard descriptor */
lev->l.private_insert = CBSSTAR_private_insert;
lev->l.private_extract = CBSSTAR_private_extract;
lev->l.private_eligible = CBSSTAR_private_eligible;
lev->l.private_dispatch = CBSSTAR_private_dispatch;
lev->l.private_epilogue = CBSSTAR_private_epilogue;
 
lev->l.public_guarantee = CBSSTAR_public_guarantee;
 
/* fill the CBSSTAR descriptor part */
lev->b = (struct budget_struct *)kern_alloc(sizeof(struct budget_struct)*n);
 
for (i=0; i<n; i++) {
lev->b[i].Q = 0;
lev->b[i].T = 0;
NULL_TIMESPEC(&lev->b[i].dline);
lev->b[i].dline_timer = NIL;
lev->b[i].avail = 0;
lev->b[i].current = -1;
lev->b[i].flags = CBSSTAR_ACTIVE;
lev->b[i].l=l;
iq_init(&lev->b[i].tasks, /* &freedesc */NULL, 0);
}
 
lev->n = n;
lev->freebudgets = 0;
 
for (i=0; i<MAX_PROC; i++)
lev->tb[i] = NIL;
 
lev->U = 0;
lev->Uf = 0;
lev->cap_lev = NIL;
lev->scheduling_level = master;
 
return l;
 
}
 
int CBSSTAR_setbudget(LEVEL l, TIME Q, TIME T, LEVEL local_scheduler_level, int scheduler_id)
{
CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
int r;
 
#ifdef CBSSTAR_DEBUG
cbsstar_printf("(CS:SetBud)");
#endif
 
for (r = 0; r < lev->n; r++)
if (lev->b[r].Q == 0) break;
 
if (r != lev->n) {
bandwidth_t b;
b = (MAX_BANDWIDTH / T) * Q;
/* really update lev->U, checking an overflow... */
if (Q< T && MAX_BANDWIDTH - lev->U > b) {
lev->U += b;
lev->Uf += b;
lev->freebudgets++;
lev->b[r].Q = Q;
lev->b[r].T = T;
lev->b[r].avail = Q;
lev->b[r].flags = CBSSTAR_ACTIVE;
lev->b[r].loc_sched_id = scheduler_id;
lev->b[r].loc_sched_level = local_scheduler_level;
return r;
}
else
return -2;
}
else
return -1;
}
 
int CBSSTAR_removebudget(LEVEL l, int budget)
{
 
CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
 
bandwidth_t b;
b = (MAX_BANDWIDTH / lev->b[budget].T) * lev->b[budget].Q;
 
lev->U -= b;
 
lev->b[budget].Q = 0;
lev->b[budget].T = 0;
NULL_TIMESPEC(&lev->b[budget].dline);
lev->b[budget].dline_timer = NIL;
lev->b[budget].avail = 0;
lev->b[budget].current = -1;
lev->b[budget].flags = CBSSTAR_ACTIVE;
 
return 0;
 
}
 
int CBSSTAR_adjust_budget(LEVEL l, TIME Q, TIME T, int budget)
{
 
CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
 
lev->b[budget].Q = Q;
lev->b[budget].T = T;
 
return 0;
 
}
 
int CBSSTAR_getbudgetinfo(LEVEL l, TIME *Q, TIME *T, int budget)
{
 
CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
*Q = lev->b[budget].Q;
*T = lev->b[budget].T;
 
return 0;
 
}
 
int CBSSTAR_is_active(LEVEL l, int budget)
{
CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
 
return lev->b[budget].flags;
 
}
 
int CBSSTAR_get_local_scheduler_level_from_budget(LEVEL l, int budget)
{
CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
 
return lev->b[budget].loc_sched_level;
 
}
 
int CBSSTAR_get_local_scheduler_level_from_pid(LEVEL l, PID p)
{
CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
 
return lev->b[lev->tb[p]].loc_sched_level;
 
}
 
int CBSSTAR_get_local_scheduler_id_from_budget(LEVEL l, int budget)
{
CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
 
return lev->b[budget].loc_sched_id;
 
}
 
int CBSSTAR_get_local_scheduler_id_from_pid(LEVEL l, PID p)
{
CBSSTAR_level_des *lev = (CBSSTAR_level_des *)(level_table[l]);
 
return lev->b[lev->tb[p]].loc_sched_id;
 
}
 
/shark/trunk/ports/first/modules/posixstar.c
44,8 → 44,7
#include <kernel/func.h>
#include <kernel/trace.h>
#include "posixstar.h"
#include "cbsstar.h"
#include "comm_message.h"
#include "fsf_server.h"
 
//#define POSIXSTAR_DEBUG
 
237,38 → 236,6
 
}
 
static int POSIXSTAR_private_change_level(LEVEL l, PID p)
{
 
POSIXSTAR_level_des *lev = (POSIXSTAR_level_des *)(level_table[l]);
 
/* Change task level */
if (lev->flag[p] & POSIXSTAR_CHANGE_LEVEL) {
STD_command_message msg;
proc_table[p].status = SLEEP;
 
level_table[lev->scheduling_level]->private_extract(lev->scheduling_level,p);
iq_extract(p,&lev->ready[lev->priority[p]]);
 
POSIXSTAR_private_scheduler(lev);
 
lev->nact[p] = 0;
lev->budget[p] = -1;
proc_table[p].task_level = lev->new_level[p];
msg.command = STD_ACTIVATE_TASK;
level_table[lev->new_level[p]] -> public_message(lev->new_level[p],p,&msg);
 
return 1;
 
}
 
return 0;
 
}
 
static void POSIXSTAR_public_epilogue(LEVEL l, PID p)
{
POSIXSTAR_level_des *lev = (POSIXSTAR_level_des *)(level_table[l]);
277,8 → 244,6
kern_printf("(PS:Epi:%d)",p);
#endif
 
if (POSIXSTAR_private_change_level(l,p)) return;
if (p==lev->activated) {
if (lev->yielding) {
lev->yielding = 0;
388,8 → 353,6
static int POSIXSTAR_public_message(LEVEL l, PID p, void *m)
{
POSIXSTAR_level_des *lev = (POSIXSTAR_level_des *)(level_table[l]);
STD_command_message *msg;
NRT_TASK_MODEL *nrt;
 
#ifdef POSIXSTAR_DEBUG
kern_printf("(PS:Msg:%d)",p);
400,8 → 363,6
/* Task EndCycle */
case (long)(NULL):
 
if (POSIXSTAR_private_change_level(l,p)) return 0;
 
if (lev->nact[p] > 0) {
/* continue!!!! */
lev->nact[p]--;
427,56 → 388,8
 
default:
 
msg = (STD_command_message *)m;
 
switch(msg->command) {
case STD_SET_NEW_LEVEL:
break;
lev->flag[p] |= POSIXSTAR_CHANGE_LEVEL;
lev->new_level[p] = (int)(msg->param);
 
break;
case STD_SET_NEW_MODEL:
 
nrt = (NRT_TASK_MODEL *)(msg->param);
 
lev->priority[p] = nrt->weight;
if (nrt->slice) {
lev->new_slice[p] = nrt->slice;
} else {
lev->new_slice[p] = 0;
}
if (nrt->policy == NRT_RR_POLICY)
lev->new_control[p] |= CONTROL_CAP;
if (nrt->arrivals == SAVE_ARRIVALS)
lev->nact[p] = 0;
else
lev->nact[p] = -1;
lev->flag[p] = 0;
 
break;
case STD_ACTIVATE_TASK:
 
if (lev->new_slice[p]) {
proc_table[p].avail_time = lev->new_slice[p];
proc_table[p].wcet = lev->new_slice[p];
} else {
proc_table[p].avail_time = lev->slice;
proc_table[p].wcet = lev->slice;
}
 
proc_table[p].control |= lev->new_control[p];
 
POSIXSTAR_public_activate(l,p);
 
break;
}
 
}
 
return 0;
/shark/trunk/ports/first/first-server.c
12,12 → 12,7
//=====================================================================
 
#include "fsf_contract.h"
#include "cbsstar.h"
#include "posixstar.h"
#include "rmstar.h"
#include "edfstar.h"
#include "posix.h"
#include "comm_message.h"
#include "fsf_server.h"
 
#include <pthread.h>
#include <stdlib.h>
24,16 → 19,14
 
//#define FSF_DEBUG
 
int fsf_cbsstar_level;
int fsf_posix_level;
int fsf_server_level;
 
int FSF_register_module(int posix_level, int cbsstar_level)
int FSF_register_module(int server_level)
{
 
printk("FSF Module\n");
 
fsf_posix_level = posix_level;
fsf_cbsstar_level = cbsstar_level;
fsf_server_level = server_level;
 
return 0;
 
42,7 → 35,7
/* Convert the contract specification to
* budget parameters
*/
int set_CBSSTAR_budget_from_contract
int set_SERVER_budget_from_contract
(const fsf_contract_parameters_t *contract,
int *budget)
{
51,17 → 44,17
 
switch (contract->local_scheduler_id) {
case FSF_SCHEDULER_POSIX:
local_scheduler_level = POSIXSTAR_register_level(fsf_cbsstar_level,5000,32);
local_scheduler_level = POSIXSTAR_register_level(fsf_server_level,5000,32);
break;
case FSF_SCHEDULER_EDF:
local_scheduler_level = EDFSTAR_register_level(fsf_cbsstar_level);
local_scheduler_level = EDFSTAR_register_level(fsf_server_level);
break;
case FSF_SCHEDULER_RM:
local_scheduler_level = RMSTAR_register_level(fsf_cbsstar_level);
local_scheduler_level = RMSTAR_register_level(fsf_server_level);
break;
}
*budget = CBSSTAR_setbudget(fsf_cbsstar_level,
*budget = SERVER_setbudget(fsf_server_level,
TIMESPEC2USEC(&(contract->budget_min)),
TIMESPEC2USEC(&(contract->period_max)),
local_scheduler_level,contract->local_scheduler_id);
70,15 → 63,15
 
}
 
int adjust_CBSSTAR_budget_from_contract
int adjust_SERVER_budget_from_contract
(const fsf_contract_parameters_t *contract,
int budget)
{
 
CBSSTAR_adjust_budget(fsf_cbsstar_level,
TIMESPEC2USEC(&(contract->budget_min)),
TIMESPEC2USEC(&(contract->period_max)),
budget);
SERVER_adjust_budget(fsf_server_level,
TIMESPEC2USEC(&(contract->budget_min)),
TIMESPEC2USEC(&(contract->period_max)),
budget);
 
return 0;
 
121,8 → 114,8
if (add_contract(contract))
return FSF_ERR_CONTRACT_REJECTED;
 
/* SERVER = BUDGET */
set_CBSSTAR_budget_from_contract(contract,server);
/* SERVER => BUDGET */
set_SERVER_budget_from_contract(contract,server);
 
#ifdef FSF_DEBUG
kern_printf("(New Server %d)",*server);
137,107 → 130,58
 
}
 
int fsf_bind_thread_to_server
(fsf_server_id_t server,
pthread_t thread,
void *rt_arg)
int fsf_create_thread
(fsf_server_id_t server,
pthread_t *thread,
pthread_attr_t *attr,
fsf_thread_code_t thread_code,
void *arg,
void *local_scheduler_arg)
{
 
STD_command_message *msg;
NRT_TASK_MODEL nrt;
int local_scheduler_level,scheduler_id;
 
/* Move thread from the posix module to local scheduler */
 
#ifdef FSF_DEBUG
kern_printf("(Bind thread = %d to Server = %d)",thread,server);
kern_printf("(FSF:Insert thread = %d to Server = %d)",thread,server);
#endif
 
/* Check if server and thread exsist */
if (server == -1 || thread == -1)
return FSF_ERR_BIND_THREAD;
if (server == NIL)
return FSF_ERR_INVALID_SERVER;
 
local_scheduler_level = CBSSTAR_get_local_scheduler_level_from_budget(fsf_cbsstar_level,server);
scheduler_id = CBSSTAR_get_local_scheduler_id_from_budget(fsf_cbsstar_level,server);
local_scheduler_level = SERVER_get_local_scheduler_level_from_budget(fsf_server_level,server);
scheduler_id = SERVER_get_local_scheduler_id_from_budget(fsf_server_level,server);
 
/* Check if thread is already bind */
switch (scheduler_id) {
case FSF_SCHEDULER_POSIX:
if (POSIXSTAR_getbudget(local_scheduler_level,thread) != -1)
return FSF_ERR_BIND_THREAD;
 
/* Set server on local scheduler */
POSIXSTAR_setbudget(local_scheduler_level,thread,(int)(server));
nrt_task_default_model(nrt);
nrt_task_def_save_arrivals(nrt);
nrt_task_def_arg(nrt,arg);
nrt_task_def_ctrl_jet(nrt);
nrt_task_def_level(nrt,local_scheduler_level);
 
/* Send change level command to posix level */
msg = (STD_command_message *)malloc(sizeof(STD_command_message));
*thread = task_create("POSIXSTAR", thread_code, &nrt, NULL);
if (*thread == NIL)
return FSF_ERR_CREATE_THREAD;
 
#ifdef FSF_DEBUG
kern_printf("(MSG POSIXSTAR LEV %d SER %d THR %d)",local_scheduler_level,server,thread);
#endif
POSIXSTAR_setbudget(local_scheduler_level, *thread, (int)(server));
 
msg->command = STD_SET_NEW_MODEL;
msg->param = (void *)(rt_arg);
level_table[local_scheduler_level]->public_message(local_scheduler_level,thread,msg);
task_activate(*thread);
 
msg->command = STD_SET_NEW_LEVEL;
msg->param = (void *)(local_scheduler_level);
task_message(msg,thread,0);
free(msg);
 
break;
case FSF_SCHEDULER_EDF:
 
if (EDFSTAR_getbudget(local_scheduler_level,thread) != -1)
return FSF_ERR_BIND_THREAD;
 
/* Set server on local scheduler */
EDFSTAR_setbudget(local_scheduler_level,thread,(int)(server));
 
/* Send change level command to posix level */
msg = (STD_command_message *)malloc(sizeof(STD_command_message));
 
#ifdef FSF_DEBUG
kern_printf("(MSG EDFSTAR LEV %d SEV %d THR %d)",local_scheduler_level,server,thread);
#endif
 
msg->command = STD_SET_NEW_MODEL;
msg->param = (void *)(rt_arg);
level_table[local_scheduler_level]->public_message(local_scheduler_level,thread,msg);
 
msg->command = STD_SET_NEW_LEVEL;
msg->param = (void *)(local_scheduler_level);
task_message(msg,thread,0);
free(msg);
 
break;
 
case FSF_SCHEDULER_RM:
 
if (RMSTAR_getbudget(local_scheduler_level,thread) != -1)
return FSF_ERR_BIND_THREAD;
 
/* Set server on local scheduler */
RMSTAR_setbudget(local_scheduler_level,thread,(int)(server));
 
/* Send change level command to posix level */
msg = (STD_command_message *)malloc(sizeof(STD_command_message));
 
#ifdef FSF_DEBUG
kern_printf("(MSG RMSTAR LEV %d SEV %d THR %d)",local_scheduler_level,server,thread);
#endif
 
msg->command = STD_SET_NEW_MODEL;
msg->param = (void *)(rt_arg);
level_table[local_scheduler_level]->public_message(local_scheduler_level,thread,msg);
 
msg->command = STD_SET_NEW_LEVEL;
msg->param = (void *)(local_scheduler_level);
task_message(msg,thread,0);
 
default:
return FSF_ERR_BIND_THREAD;
return FSF_ERR_INVALID_SERVER;
break;
}
 
245,164 → 189,6
}
 
int fsf_unbind_thread_from_server
(pthread_t thread)
{
 
int local_scheduler_level, scheduler_id;
 
/* Move thread from the local scheduler module to posix level */
 
#ifdef FSF_DEBUG
kern_printf("(UnBind thread = %d)",thread);
#endif
 
/* Check if thread exsists */
if (thread == -1)
return FSF_ERR_UNBIND_THREAD;
 
local_scheduler_level = CBSSTAR_get_local_scheduler_level_from_pid(fsf_cbsstar_level,thread);
scheduler_id = CBSSTAR_get_local_scheduler_id_from_pid(fsf_cbsstar_level,thread);
 
switch (scheduler_id) {
case FSF_SCHEDULER_POSIX:
/* Check if it is bind to a server */
if (POSIXSTAR_getbudget(local_scheduler_level,thread) == -1)
return FSF_ERR_UNBIND_THREAD;
else {
STD_command_message *msg;
NRT_TASK_MODEL nrt;
 
nrt_task_default_model(nrt);
nrt_task_def_save_arrivals(nrt);
 
/* Send change level command to local scheduler */
msg = (STD_command_message *)malloc(sizeof(STD_command_message));
 
msg->command = STD_SET_NEW_MODEL;
msg->param = (void *)(&nrt);
level_table[fsf_posix_level]->public_message(fsf_posix_level,thread,msg);
 
msg->command = STD_SET_NEW_LEVEL;
msg->param = (void *)(fsf_posix_level);
task_message(msg,thread,0);
 
free(msg);
}
break;
case FSF_SCHEDULER_EDF:
 
if (EDFSTAR_getbudget(local_scheduler_level,thread) == -1)
return FSF_ERR_UNBIND_THREAD;
else {
STD_command_message *msg;
NRT_TASK_MODEL nrt;
 
nrt_task_default_model(nrt);
nrt_task_def_save_arrivals(nrt);
 
/* Send change level command to local scheduler */
msg = (STD_command_message *)malloc(sizeof(STD_command_message));
 
msg->command = STD_SET_NEW_MODEL;
msg->param = (void *)(&nrt);
level_table[fsf_posix_level]->public_message(fsf_posix_level,thread,msg);
 
msg->command = STD_SET_NEW_LEVEL;
msg->param = (void *)(fsf_posix_level);
task_message(msg,thread,0);
 
free(msg);
}
break;
 
case FSF_SCHEDULER_RM:
 
if (RMSTAR_getbudget(local_scheduler_level,thread) == -1)
return FSF_ERR_UNBIND_THREAD;
else {
 
STD_command_message *msg;
NRT_TASK_MODEL nrt;
 
nrt_task_default_model(nrt);
nrt_task_def_save_arrivals(nrt);
 
/* Send change level command to local scheduler */
msg = (STD_command_message *)malloc(sizeof(STD_command_message));
 
msg->command = STD_SET_NEW_MODEL;
msg->param = (void *)(&nrt);
level_table[fsf_posix_level]->public_message(fsf_posix_level,thread,msg);
 
msg->command = STD_SET_NEW_LEVEL;
msg->param = (void *)(fsf_posix_level);
task_message(msg,thread,0);
 
free(msg);
 
}
 
break;
}
 
return 0;
 
}
 
int fsf_negotiate_contract_for_new_thread
(const fsf_contract_parameters_t *contract,
fsf_server_id_t *server,
pthread_t *thread,
pthread_attr_t *attr,
fsf_thread_code_t thread_code,
void *arg,
void *rt_arg)
 
{
 
int error;
 
/* Create server */
error = fsf_negotiate_contract(contract, server);
if (error) return error;
 
/* Create pthread */
if (pthread_create(thread, attr, thread_code, arg))
return FSF_ERR_CREATE_THREAD;
 
/* Bind thread to server */
error = fsf_bind_thread_to_server(*server, *thread, rt_arg);
if (error) return error;
 
return 0;
 
}
 
int fsf_negotiate_contract_for_myself
(const fsf_contract_parameters_t *contract,
fsf_server_id_t *server,
void *rt_arg)
{
 
int error;
 
/* Create server */
error = fsf_negotiate_contract(contract, server);
if (error) return error;
 
/* Bind current thread to server */
error = fsf_bind_thread_to_server(*server, exec_shadow, rt_arg);
if (error) return error;
 
return 0;
 
}
 
int fsf_get_server
(fsf_server_id_t *server,
pthread_t thread)
409,8 → 195,8
{
int local_scheduler_level, scheduler_id;
 
local_scheduler_level = CBSSTAR_get_local_scheduler_level_from_pid(fsf_cbsstar_level,thread);
scheduler_id = CBSSTAR_get_local_scheduler_id_from_pid(fsf_cbsstar_level, thread);
local_scheduler_level = SERVER_get_local_scheduler_level_from_pid(fsf_server_level,thread);
scheduler_id = SERVER_get_local_scheduler_id_from_pid(fsf_server_level, thread);
 
switch (scheduler_id) {
case FSF_SCHEDULER_POSIX:
441,8 → 227,8
if (*server < 0)
return FSF_ERR_INVALID_SERVER;
 
local_scheduler_level = CBSSTAR_get_local_scheduler_level_from_budget(fsf_cbsstar_level,*server);
scheduler_id = CBSSTAR_get_local_scheduler_id_from_budget(fsf_cbsstar_level,*server);
local_scheduler_level = SERVER_get_local_scheduler_level_from_budget(fsf_server_level,*server);
scheduler_id = SERVER_get_local_scheduler_id_from_budget(fsf_server_level,*server);
 
switch (scheduler_id) {
case FSF_SCHEDULER_POSIX:
466,7 → 252,7
break;
}
 
CBSSTAR_removebudget(fsf_cbsstar_level,*server);
SERVER_removebudget(fsf_server_level,*server);
 
level_free_descriptor(local_scheduler_level);
 
493,6 → 279,7
if (server < 0)
return FSF_ERR_INVALID_SERVER;
 
return adjust_CBSSTAR_budget_from_contract(new_contract,server);
return adjust_SERVER_budget_from_contract(new_contract,server);
 
}
 
/shark/trunk/ports/first/makefile
11,7 → 11,7
OBJS_PATH = $(BASE)/ports/first
 
FIRST = first-contract.o first-server.o first-sync.o \
./modules/cbsstar.o ./modules/posixstar.o ./modules/posix.o \
./modules/cbsstar.o ./modules/posixstar.o \
./modules/edfstar.o ./modules/rmstar.o
 
OBJS = $(FIRST)