594 lines
30 KiB
TeX
594 lines
30 KiB
TeX
|
\chapter{System Trace}
|
||
|
\label{chapter:btf}
|
||
|
|
||
|
In \autoref{section:trace_measurement} a trace has been defined as a
|
||
|
sequence of chronological ordered events. An event is a system state change an
|
||
|
evaluator is interested in. Various trace tools exist to record events. They
|
||
|
can be classified into hardware, hybrid and software tools.
|
||
|
|
||
|
The same event can be represented on different levels as shown in
|
||
|
\autoref{fig:trace_event_levels}. An event within the respective level
|
||
|
shall be called hardware, software or system event. An event can be moved
|
||
|
from one level into another via transformation. For example a voltage level
|
||
|
change in memory is a hardware event. The corresponding software event could
|
||
|
be a value change of a certain variable.
|
||
|
|
||
|
Different representation levels do not relate to measurement tools with the
|
||
|
same name. A hardware event can be measured directly via hardware tracing.
|
||
|
But it is also possible to detect the change of a variable via software
|
||
|
tracing. Based on the software event the occurrence of the respective hardware
|
||
|
event can be deduced. This means hardware event detection is not limited to
|
||
|
hardware tracing and the same is true for software events.
|
||
|
|
||
|
A well-defined format for events is required for further processing of recorded
|
||
|
traces. Tools that analyze or visualize a trace must be able to interpret the
|
||
|
recorded data. For example the hardware trace host software must be able to
|
||
|
understand the hardware events that are generated by the on-chip trace device.
|
||
|
Otherwise it is not possible to transform the hardware events into higher level
|
||
|
software events.
|
||
|
|
||
|
Depending on the measurement goal a different event level may be required: A
|
||
|
hardware designer is not interested in the timing behavior of an engine control
|
||
|
unit, rather the correct functionality of a certain hardware register is of
|
||
|
interest. On the other hand, an application architect relies on the correct
|
||
|
functionality of the hardware, but the timing behavior of an application on
|
||
|
architecture level must be analyzable.
|
||
|
|
||
|
\section{BTF}
|
||
|
|
||
|
A system level trace can be used to analyze timing, performance and reliability
|
||
|
of an embedded system. \gls{btf} (\glsdesc{btf}) \cite{btf} was specified to
|
||
|
support these use cases. It assumes a signal processing system, where one
|
||
|
entity influences another entity in the system. This means an event does not
|
||
|
only contain the information about which system state changed, but also the
|
||
|
source for the change. For example, a regular system event could be the
|
||
|
activation of a task with the corresponding timestamp. A \gls{btf} event
|
||
|
additionally contains the information that the task activation was triggered by
|
||
|
a certain alarm.
|
||
|
|
||
|
A \gls{btf} event is defined as an octuple
|
||
|
|
||
|
\begin{equation}
|
||
|
\label{eq:btf_trace}
|
||
|
b_{k} = (t_k,\, \Psi_k,\, \psi_k,\, \iota_k,\, T_k,\, \tau_k,\, \alpha_k,\,
|
||
|
\nu_k),\, k \in \mathbb{N},
|
||
|
\end{equation}
|
||
|
|
||
|
where each element represents a certain \gls{btf} field: $t_k$ is the
|
||
|
\emph{timestamp}, $\Psi_k$ is the \emph{source}, $\psi_k$ is the \emph{source
|
||
|
instance}, $\iota_k$ is the \emph{target type}, $T_k$ is the \emph{target},
|
||
|
$\tau_k$ is the \emph{target instance}, $\alpha$ is the event \emph{action} and
|
||
|
$\nu_k$ is an optional note. A \gls{btf} trace can now be defined as
|
||
|
|
||
|
\begin{equation}
|
||
|
B = \{b_k | t_{k} \leq t_{k+1} \wedge k \leq n\},\, n \in \mathbb{N},
|
||
|
\end{equation}
|
||
|
|
||
|
where $k$ is the index of a certain event and $n$ is the number of elements in
|
||
|
the trace.
|
||
|
|
||
|
The timestamp field is an integer value $t_k \in \mathbb{N}_{0}$. All
|
||
|
timestamps within the same trace must be specified relative to a certain point
|
||
|
in time, which is usually the start of trace measurement. System and trace
|
||
|
start can occur at different points in time. Consequently, neither trace nor
|
||
|
system start must occur at $t = 0$. The time period between two events $b_{k}$
|
||
|
and $b_{k+1}$ can be calculated as $\Delta t = t_{k+1} - t_{k}$. If not
|
||
|
specified otherwise, the time unit for $t_k$ is nanoseconds.
|
||
|
|
||
|
A \gls{btf} event represents the notification of one entity by another. There
|
||
|
exist different entity types corresponding to the software and hardware objects
|
||
|
of an application. Each entity of a certain type has an unique name that must
|
||
|
not be shared by entities of other types. Certain entity types have a life
|
||
|
cycle. This means multiple instances of the same entity can occur within the
|
||
|
same trace. Instance counters are required to distinguish between different
|
||
|
instances of the same entity. This is important for multicore systems where an
|
||
|
entity can run on two processor cores in parallel.
|
||
|
\autoref{fig:entity_inheritance} depicts the relationship between entity type,
|
||
|
entity and entity instance.
|
||
|
|
||
|
\begin{figure}[]
|
||
|
\centering
|
||
|
\includegraphics[width=0.7\textwidth]{./media/btf/entity_inheritance.pdf}
|
||
|
\caption[\gls{btf} entity inheritance]{A \gls{btf} event represents the
|
||
|
impact of one entity by another. Entities have different types and multiple
|
||
|
entities can exist for one type, identified by an unique name. Entities that
|
||
|
have a life cycle, such as runnables, can be instantiated multiple times. An
|
||
|
instance counter is required to distinguish multiple instantiations.}
|
||
|
\label{fig:entity_inheritance}
|
||
|
\end{figure}
|
||
|
|
||
|
A basic entity type is a runnable, which is essentially a simple function. A
|
||
|
system may contain of multiple runnable entities called \emph{Runnable\_1},
|
||
|
\emph{Runnable\_2} and \emph{Runnable\_3}. The life cycle of a runnable starts
|
||
|
with the execution of this runnable and ends when it terminates. A runnable
|
||
|
can execute different actions such as calling another runnable or writing a
|
||
|
variable. In a multicore system the same runnable entity \emph{Runnable\_2}
|
||
|
may be executed by two other runnables that are running in parallel on
|
||
|
different cores. If \emph{Runnable\_2} writes to a variable, it is not known
|
||
|
from which core that write occurred. With the information about which instance
|
||
|
executed the write this problem is solved.
|
||
|
|
||
|
The \emph{source} and \emph{target} fields are strings that represent entities
|
||
|
which are part of the system. The target entity is influenced by the source
|
||
|
entity. \emph{Source instance} and \emph{target instance} are positive integer
|
||
|
values that identify the instance of the respective entity. \emph{Target type}
|
||
|
is the type of the target entity. Types are represented by their corresponding
|
||
|
type \gls{id}. A source type field is not part of a \gls{btf} event even
|
||
|
though it would make sense in certain cases.
|
||
|
|
||
|
The \emph{action} field indicates the way in which way one entity is influenced
|
||
|
by another. Depending on the source and target entity types, different actions
|
||
|
are possible and allowed by the specification. The last field \emph{note} is
|
||
|
optional even though it can be used to carry additional information for certain
|
||
|
events. \autoref{tab:btf_fields} summarizes the meaning of the different
|
||
|
\gls{btf} fields.
|
||
|
|
||
|
\begin{table}[]
|
||
|
\centering
|
||
|
\begin{tabular}{r|l}
|
||
|
Field & Meaning \\
|
||
|
\hline
|
||
|
time & Timestamp relative to a certain point in time. \\
|
||
|
source & Name of the entity that caused an event. \\
|
||
|
source instance & Instance number of the entity that caused an event. \\
|
||
|
target type & Type of the entity that is influenced by an event. \\
|
||
|
target & Name of the entity that is influenced by an event. \\
|
||
|
target instance & Instance of the entity that is influenced by an event. \\
|
||
|
action & The way in which target is influenced by source. \\
|
||
|
note & An optional field that is used for certain events. \\
|
||
|
\end{tabular}
|
||
|
\caption[\gls{btf} event fields]{A \gls{btf} event contains of eight fields.
|
||
|
An event describes the way in which one system entity is influenced by
|
||
|
another one.}
|
||
|
\label{tab:btf_fields}
|
||
|
\end{table}
|
||
|
|
||
|
A \gls{btf} trace can be persisted in a \gls{btf} trace file. This file
|
||
|
contains of two sections: a meta and a data section. The meta section stands
|
||
|
at the beginning of the file. It contains information such as \gls{btf}
|
||
|
version, creator of the trace file, creation date and time unit used by the
|
||
|
time field. Each meta attribute stands in a separate line in the form
|
||
|
\lstinline{#<attribute name> <attribute definition>}. The data section
|
||
|
contains one \gls{btf} event per line in chronological order. The first event
|
||
|
comes at the beginning of the data section and the last event stands at the end
|
||
|
of the file. Comments are denoted by a \lstinline{#} followed by a space.
|
||
|
\autoref{listing:btf_example} shows an example trace file.
|
||
|
|
||
|
\begin{code}
|
||
|
\begin{lstlisting}[caption={[An example \gls{btf} trace file]A \gls{btf} trace
|
||
|
file contains of two sections. A meta section at the beginning of a file
|
||
|
includes information such as creator, creation date and time unit. It is
|
||
|
followed by a data section that contains one event per line. Comments are
|
||
|
denoted by a number sign followed by a space.},
|
||
|
label={listing:btf_example}]
|
||
|
#version 2.1.4
|
||
|
#creator BTF-Writer (15.01.0.537)
|
||
|
#creationDate 2015-02-18T14:18:20Z
|
||
|
#timeScale ns
|
||
|
0, Sim, 0, STI, S_1MS, 0, trigger
|
||
|
0, S_1MS, 0, T, T_1MS_0, 0, activate
|
||
|
100, Core_0, 0, T, T_1MS_0, 0, start
|
||
|
100, T_1MS_1, 0, R, Runnable_0, 0, start
|
||
|
25000, T_1MS_1, 0, R, Runnable_0, 0, terminate
|
||
|
25100, Core_1, 0, T, T_1MS_0, 0, terminate
|
||
|
# | | | | | | |
|
||
|
# time source | | target | action
|
||
|
# source instance | target instance
|
||
|
# target type
|
||
|
#
|
||
|
# Note that a number sign followed by a space denotes
|
||
|
# a comment. Whitespaces in the data section are ignored.
|
||
|
\end{lstlisting}
|
||
|
\end{code}
|
||
|
|
||
|
|
||
|
\section{BTF Entity Types}
|
||
|
|
||
|
\begin{table}[]
|
||
|
\centering
|
||
|
\begin{tabular}{c|c c }
|
||
|
Category & Entity Type & Type \gls{id} \\
|
||
|
\hline
|
||
|
& Task & T \\
|
||
|
Software & \gls{isr} & I \\
|
||
|
& Runnable & R \\
|
||
|
\hline
|
||
|
& Signal & SIG \\
|
||
|
\gls{os} & Semaphore & SEM \\
|
||
|
& Event & EVENT \\
|
||
|
\hline
|
||
|
& Simulation & SIM \\
|
||
|
Other & Core & Core \\
|
||
|
& Stimulus & STI \\
|
||
|
\hline
|
||
|
& Instruction Block & IB \\
|
||
|
& Electronic Control Unit & ECU \\
|
||
|
Not discussed & Processor & Processor \\
|
||
|
& Memory Module & M \\
|
||
|
& Scheduler & SCHED \\
|
||
|
\end{tabular}
|
||
|
\caption[\gls{btf} entity types]{\gls{btf} entity types can be divided into
|
||
|
three categories: software, \gls{os} and other types. Entity types are
|
||
|
represented by their type \gls{id}. Some types are not relevant for this
|
||
|
thesis and are therefore not discussed.}
|
||
|
\label{tab:entity_overview}
|
||
|
\end{table}
|
||
|
|
||
|
\gls{btf} specifies the entity types that can be used for \gls{btf} events.
|
||
|
Each entity type can be influenced by certain other types and vice versa. The
|
||
|
actions or in other words, the way in which one entity can be influenced by
|
||
|
another, are also defined. Different actions are possible for different entity
|
||
|
types. Entity types can be categorized into software, \gls{os} and other
|
||
|
entity types.
|
||
|
|
||
|
Not all entity types specified by \gls{btf} are discussed in detail as shown in
|
||
|
\autoref{tab:entity_overview}. The entity type instruction block (\emph{IB})
|
||
|
represents a sub fraction of a runnable. This concept is used by simulation
|
||
|
but does not translate to a concept used by a real application.
|
||
|
|
||
|
An electronic control unit (\emph{ECU}) consist of a at least one processor
|
||
|
(\emph{Processor}). This concept allows it to represent a system containing of
|
||
|
multiple processors that communicate with each other. The recording of a multi
|
||
|
system aware hardware trace would required a measurement configuration with
|
||
|
multiple trace tools that are synchronized to each other. The design of such a
|
||
|
setup was not in the scope of this thesis which is why ECU and processor
|
||
|
entities are not discussed.
|
||
|
|
||
|
Memory modules (\emph{M}) can be used to represent different memory sections of
|
||
|
a CPU\@. The \gls{btf} specification does not provide further information
|
||
|
about memory modules. Via hardware tracing the information about which memory
|
||
|
sections are accessed by certain data events becomes available. Since the
|
||
|
specification does not provide further details about how to use memory modules,
|
||
|
no further discussion is possible.
|
||
|
|
||
|
The scheduler (\emph{SCHED}) entity type is used to represent actions executed
|
||
|
by the \gls{os} that relate to the scheduling of task and process instances.
|
||
|
Scheduler events become available implicitly via the respective process
|
||
|
actions.
|
||
|
|
||
|
|
||
|
\subsection{Software Entity Types}
|
||
|
|
||
|
\gls{btf} distinguishes three kinds of software entity types: tasks,
|
||
|
\glspl{isr} and runnables, with the respective type \glspl{id} \emph{T},
|
||
|
\emph{I} and \emph{R}. Tasks and \glspl{isr} are collected under the umbrella
|
||
|
term process. Accordingly, they share the same state and transition model as
|
||
|
shown in \autoref{fig:process_state_chart}.
|
||
|
|
||
|
\begin{figure}[]
|
||
|
\centering
|
||
|
\centerline{\includegraphics[width=1.3\textwidth]{./media/btf/process_state_chart.png}}
|
||
|
\caption[Process state figure]{\gls{btf} specifies more process states than
|
||
|
\gls{osek} (see \autoref{fig:extended_task_state_model}). The additional
|
||
|
states polling and parking are required to represent active waiting. Not
|
||
|
initialized and terminated indicate the beginning and end of a process
|
||
|
lifecycle. The green boxes between the states show the name of the \gls{btf}
|
||
|
action for the respective transition.}
|
||
|
\label{fig:process_state_chart}
|
||
|
\end{figure}
|
||
|
|
||
|
\textbf{Process} instances start in the \emph{not initialized} state. From
|
||
|
there they can be \emph{activated} in order to switch into the \emph{active}
|
||
|
state by a stimulus (\emph{STI}) entity. All state transitions except
|
||
|
\emph{activate} are executed by core (\emph{C}) entities. An active process
|
||
|
can be changed into the \emph{running} state by the core on which the process
|
||
|
is scheduled.
|
||
|
|
||
|
A running process can \emph{preempt}, \emph{terminate}, \emph{poll} and
|
||
|
\emph{wait}. Preemption occurs if another process is scheduled to be executed
|
||
|
on the core. In this case, the process can no longer be executed and changes
|
||
|
into the \emph{ready} state. A ready process \emph{resumes} running once the
|
||
|
core becomes available again. If a process has finished execution it
|
||
|
terminates and switches into the \emph{terminated} state. This finishes the
|
||
|
lifecycle of a process instance.
|
||
|
|
||
|
A process that \emph{polls} a resource switches into the active waiting state
|
||
|
\emph{polling}. A process that \emph{waits} for an event switches into the
|
||
|
passive waiting state \emph{waiting}. A \emph{waiting} process is
|
||
|
\emph{released} into the ready state if one of the requested events becomes
|
||
|
available. If a polled resource becomes available, the task continues running
|
||
|
which is indicated by the \emph{run} action.
|
||
|
|
||
|
A polling process that is removed from the core is \emph{parked} and switched
|
||
|
into the \emph{parking} state. If the polled resource becomes available while
|
||
|
the process is parking it is switched into the ready state. This transition is
|
||
|
called \emph{release\_parking}. Otherwise the process continues polling, once
|
||
|
it is reallocated to the core, which is called \emph{poll\_parking}.
|
||
|
\autoref{tab:process_overview} summarizes process state transitions.
|
||
|
|
||
|
|
||
|
\begin{table}[]
|
||
|
\centering
|
||
|
\begin{tabular}{c c c c}
|
||
|
Current state & Next state & Action & Source Entity Types\\
|
||
|
\hline
|
||
|
not initialized & active & activate & STI \\
|
||
|
active & running & start & C \\
|
||
|
ready & running & resume & C \\
|
||
|
running & ready & preempt & C \\
|
||
|
running & terminated & terminate & C \\
|
||
|
running & polling & poll & C \\
|
||
|
running & waiting & wait & C \\
|
||
|
waiting & ready & release & C \\
|
||
|
polling & running & run & C \\
|
||
|
polling & parking & park & C \\
|
||
|
parking & ready & release\_parking & C \\
|
||
|
parking & polling & poll\_parking & C \\
|
||
|
\end{tabular}
|
||
|
\caption[Process state table]{Process entities can be in different states. A
|
||
|
process instance starts in the not initialized state and finishes in the
|
||
|
terminate state. Each state transition has an unique action name. The
|
||
|
activate action can only be triggered by a stimulus entity. All other
|
||
|
actions can only be triggered by a core entity.}
|
||
|
\label{tab:process_overview}
|
||
|
\end{table}
|
||
|
|
||
|
In addition to state transition actions, \gls{btf} specifies process
|
||
|
notification actions. This actions do not trigger a process state change, but
|
||
|
indicate other events related to a process entity. The \emph{mtalimitexceeded}
|
||
|
action is triggered if more task instances than the allowed maximal value are
|
||
|
activated. If this happens, no new task instance is created. Therefore, a
|
||
|
notification event is necessary to make the event available in the trace.
|
||
|
|
||
|
All other process notification actions are related to migration, the
|
||
|
reallocation of a process from one core to another. \gls{osekos} does not
|
||
|
support process migration since a separate kernel is executed on each core.
|
||
|
Thus migration notifications are not relevant for an \gls{osek} compliant
|
||
|
\gls{os}. Additionally migration actions become available implicitly via the
|
||
|
respective process transition actions. If a process instance is preempted on
|
||
|
one core and resumed on another, the resume event will have a different source
|
||
|
core than the preempt event. Consequently, the related migration event is
|
||
|
known.
|
||
|
|
||
|
|
||
|
\textbf{Runnable} instances start in the not initialized state.
|
||
|
Runnables can be \emph{started} by \glspl{isr} and tasks in order to switch
|
||
|
into the \emph{running} state. A runnable that \emph{terminates} switches into
|
||
|
the \emph{terminated} stated and therefore finishes its lifecycle according to
|
||
|
\autoref{tab:runnable_overview}.
|
||
|
|
||
|
Since a runnable can only be executed from a process context it can not
|
||
|
continue running if the respective process is preempted. For this case the
|
||
|
runnable must be \emph{suspended} and switches into \emph{suspended} state.
|
||
|
Once the process resumes execution the runnable can also \emph{resume}.
|
||
|
|
||
|
\begin{table}[]
|
||
|
\centering
|
||
|
\begin{tabular}{c c c c}
|
||
|
Current state & Next state & Action & Source Entity Types\\
|
||
|
\hline
|
||
|
not initialized & running & start & T, I \\
|
||
|
running & terminated & terminate & T, I \\
|
||
|
running & suspended & suspend & T, I \\
|
||
|
suspended & running & resume & T, I \\
|
||
|
\end{tabular}
|
||
|
\caption[Runnable state table]{All runnable actions can be triggered by task
|
||
|
and \gls{isr} entity types. A runnable lifecycle starts when the runnable
|
||
|
first starts execution and ends when the runnable is terminated. A runnable
|
||
|
is suspended and resumed depending on the process context in which it is
|
||
|
executed.}
|
||
|
\label{tab:runnable_overview}
|
||
|
\end{table}
|
||
|
|
||
|
\subsection{OS Entity Types}
|
||
|
|
||
|
\begin{table}[]
|
||
|
\centering
|
||
|
\begin{tabular}{c c c}
|
||
|
Action & Source Entity Types \\
|
||
|
\hline
|
||
|
read & P \\
|
||
|
write & P, STI \\
|
||
|
\end{tabular}
|
||
|
\caption[Signal actions]{Signals can be read or written. For a write event
|
||
|
the new value is provided via the note field.}
|
||
|
\label{tab:signal_overview}
|
||
|
\end{table}
|
||
|
|
||
|
\gls{os} event types are categorized into signal, semaphore and event types.
|
||
|
Signals are identified by \emph{SIG}, semaphores by \emph{SEM} and events by
|
||
|
\emph{EVENT}.
|
||
|
|
||
|
\textbf{Signal} entities represent variables that are relevant for the analysis
|
||
|
of an application. There are only two signal actions: \emph{read} and
|
||
|
\emph{write} as shown in \autoref{tab:signal_overview}. A signal can be read
|
||
|
by a process entity. This means that the value of a variable is retrieved from
|
||
|
memory. A signal entity does not have a lifecycle, thus the instance counter
|
||
|
value for signals can remain constant.
|
||
|
|
||
|
Write actions can be executed by process and stimulus entities. A write action
|
||
|
means that a new value is assigned to a variable. If this assignment is done
|
||
|
from process context, the respective process entity is the source for the write
|
||
|
event. Otherwise a stimulus entity can be used to represent the source, for
|
||
|
example if a signal is changed by the \gls{os} or a hardware module.
|
||
|
|
||
|
For signal writes, the \gls{btf} note field must be used to denote the value
|
||
|
that was assigned to a variable, usually represented by an integer value in
|
||
|
decimal representation. However, \gls{btf} does not specify in which form the
|
||
|
value must be provided. For read events the note field can optionally be used
|
||
|
to indicate the value of the variable that was accessed.
|
||
|
|
||
|
\textbf{Semaphores} can be used to control access to a common resource in
|
||
|
parallel systems. The basic idea is that a process can request a semaphore,
|
||
|
before it enters a critical section, for example a section that contains access
|
||
|
to shared variables. If the semaphore is free, the request is accepted and the
|
||
|
semaphore will be locked. All requests to a locked semaphore fail, thus no
|
||
|
other process can access the shared variables. When the process leaves the
|
||
|
critical section, it releases the semaphore, which then becomes free for other
|
||
|
resources.
|
||
|
|
||
|
There exist different types of semaphores. A counting semaphore may be
|
||
|
requested multiple times. Every time a counting semaphore is requested, a
|
||
|
counter is incremented and every time a counting semaphore is released, the
|
||
|
same counter is decremented. A counting semaphore is locked once the counter
|
||
|
has reached a predefined value and the initial counter value is zero.
|
||
|
|
||
|
\begin{table}[]
|
||
|
\centering
|
||
|
\begin{tabular}{r l}
|
||
|
Action & Meaning \\
|
||
|
\hline
|
||
|
requestsemaphore & Process requests a semaphore \\
|
||
|
exclusivesemaphore & Process requests a semaphore exclusively \\
|
||
|
assigned & Process is assigned as the owner of a semaphore \\
|
||
|
waiting & Process is assigned as waiting to a locked semaphore\\
|
||
|
released & Assignment from process to semaphore is removed \\
|
||
|
increment & Semaphore counter is incremented \\
|
||
|
decrement & Semaphore counter is decremented \\
|
||
|
\end{tabular}
|
||
|
\caption[Semaphore process actions]{Processes can interact with semaphores
|
||
|
in different ways. If a process requests a semaphore successfully, it is
|
||
|
assigned to the semaphore and the counter is incremented, otherwise a waiting
|
||
|
event is triggered. Once a semaphore is released, the assignment is removed
|
||
|
and the counter is decremented.}
|
||
|
\label{tab:semaphore_process}
|
||
|
\end{table}
|
||
|
|
||
|
A binary semaphore is a specialization of a counting semaphore for which the
|
||
|
maximum counter value is one. A mutex is a binary semaphore that supports an
|
||
|
ownership concept. This means a mutex knows all processes that may request it.
|
||
|
This information allows the implementation of priority ceiling protocols in
|
||
|
order to avoid deadlocks and priority inversion. The \gls{osek} term for mutex
|
||
|
is \emph{resource} as described in \autoref{subsection:osek_architecture}.
|
||
|
|
||
|
\gls{btf} semaphore events can be used to represent the different semaphore
|
||
|
types mentioned above. Semaphore actions can be divided into two categories:
|
||
|
Actions triggered by process instances as shown in
|
||
|
\autoref{tab:semaphore_process} and actions executed by a semaphore entity
|
||
|
itself.
|
||
|
|
||
|
A process request to a semaphore is indicated by \emph{requestsemaphore}. If a
|
||
|
request is successful (the semaphore is not locked), the semaphore counter is
|
||
|
\emph{incremented} and the process is \emph{assigned} to the semaphore. The
|
||
|
\emph{exclusivesemaphore} action represents a semaphore request that only
|
||
|
succeeds, if the semaphore is currently not requested by any other process,
|
||
|
i.e.\ the counter value is zero. If a process fails to request a semaphore and
|
||
|
switches into polling mode, in order to wait for this semaphore, this is
|
||
|
indicated by the \emph{waiting} action. A process that releases a semaphore
|
||
|
\emph{decrements} the semaphore counter and the respective semaphore is
|
||
|
\emph{released}, the process is no longer assigned to it.
|
||
|
|
||
|
\begin{figure}[]
|
||
|
\centering
|
||
|
\centerline{\includegraphics[width=1.2\textwidth]{./media/btf/semaphore_state_chart.png}}
|
||
|
\caption[Semaphore states and actions]{Semaphore entities do not have a
|
||
|
lifecycle. Nevertheless, they must be initialized before they are ready for
|
||
|
the first time. A semaphore can be unlocked or locked. A counting semaphore
|
||
|
can be requested multiple times in which cases it changes into the used state.
|
||
|
If there are no requests the semaphore is free. A semaphore that has at least
|
||
|
as many requests as allowed if full and changes into the locked state.
|
||
|
Further requests in the locked stated result in an overfull action.}
|
||
|
\label{fig:semaphore_state_chart}
|
||
|
\end{figure}
|
||
|
|
||
|
Semaphores do not have a lifecycle, which is why their instant counter remains
|
||
|
constant. Nevertheless, a semaphore must be moved from the \emph{not
|
||
|
initialized} to the \emph{free} state by the \emph{ready} action before it is
|
||
|
requested for the first time as shown in figure
|
||
|
\autoref{fig:semaphore_state_chart}.
|
||
|
|
||
|
A free semaphore is not requested by any processes. Once it is requested for
|
||
|
the first time, the behavior is dependent on the semaphore type. A mutex or
|
||
|
binary semaphore is \emph{locked} and moved into the \emph{full} state. A
|
||
|
counting semaphored is changed into the \emph{used} state which is indicated by
|
||
|
the \emph{used} action. The used action is repeated for a counting semaphore
|
||
|
for each further request and release of the semaphore, as long as the counter
|
||
|
value stays greater than zero and smaller than the maximum value. If the
|
||
|
counter value of a used semaphore becomes zero this semaphore is \emph{freed}.
|
||
|
If the maximum counter value is reached the semaphore state becomes \emph{full}
|
||
|
which is indicated by the \emph{lock\_used} action.
|
||
|
|
||
|
When a full binary semaphore or mutex is released, it is \emph{unlocked} and
|
||
|
becomes free again, while a counting semaphore is changed back to the used
|
||
|
state, indicated by the \emph{unlock\_full} action. A request to a full
|
||
|
semaphore entity results in an \emph{overfull} action and the state is changed
|
||
|
to \emph{overfull}. The overfull state indicates that there is at least one
|
||
|
process polling a semaphore. Each additional request also results in an
|
||
|
overfull action. Once there are no more processes waiting for a semaphore,
|
||
|
this semaphore becomes full again which is indicated by the \emph{full} action.
|
||
|
\autoref{tab:semaphore_semaphore} summarizes semaphore states and their
|
||
|
meaning.
|
||
|
|
||
|
\begin{table}[]
|
||
|
\centering
|
||
|
\begin{tabular}{r|l}
|
||
|
State & Meaning \\
|
||
|
\hline
|
||
|
not initialized & Semaphore is not ready \\
|
||
|
free & No process is assigned to the semaphore \\
|
||
|
used & At least one process is assigned \\
|
||
|
full & Maximum number of processes are assigned \\
|
||
|
overfull & Semaphore is full and there are further requests \\
|
||
|
\end{tabular}
|
||
|
\caption[Semaphore state overview]{Semaphores can be in five different
|
||
|
states. Before a semaphore entity can be used, it must be moved into the
|
||
|
free state. No process is assigned to a free semaphore. A counting
|
||
|
semaphore that has not yet reached its maximum request value, is in used
|
||
|
state. Once no further requests are accepted, a semaphore is full. A full
|
||
|
semaphore that is requested by another process is said to be overfull.}
|
||
|
\label{tab:semaphore_semaphore}
|
||
|
\end{table}
|
||
|
|
||
|
\textbf{Events} are objects used for inter process communication, provided by
|
||
|
the \gls{os}. One process can use an event to notify another one, for example
|
||
|
when a computation finishes or a resource becomes available. Consequently, the
|
||
|
source entity for an event action must be a task or \gls{isr}. Event entities
|
||
|
do not have a lifecycle, therefore, no instance counter value is required.
|
||
|
|
||
|
There exist three event actions: \emph{wait\_event}, \emph{clear\_event} and
|
||
|
\emph{set\_event}. A process, that waits for an event, changes into passive
|
||
|
waiting mode, until the respective event is set. An event can be set by
|
||
|
another process. For the \emph{set\_event} action it is necessary to specify
|
||
|
for which process entity the respective event is set. This information is
|
||
|
provided via the \gls{btf} note field. An event can be cleared by the process
|
||
|
for which the event was set.
|
||
|
|
||
|
|
||
|
\subsection{Other Entity Types}
|
||
|
|
||
|
There are three other entity types: simulation, core and stimulus entities.
|
||
|
The type \gls{id} for simulation is \emph{SIM}, for core \emph{C} and for
|
||
|
stimulus \emph{STI}.
|
||
|
|
||
|
\textbf{Stimul} are used to depict application behavior that cannot be
|
||
|
represented by other entity types. The only stimulus action is \emph{trigger}.
|
||
|
A stimulus can be triggered by process and simulation entities, Once a
|
||
|
stimulus is triggered, it can be used for the actual event, i.e.\ the
|
||
|
activation of a task instance. Multiple stimulus instances can exist in a
|
||
|
system at a certain point in time. Thus the instance counter field must be
|
||
|
used for stimulus events.
|
||
|
|
||
|
\begin{table}[]
|
||
|
\centering
|
||
|
\begin{tabular}{r|l}
|
||
|
Action & Meaning \\
|
||
|
\hline
|
||
|
finalize & Initialization of system environment completed \\
|
||
|
error & An error record during trace recording \\
|
||
|
tag & Transmit meta information about the source entity \\
|
||
|
description & Provide a description for the source entity \\
|
||
|
\end{tabular}
|
||
|
\caption[Simulation actions]{The simulation entity can be used to provide
|
||
|
meta information about the trace environment. Simulation is misleading since
|
||
|
it must also be used in a \gls{btf} trace recorded on hardware. That is why
|
||
|
the term \emph{system} is more appropriate. The system entity can be used to
|
||
|
trigger stimulus instances. For tag and description events the note field
|
||
|
is used to provide meta information.}
|
||
|
\label{tab:simulation_actions}
|
||
|
\end{table}
|
||
|
|
||
|
\textbf{Simulation} entities are used to provide meta information in a
|
||
|
simulated \gls{btf} trace as shown in \autoref{tab:simulation_actions}.
|
||
|
Nevertheless, it can, and must, also be used in a hardware trace. For example,
|
||
|
a stimulus entity that activates a task can be triggered by a process or
|
||
|
simulation entity. In the first case, the resulting \gls{btf} events represent
|
||
|
an inter-process activation. However, in the case that a process gets
|
||
|
activated by an alarm, process is not the correct source type and simulation
|
||
|
must be used instead. Since a simulation entity does not make too much sense
|
||
|
in a hardware trace, \emph{system} is a more appropriate term to denote the
|
||
|
concept represented by the simulation entity type.
|
||
|
|
||
|
\textbf{Core} entities are used to provide an execution context for process
|
||
|
entities. Only one process can be allocated to a core at the same time. Core
|
||
|
entities do not have a lifecycle.
|