<HTML><HEAD><TITLE>N1907=05-0167, A Mult-threading Library for Standard C++, Revision 1 </TITLE></HEAD><BODY>

<CENTER>
<H1><A NAME="A Multi-threading Library for Standard C++, Revision 1">A Multi-threading Library for Standard C++, Revision 1</A></H1>
</CENTER>

<TABLE ALIGN="RIGHT" CELLSPACING="0" CELLPADDING="0">
<TR>
<TD ALIGN="RIGHT"><B><I>Document number:</I></B></TD>
<TD>&nbsp; N1907=05-0167</TD>
</TR>
<TR>
<TD ALIGN="RIGHT"><B><I>Date:</I></B></TD>
<TD>&nbsp; 2005-10-19</TD>
</TR>
<TR>
<TD ALIGN="RIGHT"><B><I>Project:</I></B></TD>
<TD>&nbsp; Programming Language C++</TD>
</TR>
<TR>
<TD ALIGN="RIGHT"><B><I>Reference:</I></B></TD>
<TD>&nbsp; ISO/IEC IS 14882:2003(E)</TD>
</TR>
<TR>
<TD ALIGN="RIGHT"><B><I>Reply to:</I></B></TD>
<TD>&nbsp; Pete Becker</TD>
</TR>
<TR>
<TD></TD>
<TD>&nbsp; Dinkumware, Ltd.</TD>
</TR>
<TR>
<TD></TD>
<TD>&nbsp; petebecker@acm.org</TD>
</TR>
</TABLE>
<BR CLEAR="ALL">

<HR>

<H2><A NAME="Table of Contents">Table of Contents</A></H2>

<P><B><A HREF="#Overview">Overview</A>
&#183; <A HREF="#Memory Visibility">Memory Visibility</A>
&#183; <A HREF="#Condition Variables">Condition Variables</A>
&#183; <A HREF="#Mutexes">Mutexes</A>
&#183; <A HREF="#Once Functions">Once Functions</A>
&#183; <A HREF="#Thread-specific Storage">Thread-specific Storage</A>
&#183; <A HREF="#Open Issues">Open Issues</A>
</B></P>

<P><B><A HREF="#C++ Interface">C++ Interface</A>
&#183; <A HREF="#C Interface">C Interface</A>
</B></P>

<HR>

<H2><A NAME="Overview">Overview</A></H2>

<P>A <B><A NAME="intro thread">thread</A></B> is a separate flow of execution within an application.
On a multi-processor system threads can execute simultaneously on different processors.
On a single-processor system and on a multi-processor system with fewer available
processors than active threads two or more threads must share a processor.
The details of switching a processor from one thread to another are handled
by the operating system.</P>

<P>The Dinkum Threads Library lets you create and control multiple threads,
and synchronize the sharing of data between these threads. It consists of
compatible and complementary interfaces for programming in either C or C++.
The <A HREF="#C Interface">C Interface</A> is very similar to the
thread support interface defined in the
the <A HREF="http://www.unix-systems.org/version3/ieee_std.html">Posix</A> Standard
(also known as <B><A NAME="pthreads">pthreads</A></B>), while the
<A HREF="#C++ Interface">C++ Interface</A> is very similar to the
<B><A HREF="http://www.boost.org/libs/thread/doc/index.html">boost.threads</A></B>
library for C++.</P>

<P>When a C or C++ program begins execution it runs in a single thread, executing
the <CODE>main</CODE> function. The program can create additional threads as needed.
Each thread has its own copy of all <CODE>auto</CODE> variables, so <CODE>auto</CODE>
values in one thread are independent of <CODE>auto</CODE> values in the other threads.
Data with static storage duration is accessible to all threads, so those values are shared.
However, changes to values in shared data often are not immediately visible in other threads.
A multi-threaded application uses condition variables, mutexes, and once functions
to coordinate the use of shared data by its threads, in order to ensure
that shared data is not made inconsistent by simultaneous changes from more than one thread,
that changes to shared data are visible to a thread when needed, and that a thread that
needs data that is being created by another thread can be notified when that data becomes
available.</P>

<H2><A NAME="Memory Visibility">Memory Visibility</A></H2>

<P>Changes made by one thread to values in shared data often are not immediately
<B><A NAME="intro visible">visible</A></B> in other threads.

For example, on a system with two separate processors and two threads running on the
two processors, if the two processors simply
share main memory an attempt by one processor to write data while the other processor
reads the same data could result in the second processor reading a data value that
has only been partially changed by the other processor. In order to avoid this inconsistency
one processor has to lock the other one out until it finishes. This locking is usually done through
the hardware and is known as a <I>bus lock</I>. Bus locks are unavoidable, but they slow
the processors down. To minimize the effect of this slowdown, multi-processor systems
have separate cache memory for each processor. This cache memory holds a copy of some
of the data in main memory. When a processor writes data it writes to the cache.
Sometime later the changes made to the cache are written to main memory. Thus, the
processors could each have a different value for a data item in their caches, and
those values could be different from the value in main memory.</P>

<P>There are three times at which changes made to memory by one thread are guaranteed
to be visible in another thread:</P>

<UL>
<LI>when a thread is created, changes to memory made by the creating thread
prior to creating the new thread are visible to the new thread</LI>

<LI>when a thread locks a mutex, changes made by other threads prior to unlocking
the same mutex are visible to the locking thread</LI>

<LI>when a thread joins another thread, changes made by the joined thread prior to
exiting are visible to the joining thread</LI>
</UL>

<P>In practice this means that:</P>

<UL>
<LI>constant data that is initialized before a thread starts can be accessed in
the thread without further precautions</LI>
<LI>modifiable data should be accessed only from code controlled by
a mutex, both in threads that modify the data and in threads that use the
data</LI>
</UL>

<P>Note, however, that locking a mutex to prevent modification of shared data while
it is being read also prevents other threads from locking the mutex in order to read the data.
Such critical sections should be kept as short as possible to avoid blocking other
threads any longer than necessary.</P>

<H2><A NAME="Condition Variables">Condition Variables</A></H2>

<P>A <B><A NAME="intro condition variable">condition variable</A></B> is used
by a thread to wait until another thread notifies it that a condition has become
true. Code that waits for a condition variable must also use a
<A HREF="#intro mutex">mutex</A>; before calling any of the functions that
wait for the condition variable
the calling thread must lock the mutex, and when the called
function returns the mutex will be locked. During the time that a
thread is blocked waiting for the condition to become true the mutex
is not locked.</P>

<P><B><A NAME="intro spurious wakeups">Spurious wakeups</A></B> occur
when threads waiting for condition variables become unblocked
without appropriate notifications. Code that waits for a condition to
become true should explicitly check that condition when returning from
a wait function to recognize such spurious wakeups.
This is usually done with a loop:</P>

<PRE>while (condition is false)
    wait for condition variable;</PRE>

<P>The condition variable functions use a mutex internally; when a thread returns
from a wait function any changes made to memory by threads that called a wait
function or a notify function before the return will be
<A HREF="#intro visible">visible</A> to the caller.</P>

<H2><A NAME="Mutexes">Mutexes</A></H2>

<P>A <B><A NAME="intro mutex">mutex</A></B> is used to insure that only one
thread executes a region of code, known as a critical section, at any one time.
On entry into the critical section the code locks the mutex; if no other thread
holds the mutex the lock operation succeeds and the calling thread holds the mutex.
On exit from the critical section the code unlocks the mutex. If another thread
holds the mutex when a thread tries to lock it the thread that tried to lock the mutex
blocks until the mutex is unlocked. When more than one thread is blocked waiting for
the mutex an unlock releases one of the blocked threads.</P>

<P>A mutex can be <B><A NAME="intro recursive">recursive</A></B>
or <B><A NAME="intro non-recursive">non-recursive</A></B>. When a thread that already holds
a recursive mutex attempts to lock it again the thread does not block. The
thread must unlock the mutex as many times as it locked it before any other
thread will be permitted to lock the mutex. When a thread that already holds
a non-recursive mutex attempts to lock it again the thread will block. Since
the thread cannot then unlock the mutex, the result is a deadlock. Non-recursive
mutexes are usually smaller and faster than recursive mutexes, so a properly written
program that uses non-recursive mutexes can be faster than one that uses
recursive mutexes.</P>

<P>A mutex supports <B><A NAME="intro test and return">test and return</A></B>
if it provides a lock call that does not block if the mutex is already locked. Such a lock
call returns a value that indicates whether the mutex was locked as a result of the call.</P>

<P>A mutex supports <B><A NAME="intro timeout">timeout</A></B>
if it provides a lock call that blocks until no later than a specified time
waiting for the mutex to be unlocked. Such a lock call returns a value that indicates
whether the mutex was locked as a result of the call.</P>

<H2><A NAME="Once Functions">Once Functions</A></H2>

<P>A <B><A NAME="intro once function">once function</A></B> is a function that should only be
called once during a program's execution. Once functions are typically used to initialize
data that is shared between threads: the first thread that needs the data
initializes it by calling the once function, and later threads that need the data do not call
the once function. Each once function should have an associated
once flag, statically initialized to indicate that the function has not been called.
Code that needs to insure that the once function has been called calls
<A HREF="#call_once"><CODE>call_once</CODE></A>, passing the flag and the address
of the once function. The code in <CODE>call_once</CODE> atomically checks the
flag, and if the flag indicates that the function has not been called, calls the
once function and sets the flag to indicate that the function has been called.</P>

<P>The function <CODE>call_once</CODE> uses a mutex internally; when it returns
any changes made to memory by the once function will be
<A HREF="#intro visible">visible</A> to the caller.</P>

<H2><A NAME="Thread-specific Storage">Thread-specific Storage</A></H2>

<P>Thread-specific storage is global data that can hold a distinct value for each
thread that uses it. This permits functions executing in a single thread to share
data without interfering with the data shared by the same functions when executing
in other threads.</P>

<H2><A NAME="Open Issues">Open Issues</A></H2>

<UL>
<LI>Need access to system's thread cookie, to be able to use system-specific functions</LI>
<UL>
<LI>Suggested resolution: add a typedef <CODE>native_thrd_t</CODE> whose content
is unspecified, and two global functions,
<CODE>native_thrd_t get_thrd_t(const thread&amp;)</CODE> for C++ thread objects and
<CODE>native_thrd_t get_thrd_t(thrd_t)</CODE> for C thread identifiers.</LI>
<LI>Note: this might not be a complete solution. Windows uses both a <CODE>HANDLE</CODE>
and a thread identifier, in different contexts.</LI>
</UL>
<LI>Need to be able to unlock mutexes in C++ without exiting block scope</LI>
<UL>
<LI>Suggested resolution: I may have misunderstood, but it looks like this is
already present. See <A HREF="#scoped_lock::unlock">scoped_lock::unlock</A>.</LI>
</UL>
<LI>May want to replace <CODE>xtime</CODE> stuff with the new Date/Time stuff.</LI>
<LI>Boost has added two C++ classes since this documentation was written. We should
consider adding <CODE>class barrier</CODE> to synchronize multiple threads and
variations on <CODE>class read_write_mutex</CODE> for synchronizing multiple readers
and writers.</LI>
<LI>Mutex locks in the C++ interface provide an <CODE>operator void*</CODE> to test
their state. Since we seem to be moving to <CODE>operator
unspecified-boolean-type</CODE> for this sort of test, we should probably change
these operators accordingly.</LI>
</UL>

<H2><A NAME="C++ Interface">C++ Interface</A></H2>

<HR>
<P><B><CODE><A HREF="#call_once">call_once</A>
&#183; <A HREF="#condition">condition</A>
&#183; <A HREF="#lock_error">lock_error</A>
&#183; <A HREF="#mutex">mutex</A>
&#183; <A HREF="#once_flag">once_flag</A>
&#183; <A HREF="#ONCE_FLAG_INIT">ONCE_FLAG_INIT</A>
&#183; <A HREF="#once_init">once_init</A>
&#183; <A HREF="#recursive_mutex">recursive_mutex</A>
&#183; <A HREF="#recursive_timed_mutex">recursive_timed_mutex</A>
&#183; <A HREF="#recursive_try_mutex">recursive_try_mutex</A>
&#183; <A HREF="#thread">thread</A>
&#183; <A HREF="#thread_group">thread_group</A>
&#183; <A HREF="#thread_resource_error">thread_resource_error</A>
&#183; <A HREF="#thread_specific_ptr">thread_specific_ptr</A>
&#183; <A HREF="#timed_mutex">timed_mutex</A>
&#183; <A HREF="#try_mutex">try_mutex</A>
</CODE></B></P>
<HR>

<PRE>namespace std {
namespace tr2 {

    /* ERROR REPORTING */
class <B><A HREF="#lock_error">lock_error</A></B>;
class <B><A HREF="#thread_resource_error">thread_resource_error</A></B>;

    /* THREADS */
class <B><A HREF="#thread">thread</A></B>;
class <B><A HREF="#thread_group">thread_group</A></B>;

    /* MUTEXES */
class <B><A HREF="#mutex">mutex</A></B>;
class <B><A HREF="#try_mutex">try_mutex</A></B>;
class <B><A HREF="#timed_mutex">timed_mutex</A></B>;

class <B><A HREF="#recursive_mutex">recursive_mutex</A></B>;
class <B><A HREF="#recursive_try_mutex">recursive_try_mutex</A></B>;
class <B><A HREF="#recursive_timed_mutex">recursive_timed_mutex</A></B>;

    /* CONDITION VARIABLES */
class <B><A HREF="#condition">condition</A></B>;

    /* THREAD-SPECIFIC STORAGE */
class <B><A HREF="#thread_specific_ptr">thread_specific_ptr</A></B>;

    /* ONCE FUNCTIONS */
typedef <I>o-type</I> <B><A HREF="#once_flag">once_flag</A></B>;
const once_flag <B><A HREF="#once_init">once_init</A></B> = .....;
void <B><A HREF="#call_once">call_once</A></B>(void (*func)(void), once_flag& flag);    // C++ Only
void <B><A HREF="#call_once">call_once</A></B>(once_flag *flag, void (*func)(void));
} }</PRE>

<H2><A NAME="call_once"><CODE>call_once</CODE></A></H2>

<PRE>void <B>call_once</B>(void (*func)(void), once_flag& flag);    // C++ Only
void <B>call_once</B>(once_flag *pflag, void (*func)(void));</PRE>

<P>The functions use <CODE>flag</CODE> and <CODE>*pflag</CODE> to ensure that
<CODE>func</CODE> is called exactly once.</P>

<H2><A NAME="condition"><CODE>condition</CODE></A></H2>

<HR>
<P><B><CODE><A HREF="#condition::condition">condition</A>
&#183; <A HREF="#condition::~condition">~condition</A>
&#183; <A HREF="#condition::notify_all">notify_all</A>
&#183; <A HREF="#condition::notify_one">notify_one</A>
&#183; <A HREF="#condition::timed_wait">timed_wait</A>
&#183; <A HREF="#condition::wait">wait</A>
</CODE></B></P>
<HR>

<PRE>class <B>condition</B>
    {
public:
    <B><A HREF="#condition::condition">condition</A></B>();
    <B><A HREF="#condition::~condition">~condition</A></B>();

    template &lt;class Lock&gt;
        void <B><A HREF="#condition::wait">wait</A></B>(Lock& lock);
    template &lt;class Lock, class Pred&gt;
        void <B><A HREF="#condition::wait">wait</A></B>(Lock& lock, Pred pred);

    template &lt;class Lock&gt;
        bool <B><A HREF="#condition::timed_wait">timed_wait</A></B>(Lock& lock, const xtime& xt);
    template &lt;class Lock, class Pred&gt;
        bool <B><A HREF="#condition::timed_wait">timed_wait</A></B>(Lock& lock, const xtime& xt, Pred pred);

    void <B><A HREF="#condition::notify_one">notify_one</A></B>();
    void <B><A HREF="#condition::notify_all">notify_all</A></B>();

<I>    // exposition only
private:

    // not implemented
    condition(const condition&amp;);
    condition&amp; operator=(const condition&amp;);</I>
    };</PRE>

<P>The class describes an object that manages a
<A HREF="#intro condition variable">condition variable</A>.
Use <A HREF="#condition::wait">wait</A> or
<A HREF="#condition::timed_wait">timed_wait</A>
to wait for a condition to become true. Use
<A HREF="#condition::notify_one">notify_one</A>
to notify one waiting thread that the condition has become true and
<A HREF="#condition::notify_all">notify_all</A>
to notify all waiting threads that the condition has become true.
Objects of class <CODE>condition</CODE> cannot be copied.</P>

<H3><CODE><A NAME="condition::condition">condition::condition</A></CODE></H3>

<PRE><B>condition</B>();</PRE>

<P>The constructor constructs a <CODE>condition</CODE> object;
a thread that calls <CODE>wait</CODE> on a newly
constructed <CODE>condition</CODE> object will block.</P>

<H3><CODE><A NAME="condition::~condition">condition::~condition</A></CODE></H3>

<PRE><B>~condition</B>();</PRE>

<P><I>Requires:</I>
no threads are blocked waiting for the condition object.</P>

<P>The destructor releases any resources used by the <CODE>condition</CODE> object.</P>

<H3><CODE><A NAME="condition::notify_one">condition::notify_one</A></CODE></H3>

<PRE>void <B>notify_one</B>();</PRE>

<P>The member function unblocks one of the threads that is blocked on the
<CODE>condition</CODE> object at the time of the call. If no threads are blocked
on the object at the time of the call the function does nothing.</P>

<H3><CODE><A NAME="condition::notify_all">condition::notify_all</A></CODE></H3>

<PRE>void <B>notify_all</B>();</PRE>

<P>The member function unblocks all of the threads that are blocked on the
<CODE>condition</CODE> object at the time of the call. If no threads are blocked
on the object at the time of the call the function does nothing.</P>

<H3><CODE><A NAME="condition::timed_wait">condition::timed_wait</A></CODE></H3>

<PRE>template &lt;class Lock&gt;
    bool <B>timed_wait</B>(Lock& lock, const xtime& xt);
template &lt;class Lock, class Pred&gt;
    bool <B>timed_wait</B>(Lock& lock, const xtime& xt, Pred pred);</PRE>

<P><I>Throws:</I> an object of class
<CODE><A HREF="#lock_error">lock_error</A></CODE> if
the <A HREF="#lock object">lock object</A> <CODE>lock</CODE>
is not locked.</P>

<P>The first member function atomically unlocks <CODE>lock</CODE> and blocks
until the <CODE>condition</CODE> object is signaled by a call to
<A HREF="#condition::notify_one">notify_one</A> or to
<A HREF="#condition::notify_all">notify_all</A>, or until after the time specified
by the <A HREF="#xtime">xtime</A> object <CODE>xt</CODE>.
When the calling thread becomes unblocked it locks the lock object <CODE>lock</CODE>
before it returns. The function returns <CODE>false</CODE> if it returned because the time
<CODE>xt</CODE> had passed, otherwise it returns <CODE>true</CODE>.</P>

<P>The second member function atomically unlocks <CODE>lock</CODE> and blocks
until the <CODE>condition</CODE> object is signaled by a call to
<CODE>notify_one</CODE> or to <CODE>notify_all</CODE> and the predicate
<CODE>pred()</CODE> returns true
(that is, the function incorporates the loop that is needed to avoid
<A HREF="#intro spurious wakeups">spurious wakeups</A>),
or until after the time specified
by the <A HREF="#xtime">xtime</A> object <CODE>xt</CODE>.
When the calling thread becomes unblocked it locks the lock object <CODE>lock</CODE>
before it returns. The function returns <CODE>false</CODE> if it returned because the time
<CODE>xt</CODE> had passed, otherwise it returns <CODE>true</CODE>.</P>

<H3><CODE><A NAME="condition::wait">condition::wait</A></CODE></H3>

<PRE>template &lt;class Lock&gt;
    void <B>wait</B>(Lock& lock);
template &lt;class Lock, class Pred&gt;
    void <B>wait</B>(Lock& lock, Pred pred);</PRE>

<P><I>Throws:</I> an object of class
<CODE><A HREF="#lock_error">lock_error</A></CODE> if
the <A HREF="#lock object">lock object</A> <CODE>lock</CODE>
is not locked.</P>

<P>The first member function atomically unlocks <CODE>lock</CODE> and blocks
until the <CODE>condition</CODE> object is signaled by a call to
<A HREF="#condition::notify_one">notify_one</A> or to
<A HREF="#condition::notify_all">notify_all</A>. When the calling thread becomes
unblocked it locks the lock object <CODE>lock</CODE> before it returns.</P>

<P>The second member function atomically unlocks <CODE>lock</CODE> and blocks
until the <CODE>condition</CODE> object is signaled by a call to
<CODE>notify_one</CODE> or to <CODE>notify_all</CODE> and the predicate
<CODE>pred()</CODE> returns true
(that is, the function incorporates the loop that is needed to avoid
<A HREF="#intro spurious wakeups">spurious wakeups</A>).
When the calling thread becomes
unblocked it locks the lock object <CODE>lock</CODE> before it returns.</P>

<H2><A NAME="lock_error"><CODE>lock_error</CODE></A></H2>

<PRE>class lock_error</B>
    : public std::runtime_error
    {
public:
    lock_error();
    };</PRE>

<P>The class describes an exception thrown to indicate that an attempted
operation involving a lock failed because the lock was not in a required state.</P>

<H2><A NAME="once_flag"><CODE>once_flag</CODE></A></H2>

<PRE>typedef <I>o-type</I> <B>once_flag</B>;</PRE>

<P>The type describes a data object for use as the first argument to
<A HREF="#call_once"><CODE>call_once</CODE></A>.</P>

<H2><A NAME="ONCE_FLAG_INIT"><CODE>ONCE_FLAG_INIT</CODE></A></H2>

<PRE>#define <B>ONCE_FLAG_INIT</B> <I>&lt;object initializer&gt;</I></PRE>

<P>The macro yields a value that can be used to initialize an object of
type <A HREF="#once_flag">once_flag</A>.</P>

<H2><A NAME="once_init"><CODE>once_init</CODE></A></H2>

<PRE>const once_flag <B>once_init</B> = .....;</PRE>

<P>The object provides an initial value for objects of type <CODE>once_flag</CODE>.</P>

<H2><A NAME="mutex"><CODE>mutex</CODE></A></H2>

<HR>
<P><B><CODE><A HREF="#mutex::mutex">mutex</A>
&#183; <A HREF="#mutex::~mutex">~mutex</A>
&#183; <A HREF="#scoped_lock">scoped_lock</A>
</CODE></B></P>
<HR>

<PRE>class <B>mutex</B>
    {
public:
    <B><A HREF="#mutex::mutex">mutex</A></B>();
    <B><A HREF="#mutex::~mutex">~mutex</A></B>();
    typedef SL0 <B><A HREF="#scoped_lock">scoped_lock</A></B>;

<I>    // exposition only
private:
    // not implemented
    mutex(const mutex&amp;);
    mutex&amp; operator= (const mutex&amp;);</I>
    };</PRE>

<P>The class describes an object that
can be used with a <A HREF="#scoped_lock">scoped lock</A>
to provide a non-recursive <A HREF="#intro mutex">mutex</A>.
Objects of class <CODE>mutex</CODE> cannot be copied.</P>

<H3><CODE><A NAME="mutex::mutex">mutex::mutex</A></CODE></H3>

<PRE><B>mutex</B>();</PRE>

<P>The constructor constructs a <CODE>mutex</CODE> in the unlocked state.</P>

<H3><CODE><A NAME="mutex::~mutex">mutex::~mutex</A></CODE></H3>

<PRE><B>~mutex</B>();</PRE>

<P><I>Requires:</I>
the object must not be locked.</P>

<P>The destructor releases any resources used by the object.</P>

<H2><A NAME="recursive_mutex"><CODE>recursive_mutex</CODE></A></H2>

<HR>
<P><B><CODE><A HREF="#recursive_mutex::recursive_mutex">recursive_mutex</A>
&#183; <A HREF="#recursive_mutex::~recursive_mutex">~recursive_mutex</A>
&#183; <A HREF="#scoped_lock">scoped_lock</A>
</CODE></B></P>
<HR>

<PRE>class <B>recursive_mutex</B>
    {
public:
    <B><A HREF="#recursive_mutex::recursive_mutex">recursive_mutex</A></B>();
    <B><A HREF="#recursive_mutex::~recursive_mutex">~recursive_mutex</A></B>();
    typedef SL0 <B><A HREF="#scoped_lock">scoped_lock</A></B>;

<I>    // exposition only
private:
    // not implemented
    recursive_mutex(const recursive_mutex&amp;);
    recursive_mutex&amp; operator= (const recursive_mutex&amp;);</I>
    };</PRE>

<P>The class describes an object that
can be used with a <A HREF="#lock object">lock object</A>
to provide a recursive <A HREF="#intro mutex">mutex</A>
object. Objects of class <CODE>recursive_mutex</CODE> cannot be copied.</P>

<H3><CODE><A NAME="recursive_mutex::recursive_mutex">recursive_mutex::recursive_mutex</A></CODE></H3>

<PRE><B>recursive_mutex</B>();</PRE>

<P>The constructor constructs a <CODE>mutex</CODE> in the unlocked state.</P>

<H3><CODE><A NAME="recursive_mutex::~recursive_mutex">recursive_mutex::~recursive_mutex</A></CODE></H3>

<PRE><B>~recursive_mutex</B>();</PRE>

<P><I>Requires:</I>
the object must not be locked.</P>

<P>The destructor releases any resources used by the object.</P>

<H2><A NAME="recursive_timed_mutex"><CODE>recursive_timed_mutex</CODE></A></H2>

<HR>
<P><B><CODE><A HREF="#recursive_timed_mutex::recursive_timed_mutex">recursive_timed_mutex</A>
&#183; <A HREF="#recursive_timed_mutex::~recursive_timed_mutex">~recursive_timed_mutex</A>
&#183; <A HREF="#scoped_lock">scoped_lock</A>
&#183; <A HREF="#scoped_timed_lock">scoped_timed_lock</A>
&#183; <A HREF="#scoped_try_lock">scoped_try_lock</A>
</CODE></B></P>
<HR>

<PRE>class <B>recursive_timed_mutex</B>
    {
public:
    <B><A HREF="#recursive_timed_mutex::recursive_timed_mutex">recursive_timed_mutex</A></B>();
    <B><A HREF="#recursive_timed_mutex::~recursive_timed_mutex">~recursive_timed_mutex</A></B>();
    typedef SL0 <B><A HREF="#scoped_lock">scoped_lock</A></B>;
    typedef SL1 <B><A HREF="#scoped_try_lock">scoped_try_lock</A></B>;
    typedef SL2 <B><A HREF="#scoped_timed_lock">scoped_timed_lock</A></B>;

<I>    // exposition only
private:
    // not implemented
    recursive_timed_mutex(const recursive_timed_mutex&amp;);
    recursive_timed_mutex&amp; operator= (const recursive_timed_mutex&amp;);</I>
    };</PRE>

<P>The class describes an object that
can be used with a <A HREF="#scoped_lock">scoped lock</A>,
a <A HREF="#scoped_try_lock">scoped try lock</A>
or a <A HREF="#scoped_timed_lock">scoped timed lock</A>
to provide a recursive <A HREF="#intro mutex">mutex</A>
object that supports <A HREF="#intro test and return">test and return</A>
and <A HREF="#intro timeout">timeout</A>.
Objects of class <CODE>recursive_timed_mutex</CODE> cannot be copied.</P>

<H3><CODE><A NAME="recursive_timed_mutex::recursive_timed_mutex">recursive_timed_mutex::recursive_timed_mutex</A></CODE></H3>

<PRE><B>recursive_timed_mutex</B>();</PRE>

<P>The constructor constructs a <CODE>recursive_timed_mutex</CODE> in the unlocked state.</P>

<H3><CODE><A NAME="recursive_timed_mutex::~recursive_timed_mutex">recursive_timed_mutex::~recursive_timed_mutex</A></CODE></H3>

<PRE><B>~recursive_timed_mutex</B>();</PRE>

<P><I>Requires:</I>
the object must not be locked.</P>

<P>The destructor releases any resources used by the object.</P>

<H2><A NAME="recursive_try_mutex"><CODE>recursive_try_mutex</CODE></A></H2>

<HR>
<P><B><CODE><A HREF="#recursive_try_mutex::recursive_try_mutex">recursive_try_mutex</A>
&#183; <A HREF="#recursive_try_mutex::~recursive_try_mutex">~recursive_try_mutex</A>
&#183; <A HREF="#scoped_lock">scoped_lock</A>
&#183; <A HREF="#scoped_try_lock">scoped_try_lock</A>
</CODE></B></P>
<HR>

<PRE>class <B>recursive_try_mutex</B>
    {
public:
    <B><A HREF="#recursive_try_mutex::recursive_try_mutex">recursive_try_mutex</A></B>();
    <B><A HREF="#recursive_try_mutex::~recursive_try_mutex">~recursive_try_mutex</A></B>();
    typedef SL0 <B><A HREF="#scoped_lock">scoped_lock</A></B>;
    typedef SL1 <B><A HREF="#scoped_try_lock">scoped_try_lock</A></B>;

<I>    // exposition only
private:
    // not implemented
    recursive_try_mutex(const recursive_try_mutex&amp;);
    recursive_try_mutex&amp; operator= (const recursive_try_mutex&amp;);</I>
    };</PRE>

<P>The class describes an object that
can be used with a <A HREF="#scoped_lock">scoped lock</A>
or a <A HREF="#scoped_try_lock">scoped_try_lock</A>
to provide a recursive <A HREF="#intro mutex">mutex</A>
object that supports <A HREF="#intro test and return">test and return</A>.
Objects of class <CODE>recursive_try_mutex</CODE> cannot be copied.</P>

<H3><CODE><A NAME="recursive_try_mutex::recursive_try_mutex">recursive_try_mutex::recursive_try_mutex</A></CODE></H3>

<PRE><B>recursive_try_mutex</B>();</PRE>

<P>The constructor constructs a <CODE>recursive_try_mutex</CODE> in the unlocked state.</P>

<H3><CODE><A NAME="recursive_try_mutex::~recursive_try_mutex">recursive_try_mutex::~recursive_try_mutex</A></CODE></H3>

<PRE><B>~recursive_try_mutex</B>();</PRE>

<P><I>Requires:</I>
the object must not be locked.</P>

<P>The destructor releases any resources used by the object.</P>

<H2><A NAME="scoped_lock"><CODE>scoped_lock</CODE></A></H2>

<HR>
<P><B><CODE><A HREF="#scoped_lock::lock">lock</A>
&#183; <A HREF="#scoped_lock::locked">locked</A>
&#183; <A HREF="#scoped_lock::mutex_type">mutex_type</A>
&#183; <A HREF="#scoped_lock::operator const void *">operator const void *</A>
&#183; <A HREF="#scoped_lock::scoped_lock">scoped_lock</A>
&#183; <A HREF="#scoped_lock::~scoped_lock">~scoped_lock</A>
&#183; <A HREF="#scoped_lock::unlock">unlock</A>
</CODE></B></P>
<HR>

<P>Every mutual exclusion class <CODE>mtx</CODE> defines a nested
type <CODE>mtx::scoped_lock</CODE> that can be used to create a
<A HREF="#lock object">lock object</A> for an object of the type <CODE>mtx</CODE>.</P>

<P>A <B><A NAME="lock object">lock object</A></B> is an object whose constructor
locks an associated mutex object and whose destructor
unlocks the mutex object. Thus, unlocking is
guaranteed in the presence of exceptions.
Lock objects cannot be copied.</P>

<PRE>class <B>mtx::scoped_lock</B>
    {
public:
    typedef mtx <A HREF="#scoped_lock::mutex_type">mutex_type</A>;

    <A HREF="#scoped_lock::scoped_lock">scoped_lock</A>(mtx& m);
    <A HREF="#scoped_lock::scoped_lock">scoped_lock</A>(mtx& m, bool lck);
    <A HREF="#scoped_lock::~scoped_lock">~scoped_lock</A>();

    <A HREF="#scoped_lock::operator const void *">operator const void *</A>() const;
    bool <A HREF="#scoped_lock::locked">locked</A>() const;

    void <A HREF="#scoped_lock::lock">lock</A>();
    void <A HREF="#scoped_lock::unlock">unlock</A>();

<I>    // exposition only
private:
    mtx& <B>mm</B>;
    bool <B>is_locked</B>;

    // not implemented
    scoped_lock::scoped_lock(const scoped_lock&);
    scoped_lock& scoped_lock::operator= (const scoped_lock&);</I>
    };</PRE>

<H3><CODE><A NAME="scoped_lock::lock">scoped_lock::lock</A></CODE></H3>

<PRE>void <B>lock</B>();</PRE>

<P>The member function locks the stored mutual exclusion object <CODE>mm</CODE>
and sets the stored value <CODE>is_locked</CODE> to <CODE>true</CODE>.</P>

<H3><CODE><A NAME="scoped_lock::locked">scoped_lock::locked</A></CODE></H3>

<PRE>bool <B>locked</B>() const;</PRE>

<P>The member function returns the stored value <CODE>is_locked</CODE>.</P>

<H3><CODE><A NAME="scoped_lock::mutex_type">scoped_lock::mutex_type</A></CODE></H3>

<PRE>typedef mtx <B>mutex_type</B>;</PRE>

<P>The nested type is a synonym for the containing type <CODE>mtx</CODE>.</P>

<H3><CODE><A NAME="scoped_lock::operator const void *">scoped_lock::operator const void *</A></CODE></H3>

<PRE><B>operator const void *</B>() const;</PRE>

<P>The member function returns 0 if the stored value <CODE>is_locked</CODE> is <CODE>false</CODE>,
otherwise a non-0 pointer value.</P>

<H3><CODE><A NAME="scoped_lock::scoped_lock">scoped_lock::scoped_lock</A></CODE></H3>

<PRE><B>scoped_lock</B>(mtx& m);
<B>scoped_lock</B>(mtx& m, bool lck);</PRE>

<P>The first constructor constructs a <CODE>scoped_lock</CODE> object with stored
value <CODE>mm</CODE> set to <CODE>m</CODE> and then calls <CODE>lock</CODE>.</P>

<P>The second constructor constructs a <CODE>scoped_lock</CODE> object with stored
value <CODE>mm</CODE> set to <CODE>m</CODE>. If <CODE>lck</CODE> is <CODE>true</CODE>
the constructor calls <CODE>lock</CODE>. Otherwise the
stored value <CODE>is_locked</CODE> is set to <CODE>false</CODE>.</P>

<H3><CODE><A NAME="scoped_lock::~scoped_lock">scoped_lock::~scoped_lock</A></CODE></H3>

<PRE><B>~scoped_lock</B>();</PRE>

<P>The destructor calls <CODE>unlock</CODE> if the stored value <CODE>is_locked</CODE>
is <CODE>true</CODE>. Otherwise the destructor does nothing.</P>

<H3><CODE><A NAME="scoped_lock::unlock">scoped_lock::unlock</A></CODE></H3>

<PRE>void <B>unlock</B>();</PRE>

<P>The member function unlocks the stored mutual exclusion object <CODE>mm</CODE>
and sets the stored value <CODE>is_locked</CODE> to <CODE>false</CODE>.
Note that if <CODE>mm</CODE> is a <A HREF="#intro recursive">recursive</A>
mutex unlocking <CODE>mm</CODE> doesn't necessarily put <CODE>mm</CODE> into
the unlocked state.</P>

<H2><A NAME="scoped_timed_lock"><CODE>scoped_timed_lock</CODE></A></H2>

<HR>
<P><B><CODE><A HREF="#scoped_timed_lock::lock">lock</A>
&#183; <A HREF="#scoped_timed_lock::locked">locked</A>
&#183; <A HREF="#scoped_timed_lock::mutex_type">mutex_type</A>
&#183; <A HREF="#scoped_timed_lock::operator const void *">operator const void *</A>
&#183; <A HREF="#scoped_timed_lock::scoped_timed_lock">scoped_timed_lock</A>
&#183; <A HREF="#scoped_timed_lock::~scoped_timed_lock">~scoped_timed_lock</A>
&#183; <A HREF="#scoped_timed_lock::timed_lock">timed_lock</A>
&#183; <A HREF="#scoped_timed_lock::unlock">unlock</A>
</CODE></B></P>
<HR>

<P>A mutual exclusion class <CODE>mtx</CODE> that supports
<A HREF="#intro timeout">timeout</A>
defines a nested type <CODE>mtx::scoped_timed_lock</CODE>
that can be used to create a
<A HREF="#lock object">lock object</A> for an object of the type <CODE>mtx</CODE>.</P>

<PRE>class <B>mtx::scoped_timed_lock</B>
    {
public:
    typedef mtx <A HREF="#scoped_timed_lock::mutex_type">mutex_type</A>;

    <A HREF="#scoped_timed_lock::scoped_timed_lock">scoped_timed_lock</A>(mtx& m, const xtime& xt);
    <A HREF="#scoped_timed_lock::scoped_timed_lock">scoped_timed_lock</A>(mtx& m, bool lck);
    <A HREF="#scoped_timed_lock::~scoped_timed_lock">~scoped_timed_lock</A>();

    <A HREF="#scoped_timed_lock::operator const void *">operator const void *</A>() const;
    bool <A HREF="#scoped_timed_lock::locked">locked</A>() const;

    void <A HREF="#scoped_timed_lock::lock">lock</A>();
    bool <A HREF="#scoped_timed_lock::timed_lock">timed_lock</A>(const xtime& xt);
    void <A HREF="#scoped_timed_lock::unlock">unlock</A>();

<I>    // exposition only
private:
    mtx& <B>mm</B>;
    bool <B>is_locked</B>;

    // not implemented
    scoped_timed_lock::scoped_timed_lock(const scoped_timed_lock&);
    scoped_timed_lock& scoped_timed_lock::operator= (const scoped_timed_lock&);</I>
    };</PRE>

<H3><CODE><A NAME="scoped_timed_lock::lock">scoped_timed_lock::lock</A></CODE></H3>

<PRE>void <B>lock</B>();</PRE>

<P>The member function locks the stored mutual exclusion object <CODE>mm</CODE>
and sets the stored value <CODE>is_locked</CODE> to <CODE>true</CODE>.</P>

<H3><CODE><A NAME="scoped_timed_lock::locked">scoped_timed_lock::locked</A></CODE></H3>

<PRE>bool <B>locked</B>() const;</PRE>

<P>The member function returns the stored value <CODE>is_locked</CODE>.</P>

<H3><CODE><A NAME="scoped_timed_lock::mutex_type">scoped_timed_lock::mutex_type</A></CODE></H3>

<PRE>typedef mtx <B>mutex_type</B>;</PRE>

<P>The nested type is a synonym for the containing type <CODE>mtx</CODE>.</P>

<H3><CODE><A NAME="scoped_timed_lock::operator const void *">scoped_timed_lock::operator const void *</A></CODE></H3>

<PRE><B>operator const void *</B>() const;</PRE>

<P>The member function returns 0 if the stored value <CODE>is_locked</CODE> is <CODE>false</CODE>,
otherwise a non-0 pointer value.</P>

<H3><CODE><A NAME="scoped_timed_lock::scoped_timed_lock">scoped_timed_lock::scoped_timed_lock</A></CODE></H3>

<PRE><B>scoped_timed_lock</B>(mtx& m, const xtime& xt);
<B>scoped_timed_lock</B>(mtx& m, bool lck);</PRE>

<P>The first constructor constructs a <CODE>scoped_timed_lock</CODE> object with stored
value <CODE>mm</CODE> set to <CODE>m</CODE>, then calls <CODE>timed_lock(xt)</CODE>.</P>

<P>The second constructor constructs a <CODE>scoped_timed_lock</CODE> object with stored
value <CODE>mm</CODE> set to <CODE>m</CODE>. If <CODE>lck</CODE> is <CODE>true</CODE>
the constructor calls <CODE>lock</CODE>. Otherwise the
stored value <CODE>is_locked</CODE> is set to <CODE>false</CODE>.</P>

<H3><CODE><A NAME="scoped_timed_lock::~scoped_timed_lock">scoped_timed_lock::~scoped_timed_lock</A></CODE></H3>

<PRE><B>~scoped_timed_lock</B>();</PRE>

<P>The destructor calls <CODE>unlock</CODE> if the stored value <CODE>is_locked</CODE>
is <CODE>true</CODE>. Otherwise the destructor does nothing.</P>

<H3><CODE><A NAME="scoped_timed_lock::timed_lock">scoped_timed_lock::timed_lock</A></CODE></H3>

<PRE>bool <B>timed_lock</B>(const xtime& xt);</PRE>

<P>The member function attempts to lock the stored mutual exclusion object <CODE>mm</CODE>,
using its <A HREF="#intro timeout">timeout</A> mechanism to avoid blocking beyond the time
specified by the <A HREF="#xtime">xtime</A> object <CODE>xt</CODE>,
sets the stored value <CODE>is_locked</CODE> to <CODE>true</CODE> if the lock
attempt was successful or <CODE>false</CODE> if it was not usccessful,
and returns the stored value <CODE>is_locked</CODE>.</P>

<H3><CODE><A NAME="scoped_timed_lock::unlock">scoped_timed_lock::unlock</A></CODE></H3>

<PRE>void <B>unlock</B>();</PRE>

<P>The member function unlocks the stored mutual exclusion object <CODE>mm</CODE>
and sets the stored value <CODE>is_locked</CODE> to <CODE>false</CODE>. Note that if
<CODE>mm</CODE> is a <A HREF="#intro recursive">recursive</A> mutex unlocking
<CODE>mm</CODE> doesn't necessarily put <CODE>mm</CODE> into the unlocked state.</P>

<H2><A NAME="scoped_try_lock"><CODE>scoped_try_lock</CODE></A></H2>

<HR>
<P><B><CODE><A HREF="#scoped_try_lock::lock">lock</A>
&#183; <A HREF="#scoped_try_lock::locked">locked</A>
&#183; <A HREF="#scoped_try_lock::mutex_type">mutex_type</A>
&#183; <A HREF="#scoped_try_lock::operator const void *">operator const void *</A>
&#183; <A HREF="#scoped_try_lock::scoped_try_lock">scoped_try_lock</A>
&#183; <A HREF="#scoped_try_lock::~scoped_try_lock">~scoped_try_lock</A>
&#183; <A HREF="#scoped_try_lock::try_lock">try_lock</A>
&#183; <A HREF="#scoped_try_lock::unlock">unlock</A>
</CODE></B></P>
<HR>

<P>A mutual exclusion class <CODE>mtx</CODE> that supports
<A HREF="#intro test and return">test and return</A>
defines a nested type <CODE>mtx::scoped_try_lock</CODE>
that can be used to create a
<A HREF="#lock object">lock object</A> for an object of the type <CODE>mtx</CODE>.</P>

<PRE>class <B>mtx::scoped_try_lock</B>
    {
public:
    typedef mtx <A HREF="#scoped_try_lock::mutex_type">mutex_type</A>;

    <A HREF="#scoped_try_lock::scoped_try_lock">scoped_try_lock</A>(mtx& m);
    <A HREF="#scoped_try_lock::scoped_try_lock">scoped_try_lock</A>(mtx& m, bool lck);
    <A HREF="#scoped_try_lock::~scoped_try_lock">~scoped_try_lock</A>();

    <A HREF="#scoped_try_lock::operator const void *">operator const void *</A>() const;
    bool <A HREF="#scoped_try_lock::locked">locked</A>() const;

    void <A HREF="#scoped_try_lock::lock">lock</A>();
    bool <A HREF="#scoped_try_lock::try_lock">try_lock</A>();
    void <A HREF="#scoped_try_lock::unlock">unlock</A>();

<I>    // exposition only
private:
    mtx& <B>mm</B>;
    bool <B>is_locked</B>;

    // not implemented
    scoped_try_lock::scoped_try_lock(const scoped_try_lock&);
    scoped_try_lock& scoped_try_lock::operator= (const scoped_try_lock&);</I>
    };</PRE>

<H3><CODE><A NAME="scoped_try_lock::lock">scoped_try_lock::lock</A></CODE></H3>

<PRE>void <B>lock</B>();</PRE>

<P>The member function locks the stored mutual exclusion object <CODE>mm</CODE>
and sets the stored value <CODE>is_locked</CODE> to <CODE>true</CODE>.</P>

<H3><CODE><A NAME="scoped_try_lock::locked">scoped_try_lock::locked</A></CODE></H3>

<PRE>bool <B>locked</B>() const;</PRE>

<P>The member function returns the stored value <CODE>is_locked</CODE>.</P>

<H3><CODE><A NAME="scoped_try_lock::mutex_type">scoped_try_lock::mutex_type</A></CODE></H3>

<PRE>typedef mtx <B>mutex_type</B>;</PRE>

<P>The nested type is a synonym for the containing type <CODE>mtx</CODE>.</P>

<H3><CODE><A NAME="scoped_try_lock::operator const void *">scoped_try_lock::operator const void *</A></CODE></H3>

<PRE><B>operator const void *</B>() const;</PRE>

<P>The member function returns 0 if the stored value <CODE>is_locked</CODE> is <CODE>false</CODE>,
otherwise a non-0 pointer value.</P>

<H3><CODE><A NAME="scoped_try_lock::scoped_try_lock">scoped_try_lock::scoped_try_lock</A></CODE></H3>

<PRE><B>scoped_try_lock</B>(mtx& m);
<B>scoped_try_lock</B>(mtx& m, bool lck);</PRE>

<P>The first constructor constructs a <CODE>scoped_try_lock</CODE> object with stored
value <CODE>mm</CODE> set to <CODE>m</CODE>, then calls <CODE>try_lock</CODE>.</P>

<P>The second constructor constructs a <CODE>scoped_try_lock</CODE> object with stored
value <CODE>mm</CODE> set to <CODE>m</CODE>. If <CODE>lck</CODE> is <CODE>true</CODE>
the constructor calls <CODE>lock</CODE>. Otherwise the
stored value <CODE>is_locked</CODE> is set to <CODE>false</CODE>.</P>

<H3><CODE><A NAME="scoped_try_lock::~scoped_try_lock">scoped_try_lock::~scoped_try_lock</A></CODE></H3>

<PRE><B>~scoped_try_lock</B>();</PRE>

<P>The destructor calls <CODE>unlock</CODE> if the stored value <CODE>is_locked</CODE>
is <CODE>true</CODE>. Otherwise the destructor does nothing.</P>

<H3><CODE><A NAME="scoped_try_lock::try_lock">scoped_try_lock::try_lock</A></CODE></H3>

<PRE>bool <B>try_lock</B>();</PRE>

<P>The member function attempts to lock the stored mutual exclusion object <CODE>mm</CODE>,
using its <A HREF="#intro test and return">test and return</A> mechanism,
sets the stored value <CODE>is_locked</CODE> to <CODE>true</CODE> if
the lock attempt was successful or <CODE>false</CODE> if it was not
successful, and returns the stored value <CODE>is_locked</CODE>.</P>

<H3><CODE><A NAME="scoped_try_lock::unlock">scoped_try_lock::unlock</A></CODE></H3>

<PRE>void <B>unlock</B>();</PRE>

<P>The member function unlocks the stored mutual exclusion object <CODE>mm</CODE>
and sets the stored value <CODE>is_locked</CODE> to <CODE>false</CODE>. Note that if
<CODE>mm</CODE> is a <A HREF="#intro recursive">recursive</A> mutex unlocking
<CODE>mm</CODE> doesn't necessarily put <CODE>mm</CODE> into the unlocked state.</P>

<H2><A NAME="thread"><CODE>thread</CODE></A></H2>

<HR>
<P><B><CODE><A HREF="#thread::join">join</A>
&#183; <A HREF="#thread::operator!=">operator!=</A>
&#183; <A HREF="#thread::operator==">operator==</A>
&#183; <A HREF="#thread::sleep">sleep</A>
&#183; <A HREF="#thread::thread">thread</A>
&#183; <A HREF="#thread::yield">yield</A>
</CODE></B></P>
<HR>

<PRE>class <B>thread</B>
    {
public:
    <B><A HREF="#thread::thread">thread</A></B>();
    template &lt;class Func&gt;
        explicit <B><A HREF="#thread::thread">thread</A></B>(Func func);

    bool <B><A HREF="#thread::operator==">operator==</A></B> (const thread&amp; other) const;
    bool <B><A HREF="#thread::operator!=">operator!=</A></B> (const thread&amp; other) const
        {return !operator==(other); }

    void <B><A HREF="#thread::join">join</A></B>();
    static void <B><A HREF="#thread::sleep">sleep</A></B>(const xtime&amp; xt);
    static void <B><A HREF="#thread::yield">yield</A></B>();

<I>    // exposition only
private:

    // not implemented
    thread(const thread&amp;);
    thread&amp; operator= (const thread&amp;);</I>
    };</PRE>

<P>The class describes an object for observing the state of a thread
(<A HREF="#thread::join">join</A>) and managing the state of the current
thread (<A HREF="#thread::sleep">sleep</A>,
<A HREF="#thread::yield">yield</A>).
Objects of class <CODE>thread</CODE> cannot be copied.</P>

<P>A <CODE>thread</CODE> object is <B><A NAME="joinable">joinable</A></B> if
it was constructed as a joinable object, the application has not made a
call to <A HREF="#thread::join">thread::join</A> for that object, and the
application has not made a call to
<A HREF="#thread_group::join_all">thread_group::join_all</A> for a
<CODE>thread_group</CODE> object observing that thread object.</P>

<H3><CODE><A NAME="thread::join">thread::join</A></CODE></H3>

<PRE>void <B>join</B>();</PRE>

<P><I>Requires:</I>
the object must be <A HREF="#joinable">joinable</A>.</P>

<P>The member function marks this <CODE>thread</CODE> object
as non-joinable then blocks until the thread observed by this
<CODE>thread</CODE> object terminates.</P>

<H3><CODE><A NAME="thread::operator!=">thread::operator!=</A></CODE></H3>

<PRE>bool <B>operator!=</B> (const thread&amp; other) const
    {return !operator==(other); }</PRE>

<P><I>Requires:</I> the observed thread has not terminated.</P>

<P>The member function returns <CODE>!operator==(other)</CODE>.</P>

<H3><CODE><A NAME="thread::operator==">thread::operator==</A></CODE></H3>

<PRE>bool <B>operator==</B> (const thread&amp; other) const;</PRE>

<P><I>Requires:</I> the observed thread has not terminated.</P>

<P>The member function returns true only if this <CODE>thread</CODE>
object and <CODE>other</CODE> observe the same thread.</P>

<H3><CODE><A NAME="thread::sleep">thread::sleep</A></CODE></H3>

<PRE>static void <B>sleep</B>(const xtime&amp; xt);</PRE>

<P>The static member function blocks the calling thread
at least until the time specified by the <A HREF="#joinable">joinable</A>
<CODE>thread</CODE> object that observes the thread
that constructed the object.</P>

<P>The second constructor constructs a <A HREF="#joinable">joinable</A>
<CODE>thread</CODE> object that observes a new thread
executing <CODE>func()</CODE>, where <CODE>func</CODE>
is the name of a function that takes no arguments and returns void, or
the name of an object of a class that provides an <CODE>operator()</CODE>
that takes no arguments and returns void. The constructor does not return
until the new thread has begun execution.</P>

<H3><CODE><A NAME="thread::thread">thread::thread</A></CODE></H3>

<PRE><B>thread</B>();
template&lt;class Func&gt;
    explicit <B>thread</B>(Func func);</PRE>

<P>The first constructor constructs a non-<A HREF="#joinable">joinable</A>
<CODE>thread</CODE> object that observes the thread
that constructed the object.</P>

<P>The second constructor constructs a <A HREF="#joinable">joinable</A>
<CODE>thread</CODE> object that observes a new thread
executing <CODE>func()</CODE>, where <CODE>func</CODE>
is the name of a function that takes no arguments and returns void, or
the name of an object of a class that provides an <CODE>operator()</CODE>
that takes no arguments and returns void. The constructor does not return
until the new thread has begun execution.</P>

<H3><CODE><A NAME="thread::yield">thread::yield</A></CODE></H3>

<PRE>static void <B>yield</B>();</PRE>

<P>The member function requests the runtime system to put the
calling thread at the back of the execution queue for threads
with the same priority as the calling thread.</P>

<H2><A NAME="thread_group"><CODE>thread_group</CODE></A></H2>

<HR>
<P><B><CODE><A HREF="#thread_group::add_thread">add_thread</A>
&#183; <A HREF="#thread_group::create_thread">create_thread</A>
&#183; <A HREF="#thread_group::join_all">join_all</A>
&#183; <A HREF="#thread_group::remove_thread">remove_thread</A>
&#183; <A HREF="#thread_group::thread_group">thread_group</A>
&#183; <A HREF="#thread_group::~thread_group">~thread_group</A>
</CODE></B></P>
<HR>

<PRE>class <B>thread_group</B>
    {
public:
    <B><A HREF="#thread_group::thread_group">thread_group</A></B>();
    <B><A HREF="#thread_group::~thread_group">~thread_group</A></B>();

    template &lt;class Func&gt;
        thread *<B><A HREF="#thread_group::create_thread">create_thread</A></B>(Func func);

    void <B><A HREF="#thread_group::add_thread">add_thread</A></B>(thread *thrd);
    void <B><A HREF="#thread_group::remove_thread">remove_thread</A></B>(thread *thrd);
    void <B><A HREF="#thread_group::join_all">join_all</A></B>();

<I>    // exposition only
private:

    // not implemented
    thread_group(const thread_group&amp;);
    thread_group&amp; operator= (const thread_group&amp;);</I>
    };</PRE>

<P>The class describes an object for observing the states of multiple objects
of class <CODE>thread</CODE> (<A HREF="#thread_group::join_all">join_all</A>)
without having to observe each of the threads individually. Objects of class
<CODE>thread</CODE> to be observed by a <CODE>thread_group</CODE> object must
be created with <CODE>new</CODE>; they will be destroyed by the
<CODE>thread_group</CODE> object's destructor.
Objects of class <CODE>thread_group</CODE> cannot be copied.</P>

<H3><CODE><A NAME="thread_group::add_thread">thread_group::add_thread</A></CODE></H3>

<PRE>void <B>add_thread</B>(thread *thrd);</PRE>

<P><I>Requires:</I>
<CODE>*thrd</CODE> must be <A HREF="#joinable">joinable</A>.</P>

<P>The member function adds <CODE>*thrd</CODE> to the group of <CODE>thread</CODE>
objects observed by the <CODE>thread_group</CODE> object. Calling <CODE>add_thread</CODE>
with a <CODE>thread</CODE> object that is already in the group does nothing.</P>

<H3><CODE><A NAME="thread_group::create_thread">thread_group::create_thread</A></CODE></H3>

<PRE>template &lt;class Func&gt;
    thread *<B>create_thread</B>(Func func);</PRE>

<P>The member function calls <CODE>thread *res = new thread(func)</CODE>, and if
the call succeeds calls <CODE>add_thread(res)</CODE>. It returns <CODE>res</CODE>.</P>

<H3><CODE><A NAME="thread_group::join_all">thread_group::join_all</A></CODE></H3>

<PRE>void <B>join_all</B>();</PRE>

<P>The member function effectively calls
<CODE>thr.join()</CODE> for each <CODE>thread</CODE> object <CODE>thr</CODE>
in the group of <CODE>thread</CODE> objects observed by the <CODE>thread_group</CODE>
object.</P>

<H3><CODE><A NAME="thread_group::remove_thread">thread_group::remove_thread</A></CODE></H3>

<PRE>void <B>remove_thread</B>(thread *thrd);</PRE>

<P>The member function removes <CODE>*thrd</CODE> from the group of <CODE>thread</CODE>
objects observed by the <CODE>thread_group</CODE> object. If <CODE>*thrd</CODE>
is not in the group the function does nothing.</P>

<H3><CODE><A NAME="thread_group::thread_group">thread_group::thread_group</A></CODE></H3>

<PRE><B>thread_group</B>();</PRE>

<P>The constructor constructs a <CODE>thread_group</CODE> object with an empty
group of <CODE>thread</CODE> objects.</P>

<H3><CODE><A NAME="thread_group::~thread_group">thread_group::~thread_group</A></CODE></H3>

<PRE><B>~thread_group</B>();</PRE>

<P>The destructor effectively executes <CODE>delete thrd</CODE> for every <CODE>thread</CODE>
object <CODE>*thrd</CODE> in the group.</P>

<H2><A NAME="thread_resource_error"><CODE>thread_resource_error</CODE></A></H2>

<PRE>class <A NAME="thread_resource_error"><B>thread_resource_error</B></A>
    : public std::runtime_error
    {
public:
    thread_resource_error();
    };</PRE>

<P>The class describes an exception thrown to indicate that an attempted
operation failed because a required resource other than memory was not available.</P>

<H2><A NAME="thread_specific_ptr"><CODE>thread_specific_ptr</CODE></A></H2>

<HR>

<P><B><CODE><A HREF="#thread_specific_ptr::get">get</A>
&#183; <A HREF="#thread_specific_ptr::operator-&gt;">operator-&gt;</A>
&#183; <A HREF="#thread_specific_ptr::operator*">operator*</A>
&#183; <A HREF="#thread_specific_ptr::release">release</A>
&#183; <A HREF="#thread_specific_ptr::reset">reset</A>
&#183; <A HREF="#thread_specific_ptr::thread_specific_ptr">thread_specific_ptr</A>
&#183; <A HREF="#thread_specific_ptr::~thread_specific_ptr">~thread_specific_ptr</A>
</CODE></B></P>
<HR>

<PRE>template &lt;class T&gt;
class <B>thread_specific_ptr</B>
    {
public:
    <B><A HREF="#thread_specific_ptr::thread_specific_ptr">thread_specific_ptr</A></B>();
    <B><A HREF="#thread_specific_ptr::~thread_specific_ptr">~thread_specific_ptr</A></B>();

    T *<B><A HREF="#thread_specific_ptr::get">get</A></B>() const;
    T *<B><A HREF="#thread_specific_ptr::operator-&gt;">operator-&gt;</A></B>() const;
    T& <B><A HREF="#thread_specific_ptr::operator*">operator*</A></B>() const;
    T *<B><A HREF="#thread_specific_ptr::release">release</A></B>();
    void <B><A HREF="#thread_specific_ptr::reset">reset</A></B>(T *ptr = 0);

    // exposition only
private:
    T *<B>data</B>;

    // not implemented
    thread_specific_ptr::thread_specific_ptr(const thread_specific_ptr&);
    thread_specific_ptr&lt;T&gt;& thread_specific_ptr::operator= (const thread_specific_ptr&lt;T&gt;&);
    };</PRE>

<P>The template class describes an object that controls
<A HREF="#Thread-specific Storage">thread-specific storage</A> for a
data object of type <CODE>T</CODE> or of a type derived from <CODE>T</CODE>.
The template holds a pointer <CODE>data</CODE> of type <CODE>T*</CODE>;
the stored value <CODE>data</CODE> can be different in different threads,
so threads can use different data objects,
accessed through the same <CODE>thread_specific_ptr</CODE> object.
Objects of class <CODE>thread_specific_ptr&lt;T&gt;</CODE> cannot be copied.</P>

<H3><CODE><A NAME="thread_specific_ptr::get">thread_specific_ptr::get</A></CODE></H3>

<PRE>T *<B>get</B>() const;</PRE>

<P>The member function returns the thread-specific stored value <CODE>data</CODE>.</P>

<H3><CODE><A NAME="thread_specific_ptr::operator-&gt;">thread_specific_ptr::operator-&gt;</A></CODE></H3>

<PRE>T *<B>operator-&gt;</B>() const;</PRE>

<P><I>Requires:</I>
<CODE>get() != 0</CODE>.</P>

<P>The member function returns the thread-specific stored value <CODE>data</CODE>.</P>

<H3><CODE><A NAME="thread_specific_ptr::operator*">thread_specific_ptr::operator*</A></CODE></H3>

<PRE>T& <B>operator*</B>() const;</PRE>

<P><I>Requires:</I>
<CODE>get() != 0</CODE>.</P>

<P>The member function returns <CODE>*get()</CODE>.</P>

<H3><CODE><A NAME="thread_specific_ptr::release">thread_specific_ptr::release</A></CODE></H3>

<PRE>T *<B>release</B>();</PRE>

<P>The member function sets the thread-specific stored value <CODE>data</CODE> to 0
and returns the previous value of the stored value <CODE>data</CODE>.</P>

<H3><CODE><A NAME="thread_specific_ptr::reset">thread_specific_ptr::reset</A></CODE></H3>

<PRE>void <B>reset</B>(T *ptr = 0);</PRE>

<P>The member function does nothing if the thread-specific stored value <CODE>data</CODE>
equals <CODE>ptr</CODE>; otherwise it
deletes the thread-specific stored value <CODE>data</CODE> and
sets the thread-specific stored value <CODE>data</CODE> to <CODE>ptr</CODE>.</P>

<H3><CODE><A NAME="thread_specific_ptr::thread_specific_ptr">thread_specific_ptr::thread_specific_ptr</A></CODE></H3>

<PRE><B>thread_specific_ptr</B>();</PRE>

<P>The constructor constructs a <CODE>thread_specific_ptr&lt;T&gt;</CODE> object
with initial stored value <CODE>data</CODE> equal to 0 for all threads.</P>

<H3><CODE><A NAME="thread_specific_ptr::~thread_specific_ptr">thread_specific_ptr::~thread_specific_ptr</A></CODE></H3>

<PRE><B>~thread_specific_ptr</B>();</PRE>

<P>The destructor frees resources used by the object. It does not delete thread-specific
data pointers.</P>

<H2><A NAME="timed_mutex"><CODE>timed_mutex</CODE></A></H2>

<HR>
<P><B><CODE><A HREF="#scoped_lock">scoped_lock</A>
&#183; <A HREF="#scoped_timed_lock">scoped_timed_lock</A>
&#183; <A HREF="#scoped_try_lock">scoped_try_lock</A>
&#183; <A HREF="#timed_mutex::timed_mutex">timed_mutex</A>
&#183; <A HREF="#timed_mutex::~timed_mutex">~timed_mutex</A>
</CODE></B></P>
<HR>

<PRE>class <B>timed_mutex</B>
    {
public:
    <B><A HREF="#timed_mutex::timed_mutex">timed_mutex</A></B>();
    <B><A HREF="#timed_mutex::~timed_mutex">~timed_mutex</A></B>();
    typedef SL0 <B><A HREF="#scoped_lock">scoped_lock</A></B>;
    typedef SL1 <B><A HREF="#scoped_try_lock">scoped_try_lock</A></B>;
    typedef SL2 <B><A HREF="#scoped_timed_lock">scoped_timed_lock</A></B>;

<I>    // exposition only
private:
    // not implemented
    timed_mutex(const timed_mutex&amp;);
    timed_mutex&amp; operator= (const timed_mutex&amp;);</I>
    };</PRE>

<P>The class describes an object that
can be used with a <A HREF="#scoped_lock">scoped lock</A>,
a <A HREF="#scoped_try_lock">scoped try lock</A>
or a <A HREF="#scoped_timed_lock">scoped timed lock</A>
to provide a non-recursive <A HREF="#intro mutex">mutex</A>
that supports <A HREF="#intro test and return">test and return</A>
and <A HREF="#intro timeout">timeout</A>.
Objects of class <CODE>timed_mutex</CODE> cannot be copied.</P>

<H3><CODE><A NAME="timed_mutex::timed_mutex">timed_mutex::timed_mutex</A></CODE></H3>

<PRE><B>timed_mutex</B>();</PRE>

<P>The constructor constructs a <CODE>timed_mutex</CODE> in the unlocked state.</P>

<H3><CODE><A NAME="timed_mutex::~timed_mutex">timed_mutex::~timed_mutex</A></CODE></H3>

<PRE><B>~timed_mutex</B>();</PRE>

<P><I>Requires:</I>
the object must not be locked.</P>

<P>The destructor releases any resources used by the object.</P>

<H2><A NAME="try_mutex"><CODE>try_mutex</CODE></A></H2>

<HR>
<P><B><CODE><A HREF="#scoped_lock">scoped_lock</A>
&#183; <A HREF="#scoped_try_lock">scoped_try_lock</A>
&#183; <A HREF="#try_mutex::try_mutex">try_mutex</A>
&#183; <A HREF="#try_mutex::~try_mutex">~try_mutex</A>
</CODE></B></P>
<HR>

<PRE>class <B>try_mutex</B>
    {
public:
    <B><A HREF="#try_mutex::try_mutex">try_mutex</A></B>();
    <B><A HREF="#try_mutex::~try_mutex">~try_mutex</A></B>();
    typedef SL0 <B><A HREF="#scoped_lock">scoped_lock</A></B>;
    typedef SL1 <B><A HREF="#scoped_try_lock">scoped_try_lock</A></B>;

<I>    // exposition only
private:
    // not implemented
    try_mutex(const try_mutex&amp;);
    try_mutex&amp; operator= (const try_mutex&amp;);</I>
    };</PRE>

<P>The class describes an object that
can be used with a <A HREF="#scoped_lock">scoped lock</A>
or a <A HREF="#scoped_try_lock">scoped try lock</A>
to provide a non-recursive <A HREF="#intro mutex">mutex</A>
that supports <A HREF="#intro test and return">test and return</A>.
Objects of class <CODE>try_mutex</CODE> cannot be copied.</P>

<H3><CODE><A NAME="try_mutex::try_mutex">try_mutex::try_mutex</A></CODE></H3>

<PRE><B>try_mutex</B>();</PRE>

<P>The constructor constructs a <CODE>try_mutex</CODE> in the unlocked state.</P>

<H3><CODE><A NAME="try_mutex::~try_mutex">try_mutex::~try_mutex</A></CODE></H3>

<PRE><B>~try_mutex</B>();</PRE>

<P><I>Requires:</I>
the object must not be locked.</P>

<P>The destructor releases any resources used by the object.</P>

<H2><A NAME="C Interface">C Interface</A></H2>

<HR>
<P><B><CODE><A HREF="#call_once">call_once</A>
&#183; <A HREF="#cnd_broadcast">cnd_broadcast</A>
&#183; <A HREF="#cnd_destroy">cnd_destroy</A>
&#183; <A HREF="#cnd_init">cnd_init</A>
&#183; <A HREF="#cnd_signal">cnd_signal</A>
&#183; <A HREF="#cnd_t">cnd_t</A>
&#183; <A HREF="#cnd_timedwait">cnd_timedwait</A>
&#183; <A HREF="#cnd_wait">cnd_wait</A>
&#183; <A HREF="#mtx_destroy">mtx_destroy</A>
&#183; <A HREF="#mtx_init">mtx_init</A>
&#183; <A HREF="#mtx_lock">mtx_lock</A>
&#183; <A HREF="#mtx_plain">mtx_plain</A>
&#183; <A HREF="#mtx_recursive">mtx_recursive</A>
&#183; <A HREF="#mtx_t">mtx_t</A>
&#183; <A HREF="#mtx_timed">mtx_timed</A>
&#183; <A HREF="#mtx_timedlock">mtx_timedlock</A>
&#183; <A HREF="#mtx_try">mtx_try</A>
&#183; <A HREF="#mtx_trylock">mtx_trylock</A>
&#183; <A HREF="#mtx_unlock">mtx_unlock</A>
&#183; <A HREF="#once_flag">once_flag</A>
&#183; <A HREF="#ONCE_FLAG_INIT">ONCE_FLAG_INIT</A>
&#183; <A HREF="#thrd_busy">thrd_busy</A>
&#183; <A HREF="#thrd_create">thrd_create</A>
&#183; <A HREF="#thrd_current">thrd_current</A>
&#183; <A HREF="#thrd_detach">thrd_detach</A>
&#183; <A HREF="#thrd_equal">thrd_equal</A>
&#183; <A HREF="#thrd_error">thrd_error</A>
&#183; <A HREF="#thrd_exit">thrd_exit</A>
&#183; <A HREF="#thrd_join">thrd_join</A>
&#183; <A HREF="#thrd_nomem">thrd_nomem</A>
&#183; <A HREF="#thrd_sleep">thrd_sleep</A>
&#183; <A HREF="#thrd_start_t">thrd_start_t</A>
&#183; <A HREF="#thrd_success">thrd_success</A>
&#183; <A HREF="#thrd_t">thrd_t</A>
&#183; <A HREF="#thrd_timedout">thrd_timedout</A>
&#183; <A HREF="#thrd_yield">thrd_yield</A>
&#183; <A HREF="#TIME_UTC">TIME_UTC</A>
&#183; <A HREF="#tss_create">tss_create</A>
&#183; <A HREF="#TSS_DTOR_ITERATIONS">TSS_DTOR_ITERATIONS</A>
&#183; <A HREF="#tss_delete">tss_delete</A>
&#183; <A HREF="#tss_dtor_t">tss_dtor_t</A>
&#183; <A HREF="#tss_get">tss_get</A>
&#183; <A HREF="#tss_set">tss_set</A>
&#183; <A HREF="#tss_t">tss_t</A>
&#183; <A HREF="#xtime">xtime</A>
&#183; <A HREF="#xtime_get">xtime_get</A>
</CODE></B></P>
<HR>

<H3><A NAME="Return Values">Return Values</A></H3>

<P>Most of the functions
<B><A NAME="return value">return a value</A></B> of type <CODE>int</CODE> that indicates whether
the function succeeded. The values are as follows:</P>

<UL>
<LI><A HREF="#thrd_success">thrd_success</A>
-- the function succeeded</LI>
<LI><A HREF="#thrd_nomem">thrd_nomem</A>
-- the function was unable to allocate memory</LI>
<LI><A HREF="#thrd_timedout">thrd_timedout</A>
-- the time specified in a timed wait function was reached without
acquiring the requested resource</LI>
<LI><A HREF="#thrd_busy">thrd_busy</A>
-- a resource requested by a
<A HREF="#intro test and return">test and return</A> function is already in use</LI>
<LI><A HREF="#thrd_error">thrd_error</A>
-- some other error occurred</LI>
</UL>

<H3>Threads</H3>

<P>Use the functions and types with the prefix <I><CODE>thrd</CODE></I> to manage
<A HREF="#intro thread">threads</A>. Each thread has an identifier of type
<CODE><A HREF="#thrd_t">thrd_t</A></CODE>, which is passed as an argument
to the functions that manage specific threads. Each thread begins execution in a
function of type <CODE><A HREF="#thrd_start_t">thrd_start_t</A></CODE>.
To create a new thread call the function
<CODE><A HREF="#thrd_create">thrd_create</A></CODE> with the address of the
thread identifier, the address of the thread function, and an argument to be passed
to the thread function. The thread ends when it returns from the thread function or when
it calls <CODE><A HREF="#thrd_exit">thrd_exit</A></CODE>. For convenience, a thread
can provide a <B><A NAME="result code">result code</A></B>
of type <CODE>int</CODE> when it ends, either by returning the
code from the thread function or by passing the code to <CODE>thrd_exit</CODE>.
To block a thread until another thread ends call
<CODE><A HREF="#thrd_join">thrd_join</A></CODE>, passing the
identifier of the thread to wait for and, optionally, the address of a variable of
type <CODE>int</CODE> where the result code will be stored. To properly clean up
resources allocated by the operating system, an application should call either
<CODE>thrd_join</CODE> or <CODE><A HREF="#thrd_detach">thrd_detach</A></CODE>
once for each thread created by <CODE>thrd_create</CODE>.</P>

<P>Two functions operate on the current thread; they do not take a thread identifier argument.
Use <CODE><A HREF="#thrd_sleep">thrd_sleep</A></CODE> to suspend
execution of the current thread until a particular time. Use
<CODE><A HREF="#thrd_yield">thrd_yield</A></CODE> to request that other
threads be allowed to run even if the current thread would ordinarily
continue to run.</P>

<P>Two functions operate on thread identifiers. Use
<CODE><A HREF="#thrd_equal">thrd_equal</A></CODE> to determine whether
two thread identifiers refer to the same thread.
Use <CODE><A HREF="#thrd_current">thrd_current</A></CODE> to get
a thread identifier that refers to the current thread.</P>

<H3>Condition Variables</H3>

<P>Use the functions and type with the prefix <I><CODE>cnd</CODE></I> to manage
<A HREF="#intro condition variable">condition variables</A>.
Each condition variable has an identifier of type
<CODE><A HREF="#cnd_t">cnd_t</A></CODE>, which is passed as an argument
to the functions that manage condition variables. Use
<CODE><A HREF="#cnd_init">cnd_init</A></CODE> to create a condition
variable and <CODE><A HREF="#cnd_destroy">cnd_destroy</A></CODE> to
release any resources associated with a condition variable when it is no longer needed.
To wait for a condition variable to be signalled call
<CODE><A HREF="#cnd_wait">cnd_wait</A></CODE> or
<CODE><A HREF="#cnd_timedwait">cnd_timedwait</A></CODE>.
To unblock threads waiting for a condition variable call
<CODE><A HREF="#cnd_signal">cnd_signal</A></CODE> or
<CODE><A HREF="#cnd_broadcast">cnd_broadcast</A></CODE>.</P>

<H3>Mutexes</H3>

<P>Use the functions and type with the prefix <I><CODE>mtx</CODE></I> to manage
<A HREF="#intro mutex">mutexes</A>.
Each mutex has an identifier of type
<CODE><A HREF="#mtx_t">mtx_t</A></CODE>, which is passed as an argument
to the functions that manage mutexes. Use
<CODE><A HREF="#mtx_init">mtx_init</A></CODE> to create a mutex
and <CODE><A HREF="#mtx_destroy">mtx_destroy</A></CODE> to
release any resources associated with a mutex when it is no longer needed.
To lock a mutex call
<CODE><A HREF="#mtx_lock">mtx_lock</A></CODE>,
<CODE><A HREF="#mtx_timedlock">mtx_timedlock</A></CODE> or
<CODE><A HREF="#mtx_trylock">mtx_trylock</A></CODE>. To
unlock a mutex call
<CODE><A HREF="#mtx_unlock">mtx_unlock</A></CODE>.</P>

<H3>Once Functions</H3>

<P>Use a value of type <CODE><A HREF="#once_flag">once_flag</A></CODE>,
initialized to the value <CODE><A HREF="#ONCE_FLAG_INIT">ONCE_FLAG_INIT</A></CODE>,
to ensure that a function is called exactly once by passing
a function pointer and the address of the <CODE>once_flag</CODE> object
to <CODE><A HREF="#call_once">call_once</A></CODE>.</P>

<H3>Thread-specific Storage</H3>

<P>Use the functions and types with the prefix <I><CODE>tss</CODE></I> to manage
<A HREF="#Thread-specific Storage">thread-specific storage</A>.
Each thread-specific storage pointer has an identifier of type
<CODE><A HREF="#tss_t">tss_t</A></CODE>, which is passed as an argument
to the functions that manage thread-specific storage.
Call <CODE><A HREF="#tss_create">tss_create</A></CODE>
to create a thread-specific storage pointer and
<CODE><A HREF="#tss_delete">tss_delete</A></CODE> to release any
resources associated with a thread-specific storage pointer when it is no longer
needed. To get the value held by the pointer in the current thread call
<CODE><A HREF="#tss_get">tss_get</A></CODE>. To change the value
held by the pointer in the current thread call
<CODE><A HREF="#tss_set">tss_set</A></CODE>.</P>

<P>Each thread-specific storage pointer may have an associated
<B><A NAME="destructor">destructor</A></B>, specified in the call
to <CODE>tss_create</CODE>. The destructor
will be called when a thread terminates and the value of the pointer
associated with that thread is not 0. The value of the pointer for that
thread is set to 0 before calling the destructor and the old value is
passed to the destructor. Since a destructor can store non-0 values in
thread-specific storage pointers, this process will be repeated until no pointers
for the terminating thread hold non-0 values or until a system-specific
maximum number of iterations
<CODE><A HREF="#TSS_DTOR_ITERATIONS">TSS_DTOR_ITERATIONS</A></CODE>
has been made.</P>

<PRE>    /* ERROR REPORTING */
enum {
    <B><A HREF="#thrd_success">thrd_success</A></B> = .....,
    <B><A HREF="#thrd_nomem">thrd_nomem</A></B> = .....,
    <B><A HREF="#thrd_timedout">thrd_timedout</A></B> = .....,
    <B><A HREF="#thrd_busy">thrd_busy</A></B> = .....,
    <B><A HREF="#thrd_error">thrd_error</A></B> = .....
    };

    /* THREADS */
typedef <I>o-type</I> <B><A HREF="#thrd_t">thrd_t</A></B>;
typedef int (*<B><A HREF="#thrd_start_t">thrd_start_t</A></B>)(void*);
int <B><A HREF="#thrd_create">thrd_create</A></B>(thrd_t *, thrd_start_t, void*);
int <B><A HREF="#thrd_detach">thrd_detach</A></B>(thrd_t);
void <B><A HREF="#thrd_exit">thrd_exit</A></B>(int);
int <B><A HREF="#thrd_join">thrd_join</A></B>(thrd_t, int*);
void <B><A HREF="#thrd_sleep">thrd_sleep</A></B>(const xtime*);
void <B><A HREF="#thrd_yield">thrd_yield</A></B>(void);
int <B><A HREF="#thrd_equal">thrd_equal</A></B>(thrd_t, thrd_t);
thrd_t <B><A HREF="#thrd_current">thrd_current</A></B>(void);

    /* MUTEXES */
typedef <I>o-type</I> <B><A HREF="#mtx_t">mtx_t</A></B>;
enum {
    <B><A HREF="#mtx_plain">mtx_plain</A></B> = .....,
    <B><A HREF="#mtx_try">mtx_try</A></B> = .....,
    <B><A HREF="#mtx_timed">mtx_timed</A></B> = .....,
    <B><A HREF="#mtx_recursive">mtx_recursive</A></B> = .....
    };
int <B><A HREF="#mtx_init">mtx_init</A></B>(mtx_t*, int);
void <B><A HREF="#mtx_destroy">mtx_destroy</A></B>(mtx_t*);
int <B><A HREF="#mtx_lock">mtx_lock</A></B>(mtx_t*);
int <B><A HREF="#mtx_trylock">mtx_trylock</A></B>(mtx_t*);
int <B><A HREF="#mtx_timedlock">mtx_timedlock</A></B>(mtx_t*, const xtime*);
int <B><A HREF="#mtx_unlock">mtx_unlock</A></B>(mtx_t*);

    /* CONDITION VARIABLES */
typedef <I>o_type</I> <B><A HREF="#cnd_t">cnd_t </A></B>;
int <B><A HREF="#cnd_init">cnd_init</A></B>(cnd_t*);
void <B><A HREF="#cnd_destroy">cnd_destroy</A></B>(cnd_t*);
int <B><A HREF="#cnd_wait">cnd_wait</A></B>(cnd_t*, mtx_t*);
int <B><A HREF="#cnd_timedwait">cnd_timedwait</A></B>(cnd_t*, mtx_t*, const xtime*);
int <B><A HREF="#cnd_signal">cnd_signal</A></B>(cnd_t*);
int <B><A HREF="#cnd_broadcast">cnd_broadcast</A></B>(cnd_t*);

    /* THREAD-SPECIFIC STORAGE */
typedef <I>i-type</I> <B><A HREF="#tss_t">tss_t</A></B>;
typedef void (*<B><A HREF="#tss_dtor_t">tss_dtor_t</A></B>)(void*);
int <B><A HREF="#tss_create">tss_create</A></B>(tss_t*, tss_dtor_t);
int <B><A HREF="#tss_delete">tss_delete</A></B>(tss_t);
int <B><A HREF="#tss_set">tss_set</A></B>(tss_t, void*);
void *<B><A HREF="#tss_get">tss_get</A></B>(tss_t);
#define <B><A HREF="#TSS_DTOR_ITERATIONS">TSS_DTOR_ITERATIONS</A></B> <I>&lt;integer constant expression&gt;</I>

    /* ONCE FUNCTIONS */
typedef <I>o-type</I> <B><A HREF="#once_flag">once_flag</A></B>;
#define <B><A HREF="#ONCE_FLAG_INIT">ONCE_FLAG_INIT</A></B> <I>&lt;object initializer&gt;</I>
void <B><A HREF="#call_once">call_once</A></B>(once_flag*, void (*)(void));

    /* TIME SUPPORT */
typedef <I>o-type</I> <B><A HREF="#xtime">xtime</A></B>;
enum { <B><A HREF="#TIME_UTC">TIME_UTC</A></B> = <I>&lt;integer constant expression&gt</I> };
int <B><A HREF="#xtime_get">xtime_get</A></B>(xtime *, int);</PRE>

<H2><A NAME="cnd_broadcast"><CODE>cnd_broadcast</CODE></A></H2>

<PRE>int <B>cnd_broadcast</B>(cnd_t *cond);</PRE>

<P><I>Returns:</I> the usual <A HREF="#return value">return value</A>.</P>

<P>The function unblocks all of the threads that are blocked on the
<A HREF="#intro condition variable">condition variable</A>
<CODE>*cond</CODE> at the time of the call. If no threads are blocked
on the condition variable at the time of the call the function does nothing.</P>

<H2><A NAME="cnd_destroy"><CODE>cnd_destroy</CODE></A></H2>

<PRE>void <B>cnd_destroy</B>(cnd_t *cond);</PRE>

<P><I>Requires:</I>
no threads are blocked waiting for <CODE>*cond</CODE>.</P>

<P>The function releases any resources used by the
<A HREF="#intro condition variable">condition variable</A> <CODE>*cond</CODE>.</P>

<H2><A NAME="cnd_init"><CODE>cnd_init</CODE></A></H2>

<PRE>int <B>cnd_init</B>(cnd_t *cond);</PRE>

<P><I>Returns:</I> the usual <A HREF="#return value">return value</A>.</P>

<P>The function creates a
<A HREF="#intro condition variable">condition variable</A>.
If it succeeds
it sets <CODE>*cond</CODE> to a value that uniquely identifies the
newly created condition variable.
A thread that calls <A HREF="#cnd_wait">cnd_wait</A> on a newly created condition variable
will block.</P>

<H2><A NAME="cnd_signal"><CODE>cnd_signal</CODE></A></H2>

<PRE>int <B>cnd_signal</B>(cnd_t *cond);</PRE>

<P><I>Returns:</I> the usual <A HREF="#return value">return value</A>.</P>

<P>The function unblocks one of the threads that is blocked on the
<A HREF="#intro condition variable">condition variable</A>
<CODE>*cond</CODE> at the time of the call. If no threads are blocked
on the condition variable at the time of the call the function does nothing.</P>

<H2><A NAME="cnd_t"><CODE>cnd_t</CODE></A></H2>

<PRE>typedef <I>o-type</I> <B>cnd_t</B>;</PRE>

<P>The type is an object type <I>o-type</I> that holds an identifier for a
<A HREF="#intro condition variable">condition variable</A>.</P>

<H2><A NAME="cnd_timedwait"><CODE>cnd_timedwait</CODE></A></H2>

<PRE>int <B>cnd_timedwait</B>(cnd_t *cond, mtx_t *mtx, const xtime *xt);</PRE>

<P><I>Requires:</I>
the <A HREF="#intro mutex">mutex</A> <CODE>*mtx</CODE>
must be locked by the calling thread</P>

<P><I>Returns:</I> the usual <A HREF="#return value">return value</A>.</P>

<P>The function atomically unlocks the <A HREF="#intro mutex">mutex</A>
<CODE>*mtx</CODE> and blocks until the
<A HREF="#intro condition variable">condition variable</A>
<CODE>*cond</CODE> is signaled by a call to
<A HREF="#cnd_signal">cnd_signal</A> or to
<A HREF="#cnd_broadcast">cnd_broadcast</A>, or until after the time specified
by the <A HREF="#xtime">xtime</A> object <CODE>*xt</CODE>.
When the calling thread becomes unblocked it locks <CODE>*mtx</CODE>
before it returns.</P>

<H2><A NAME="cnd_wait"><CODE>cnd_wait</CODE></A></H2>

<PRE>int <B>cnd_wait</B>(cnd_t *cond, mtx_t *mtx);</PRE>

<P><I>Requires:</I>
the <A HREF="#intro mutex">mutex</A> <CODE>*mtx</CODE>
must be locked by the calling thread</P>

<P><I>Returns:</I> the usual <A HREF="#return value">return value</A>.</P>

<P>The function atomically unlocks the <A HREF="#intro mutex">mutex</A>
<CODE>*mtx</CODE> and blocks until the <A HREF="#intro condition variable">condition variable</A>
<CODE>*cond</CODE> is signaled by a call to
<A HREF="#cnd_signal">cnd_signal</A> or to
<A HREF="#cnd_broadcast">cnd_broadcast</A>. When the calling thread becomes
unblocked it locks <CODE>*mtx</CODE> before it returns.</P>

<H2><A NAME="mtx_destroy"><CODE>mtx_destroy</CODE></A></H2>

<PRE>void <B>mtx_destroy</B>(mtx_t *mtx);</PRE>

<P><I>Requires:</I>
no threads are blocked waiting for <CODE>*mtx</CODE>.</P>

<P>The function releases any resources used by the
<A HREF="#intro mutex">mutex</A> <CODE>*mtx</CODE>.</P>

<H2><A NAME="mtx_init"><CODE>mtx_init</CODE></A></H2>

<PRE>int <B>mtx_init</B>(mtx_t *mtx, int type);</PRE>

<P><I>Returns:</I> the usual <A HREF="#return value">return value</A>.</P>

<P>The function creates a <A HREF="#intro mutex">mutex</A> object with
properties indicated by <CODE>type</CODE>, which must have one of
the six values</P>

<UL>
<LI><CODE><A HREF="#mtx_plain">mtx_plain</A></CODE> -- for a simple
<A HREF="#intro non-recursive">non-recursive</A> mutex</LI>
<LI><CODE><A HREF="#mtx_timed">mtx_timed</A></CODE> -- for a
non-recursive mutex that supports <A HREF="#intro timeout">timeout</A></LI>
<LI><CODE><A HREF="#mtx_try">mtx_try</A></CODE> -- for a
non-recursive mutex that supports <A HREF="#intro test and return">test and return</A></LI>
<LI><CODE>mtx_plain | <A HREF="#mtx_recursive">mtx_recursive</A></CODE> -- for a simple
<A HREF="#intro recursive">recursive</A> mutex</LI>
<LI><CODE>mtx_timed | mtx_recursive</CODE> -- for a
recursive mutex that supports <A HREF="#intro timeout">timeout</A></LI>
<LI><CODE>mtx_try | mtx_recursive</CODE> -- for a
recursive mutex that supports <A HREF="#intro test and return">test and return</A></LI>
</UL>

<P>If it succeeds it sets <CODE>*mtx</CODE> to a value that uniquely
identifies the newly created mutex.</P>

<H2><A NAME="mtx_lock"><CODE>mtx_lock</CODE></A></H2>

<PRE>int <B>mtx_lock</B>(mtx_t *mtx);</PRE>

<P><I>Requires:</I>
if the <A HREF="#intro mutex">mutex</A> is
<A HREF="#intro non-recursive">non-recursive</A> it must not
be locked by the calling thread.</P>

<P><I>Returns:</I> the usual <A HREF="#return value">return value</A>.</P>

<P>The function blocks until it locks the
<A HREF="#intro mutex">mutex</A> <CODE>*mtx</CODE>.</P>

<H2><A NAME="mtx_plain"><CODE>mtx_plain</CODE></A></H2>

<PRE>enum { <B>mtx_plain</B> = ..... };</PRE>

<P>The compile-time constant is passed to
<A HREF="#mtx_init">mtx_init</A> to create a
<A HREF="#intro mutex">mutex</A> object that supports neither
<A HREF="#intro timeout">timeout</A> nor
<A HREF="#intro test and return">test and return</A>.</P>

<H2><A NAME="mtx_recursive"><CODE>mtx_recursive</CODE></A></H2>

<PRE>enum { <B>mtx_recursive</B> = ..... };</PRE>

<P>The compile-time constant is passed to
<A HREF="#mtx_init">mtx_init</A> to create a
<A HREF="#intro mutex">mutex</A> object that supports
<A HREF="#intro recursive">recursive</A> locking.</P>

<H2><A NAME="mtx_t"><CODE>mtx_t</CODE></A></H2>

<PRE>typedef <I>o-type</I> <B>mtx_t</B>;</PRE>

<P>The type is an object type <I>o-type</I> that holds an identifier for a
<A HREF="#intro mutex">mutex</A>.</P>

<H2><A NAME="mtx_timed"><CODE>mtx_timed</CODE></A></H2>

<PRE>enum { <B>mtx_timed</B> = ..... };</PRE>

<P>The compile-time constant is passed to
<A HREF="#mtx_init">mtx_init</A> to create a
<A HREF="#intro mutex">mutex</A> object that supports
<A HREF="#intro timeout">timeout</A>.</P>

<H2><A NAME="mtx_timedlock"><CODE>mtx_timedlock</CODE></A></H2>

<PRE>int <B>mtx_timedlock</B>(mtx_t *mtx, const xtime *xt);</PRE>

<P><I>Requires:</I>
the <A HREF="#intro mutex">mutex</A> <CODE>*mtx</CODE>
must be of type <A HREF="#mtx_timed">mtx_timed</A> or
of type <CODE>mtx_timed | mtx_recursive</CODE>.</P>

<P><I>Returns:</I> the usual <A HREF="#return value">return value</A>.</P>

<P>The function blocks until it locks the
<A HREF="#intro mutex">mutex</A> <CODE>*mtx</CODE>
or until the time specified by the
<A HREF="#xtime">xtime</A> object <CODE>*xt</CODE>.</P>

<H2><A NAME="mtx_try"><CODE>mtx_try</CODE></A></H2>

<PRE>enum { <B>mtx_try</B> = ..... };</PRE>

<P>The compile-time constant is passed to
<A HREF="#mtx_init">mtx_init</A> to create a
<A HREF="#intro mutex">mutex</A> object that supports
<A HREF="#intro test and return">test and return</A>.</P>

<H2><A NAME="mtx_trylock"><CODE>mtx_trylock</CODE></A></H2>

<PRE>int <B>mtx_trylock</B>(mtx_t *mtx);</PRE>

<P><I>Requires:</I>
the <A HREF="#intro mutex">mutex</A> <CODE>*mtx</CODE>
must be of type <A HREF="#mtx_try">mtx_try</A>,
of type <CODE>mtx_try | mtx_recursive</CODE>,
of type <A HREF="#mtx_timed">mtx_timed</A>,
or of type <CODE>mtx_timed | mtx_recursive</CODE>.</P>

<P><I>Returns:</I> the usual <A HREF="#return value">return value</A>.</P>

<P>The function attempts to lock the
<A HREF="#intro mutex">mutex</A> <CODE>*mtx</CODE>.
If the mutex is already locked the function returns without blocking.</P>

<H2><A NAME="mtx_unlock"><CODE>mtx_unlock</CODE></A></H2>

<PRE>int <B>mtx_unlock</B>(mtx_t *mtx);</PRE>

<P><I>Requires:</I>
the <A HREF="#intro mutex">mutex</A> <CODE>*mtx</CODE>
must be locked by the calling thread.</P>

<P><I>Returns:</I> the usual <A HREF="#return value">return value</A>.</P>

<P>The function unlocks the <A HREF="#intro mutex">mutex</A> <CODE>*mtx</CODE>.</P>

<H2><A NAME="thrd_busy"><CODE>thrd_busy</CODE></A></H2>

<PRE>enum { <B>thrd_busy</B> = ..... };</PRE>

<P>The compile-time constant is returned by a function to indicate
that the requested operation failed because
a resource requested by a <A HREF="#intro test and return">test and return</A>
function is already in use.</P>

<H2><A NAME="thrd_create"><CODE>thrd_create</CODE></A></H2>

<PRE>int <B>thrd_create</B>(thrd_t *thr, thrd_start_t func, void *arg);</PRE>

<P><I>Returns:</I> the usual <A HREF="#return value">return value</A>.</P>

<P>The function creates a new <A HREF="#intro thread">thread</A>
executing <CODE>func(arg)</CODE>.
If it succeeds it sets <CODE>*thr</CODE> to a value that uniquely identifies the
newly created thread. The function does not return until the new thread has
begun execution.</P>

<H2><A NAME="thrd_current"><CODE>thrd_current</CODE></A></H2>

<PRE>thrd_t <B>thrd_current</B>(void);</PRE>

<P>The function returns a value that uniquely identifies
the <A HREF="#intro thread">thread</A>
that called it.</P>

<H2><A NAME="thrd_detach"><CODE>thrd_detach</CODE></A></H2>

<PRE>int <B>thrd_detach</B>(thrd_t thr);</PRE>

<P><I>Requires:</I>
the application must not have previously called
<CODE>thrd_detach</CODE> or
<A HREF="#thrd_join">thrd_join</A> for the
<A HREF="#intro thread">thread</A> identified by <CODE>thr</CODE>.</P>

<P><I>Returns:</I> the usual <A HREF="#return value">return value</A>.</P>

<P>The function tells the operating system to dispose of any resources allocated to the
thread identified by <CODE>thr</CODE> when that thread terminates.</P>

<H2><A NAME="thrd_equal"><CODE>thrd_equal</CODE></A></H2>

<PRE>int <B>thrd_equal</B>(thrd_t thr0, thrd_t thr1);</PRE>

<P>The function returns zero if <CODE>thr0</CODE> and <CODE>thr1</CODE> refer to
different threads. Otherwise it returns a non-zero value.</P>

<H2><A NAME="thrd_error"><CODE>thrd_error</CODE></A></H2>

<PRE>enum { <B>thrd_error</B> = ..... };</PRE>

<P>The compile-time constant is returned by a function to indicate
that the requested operation failed.</P>

<H2><A NAME="thrd_exit"><CODE>thrd_exit</CODE></A></H2>

<PRE>void <B>thrd_exit</B>(int res);</PRE>

<P>The function terminates execution of the calling
<A HREF="#intro thread">thread</A> and sets its
<A HREF="#result code">result code</A> to <CODE>res</CODE>.</P>

<H2><A NAME="thrd_join"><CODE>thrd_join</CODE></A></H2>

<PRE>int <B>thrd_join</B>(thrd_t thr, int *res);</PRE>

<P><I>Requires:</I>
the application must not have previously called
<CODE>thrd_join</CODE> or
<A HREF="#thrd_detach">thrd_detach</A> for the
<A HREF="#intro thread">thread</A> identified by <CODE>thr</CODE>.</P>

<P><I>Returns:</I> the usual <A HREF="#return value">return value</A>.</P>

<P>The function tells the operating system to dispose of any resources allocated to the
<CODE>thread</CODE> identified by <CODE>thr</CODE> when that thread terminates and
blocks until that thread has terminated. If <CODE>res</CODE>
is not a null pointer it stores the thread's
<A HREF="#result code">result code</A>
in <CODE>*res</CODE>.</P>

<H2><A NAME="thrd_nomem"><CODE>thrd_nomem</CODE></A></H2>

<PRE>enum { <B>thrd_nomem</B> = ..... };</PRE>

<P>The compile-time constant is returned by a function to indicate
that the requested operation failed because
it was unable to allocate memory.</P>

<H2><A NAME="thrd_sleep"><CODE>thrd_sleep</CODE></A></H2>

<PRE>void <B>thrd_sleep</B>(const xtime *xt);</PRE>

<P>The function suspends execution of the calling
<A HREF="#intro thread">thread</A>
until after the time specified by the
<A HREF="#xtime">xtime</A> object <CODE>*xt</CODE>.</P>

<H2><A NAME="thrd_start_t"><CODE>thrd_start_t</CODE></A></H2>

<PRE>typedef int (*<B>thrd_start_t</B>)(void*);</PRE>

<P>The type is the function type that is passed to
<A HREF="#thrd_create">thrd_create</A> to create a new
<A HREF="#intro thread">thread</A>.</P>

<H2><A NAME="thrd_success"><CODE>thrd_success</CODE></A></H2>

<PRE>enum { <B>thrd_success</B> = ..... };</PRE>

<P>The compile-time constant is returned by a function to indicate
that the requested operation succeeded.</P>

<H2><A NAME="thrd_t"><CODE>thrd_t</CODE></A></H2>

<PRE>typedef <I>o-type</I> <B>thrd_t</B>;</PRE>

<P>The type is an object type <I>o-type</I> that holds an identifier for a
<A HREF="#intro thread">thread</A>.</P>

<H2><A NAME="thrd_timedout"><CODE>thrd_timedout</CODE></A></H2>

<PRE>enum { <B>thrd_timedout</B> = ..... };</PRE>

<P>The compile-time constant is returned by a timed wait function to indicate
that the time specified in the call was reached without acquiring the
requested resource.</P>

<H2><A NAME="thrd_yield"><CODE>thrd_yield</CODE></A></H2>

<PRE>void <B>thrd_yield</B>(void);</PRE>

<P>The function permits other threads to run even if the current thread would
ordinarily continue to run.</P>

<H2><A NAME="TIME_UTC"><CODE>TIME_UTC</CODE></A></H2>

<PRE>enum { <B>TIME_UTC</B> = <I>&lt;integer constant expression&gt</I> };</PRE>

<P>The compile-time constant is a non-zero value that designates Coordinated Universal
Time (UTC) as the time base for the values set by <A HREF="#xtime_get">xtime_get</A>.</P>

<H2><A NAME="tss_create"><CODE>tss_create</CODE></A></H2>

<PRE>int <B>tss_create</B>(tss_t *key, tss_dtor_t dtor);</PRE>

<P><I>Returns:</I> the usual <A HREF="#return value">return value</A>.</P>

<P>The function creates a
<A HREF="#Thread-specific Storage">thread-specific storage</A>
pointer with <A HREF="#destructor">destructor</A> <CODE>dtor</CODE>,
which may be null. If it succeeds it sets <CODE>*key</CODE> to a value that uniquely
identifies the newly created pointer.</P>

<H2><A NAME="TSS_DTOR_ITERATIONS"><CODE>TSS_DTOR_ITERATIONS</CODE></A></H2>

<PRE>#define <B>TSS_DTOR_ITERATIONS</B> <I>&lt;integer constant expression&gt;</I></PRE>

<P>The macro yields the maximum number of times that
<A HREF="#destructor">destructors</A> will
be called when a thread terminates.</P>

<H2><A NAME="tss_dtor_t"><CODE>tss_dtor_t</CODE></A></H2>

<PRE>typedef void (*<B>tss_dtor_t</B>)(void*);</PRE>

<P>The type is the function type for a
<A HREF="#destructor">destructor</A> for a
<A HREF="#Thread-specific Storage">thread-specific storage</A> pointer.</P>

<H2><A NAME="tss_delete"><CODE>tss_delete</CODE></A></H2>

<PRE>void <B>tss_delete</B>(tss_t key);</PRE>

<P>The function releases any resources used by the
<A HREF="#Thread-specific Storage">thread-specific storage</A>
pointer <CODE>key</CODE>.</P>

<H2><A NAME="tss_get"><CODE>tss_get</CODE></A></H2>

<PRE>void *<B>tss_get</B>(tss_t key);</PRE>

<P>The function returns the value for the current thread held in the
<A HREF="#Thread-specific Storage">thread-specific storage</A>
pointer identified by <CODE>key</CODE>.</P>

<H2><A NAME="tss_set"><CODE>tss_set</CODE></A></H2>

<PRE>int <B>tss_set</B>(tss_t key, void *val);</PRE>

<P><I>Returns:</I> the usual <A HREF="#return value">return value</A>.</P>

<P>The function sets the value for the current thread held in the
<A HREF="#Thread-specific Storage">thread-specific storage</A>
pointer identified by <CODE>key</CODE> to <CODE>val</CODE>.</P>

<H2><A NAME="tss_t"><CODE>tss_t</CODE></A></H2>

<PRE>typedef <I>o-type</I> <B>tss_t</B>;</PRE>

<P>The type is an object type <I>o-type</I> that holds an identifier for a
<A HREF="#Thread-specific Storage">thread-specific storage</A>
pointer.</P>

<H2><A NAME="xtime"><CODE>xtime</CODE></A></H2>

<PRE>typedef struct {
    int sec;    <B>/* seconds since 1 Jan. 1970 00:00:00 */</B>
    int nsec;   <B>/* nanoseconds since time specified by sec */</B>
    } <B>xtime</B>;</PRE>

<P>The struct <CODE>xtime</CODE> contains members that describe times with
nanosecond resolution. The comment following each member desribes its meaning.</P>

<H2><A NAME="xtime_get"><CODE>xtime_get</CODE></A></H2>

<PRE>int <B>xtime_get</B>(xtime *xt, int base);</PRE>

<P>The function sets the <CODE>xtime</CODE> object pointed to by
<CODE>xt</CODE> to hold the current time based on the time base
<CODE>base</CODE>. If successful it returns the non-zero value <CODE>base</CODE>,
which must be <A HREF="#TIME_UTC">TIME_UTC</A>;
otherwise it returns 0.</P>

<HR>
<P><I>
Copyright &#169; 2002, 2005 by Dinkumware, Ltd.
Permission is granted to use this document for standardization purposes.
This material is derived in part from documentation bearing the
following restrictions:</I></P>

<BLOCKQUOTE>
<PRE>&#169; Copyright William E. Kempf 2001</PRE>

<P>Permission to use, copy, modify, distribute and sell this software and its
documentation for any purpose is hereby granted without fee, provided that the
above copyright notice appear in all copies and that both that copyright notice
and this permission notice appear in supporting documentation.
William E. Kempf makes no representations about the suitability of this software
for any purpose. It is provided "as is" without express or implied warranty.</P>
</BLOCKQUOTE>
</BODY></HTML>
