<?xml version="1.0"?>

<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBk XML V4.1.2//EN"
               "/usr/share/sgml/docbook/dtd/xml/4.1.2/docbookx.dtd">

<book>
  <bookinfo>
    <title>POSIX Timers </title>
      <authorgroup>
	<author>
	  <firstname>Josep</firstname>
	  <surname>Vidal</surname>
	  <affiliation>
	    <orgname>DISCA, Universidad Politecnica de Valencia</orgname>
	    <address>e-mail: <email>jvidal@disca.upv.es</email></address>
	  </affiliation>
	</author>
      </authorgroup>

    <pubdate>January 2002</pubdate>
    <copyright>
      <year>2002</year>
      <holder>OCERA Consortium</holder>
    </copyright>
  </bookinfo>

  <chapter>
    <title>POSIX Timers </title>
    

    <!-- ================================ Summary ============== -->
    <section>
      <title>Summary</title>
      
      <variablelist>
	<varlistentry>
	  <term>Name</term>
	  <listitem>
	    <para>
	   POSIX Timers   
	    </para>

	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term>Description</term>
	  <listitem>
	    <para>
	      POSIX timers provides mechanisms to notify a thread when the time 
	      (measured by a particular clock) has reached a specified value, or when 
	      a specified amount of time has passed. Although RTLinux has good and accurate 
	      timing facilities, it do not provides general timer functionality. RTLinux defines 
	      only one timer for each thread, which is used to implement the periodic behaviour 
	      of the thread. This component implements the POSIX real-time extensions.
	    </para>
	  </listitem>
	</varlistentry>

	<varlistentry>
	  <term>Author</term>
	  <listitem>
	    <para>
	      Josep Vidal Canet (jvidal@disca.upv.es)
	    </para>
	  </listitem>
	</varlistentry>
	
	<varlistentry>
	  <term>Reviewer</term>
	  <listitem>
	    <para>
	      Ismael Ripoll Ripoll
	    </para>
	  </listitem>
	</varlistentry>
	
	<varlistentry>
	  <term>Layer</term>
	  <listitem>
	    <para>
	      Low-Level component.
	    </para>
	  </listitem>
	</varlistentry>
	
	<varlistentry>
	  <term>Version</term>
	  <listitem>
	    <para>
	      0.2
	    </para>
	  </listitem>
	</varlistentry>
	
	<varlistentry>
	  <term>Status</term>
	  <listitem>
	    <para>
	      Finished. Included in  RTLinux-3.2pre2 release.
	    </para>
	  </listitem>
	</varlistentry>
	
	<varlistentry>
	  <term>Dependencies</term>
	  <listitem>
	    <para>
	      Psignals component and RTLinux-3.2pre1. Also tested/available for RTLinux-3.1, RTLinux-3.2pre2.
	    </para>
	  </listitem>
	</varlistentry>
	
	<varlistentry>
	  <term>Release Date</term>
	  <listitem>
	    <para>
	      M2
	    </para>
	  </listitem>
	</varlistentry>
      </variablelist>
  </section>


    <!-- ================================ Description ============== -->
    <section>
      <title>Descritpion</title>
      <para>
	POSIX timers allows a mechanism that can notify a thread when the time as measured 
	by a particular clock has reached or passed a specified value, or when a specified 
	amount of time has passed.
      </para>
      <para>
	Facilities supported by POSIX timers that are desirable for real-time operating systems:
      </para>
      
      <itemizedlist>
	  <listitem>
	  <para>
	    Support for additional clocks.
	  </para>
	</listitem>
	
	<listitem>
	  <para>
	    Allowance for greater time resolution (modern timers are capable of nanosecond 
	    resolution; the hardware should support it)
	  </para>
	  
	</listitem>
	<listitem>
	  <para>
	    Ability to use something other than SIGALARM to indicate timer expiration 
	    (in particular, a POSIX.4 real-time extended signal would be nice)
	  </para>
	  
	</listitem>
      </itemizedlist>
      
      <para>
	Therefore POSIX timers allows greater  time resolution, implementation-defined timers, 
	and more flexibility in signal delivery.
      </para>
      
      <section>
	<title>Creating a timer</title>
	<para>
	  Here is a simple and portable way of creating a timer:	
	</para>

	  <programlisting>
	      <![CDATA[
	      #include <signal.h>
	      #include <time.h>
	      #define A_DESCRIPTIVE_NAME 13
	      int err;
	      struct sigevent signal_specification;
	      timer_t created_timer; /* Contains the ID of the created timer */ 
	      /* What signal should be generated when this timer expires ? */
	      signal_specification.sigev_signo= RTL_SIGUSR1;
	      signal_specification.sigev_value.sival_int = A_DESCRIPTIVE_NAME
	      err=timer_create(CLOCK_REALTIME, &signal_specification, &created_timer);
	      ]]></programlisting>  

	<para>
	    The code snipped creates a timer based upon the system clock called 
	  <varname>CLOCK_REALTIME</varname>. <varname>CLOCK_REALTIME</varname> exists on all 
	  POSIX.4-conformant systems, so it can be used. A machine may define other clocks, 
	  corresponding perhaps to extra, dedicated hardware resources on a particular 
	  target machine. The POSIX.4 conformance statement should indicate what clocks are 
	  available on a particular system.
	</para>

	<para>
	  The <emphasis>evp</emphasis> argument, if non-NULL, points to a sigevent structure. This structure, allocated 
	  by the application, defines the asynchronous notification to occur as specified in 
	  Signal Generation and Delivery when the timer expires. If the <emphasis>evp</emphasis> argument is NULL, 
	  the effect is as if the <emphasis>evp</emphasis> argument pointed to a <structname>sigevent</structname> 
	  structure with the <structfield>sigev_notify</structfield> member having the value 
	  <varname>SIGEV_SIGNAL</varname>, the <structfield>sigev_signo</structfield> having a default signal 
	  number, and the <structfield>sigev_value</structfield> member having the value of the timer ID. If 
	  you want to specify a particular signal to be delivered on timer expirations, use the struct 
	  <structname>sigevent</structname>, as defined in <filename>signal.h</filename>:
	</para>
	  
	<programlisting>
	    <![CDATA[
	    struct sigevent {
	    int sigev_notify; /*notification mechanism */
	    int sigev_signo; /*signal number */
	    union sigval sigev_value; /* signal data value */
	    }
	    ]]>
	</programlisting>  
	  
	<para>
	  This structure contains three members: <structfield>sigev_notify</structfield> is a flag value that 
	  specifies what sort of notification should be used upon timer expiration (signals, nothing, or something 
	  else). Currently, only two values are defined for <structfield>sigev_notify</structfield>: SIGEV_SIGNAL 
	  means to send the signal described by the remainder of the struct <structname>sigevent</structname>, 
	  and SIVEV_NONE means to send no notification at all upon timer expiration. 
	</para>
	  
	<para>
	  The third parameter is where the system stored th ID of the created timer. You will need this 
	  ID in order to use the timer.
	</para>      
      </section>
	
      <section>
	<title>Arming a timer</title>
	<para>
	  Once there is a timer ID, it can be set as in the following example:
	</para>
	
	<programlisting>
	    <![CDATA[
	    #include <time.h>
	    struct itimerspec new_setting, old_setting;
	    new_setting.it_value.tv_sec=1;
	    new_setting.it_value.tv_nsec=0; 
	    new_setting.it_interval.tv_sec=0;
	    new_setting.it_interval.tv_nsec=100*1000;
	    err=timer_settime(created_timer, 0, &new_setting, &old_setting);
	    ]]>
	</programlisting>  
	
	<para>
	  This example sets the interval timer to expire in 1 second, and every 100.000 
	  nanoseconds thereafter. The old timer setting is returned in the structure 
	  <structname>old_setting</structname>. With the  second parameter, you tell the system 
	  to interpret the interval timer setting as an absolute (TIMER_ABSTIME) or as a relative 
	  setting, like in the above example.
	</para>
	
	<para>
	  Two timer types are required for a system to support realtime applications:
	</para>
	
	<itemizedlist>
	  <listitem>
	    <para>
	      One-shot: A one-shot timer is a timer that is armed with an initial expiration time, 
	      either relative to the current time or at an absolute time (based on some timing base, 
	      such as time in seconds and nanoseconds since the Epoch). The timer expires once and 
	      then is disarmed. With the specified facilities, this is accomplished by setting the 
	      <structfield>it_value</structfield> member of the <emphasis> value</emphasis> argument 
	      to the desired expiration time and the it_interval member to zero.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Periodic: A periodic timer is a timer that is armed with an initial expiration time, 
	      again either relative or absolute, and a repetition interval. When the initial expiration 
	      occurs, the timer is reloaded with the repetition interval and continues counting. With 
	      the specified facilities, this is accomplished by setting the <structfield>it_value</structfield> 
	      member of the value argument to the desired initial expiration time and the 
	      <structfield>it_interval</structfield> member to the desired repetition interval.
	    </para>
	  </listitem>
	</itemizedlist>
	
	<para>
	  For both of these types of timers, the time of the initial timer expiration can be specified in two ways:
	</para>
	  
	<itemizedlist>
	  <listitem>
	    <para>
	      Relative (to the current time).
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Absolute.
	    </para>
	  </listitem>
	</itemizedlist>
	

      </section>

      <section>
	<title>Specification structures</title>
	<para>
	    Many of the timing facility functions accept or return time value specifications. A time 
	  value structure timespec specifies a single time value and includes at least the following 
	  members:
	</para>
	
	<table id="Table1">
	  <title>Timespec structure</title>
	  <tgroup cols="3" align="center">
	    <thead>
	      <row>
		<entry>Member type</entry>
		<entry>Member name</entry>
		<entry>Description</entry>
	      </row>
	    </thead>
	    
	    <tbody valign="middle">
	      
	      <row>
		<entry>time_t</entry>
		<entry>tv_sec</entry>
		<entry>Seconds</entry>
	      </row>
	   	      
	      <row>
		<entry>long</entry>
		<entry>tv_nsec</entry>
		<entry>Nanoseconds</entry>
	      </row>
	    </tbody>
	  </tgroup>	 
	</table>

	<para>
	  The <structfield>tv_nsec</structfield> member is only valid if greater than 
	  or equal to zero, and less than the number of nanoseconds in a second 
	  (1000 million). The time interval described by this structure is 
	  (tv_sec * 10^9 + tv_nsec) nanoseconds.
	</para>
	
	<para>
	  A time value structure <structname>itimerspec</structname> specifies an initial 
	  timer value and a repetition interval for use by the per-process timer 
	  functions. This structure includes at least the 
	  following members:
	</para>
	
	<table id="Table2">
	  <title>Timespec structure</title>
	  <tgroup cols="3" align="center">
	    <thead>
	      <row>
		<entry>Member type</entry>
		<entry>Member name</entry>
		<entry>Description</entry>
	      </row>
	    </thead>
	    
	    <tbody valign="middle">
	      
	      <row>
		  <entry>struct itimerspec </entry>
		  <entry>it_interval </entry>
		  <entry>Timer period </entry>
	      </row>
	    
	      <row>
		  <entry>struct timespec </entry>
		  <entry>it_value </entry>
		  <entry>Timer expiration</entry>
	      </row>
	    </tbody>
	  </tgroup>	 
	</table>

	<para>
	  If the value described by <structfield>it_value</structfield> is non-zero, 
	  it indicates the time to or time of the next timer expiration (for relative 
	  and absolute timer values, respectively). If the value described by it_value 
	  is zero, the timer shall be disarmed.
	</para>
	
	<para>
	  If the value described by <structfield>it_interval</structfield> is non-zero, it specifies an interval 
	  which shall be used in reloading the timer when it expires; that is, a 
	  periodic timer is specified. If the value described by <structfield>it_interval</structfield> is zero, 
	  the timer is disarmed after its next expiration; that is, a one-shot timer is specified.
	</para>
	
      </section>
      
    </section>
    
    
    <!-- ================================ API/Compatibility =========== -->
    <section>
      <title>API/Compatibility</title>
      <para>
	This component provides all the functionalities described by the POSIX standard, 
	but the one related to real-time signals, because the signals component does not provide it. 
      </para>
      
      <funcsynopsis>
	<funcsynopsisinfo>/* Creating a timer. Timer created is returned in timer_id location */</funcsynopsisinfo>
	<funcprototype>
	  <funcdef>int <function>timer_create</function></funcdef>
	  <paramdef>clockid_t <parameter>clockid</parameter></paramdef>
	  <paramdef>struct sigevent *<parameter>restrict evp</parameter></paramdef>
	  <paramdef>timer_t *<parameter>restrict timer_id</parameter></paramdef>
	</funcprototype>
	<funcsynopsisinfo>/* Removing timer referenced by timer_id */</funcsynopsisinfo>
	<funcprototype>
	  <funcdef>int <function>timer_delete</function></funcdef>
	  <paramdef>timer_t *<parameter>timer_id</parameter></paramdef>
	</funcprototype>
	<funcsynopsisinfo>/* Setting timer referenced by location timer_id */</funcsynopsisinfo>
	<funcprototype>
	  <funcdef>int <function> timer_settime</function></funcdef>
	  <paramdef>timer_t <parameter>timer_id</parameter></paramdef>
	  <paramdef>int <parameter>flags</parameter></paramdef>
	  <paramdef>const struct itimerspec *<parameter>new_setting</parameter></paramdef>
	  <paramdef>struct itimerspec *<parameter>old_setting</parameter></paramdef>
	</funcprototype>
	<funcsynopsisinfo>/* Getting time remainning until next expiration*/ </funcsynopsisinfo>
	<funcprototype>
	  <funcdef>int <function>timer_gettime</function></funcdef>
	  <paramdef>timer_t <parameter>timer_id</parameter></paramdef>
	  <paramdef>struct itimerspec *<parameter>expires</parameter></paramdef>
	</funcprototype>
	<funcprototype>
	  <funcdef>int <function>timer_getoverrun</function></funcdef>
	  <paramdef>timer_t <parameter>timer_id</parameter></paramdef>
	</funcprototype>
      </funcsynopsis>
      

      <para>
	Timers implementation supports both CLOCK_MONOTONIC and CLOCK_REALTIME.
      </para>
      
    </section>
    

    <!-- ================================ Implementation =========== -->
      <section>
	<title>Implementation issues</title>
	<para>
	  In RTLinux timer_t type is implemented as a pointer to the timer structure. When a timer is created, the memory required to store the timer_struct is dynamically allocated. For this reason, timer_create() can only be called while in Linux space, that is, all timers must be created in the init_module(). For the same reason, timers can only be deleted in cleaun_module(). This implementation follows the general style of RTLinux used in mutex, semaphores, threads, etc; all data is preallocated before the threads are started. Timers are stored in a linked list sorted by thread owner priority, which speeds-up the code that finds the next timer to expire. 
	</para>
	
	<para>
	  Right now, following files of the RTLinux version 3.2pre1 has been modified/added. Modifications are in-crusted with 
	  <programlisting><![CDATA[ #ifdef CONFIG_OC_PTIMERS ]]></programlisting> :
	</para>
	
	<para>
	  In schedulers directory:
	</para>
	<programlisting>
	  <![CDATA[
	  rtl_sched.c, rtl_timer.c.
	    ]]></programlisting>  
	
	<para>
	  In include directory:
	</para>
	<programlisting>
	  <![CDATA[
	  rtl_sched.h, rtl_timer.h, include/rtl_time.h, include/posix/time.h
	  ]]></programlisting>  
	
	<para>
	  Timers implementation supports both CLOCK_MONOTONIC and CLOCK_REALTIME.
	</para>
	
      </section>
      
      
      <section>
	<title>Tests and validation</title>
	<para>
	  We have used several test sets to validate the component.  Next a brief description of each test suit is provided:
	</para>
    
      
      <itemizedlist>
	<listitem>
	  <para>Self built test suite: Among other things these programs checks:</para>
	  <para>	  
	    <itemizedlist>
	      <listitem>
		<para>
		  Timers resolution for both absolute and relative specs.  
		</para>
	      </listitem>
	      
	      <listitem>
		<para>
		  Timers emulation of multitasking.    
		</para>
	      </listitem>
	      <listitem>
		<para>
		  POSIX timers API.   
		</para>
	      </listitem>
	      <listitem>
		<para>
		  Timers effects over RTLinux scheduler API functions (pthread_make_periodic_np(), pthread_wait_np()).    
		</para>
	      </listitem>
	    </itemizedlist>
	  </para>
	</listitem>
	
     	<listitem>
	  <para>POSIX Test Suite:</para>
	  <para>
	    <itemizedlist>
	      <listitem>
		<para>  Recently the Open POSIX Test Suite released a test suite with timers coverage. We have 
		  used these tests slightly modified to run on RTLinux. These tests are divided into four 
		  directories. Each one corresponding with the functionality to test (timer_create(),timer_delete(), 
		  timer_settime(), timer_gettime()).   </para>
	      </listitem>
	    </itemizedlist>
	  </para>
	</listitem>
	
	<listitem>
	  <para>High Resolution Timers Linux implementation test suite.</para>
	  
	  
	  <para>	  
	    <itemizedlist>
	    <listitem>
	      <para> Slightly modified to run on RTLinux. </para>
	    </listitem>
	  </itemizedlist>
	  </para>
	</listitem>
      </itemizedlist>
	   
      

	
      <!-- ================================ Validation criteria ==== -->
      <section>
	<title>Validation criteria</title>
	<para>
All tests have been passed (internal tests and independent external ones). 
	</para>
	<para>
As in the case of signals component, increases RTLinux POSIX compatibility and reduces the cost of porting applications to Rtlinux. Allows to implement watchdog timers. 
	</para>
	<para>
The timers overhead is negligible when no timer is armed. When several timers are armed, the overhead introduced is O(n) where n is the number of armed timers. Due to the flexibility and changing scenarios (priority inheritance, scheduler operational modes, different scheduling policies, etc.) it is not possible to use advanced data structures to achieve better worst case overhead. It is possible to use some heuristics to improve the response time in some cases, but the worst case remains the same.
	</para>

      </section>
	<!-- ================================ Tests ================== -->
	<section>
	  <title>Tests</title>
	  <section>
	    <title>Self built tests</title>
	    <section>
	      <title>Test 1</title>
	      <para>
		This test measures timer accuracy for both relative and absolute timer specifications. To do it, follows next procedure: Create a thread and program a periodic timer with  some period (relative spec) or a one-shot timer for absolute specification. Then let expire the timer n times. If it is absolute, reprogram each time the timer by adding the period to the absolute time specification. After n expirations, calculate the teoric time transcurred (n*period) and the real (end_time -start_time). Finally, print the error as difference between the teoric time transcurred and the real one.
		
	      </para>
	    </section>
	    <section>
	      <title>Test 2</title>
	      <para>
		This test measures POSIX.1 Signals bandwidth, following next procedure: Create two threads, a parent and a child. During an interval of time send signals between them. Measure signals send/received per milisecond.
	      </para>
	    </section>
	    <section>
	      <title>Test 3</title>
	      <para>
		Simple program to test timers API, with the following procedure:  Create a user-defined number of tasks.  Make periodic them, with a period of 2 minutes. Arm timers for each task. The firs tasks arms a  one-shot timer and the others repeating timers with an interval of 1 second.  Install a handler for each timer that wakes up each task every timer expiration.         Check that task period changes (for all tasks but the first) from 2 minutes to 1 second due to timers expirations and handlers executions. 
	      </para>
	    </section>
	    <section>
	      <title>Test 4</title>
	      <para>
	This program test RTLinux POSIX.4 timers emulation of multitasking. Provides support for testing both CLOCK_REALTIME & CLOCK_MONOTONIC. Also for system clock on mode ONESHOT or PERIODIC deppending on the  defines.	
	      </para>
	      <para>
		Test follows next procedure:  Create a user-defined number of tasks. Set the system clock on mode ONESHOT or PERIODIC.  Schedule them, using RTLinux API or timers & signals. Analyse test chronograms. NOTE: You will observe that the scheduler result using the RTLinux API and timers + signals, is basically the same. Also you will observe that test chronogram for timers based on CLOCK_MONOTONIC and system clock on mode periodic is not synchronous. This is OK, since in RTLinux CLOCK_MONOTONIC with system clock on mode periodic is different from CLOCK_REALTIME (the one used by the scheduler and test chronogram). The monitor directory comes with a patched version of the scheduler that informs about tasks activations and executions times. Also provides a       program (reader) to  get kernel information. You need to place the program crono in that directory in order to see the chronograms (available from http://bernia.disca.upv.es/rtportal).	
	      </para>
	    </section>
	    
	    <section>
	      <title>Test 5</title>
	      <para>
		Check that a timer can be programed by different threads. Test follows next procedure: Create two tasks. The first time both arm a timer. Only the last is the owner and therefore the one that will receive notification of timer expiraition. The handler for that timer wakes up the other task, allowing it to program an action for the signal of the timer and set the timer.  The proces is repeated printing the time passed since last timer expiration. Each time the timer is being programmed by a different thread.
	      </para>
	    </section>
	    
	  </section>
	  <section>
	    <title>Posix Test Suite</title>
	    
	    <para>
	      The POSIX Test Suite is an open source test suite with the goal of performing conformance, functional, and stress testing of the IEEE 1003.1-2001 System Interfaces specification in a manner that is agnostic to any given implementation.  
	    </para>
	    
	    <para>
	      Among other POSIX functionalities, these suite supports timers testing. We have used these tests slightly modified to run on RTLinux. Timers tests are divided into four directories. Each one corresponding with the functionality to test (timer_create(),timer_delete(), timer_settime(), timer_gettime()).     
	    </para>
	    <para>
	      Every test is well documented and ends with a report of assertions passed and failed.
	    </para>
	    
	  </section>
	  <section>
	    <title>High resolution timers test suite </title>
	    
	    <para>
	      This is the timers test suite provided by high resolution timers Linux implementation. The tests consists in two programs that test in a hard way timers functionality and implementation stability. More than 40 assertions are make against timers implementation.
	    </para>
	    
	  </section>
	</section>
	
	<!-- ================================ Results and comments === -->
	<section>
      <title>Results and comments</title>
	  
	  <para>
	  We try to do our best on achieving good timers accuracy and emmulation of multitasking.	
	    One of  the previous commented test timers resolution measures timers accuracy for both  absolute and relative specifications. Test results vary depending on available hardware. In a PIII 500 MHZ with APIC, the resolution available is 10 microseconds for absolutes timers and 20 microseconds for relative timers. On a K6 II 3D NOW 300 MHZ without APIC the error is doubled (22 us absolute timers & 39 us relative timers). This results have been taken with CLOCK_REALTIME and system clock on mode ONE-SHOT (default mode).
	  </para>
	  <para>
Using timers for multitasking emmulation was checked in one of the previous tests. From the test results, showed in next two chronograms it can observed that there is no difference between using RTLinux API (pthread_make_periodic_np, pthread_wait_np) and usign timers and signals to run periodic tasks.
	  <figure id="fig1"><title>Chronogram execution using RTLinux API</title>
	    <graphic fileref="img/timers_image0.png" format="PNG" srccredit="Chronogram execution usign RTLinux API" scale="40"/>
	  </figure>	  
	  <figure id="fig2"><title>Chronogram execution using timers & signals</title>
	    <graphic fileref="img/timers_image1.png" format="PNG" srccredit="Chronogram execution usign timers & signals" scale="40"/>
	  </figure>	  
	  </para>
	</section>
	
      </section>
      <section>
	
	<title>Examples</title>

	<section>
	  <title>How to run the examples</title>
	  <para>
	    In order to run any example, t he user must type make test in the example directory. 
	  </para>
	</section>
	

	<section>
	  
	  <title>Description</title>
	  <para>
	    In the examples directory, two simple programs showing basic timers functionality are provided. The first one, implements periodic threads using signals and timers, while the second uses a timers to avoid machine hang up due to huge quantity of recursive calculations.
	  </para>
      </section>

           
    </section>
  
      <section>
      
	<title>Installation instructions </title>
	<para>
	  In order to install POSIX timers in RTLinux, please follow next steps:
	</para>
	
	
	<itemizedlist>
	  <listitem>
	    <para>
	      Install POSIX signals component.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Install POSIX timers component. To do this, edit Makefile, 
	      set RTLINUX variable to your RTLinux copy path and type <command>make install</command>.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Change to the RTLinux directory and type make xconfig. Next enable 
	    both posix signals and timers and type<command> make clean ; make</command>.
	    </para>
	  </listitem>
	  <listitem>
	    <para>
	      Note: You can't select POSIX timers, if POSIX signals isn't selected. This is OK, 
	      since POSIX timers depends on POSIX signals implementation.
	    </para>
	  </listitem>
	</itemizedlist>
	
      </section>
      
    </chapter>
  </book>