Rev 2 |
Rev 29 |
Go to most recent revision |
Blame |
Compare with Previous |
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>
* 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: descr.h,v 1.1.1.1 2002-03-29 14:12:51 pj Exp $
File: $File$
Revision: $Revision: 1.1.1.1 $
Last update: $Date: 2002-03-29 14:12:51 $
------------
Kernel main data structures
This file declare:
- the descriptors
- cleanup handlers
- levels
- mutexes
- mutex attributes
- resource levels
**/
/*
* Copyright (C) 2000 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 __KERNEL_DESCR_H__
#define __KERNEL_DESCR_H__
#include <ll/ll.h>
#include <kernel/model.h>
#include <kernel/types.h>
#include <limits.h>
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CLEANUP HANDLER STRUCTURES
Derived directly from posix standard, B.18.2.3
This structure implements the task cleanup functions queue...
look at kern.c!
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
struct _task_handler_rec {
void (*f)(void *);
void *a;
struct _task_handler_rec *next;
};
struct condition_struct;
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
GENERAL TASK DESCRIPTOR
In this type definition there is all the basic information for
handling a task in the system.
All the informations scheduler-dependent (like deadline, priority,
and so on) are put in the level module files.
In any case, a priority field is inserted to simplify the implementation
of most of the scheduling algorithms
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
typedef struct {
DWORD task_ID; /*+ progressive task counter ID +*/
LEVEL task_level; /*+ the "real" level that owns the task +*/
CONTEXT context; /*+ Context area pointer (see vm.h) +*/
BYTE *stack; /*+ Pointer to stack area base +*/
TASK (*body)(); /*+ Pointer to the code of the task
(starting address) +*/
char name[MAX_TASKNAME]; /*+ Text identifing the process name +*/
WORD status; /*+ actual task status
(it could be EXE, SLEEP, IDLE, ...) +*/
WORD pclass; /*+ The code number of the task model used +*/
WORD group; /*+ 0 if task is single, else group id +*/
WORD stacksize; /*+ Task stack size +*/
DWORD control; /*+ Control task operating mode
Refer to the TASK_MODEL type for its use +*/
int frozen_activations; /*+ number of frozen activation;
see kern.c, task_block_activations
see model.h,flag in control field +*/
/* sigset_t!!! */
int sigmask; /*+ The task signal mask +*/
int sigpending; /*+ The signal pending mask +*/
int sigwaiting; /*+ The signal waiting mask +*/
struct timespec request_time;
/*+ Last request time for the task +*/
int avail_time; /*+ the time the task can execute before a
timer fire. see also the control field
and bits related in model.h +*/
PID shadow; /*+ Shadow task +*/
struct _task_handler_rec *cleanup_stack;
/*+ The cleanup stack +*/
QUEUE next,prev; /*+ Next/Prev Index in the queue +*/
int errnumber;
/* Job Execution Time fields */
TIME jet_table[JET_TABLE_DIM];
/*+ Execution time of the last
activations of the task. +*/
int jet_tvalid; /*+ number of valid entry in the jet_table +*/
int jet_curr; /*+ Current entry in the jet_table +*/
TIME jet_max; /*+ Maximum Execution time since task_create
or last jet_delstat +*/
TIME jet_sum; /*+ Mean Execution time since task_create
or last jet_delstat +*/
TIME jet_n; /*+ Number of instances on witch the mean
time have to be computed +*/
/* task_join fields */
PID waiting_for_me; /*+ the task that waits my dead,
NIL if there aren't +*/
void *return_value; /*+ task return value +*/
/* task specific data (it uses directly POSIX constant) */
void *keys[PTHREAD_KEYS_MAX];
/* condition variable field */
struct condition_struct *cond_waiting;
/*+ the condition on that the task is
waiting +*/
/* stuff used in most algorithms; they are not used directly in
* the generic kernel, with exclusion of delay_timer that is used
* also in cond_timedwait
*/
DWORD priority; /*+ A priority field +*/
struct timespec timespec_priority; /*+ Another priority field +*/
int delay_timer; /*+ A field useful to store the delay timer +*/
int wcet; /*+ a worst case time execution +*/
} proc_des;
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
LEVEL DESCRIPTOR
In this type definition there is all the basic information for
handling a scheduling level in the system.
All the informations that depends on the particular module are put
in the level module files.
The initialization of a level is splitted in two parts:
- the registration -> called before the system initialization, typically
AFTER the resource registration
- the level_init -> called during the system initialization,
BEFORE the resource_init(s)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
typedef struct {
char level_name[MAX_LEVELNAME]; /*+ for statistical pourposes +*/
WORD level_code; /*+ level identification code +*/
BYTE level_version; /*+ level version +*/
/* LEVEL CALLS */
int (*level_accept_task_model)(LEVEL l, TASK_MODEL *m);
/*+ models that a task can manage. returns
0 if the level can manage the model,
-1 if not +*/
int (*level_accept_guest_model)(LEVEL l, TASK_MODEL *m);
/*+ models that a task can manage as guest
tasks. returns
0 if the level can manage the model,
-1 if not +*/
// void (*level_init)(); /*+ initialization of the level module +*/
// void (*level_end)(); /*+ level termination (at system end... +*/
void (*level_status)(LEVEL l);/*+ print level statistics... +*/
PID (*level_scheduler)(LEVEL l);
/*+ the level scheduler returns a task
chosen among those belonging to the
level +*/
int (*level_guarantee)(LEVEL l, bandwidth_t *freebandwidth);
/*+ 0 if the level is guaranteed, -1 if not
no guarantee if (*f)()=null
the function updates the parameter
(see guarantee() ) +*/
/* TASK CALLS */
int (*task_create)(LEVEL l, PID p, TASK_MODEL *m);
/*+ the task p is created into the level
returns 0->ok, -1->error +*/
void (*task_detach)(LEVEL l, PID p);
/*+ there is an error in the task_create
after the task call task_create.
The function delete all the informations
about the task in the level.
For the resources levels there is the
res_detach: res_detach is called also
when killing a task +*/
int (*task_eligible)(LEVEL l, PID p);
/*+ correctness control when a task is
chosen by a level scheduler (used with
aperiodic servers) 0->ok, -1->no +*/
void (*task_dispatch)(LEVEL l, PID p, int nostop);
/*+ a task go in the EXEC status (called
by dispatch() ) +*/
void (*task_epilogue)(LEVEL l, PID p);
/*+ a task has finished the current slice+*/
void (*task_activate)(LEVEL l, PID p);
/*+ the task is activated... +*/
void (*task_insert)(LEVEL l, PID p);
/*+ opposite to task_extract +*/
void (*task_extract)(LEVEL l, PID p);
/*+ remove the task from the "ready" (if any)
queue +*/
void (*task_endcycle)(LEVEL l, PID p);
/*+ the (periodic) task finish the cycle +*/
void (*task_end)(LEVEL l, PID p);
/*+ the task is killed; we have to remove
it from the level queues, test if it
is in the exec state, etc... it can
modify the state of the task (-> FREE,
ZOMBIE...), but
cannot call the scheduler directly (it
is called by the task_makefree.
Note: the task can be in a state
different from those managed by the
level because the task may be blocked.
the res_detach is in any case called
AFTER the task_end. +*/
void (*task_sleep)(LEVEL l, PID p);
/*+ this function will fall asleep the
task in the EXE state. +*/
void (*task_delay)(LEVEL l, PID p,DWORD tickdelay);
/* guest CALLS:
these functions are called from an Aperiodic Server Level for the task
that are inserted in the local queues */
int (*guest_create)(LEVEL l, PID p, TASK_MODEL *m);
/*+ the task is already created in another
level and it is inserted in the current
level; returns 0->ok, -1->error +*/
void (*guest_detach)(LEVEL l, PID p);
/*+ there is an error in a task creation
of a task made by an aperiodic server
The function delete all the informations
about the task in the level. +*/
void (*guest_dispatch)(LEVEL l, PID p, int nostop);
/*+ a task belonging to another level but
inserted in the current level go in the
EXEC status (called by dispatch() ) +*/
void (*guest_epilogue)(LEVEL l, PID p);
/*+ a task has finished the current slice+*/
void (*guest_activate)(LEVEL l, PID p);
/*+ the task is activated... +*/
void (*guest_insert)(LEVEL l, PID p);
/*+ remove the task from the "ready" (if any)
queue +*/
void (*guest_extract)(LEVEL l, PID p);
/*+ opposite to guest_insert +*/
void (*guest_endcycle)(LEVEL l, PID p);
/*+ the task finish the cycle +*/
void (*guest_end)(LEVEL l, PID p);
/*+ the task is killed +*/
void (*guest_sleep)(LEVEL l, PID p);
void (*guest_delay)(LEVEL l, PID p, TIME tickdelay);
} level_des;
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
RESOURCE DESCRIPTOR
In this type definition there is all the basic information for
handling a resource module in the system.
All the informations protocol-dependent (like ceiling, task that use
a particular resource, and so on) are put in the resource module files.
In general, the initialization of a resource module is splitted in two
parts:
- the registration -> tipically done with a finction called
XXX_register_module. It is called before the
system initialization, in
the function __kernel_register_levels__().
- the initialization -> called during the system initialization,
This is done posting some init functions with
the sys_at_init()
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
typedef struct {
char res_name[MAX_MODULENAME];/*+ for statistical pourposes +*/
WORD res_code; /*+ resource module identification code +*/
BYTE res_version; /*+ resource module version +*/
int rtype; /*+ resource module extented interface
code (see model.h) +*/
void (*resource_status)(); /*+ print resource protocol statistics...+*/
int (*level_accept_resource_model)(RLEVEL l, RES_MODEL *r);
/*+ this function is called when the process
is created. it returns 0 if the RES_MODEL
can be managed by the level,-1 if not+*/
void (*res_register)(RLEVEL l, PID p, RES_MODEL *r);
/*+ When the system knows that a resource
model can be registered by a level,
it calls this function. It registers all
the information about the task and the
model. +*/
void (*res_detach)(RLEVEL l, PID p);
/*+ this function is called when the task
is killed or some error is occurred
in the task_create. It have to unlink
the task from the module... If the task
is already unlinked from the protocol
no action is done +*/
} resource_des;
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MUTEX DESCRIPTOR
In this type definition there is all the basic fields for
handling a mutex in the system
Many of the informations protocol-dependent (like ceiling, and so on)
are put in the resource module or are pointef by the field opt.
The opt field is used because in this way a mutex can be allocated in
a dynamic way (in this case opt points to a dynamically allocated
structure) or in a static way (in this case opt can be an index or a
pointer to a static structure)
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
typedef struct {
RLEVEL mutexlevel; /*+ protocol used by the mutex. +*/
int use; /*+ the mutex is used in a condition wait... +*/
void *opt;
} mutex_t;
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MUTEX RESOURCE DESCRIPTOR
This object is a resource_des object with a set of functions used to
implement the mutex behaviour.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
typedef struct {
resource_des r;
int (*level_accept_mutexattr)(RLEVEL l, const mutexattr_t *a);
/*+ this function is called when a mutex
is created. it returns 0 if the
mutexattr_t
can be managed by the level,-1 if not+*/
int (*init) (RLEVEL l, mutex_t *m, const mutexattr_t *a);
int (*destroy)(RLEVEL l, mutex_t *m);
int (*lock) (RLEVEL l, mutex_t *m);
int (*trylock)(RLEVEL l, mutex_t *m);
int (*unlock) (RLEVEL l, mutex_t *m);
} mutex_resource_des;
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CONDITION VARIABLE DESCRIPTOR
This is the condition variable descriptor.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
typedef struct condition_struct {
QUEUE waiters; /*+ queue for tasks waiting on the condition +*/
mutex_t *used_for_waiting;
} cond_t;
#endif /* __TYPE_H__ */