Rev 657 |
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.5 2004-05-17 15:03:50 anton Exp $
File: $File$
Revision: $Revision: 1.5 $
Last update: $Date: 2004-05-17 15:03:50 $
------------
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 <kernel/iqueue.h>
#include <limits.h>
#include "ll/sys/cdefs.h"
__BEGIN_DECLS
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
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 +*/
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 +*/
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
*/
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.
Here a small description of the various functions:
-------------------------------------------------------------------
- PUBLIC Functions:
on one side, a module should export an interface to the Generic
Kernel, giving a set of functions that the Generic Kernel can use
to ask a service to the module. That is, the Public Functions are
called ONLY by the Generic Kernel.
- PRIVATE Functions: on the other side, a module can export an
interface to the public part of the same or of another
module. That is, Private Functions are called ONLY by Public and
Private Functions.
-------------------------------------------------------------------
int (*private_insert )(LEVEL l, PID p, TASK_MODEL *m);
Inserts a task into the internal module data structure.
void (*private_extract )(LEVEL l, PID p);
Removes a task from the internal module data structure.
int (*private_eligible)(LEVEL l, PID p);
A task inserted into the internal module data structure needs to be
scheduled. returns 0 if it can be scheduled, -1 if not.
void (*private_dispatch)(LEVEL l, PID p, int nostop);
A task inserted into the internal module data structure has been dispatched.
void (*private_epilogue)(LEVEL l, PID p);
A task inserted into the internal module data structure has been preempted.
PID (*public_scheduler)(LEVEL l);
returns a task to schedule, or -1 if no tasks are ready
int (*public_guarantee)(LEVEL l, bandwidth_t *freebandwidth);
returns 0 if the level is guaranteed, -1 if not
no guarantee if (*f)()=null
the function updates the parameter freebandwidth (see guarantee() )
int (*public_create )(LEVEL l, PID p, TASK_MODEL *m);
the task p is created into the module
returns 0->ok, -1->error
void (*public_detach )(LEVEL l, PID p);
there is an error in the public_create. The function removes all the
informations about the task in the module.
void (*public_end )(LEVEL l, PID p);
the task has been killed, or it ended regularly
int (*public_eligible )(LEVEL l, PID p);
A task needs to be scheduled. returns 0 if it can be scheduled, -1 if not.
void (*public_dispatch )(LEVEL l, PID p, int nostop);
A task has been dispatched.
void (*public_epilogue )(LEVEL l, PID p);
A task has been preempted (or its capacity is exausted).
void (*public_activate )(LEVEL l, PID p, struct timespec *t);
A task has been activated.
void (*public_unblock )(LEVEL l, PID p);
void (*public_block )(LEVEL l, PID p);
A task has been unblocked/blocked on a synchronization point
(e.g. a semaphore, a mailbox, a nanosleep).
int (*public_message )(LEVEL l, PID p, void *m);
A task sent a message m to the module.
If the message has value NULL the
behavior should be the task_endcycle primitive behavior.
The function returns an integer to the user.
If you want to avoid the call to public_epilogue, after public_message,
just write exec = exec_shadow = -1; in your public_message code.
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*/
typedef struct {
void (*private_insert )(LEVEL l, PID p, TASK_MODEL *m);
void (*private_extract )(LEVEL l, PID p);
int (*private_eligible)(LEVEL l, PID p);
void (*private_dispatch)(LEVEL l, PID p, int nostop);
void (*private_epilogue)(LEVEL l, PID p);
PID (*public_scheduler)(LEVEL l);
int (*public_guarantee)(LEVEL l, bandwidth_t *freebandwidth);
int (*public_create )(LEVEL l, PID p, TASK_MODEL *m);
void (*public_detach )(LEVEL l, PID p);
void (*public_end )(LEVEL l, PID p);
int (*public_eligible )(LEVEL l, PID p);
void (*public_dispatch )(LEVEL l, PID p, int nostop);
void (*public_epilogue )(LEVEL l, PID p);
void (*public_activate )(LEVEL l, PID p, struct timespec *t);
void (*public_unblock )(LEVEL l, PID p);
void (*public_block )(LEVEL l, PID p);
int (*public_message )(LEVEL l, PID p, void *m);
} 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 {
int rtype; /*+ resource module extented interface
code (see model.h) +*/
int (*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. returns 0 if the model
can be handled, -1 otherwise+*/
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 (*init) (RLEVEL l, mutex_t *m, 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 (=0 Ok, an
error otherwise), -1 otherwise +*/
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 {
IQUEUE waiters; /*+ queue for tasks waiting on the condition +*/
mutex_t *used_for_waiting;
} cond_t;
__END_DECLS
#endif /* __TYPE_H__ */