Subversion Repositories shark

Rev

Blame | Last modification | View Log | RSS feed

%----------------------------------------------------------------------------
\chapter{Resource Modules}
\label{CapModuliRisorsa
}
%----------------------------------------------------------------------------

In this chapter the interface of a Resource Module is described. The semanthic
of the various functions, and the approach used to handle the Shared Resource
Access Protocols are described.
%
% Tool: such section does not exists.
%
% For architectural informations look at
% Sections\ref{ArchDetail_Moduli_GestioneRisorse} and
% \ref{ArchDetail_prot_ris_condiv}.
%----------------------------------------------------------------------------
\section{Resource Modules Interface}
%----------------------------------------------------------------------------

The approach used to define the interface of a Resource Module is
similar to that used for the Scheduling Modules (look at Section
\ref{CapSchedulingModules}, \ref{SchedModules_Interface} and
\ref{SchedModules_Convenzioni}).

The interface of a Scheduling Module is less complex than that of the Scheduling
Modules: only the \textit{create} and \textit{end} events are handled in the
task life. This choice is made because the Resource Modules usually does not
influence the scheduling of the system \footnote{Note that a Resource Handling
Algorithm that modifies the scheduling of the system is more like a Scheduling
Module than a Resource Module. Some hybrid approaches can be implemented
requiring that the implementation is made using two Modules that can modify the
private data of each other.
}.

All the functions of a Resource Module are called with Interrupt
disabled.

%----------------------------------------------------------------------------
\subsubsection{\texttt{int (*res\_register)(RLEVEL l, PID p, RES\_MODEL *r);}}
%----------------------------------------------------------------------------

This function is called by the Generic Kernel by the
\texttt{task\_create} primitive to register a Resorce Model into a
Resource Module.

The function will accept as parameter the index p of the
descriptor allocated by the Generic Kernel for the task and one of
the Resource Models passed through the primitive.

The Generic Kernel guarantees that the Resource Model passed in
this function can be handled by the Module. The function returns 0
if the Module can handle the request, -1 if the task can not be
created because the Module can not guarantee the quality of
service required.

The function will set up the local Module data with the parameters
of Quality of Service passed with the Resource Model.

%----------------------------------------------------------------------------
\subsubsection{\texttt{void (*res\_detach)(RLEVEL l, PID p);}}
%----------------------------------------------------------------------------

The call of this function signals to the Module that the task p is
terminated, so all internal data structures must be updated.

This function is called independently from the fact that the task
has or not registered some Resource Model in the Module in two
cases:

\begin{itemize}
\item The primitive \texttt{task\_create} fails for some trouble
inependent from the Module; in this case the function is called
before the \texttt{public\_detach} function of the Scheduling
Module that owns the task;

\item The task terminates in the
correct way; in this case the function is called before the
function \texttt{public\_end} of the Scheduling Module that owns
the task.
\end{itemize}

In other words, this function implemets the behaviour of the
Scheduling Module's \texttt{public\_detach} and
\texttt{public\_end} functions. This is correct because the
Resource Module only react to the creation and termination events.
It doesn't matter if the task is terminated correctly or if it has
not been created\ldots{
}

%----------------------------------------------------------------------------
\section{Implementation of the Shared Resource Access Protocols}
%----------------------------------------------------------------------------

The interface exported by the Resource Modules is used also by the
Modules that implements the Shared Resource access Protocols.

The problem solved developing these Modules is the project of some
OS primitives that can be independent from the used protocol, and,
moreover, independent from a specific Module registered at
run-time.

%----------------------------------------------------------------------------
\subsection{Used Approach}
%----------------------------------------------------------------------------

The approach used is to extend the Resource Module interface; in this way also
the protocols that requires some per-task parameters can be implemented
\footnote{For example, these parameters can be the ceiling of a task on a
Priority Ceiling or SRP protocol}.

Using an Object Oriented approach the hierarchy of the Modules can be described
(look at Figure\ref{ResMudules_Gerarchia}).

\begin{figure}
\begin{center}
\includegraphics[width=9cm]{images/resmodel_Gerarchia.eps}
\end{center}
\label{ResMudules_Gerarchia}
\caption{UML Diagram that shows the class hierarchy that implements the Shared
Resource AccesProtocols.}
\end{figure}

These Modules are viewed by the Generic Kernel as Resource Modules. When a mutex
is initialized some checks \footnote{Similar to those used in the primitive
\texttt{public\_create} for the Task Models.} are done to find the Module that
extends the interface in the correct way \footnote{To know that a Module has
extended the Resource Modules Interface the \texttt{rtype} field is provided
(look at Section \ref{KernSupport_Descrittore_GestioneRisorse}).
}and therefore
implement the required protocol.

%----------------------------------------------------------------------------
\subsection{The mutexes}
%----------------------------------------------------------------------------

The mutexes are stored in the \texttt{mutex\_t} structure showed
in Figure \ref{ResModules_Fig_mutex_t}. That declaration is
contained in the file
\texttt{include/kernel/descr.h.
}%
\begin{figure}
\begin{center} \fbox{\tt{ \begin{minipage}{6cm} \begin{tabbing}
123\=123\=123\=\kill
typedef struct \{ \\
\>RLEVEL mutexlevel; \\
\>int use;\\
\>void *opt;\\
\} mutex\_t;
\end{tabbing} \end{minipage} }} \end{center}
\label{ResModules_Fig_mutex_t}
\caption{The \texttt{mutex\_t} structure.}
\end{figure}

The structure contains the following fields:

\begin{description}
\item [mutexlevel]It is the level which the Module is registered
in.

\item [use]It tells if the mutex is currently used into a
synchronization done through condition variables.

\item [opt]This field is a pointer to a structure that the Module can
dinamically alloc to handle protocol-dependent parameters \footnote{These
parameters cannot be allocated internally to the Module because the mutexes are
not statically allocated as task or semaphore descriptors.}.
\end{description
}

%----------------------------------------------------------------------------
\subsection{Interface extension}
%----------------------------------------------------------------------------

In this section the extension to the Resource Modules is
described. The proposed functions handles all the events that
belongs to amutex.

Only the function \texttt{init} is called with interrupts
disabled. The other functions have to disable the interrupts,
because there is not a generic behaviour for all these functions
(for example, the lock of a mutex may be non-blocking on some
protocols).

%----------------------------------------------------------------------------
\subsubsection{\texttt{int init(RLEVEL l, mutex\_t *m, mutexattr\_t *a);}}
%----------------------------------------------------------------------------

This function is called to init a mutex with a protocol. The
function accepts as parameters the mutex to be initialized and the
mutex attribute that store the parameters to be used in the
initialization.

The function returns a value of \texttt{0} if the mutex
initialization was successful, or an error code otherwise. The
error codes returned by the functions must be compatibles with the
functions \texttt{pthread\_mutex\_init
} of the POSIX standard.

%----------------------------------------------------------------------------
\subsubsection{\texttt{int destroy(RLEVEL l, mutex\_t *m);}}
%----------------------------------------------------------------------------

%----------------------------------------------------------------------------
\subsubsection{\texttt{int lock(RLEVEL l, mutex\_t *m);}}
%----------------------------------------------------------------------------

%----------------------------------------------------------------------------
\subsubsection{\texttt{int trylock(RLEVEL l, mutex\_t *m);}}
%----------------------------------------------------------------------------

%----------------------------------------------------------------------------
\subsubsection{\texttt{int unlock(RLEVEL l, mutex\_t *m);}}
%----------------------------------------------------------------------------

These functions implements the core functionality of the mutexes
and they have a semantic similar to the corresponding POSIX
functions. In particular they receive as parameter a pointer to a
mutex, and they returns 0 if the operation was successful or an
error code if not.

These functions have to manage internally the context change in
the system, because it is not possible to give a fixed rule for
these functions (for example, the lock operation, that usually can
block the task, is never a blocking primitive under the SRP
assumptions).