Subversion Repositories shark

Rev

Rev 1677 | Blame | Compare with Previous | Last modification | View Log | RSS feed

\documentclass[english]{report}
\usepackage[T1]{fontenc}
\usepackage[latin1]{inputenc}
\usepackage{geometry}
\geometry{verbose,a4paper}
\usepackage{float}
\usepackage{makeidx}
\makeindex
\usepackage{graphicx}

\makeatletter

\newenvironment{intest}{\noindent\large\bf\hspace*{1pt}}
{\vspace*{-5pt}\\\line(1,0){433}}

\usepackage{babel}
\makeatother
\begin{document}
\thispagestyle{empty}

\begin{center}{\LARGE S.Ha.R.K. User Manual}\end{center}{\LARGE \par}
\vfill{}

\begin{center}Volume V\end{center}
\begin{center}The S.Ha.R.K. New Tracer\end{center} \vfill{}
\begin{center}Written by\end{center}
\begin{center}Tullio Facchinetti (tullio.facchinetti at unipv.it)\end{center} \vfill{}
\begin{center}\includegraphics[width=2cm]{../common/sssup.ps}\end{center}
\begin{center}Scuola Superiore di Studi e Perfezionamento S. Anna\end{center}
\begin{center}RETIS Lab\end{center}
\begin{center}Via Carducci, 40 - 56100 Pisa\end{center}

\pagebreak

\tableofcontents{}


\chapter{The S.Ha.R.K. tracer}

The new Tracer is a powerful tool to understand what happens while a
S.Ha.R.K. \cite{Gai01} application is executed. The Tracer logs
a set of events corresponding with the most important activities
within the kernel, such as preemptions, interrupt activations,
mutexes blocks and releases, and much more.

During the execution, the kernel logs the sequence of events in
memory; such events are then written to disk or sent through the
network, typically at the end of the application execution. Each
event is made by: a high resolution timestamp (TSC, Time Stamp
Counter) corresponding to the instant at which the event has been
logged; the event type; 2 optional parameters to add additional
information to the event.

The Tracer can also be used to log custom events, since it
reserves a number of free event types for user events.

To use the features made available by the Tracer, the Tracer
functions must be enabled into the kernel by specifying

~

TRACER = NEW

~

into the \textit{shark.cfg
} configuration file. The S.Ha.R.K.
kernel must be built with this option set.

%----------------------------------------------------------------------------
\section{Chunk management}
%----------------------------------------------------------------------------

Tracer events are stored in memory into buffers called \textbf{chunks}. To be as
flexible as possible, it is possible to create many chunks, that can be linked one
after the other, using the FTrace\_chunk\_link primitive, to obtain a huge memory
buffer where to store tracer events.

Chunks are created using the \textbf{FTrace\_chunk\_create} function. During the
chunk creation, the programmer can decide the size of the chunk and its type. There
are different types of chunks, which can be specified using the following flags:

\begin{itemize}
\item FTRACE\_CHUNK\_FLAG\_FREE;
\item FTRACE\_CHUNK\_FLAG\_FULL;
\item FTRACE\_CHUNK\_FLAG\_CYC;
\item FTRACE\_CHUNK\_FLAG\_JTN;
\item FTRACE\_CHUNK\_FLAG\_STOP.
\end{itemize
}

The available flags condition the behavior of the tracer when a chunk is fullfilled.
The FTRACE\_CHUNK\_FLAG\_CYC flag specifies that when the chunk is full, the tracer
starts to insert the new events from the beginning of the same chunk. The
FTRACE\_CHUNK\_FLAG\_JTN flag (Jump To Next) indicates that, when the current chunk
is full, the next event is written at the beginning of the next chunk. The
FTRACE\_CHUNK\_FLAG\_STOP makes the tracing engine to stop when the current chunk is
full. This function has not been implemented yet.
FTRACE\_CHUNK\_FLAG\_FREE and FTRACE\_CHUNK\_FLAG\_FULL only indicate that the chunk
is free to be used or is already full.

%----------------------------------------------------------------------------
\chapter{Primitives}
%----------------------------------------------------------------------------

\vspace{7mm}

%------------------------------------------------------------
\begin{intest}
FTrace\_enable \index{FTrace\_enable}
\end{intest}

\begin{description}
\item [\textbf{int FTrace\_enable();}]
\item [\textbf{Description:}] Enable the Tracer. When this function is called, the Tracer starts
the event logging.
\end{description
}

%------------------------------------------------------------
\begin{intest}
FTrace\_disable \index{FTrace\_disable}
\end{intest}

\begin{description}
\item [\textbf{int FTrace\_disable();}]
\item [\textbf{Description:}] Disable the Tracer. When this function is called, the Tracer stops
the event logging.
\end{description
}

%------------------------------------------------------------
\begin{intest}
FTrace\_chunk\_create \index{FTrace\_chunk\_create}
\end{intest}

\begin{description}
\item [\textbf{int FTrace\_chunk\_create(int normal\_size, int emergency\_size, FTrace\_flags flags);}]
\item [\textbf{Description:}] Create a new chunk.
\item The following flags can be set to the created chunk:
\begin{itemize}
\item FTRACE\_CHUNK\_FLAG\_FREE : the chunk is free to use;
\item FTRACE\_CHUNK\_FLAG\_FULL : the chunk is full;
\item FTRACE\_CHUNK\_FLAG\_CYC : the chunk stores event in a cyclical way (see \textbf{FTrace\_chunk\_link}) ;
\item FTRACE\_CHUNK\_FLAG\_JTN : when full the chunk jumps to the next chunk;
\item FTRACE\_CHUNK\_FLAG\_STOP : when full the chunk stops. This function has not been implemented yet.
\end{itemize}
\end{description
}

%------------------------------------------------------------
\begin{intest}
FTrace\_chunk\_delete \index{FTrace\_chunk\_delete}
\end{intest}

\begin{description}
\item [\textbf{int FTrace\_chunk\_delete(int number);}]
\item [\textbf{Description:}] Delete a Chunk.
\end{description
}

%------------------------------------------------------------
\begin{intest}
FTrace\_set\_chunk\_flags \index{FTrace\_set\_chunk\_flags}
\end{intest}

\begin{description}
\item [\textbf{int FTrace\_set\_chunk\_flags(int number, FTrace\_flags flags);}]
\item [\textbf{Description:}] Set the chunk flags.
\end{description
}

%------------------------------------------------------------
\begin{intest}
FTrace\_get\_chunk\_flags \index{FTrace\_get\_chunk\_flags}
\end{intest}

\begin{description}
\item [\textbf{int FTrace\_get\_chunk\_flags(int number, FTrace\_flags *flags);}]
\item [\textbf{Description:}] Returns chunk flags.
\end{description
}

%------------------------------------------------------------
\begin{intest}
FTrace\_actual\_chunk\_select \index{FTrace\_actual\_chunk\_select}
\end{intest}

\begin{description}
\item [\textbf{int FTrace\_actual\_chunk\_select(int number);}]
\item [\textbf{Description:}] Select the actual chunk.
\end{description
}

%------------------------------------------------------------
\begin{intest}
FTrace\_chunk\_link \index{FTrace\_chunk\_link}
\end{intest}

\begin{description}
\item [\textbf{int FTrace\_chunk\_link(int chunk\_A, int chunk\_B);}]
\item [\textbf{Description:}] Link two chunks.
\end{description
}

%------------------------------------------------------------
\begin{intest}
FTrace\_get\_first\_chunk \index{FTrace\_get\_first\_chunk}
\end{intest}

\begin{description}
\item [\textbf{int FTrace\_get\_first\_chunk(FTrace\_flags flags);}]
\item [\textbf{Description:}] Find the first chunk with specific flags.
\end{description
}

%------------------------------------------------------------
\begin{intest}
FTrace\_get\_chunk\_table \index{FTrace\_get\_chunk\_table}
\end{intest}

\begin{description}
\item [\textbf{FTrace\_Chunk\_Ptr *FTrace\_get\_chunk\_table();}]
\item [\textbf{Description:}] Get chunks status.
\end{description
}

%------------------------------------------------------------
\begin{intest}
FTrace\_compress\_chunk \index{FTrace\_compress\_chunk}
\end{intest}

\begin{description}
\item [\textbf{int FTrace\_compress\_chunk(int number, FTrace\_flags new\_flags);}]
\item [\textbf{Description:}] Create a new memory region where the compressed data are stored.
\end{description
}

%------------------------------------------------------------
\begin{intest}
FTrace\_send\_chunk \index{FTrace\_send\_chunk}
\end{intest}

\begin{description}
\item [\textbf{int FTrace\_send\_chunk(int number, int osd\_flags,
FTrace\_flags new\_flags);}
]
\item [\textbf{Description:}] Send the chunk out from the memory.
\end{description
}

%------------------------------------------------------------
\begin{intest}
FTrace\_init\_disk\_writer \index{FTrace\_init\_disk\_writer}
\end{intest}

\begin{description}
\item [\textbf{int FTrace\_init\_disk\_writer(char *fname, int flag,
char *l\_ip, char *t\_ip);}
]
\item [\textbf{Description:}] Initialize the disk Tracer chunk dumper. It sets
the internal chunk sender to the function that writes chunks on disk. It
initializes the filename that will be used to open the file for saving chunks.
\end{description
}

%------------------------------------------------------------
\begin{intest}
FTrace\_disk\_writer \index{FTrace\_disk\_writer}
\end{intest}

\begin{description}
\item [\textbf{void FTrace\_disk\_writer(FTrace\_Chunk\_Ptr c);}]
\item [\textbf{Description:}] This function is called by the application when it
asks to write chunk c on disk. It saves the chunk data into the chunk\_to\_disk
array. At the runlevel after the exit, all the saved chunks will be written to
disk.
\end{description
}

%------------------------------------------------------------
\begin{intest}
FTrace\_OSD\_init\_udp \index{FTrace\_OSD\_init\_udp}
\end{intest}

\begin{description}
\item [\textbf{int FTrace\_OSD\_init\_udp(int flag, char *l\_ip, char *t\_ip);}]
\item [\textbf{Description:}] Initialize the Tracer chunk network sender using
the UDP protocol supported by S.Ha.R.K. If flag = 1 initializes the network
driver, otherwise it considers that the network layer has already been
initialized. It also sets the internal chunk sender to the function that
initializes the task for sending the chunk.
\end{description
}

%------------------------------------------------------------
\begin{intest}
FTrace\_set\_filter \index{FTrace\_set\_filter}
\end{intest}

\begin{description}
\item [\textbf{void FTrace\_set\_filter(BYTE family, int status);}]
\item [\textbf{Description:}] Set the filter for a specific family of events
(see Table \ref{tab:filter-events} for a list of all the event families). When
the filter is enabled for a given family of events, all the events belonging to
that family are not logged.\\
While \texttt{status} set to 1 enables the filter, \texttt{status}
set to 0 disables the filter.
\end{description
}

%------------------------------------------------------------
\begin{intest}
TRACER\_LOGEVENT \index{TRACER\_LOGEVENT}
\end{intest}

\begin{description}
\item [\textbf{TRACER\_LOGEVENT(WORD type, WORD par1, DWORD par2);}]
\item [\textbf{Description:}] Stores a new event of \texttt{type} type into the
current chunk, together with the 2 parameters \texttt{par1} (2 bytes) and
\texttt{par2} (4 bytes).
\end{description
}

%----------------------------------------------------------------------------
\chapter{Event types description}
\label{ch:Event-types-description
}
%----------------------------------------------------------------------------

This Chapter reports all the available event type codes currently
supported by S.Ha.R.K.

\begin{table}
\begin{center}
\begin{tabular}{|l|c|c|c|}
\hline Name & Code & Parameter 1 & Parameter 2 \\ \hline
\hline FTrace\_EVT\_empty & 0x00 & . & . \\
\hline FTrace\_EVT\_cycles\_per\_msec & 0x10 & .& [clk/msec] \\
\hline FTrace\_EVT\_trace\_start& 0x20 & . & . \\
\hline FTrace\_EVT\_trace\_stop & 0x30& . & . \\
\hline FTrace\_EVT\_blackout\_start & 0x40 & .& . \\
\hline FTrace\_EVT\_blackout\_end & 0x50 & .& . \\
\hline FTrace\_EVT\_id & 0x60 & context& pid \\
\hline FTrace\_EVT\_numevents & 0x70 & .& . \\
\hline
\end{tabular}
\end{center}
\caption{General trace events.}
\end{table}


\begin{table}
\begin{center}
\begin{tabular}{|l|c|c|c|}
\hline Name & Code & Parameter 1 & Parameter 2 \\ \hline
\hline FTrace\_EVT\_ipoint & 0x01 & number & . \\ \hline
\end{tabular}
\end{center}
\caption{Lightweight tracing events.}
\end{table}


\begin{table}
\begin{center}
\begin{tabular}{|l|c|c|c|}
\hline Name & Code & Parameter 1 & Parameter 2 \\ \hline
\hline FTrace\_EVT\_task\_create & 0x02 & context& pid \\
\hline FTrace\_EVT\_task\_activate & 0x12 & context & . \\
\hline FTrace\_EVT\_task\_dispatch & 0x22 & . & . \\
\hline FTrace\_EVT\_task\_epilogue & 0x32 & . & . \\
\hline FTrace\_EVT\_task\_end & 0x42 & context & pid \\
\hline FTrace\_EVT\_task\_begin\_cycle & 0x52 & . & . \\
\hline FTrace\_EVT\_task\_end\_cycle & 0x62 & context & level \\
\hline FTrace\_EVT\_task\_sleep & 0x72 & . & . \\
\hline FTrace\_EVT\_task\_schedule & 0x82 & exec\_shadow.context & exec.context \\
\hline FTrace\_EVT\_task\_timer & 0x92 & context & level \\
\hline FTrace\_EVT\_task\_disable& 0xA2 & . & . \\
\hline FTrace\_EVT\_task\_deadline\_miss & 0xB2 & context & . \\
\hline FTrace\_EVT\_task\_wcet\_violation & 0xC2 & context& . \\
\hline
\end{tabular}
\end{center}
\caption{Task related events.}
\end{table}

\begin{table}
\begin{center}
\begin{tabular}{|l|c|c|c|}
\hline Name & Code & Parameter 1 & Parameter 2 \\ \hline
\hline FTrace\_EVT\_interrupt\_start & 0x03 & int & . \\
\hline FTrace\_EVT\_interrupt\_end & 0x13 & int & . \\
\hline FTrace\_EVT\_interrupt\_hit & 0x23 &
\multicolumn{2}{c|}{Instant where interrupt was hit (no end)} \\
\hline FTrace\_EVT\_interrupt\_count & 0x33 &
\multicolumn{2}{c|}{Number of interrupts raised since last interrupt\_count} \\
\hline
\end{tabular}
\end{center}
\caption{Interrupt events, even more lightweight than ipoints.}
\end{table}

\begin{table}
\begin{center}
\begin{tabular}{|l|c|c|c|}
\hline Name & Code & Parameter 1 & Parameter 2 \\ \hline
\hline FTrace\_EVT\_to\_real\_mode & 0x04 & . & . \\
\hline FTrace\_EVT\_to\_protected\_mode & 0x14 & . & . \\
\hline FTrace\_EVT\_CLI & 0x24 & . & . \\ \hline
FTrace\_EVT\_STI & 0x34 & . & . \\ \hline
\end{tabular}
\end{center}
\caption{Other CPU specific events.}
\end{table}

\begin{table}
\begin{center}
\begin{tabular}{|l|c|c|c|}
\hline Name & Code & Parameter 1 & Parameter 2 \\ \hline
\hline FTrace\_EVT\_set\_priority & 0x05 & . & . \\
\hline FTrace\_EVT\_context\_switch & 0x15 & context& . \\
\hline FTrace\_EVT\_inheritance & 0x25 & exec\_shadow.context & exec.context \\
\hline
\end{tabular}
\end{center}
\caption{Changes on task attributes and state.}
\end{table}

\begin{table}
\begin{center}
\begin{tabular}{|l|c|c|c|}
\hline Name & Code & Parameter 1 & Parameter 2 \\ \hline
\hline FTrace\_EVT\_set\_mutex\_create & 0x06 & . & . \\
\hline FTrace\_EVT\_set\_mutex\_lock & 0x16 & context& mutex \\
\hline FTrace\_EVT\_set\_mutex\_inherit & 0x26 & . & . \\
\hline FTrace\_EVT\_set\_mutex\_unlock & 0x43 & context & mutex \\
\hline FTrace\_EVT\_set\_mutex\_wait & 0x46 & context & mutex \\
\hline FTrace\_EVT\_set\_mutex\_post & 0x56 & context& mutex \\
\hline
\end{tabular}
\end{center}
\caption{Mutex events.}
\end{table}

\begin{table}
\begin{center}
\begin{tabular}{|l|c|c|c|}
\hline Name & Code & Parameter 1 & Parameter 2 \\ \hline
\hline FTrace\_EVT\_signal & 0x07 & . & . \\
\hline
\end{tabular}
\end{center}
\caption{Signal events.}
\end{table}

\begin{table}
\begin{center}
\begin{tabular}{|l|c|c|c|}
\hline Name & Code & Parameter 1 & Parameter 2 \\ \hline
\hline FTrace\_EVT\_server\_create & 0x08 & . & server \\
\hline FTrace\_EVT\_server\_replenish & 0x18 & .& server \\
\hline FTrace\_EVT\_server\_exhaust & 0x28 & . & server \\
\hline FTrace\_EVT\_server\_reclaiming & 0x38 & . & server \\
\hline FTrace\_EVT\_server\_remove & 0x48 & . & server \\
\hline FTrace\_EVT\_server\_active & 0x58 & . & server \\
\hline FTrace\_EVT\_server\_using\_rec & 0x68 & reclaiming & server \\
\hline
\end{tabular}
\end{center}
\caption{Specific server events.}
\end{table}

\begin{table}
\begin{center}
\begin{tabular}{|l|c|c|c|}
\hline Name & Code & Parameter 1 & Parameter 2 \\ \hline
\hline FTrace\_EVT\_user\_event\_0 & 0x09 & free & free \\
\hline FTrace\_EVT\_user\_event\_1 & 0x19 & free & free \\
\hline FTrace\_EVT\_user\_event\_2 & 0x29 & free & free \\
\hline FTrace\_EVT\_user\_event\_3 & 0x39 & free & free \\
\hline FTrace\_EVT\_user\_event\_4 & 0x49 & free & free \\
\hline FTrace\_EVT\_user\_event\_5 & 0x59 & free & free \\
\hline FTrace\_EVT\_user\_event\_6 & 0x69 & free & free \\
\hline FTrace\_EVT\_user\_event\_7 & 0x79 & free & free \\
\hline FTrace\_EVT\_user\_event\_8 & 0x89 & free & free \\
\hline FTrace\_EVT\_user\_event\_9 & 0x99 & free & free \\
\hline FTrace\_EVT\_user\_event\_10 & 0xA9 & free & free \\
\hline FTrace\_EVT\_user\_event\_11 & 0xB9 & free & free \\
\hline FTrace\_EVT\_user\_event\_12 & 0xC9 & free & free \\
\hline FTrace\_EVT\_user\_event\_13 & 0xD9 & free & free \\
\hline FTrace\_EVT\_user\_event\_14 & 0xE9 & free & free \\
\hline
\end{tabular}
\end{center}
\caption{User defined events.}
\end{table}

\begin{table}
\begin{center}
\begin{tabular}{|l|c|c|c|}
\hline Name & Code & Parameter 1 & Parameter 2 \\ \hline
\hline FTrace\_EVT\_timer\_post & 0x0B & . & . \\
\hline FTrace\_EVT\_timer\_delete & 0x1B & . & . \\
\hline FTrace\_EVT\_timer\_wakeup\_start & 0x2B & . & . \\
\hline FTrace\_EVT\_timer\_wakeup\_end & 0x3B & context & . \\
\hline
\end{tabular}
\end{center}
\caption{Timer events.}
\end{table}

\begin{table}
\begin{center}
\begin{tabular}{|l|c|c|c|}
\hline Name & Code & Parameter 1 & Parameter 2 \\ \hline
\cline{1-1} \cline{2-2} FTrace\_EVT\_data\_pointer & 0x1A &
\multicolumn{2}{c|}{holds a pointer of data from} \\
\cline{1-1} \cline{2-2} FTrace\_EVT\_next\_chunk & 0xFF &
\multicolumn{2}{c|}{previous event} \\
\hline
\end{tabular}
\end{center}
\caption{Generic data events.}
\end{table}

\begin{table}
\begin{center}
\begin{tabular}{|l|c|}
\hline Name & Code \\ \hline
\hline FTrace\_filter\_trace\_Events & 0xF0 \\
\hline FTrace\_filter\_ipoint & 0xF1 \\
\hline FTrace\_filter\_task & 0xF2 \\
\hline FTrace\_filter\_interrupt & 0xF3 \\
\hline FTrace\_filter\_CPU & 0xF4 \\
\hline FTrace\_filter\_priority & 0xF5 \\
\hline FTrace\_filter\_mutex & 0xF6 \\
\hline FTrace\_filter\_signal & 0xF7 \\
\hline FTrace\_filter\_server & 0xF8 \\
\hline FTrace\_filter\_user & 0xF9 \\
\hline FTrace\_filter\_data & 0xFA \\
\hline FTrace\_filter\_timer & 0xFB \\
\hline FTrace\_family\_mask & 0x0F \\
\hline
\end{tabular}
\end{center}
\caption{Filter management.}
\label{tab:filter-events}
\end{table
}

%----------------------------------------------------------------------------
\chapter{Example of Tracer usage}
%----------------------------------------------------------------------------

\begin{verbatim}
/* Declarations */
int a,b,c;
SYS_FLAGS f;

/* Create 3 chunks for storing the tracer events. */
a = FTrace_chunk_create(1000000, 1000000, FTRACE_CHUNK_FLAG_FREE | FTRACE_CHUNK_FLAG_CYC);
b = FTrace_chunk_create(1000000, 1000000, FTRACE_CHUNK_FLAG_FREE | FTRACE_CHUNK_FLAG_JTN);
c = FTrace_chunk_create(1000000, 1000000, FTRACE_CHUNK_FLAG_FREE | FTRACE_CHUNK_FLAG_CYC);

FTrace_chunk_link(a,b);
FTrace_chunk_link(b,c);

/* Select the first chunk for saving the events. */
FTrace_actual_chunk_select(a);

/* Start the tracer. */
FTrace_enable();

/* Enable filtering for timer related events. */
FTrace_set_filter(FTrace_filter_timer, 1);
TRACER_LOGEVENT(FTrace_EVT_trace_start, proc_table[exec_shadow].context, clk_per_msec);

for (i = 0; i < 10; i++)
  if (proc_table[i].context != 0)
    TRACER_LOGEVENT(FTrace_EVT_id, (unsigned short int)proc_table[i].context, i);

/* do something */

/** Enable filtering for timer related events. */
FTrace_set_filter(FTrace_filter_timer, 0);

/** Change the chunk where the events are stored. */
TRACER_LOGEVENT(FTrace_EVT_next_chunk, 0, 0);
TRACER_LOGEVENT(FTrace_EVT_ipoint, 6000, 0);

/* do something */

/* Store a TFrace stop event. */
TRACER_LOGEVENT(FTrace_EVT_trace_stop, 0, 0);

/* Stop the tracer. */
FTrace_disable();

/* Initialize the network for remotely saving the trace. */
FTrace_OSD_init_udp(1, "192.168.1.10", "192.168.1.1");

/*
 * If want to save the events to disk, simply change
 * the network initialization instruction with the following line:
 * FTrace_init_disk_writer("trace.dat", 0, NULL, NULL);
 *
 */

/* Save the chunk. */
FTrace_send_chunk(a, 0, FTRACE_CHUNK_FLAG_FREE | FTRACE_CHUNK_FLAG_CYC);
FTrace_send_chunk(b, 0, FTRACE_CHUNK_FLAG_FREE | FTRACE_CHUNK_FLAG_JTN);
\end{verbatim
}

%----------------------------------------------------------------------------
\chapter{Tracer output}
%----------------------------------------------------------------------------

When the trace is saved, locally or remotely, into a file, the
resulting binary file appears as a sequence of bytes where each
event stored within the trace output file is 16 bytes long. The
format of each single event is depicted in Table \ref{tab:format}.

The fields have the following meaning:

\begin{itemize}
\item Code represents the event type (see Chapter
\ref{ch:Event-types-description} for the full list);
\item Parameter 1 and 2 are the parameters used when \texttt{TRACER\_LOGEVENT}
is invoked;
\item TSC is the Time Stamp Counter associated with the event;
\end{itemize}

If \texttt{ptr} points to the first byte of an event, the correct TSC value
can be obtained with the following instructions:

\begin{verbatim}
unsigned long long tsc_value;
tsc_value = (unsigned long long)(*(unsigned int *)(ptr + 4)) << 32;
tsc_value += (unsigned long long)(*(unsigned int *)(ptr + 8));
\end{verbatim}

\begin{table}
\begin{center}\begin{tabular}{|c|c|c|c|c|}
\hline Code & Parameter 1 & TSC (high part) & TSC (low part) & Parameter 2 \\
\hline 2 bytes & 2 bytes & 4 bytes & 4 bytes & 4 bytes \\
\hline
\end{tabular}\end{center}
\caption{Event output file format.}
\label{tab:format}
\end{table}

\printindex{}

\bibliographystyle{alpha}
\bibliography{../common/biblio}

\end{document
}