@ -1,5 +1,5 @@
/*
/* -*- mode: c++; tab-width: 2; indent-tabs-mode: nil; -*-
Copyright ( c ) 2010 Marcus Geelnard
Copyright ( c ) 2010 - 2012 Marcus Geelnard
This software is provided ' as - is ' , without any express or implied
This software is provided ' as - is ' , without any express or implied
warranty . In no event will the authors be held liable for any damages
warranty . In no event will the authors be held liable for any damages
@ -31,7 +31,7 @@ freely, subject to the following restrictions:
/// TinyThread++ is a minimal, portable implementation of basic threading
/// TinyThread++ is a minimal, portable implementation of basic threading
/// classes for C++.
/// classes for C++.
///
///
/// They closely mimic the functionality and naming of the C++ 0x standard, and
/// They closely mimic the functionality and naming of the C++ 11 standard, and
/// should be easily replaceable with the corresponding std:: variants.
/// should be easily replaceable with the corresponding std:: variants.
///
///
/// @section port_sec Portability
/// @section port_sec Portability
@ -39,7 +39,7 @@ freely, subject to the following restrictions:
/// classes, while for other systems, the POSIX threads API (pthread) is used.
/// classes, while for other systems, the POSIX threads API (pthread) is used.
///
///
/// @section class_sec Classes
/// @section class_sec Classes
/// In order to mimic the threading API of the C++ 0x standard, subsets of
/// In order to mimic the threading API of the C++ 11 standard, subsets of
/// several classes are provided. The fundamental classes are:
/// several classes are provided. The fundamental classes are:
/// @li tthread::thread
/// @li tthread::thread
/// @li tthread::mutex
/// @li tthread::mutex
@ -67,8 +67,15 @@ freely, subject to the following restrictions:
// Platform specific includes
// Platform specific includes
# if defined(_TTHREAD_WIN32_)
# if defined(_TTHREAD_WIN32_)
# define NOMINMAX
# ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN
# define __UNDEF_LEAN_AND_MEAN
# endif
# include <windows.h>
# include <windows.h>
# ifdef __UNDEF_LEAN_AND_MEAN
# undef WIN32_LEAN_AND_MEAN
# undef __UNDEF_LEAN_AND_MEAN
# endif
# else
# else
# include <pthread.h>
# include <pthread.h>
# include <signal.h>
# include <signal.h>
@ -82,22 +89,22 @@ freely, subject to the following restrictions:
/// TinyThread++ version (major number).
/// TinyThread++ version (major number).
# define TINYTHREAD_VERSION_MAJOR 1
# define TINYTHREAD_VERSION_MAJOR 1
/// TinyThread++ version (minor number).
/// TinyThread++ version (minor number).
# define TINYTHREAD_VERSION_MINOR 0
# define TINYTHREAD_VERSION_MINOR 1
/// TinyThread++ version (full version).
/// TinyThread++ version (full version).
# define TINYTHREAD_VERSION (TINYTHREAD_VERSION_MAJOR * 100 + TINYTHREAD_VERSION_MINOR)
# define TINYTHREAD_VERSION (TINYTHREAD_VERSION_MAJOR * 100 + TINYTHREAD_VERSION_MINOR)
// Do we have a fully featured C++ 0x compiler?
// Do we have a fully featured C++ 11 compiler?
# if (__cplusplus > 199711L) || (defined(__STDCXX_VERSION__) && (__STDCXX_VERSION__ >= 201001L))
# if (__cplusplus > 199711L) || (defined(__STDCXX_VERSION__) && (__STDCXX_VERSION__ >= 201001L))
# define _TTHREAD_CPP 0X _
# define _TTHREAD_CPP 11 _
# endif
# endif
// ...at least partial C++ 0x ?
// ...at least partial C++ 11 ?
# if defined(_TTHREAD_CPP 0X _) || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__GXX_EXPERIMENTAL_CPP0X__)
# if defined(_TTHREAD_CPP 11 _) || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__GXX_EXPERIMENTAL_CPP0X__)
# define _TTHREAD_CPP 0X _PARTIAL_
# define _TTHREAD_CPP 11 _PARTIAL_
# endif
# endif
// Macro for disabling assignments of objects.
// Macro for disabling assignments of objects.
# ifdef _TTHREAD_CPP 0X _PARTIAL_
# ifdef _TTHREAD_CPP 11 _PARTIAL_
# define _TTHREAD_DISABLE_ASSIGNMENT(name) \
# define _TTHREAD_DISABLE_ASSIGNMENT(name) \
name ( const name & ) = delete ; \
name ( const name & ) = delete ; \
name & operator = ( const name & ) = delete ;
name & operator = ( const name & ) = delete ;
@ -109,18 +116,18 @@ freely, subject to the following restrictions:
/// @def thread_local
/// @def thread_local
/// Thread local storage keyword.
/// Thread local storage keyword.
/// A variable that is declared with the \ c thread_local keyword makes the
/// A variable that is declared with the @ c thread_local keyword makes the
/// value of the variable local to each thread (known as thread-local storage,
/// value of the variable local to each thread (known as thread-local storage,
/// or TLS). Example usage:
/// or TLS). Example usage:
/// @code
/// @code
/// // This variable is local to each thread.
/// // This variable is local to each thread.
/// thread_local int variable;
/// thread_local int variable;
/// @endcode
/// @endcode
/// @note The \ c thread_local keyword is a macro that maps to the corresponding
/// @note The @ c thread_local keyword is a macro that maps to the corresponding
/// compiler directive (e.g. \c __declspec(thread)). While the C++0x standard
/// compiler directive (e.g. @c __declspec(thread)). While the C++11 standard
/// allows for non-trivial types (e.g. classes with constructors and
/// allows for non-trivial types (e.g. classes with constructors and
/// destructors) to be declared with the \c thread_local keyword, most pre-C++0x
/// destructors) to be declared with the @c thread_local keyword, most pre-C++11
/// compilers only allow for trivial types (e.g. \ c int). So, to guarantee
/// compilers only allow for trivial types (e.g. @ c int). So, to guarantee
/// portable code, only use trivial types for thread local storage.
/// portable code, only use trivial types for thread local storage.
/// @note This directive is currently not supported on Mac OS X (it will give
/// @note This directive is currently not supported on Mac OS X (it will give
/// a compiler error), since compile-time TLS is not supported in the Mac OS X
/// a compiler error), since compile-time TLS is not supported in the Mac OS X
@ -128,7 +135,7 @@ freely, subject to the following restrictions:
/// not support this directive.
/// not support this directive.
/// @hideinitializer
/// @hideinitializer
# if !defined(_TTHREAD_CPP 0X _) && !defined(thread_local)
# if !defined(_TTHREAD_CPP 11 _) && !defined(thread_local)
# if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
# if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__)
# define thread_local __thread
# define thread_local __thread
# else
# else
@ -138,8 +145,8 @@ freely, subject to the following restrictions:
/// Main name space for TinyThread++.
/// Main name space for TinyThread++.
/// This namespace is more or less equivalent to the \ c std namespace for the
/// This namespace is more or less equivalent to the @ c std namespace for the
/// C++ 0x thread classes. For instance, the tthread::mutex class corresponds to
/// C++ 11 thread classes. For instance, the tthread::mutex class corresponds to
/// the std::mutex class.
/// the std::mutex class.
namespace tthread {
namespace tthread {
@ -176,7 +183,7 @@ class mutex {
/// Lock the mutex.
/// Lock the mutex.
/// The method will block the calling thread until a lock on the mutex can
/// The method will block the calling thread until a lock on the mutex can
/// be obtained. The mutex remains locked until \ c unlock() is called.
/// be obtained. The mutex remains locked until @ c unlock() is called.
/// @see lock_guard
/// @see lock_guard
inline void lock ( )
inline void lock ( )
{
{
@ -192,7 +199,7 @@ class mutex {
/// Try to lock the mutex.
/// Try to lock the mutex.
/// The method will try to lock the mutex. If it fails, the function will
/// The method will try to lock the mutex. If it fails, the function will
/// return immediately (non-blocking).
/// return immediately (non-blocking).
/// @return \c true if the lock was acquired, or \ c false if the lock could
/// @return @c true if the lock was acquired, or @ c false if the lock could
/// not be acquired.
/// not be acquired.
inline bool try_lock ( )
inline bool try_lock ( )
{
{
@ -268,7 +275,7 @@ class recursive_mutex {
/// Lock the mutex.
/// Lock the mutex.
/// The method will block the calling thread until a lock on the mutex can
/// The method will block the calling thread until a lock on the mutex can
/// be obtained. The mutex remains locked until \ c unlock() is called.
/// be obtained. The mutex remains locked until @ c unlock() is called.
/// @see lock_guard
/// @see lock_guard
inline void lock ( )
inline void lock ( )
{
{
@ -282,7 +289,7 @@ class recursive_mutex {
/// Try to lock the mutex.
/// Try to lock the mutex.
/// The method will try to lock the mutex. If it fails, the function will
/// The method will try to lock the mutex. If it fails, the function will
/// return immediately (non-blocking).
/// return immediately (non-blocking).
/// @return \c true if the lock was acquired, or \ c false if the lock could
/// @return @c true if the lock was acquired, or @ c false if the lock could
/// not be acquired.
/// not be acquired.
inline bool try_lock ( )
inline bool try_lock ( )
{
{
@ -406,7 +413,7 @@ class condition_variable {
/// Wait for the condition.
/// Wait for the condition.
/// The function will block the calling thread until the condition variable
/// The function will block the calling thread until the condition variable
/// is woken by \c notify_one(), \ c notify_all() or a spurious wake up.
/// is woken by @c notify_one(), @ c notify_all() or a spurious wake up.
/// @param[in] aMutex A mutex that will be unlocked when the wait operation
/// @param[in] aMutex A mutex that will be unlocked when the wait operation
/// starts, an locked again as soon as the wait operation is finished.
/// starts, an locked again as soon as the wait operation is finished.
template < class _mutexT >
template < class _mutexT >
@ -482,7 +489,7 @@ class thread {
class id ;
class id ;
/// Default constructor.
/// Default constructor.
/// Construct a \ c thread object without an associated thread of execution
/// Construct a @ c thread object without an associated thread of execution
/// (i.e. non-joinable).
/// (i.e. non-joinable).
thread ( ) : mHandle ( 0 ) , mNotAThread ( true )
thread ( ) : mHandle ( 0 ) , mNotAThread ( true )
# if defined(_TTHREAD_WIN32_)
# if defined(_TTHREAD_WIN32_)
@ -491,7 +498,7 @@ class thread {
{ }
{ }
/// Thread starting constructor.
/// Thread starting constructor.
/// Construct a \ c thread object with a new thread of execution.
/// Construct a @ c thread object with a new thread of execution.
/// @param[in] aFunction A function pointer to a function of type:
/// @param[in] aFunction A function pointer to a function of type:
/// <tt>void fun(void * arg)</tt>
/// <tt>void fun(void * arg)</tt>
/// @param[in] aArg Argument to the thread function.
/// @param[in] aArg Argument to the thread function.
@ -501,24 +508,34 @@ class thread {
thread ( void ( * aFunction ) ( void * ) , void * aArg ) ;
thread ( void ( * aFunction ) ( void * ) , void * aArg ) ;
/// Destructor.
/// Destructor.
/// @note If the thread is joinable upon destruction, \ c std::terminate()
/// @note If the thread is joinable upon destruction, @ c std::terminate()
/// will be called, which terminates the process. It is always wise to do
/// will be called, which terminates the process. It is always wise to do
/// \ c join() before deleting a thread object.
/// @ c join() before deleting a thread object.
~ thread ( ) ;
~ thread ( ) ;
/// Wait for the thread to finish (join execution flows).
/// Wait for the thread to finish (join execution flows).
/// After calling @c join(), the thread object is no longer associated with
/// a thread of execution (i.e. it is not joinable, and you may not join
/// with it nor detach from it).
void join ( ) ;
void join ( ) ;
/// Check if the thread is joinable.
/// Check if the thread is joinable.
/// A thread object is joinable if it has an associated thread of execution.
/// A thread object is joinable if it has an associated thread of execution.
bool joinable ( ) const ;
bool joinable ( ) const ;
/// Detach from the thread.
/// After calling @c detach(), the thread object is no longer assicated with
/// a thread of execution (i.e. it is not joinable). The thread continues
/// execution without the calling thread blocking, and when the thread
/// ends execution, any owned resources are released.
void detach ( ) ;
/// Return the thread ID of a thread object.
/// Return the thread ID of a thread object.
id get_id ( ) const ;
id get_id ( ) const ;
/// Get the native handle for this thread.
/// Get the native handle for this thread.
/// @note Under Windows, this is a \c HANDLE, and under POSIX systems, this
/// @note Under Windows, this is a @ c HANDLE, and under POSIX systems, this
/// is a \c pthread_t.
/// is a @ c pthread_t.
inline native_handle_type native_handle ( )
inline native_handle_type native_handle ( )
{
{
return mHandle ;
return mHandle ;
@ -613,18 +630,18 @@ class thread::id {
// Related to <ratio> - minimal to be able to support chrono.
// Related to <ratio> - minimal to be able to support chrono.
typedef long long __intmax_t ;
typedef long long __intmax_t ;
/// Minimal implementation of the \ c ratio class. This class provides enough
/// Minimal implementation of the @ c ratio class. This class provides enough
/// functionality to implement some basic \ c chrono classes.
/// functionality to implement some basic @ c chrono classes.
template < __intmax_t N , __intmax_t D = 1 > class ratio {
template < __intmax_t N , __intmax_t D = 1 > class ratio {
public :
public :
static double _as_double ( ) { return double ( N ) / double ( D ) ; }
static double _as_double ( ) { return double ( N ) / double ( D ) ; }
} ;
} ;
/// Minimal implementation of the \ c chrono namespace.
/// Minimal implementation of the @ c chrono namespace.
/// The \ c chrono namespace provides types for specifying time intervals.
/// The @ c chrono namespace provides types for specifying time intervals.
namespace chrono {
namespace chrono {
/// Duration template class. This class provides enough functionality to
/// Duration template class. This class provides enough functionality to
/// implement \ c this_thread::sleep_for().
/// implement @ c this_thread::sleep_for().
template < class _Rep , class _Period = ratio < 1 > > class duration {
template < class _Rep , class _Period = ratio < 1 > > class duration {
private :
private :
_Rep rep_ ;
_Rep rep_ ;
@ -652,7 +669,7 @@ namespace chrono {
typedef duration < __intmax_t , ratio < 3600 > > hours ; ///< Duration with the unit hours.
typedef duration < __intmax_t , ratio < 3600 > > hours ; ///< Duration with the unit hours.
}
}
/// The namespace \ c this_thread provides methods for dealing with the
/// The namespace @ c this_thread provides methods for dealing with the
/// calling thread.
/// calling thread.
namespace this_thread {
namespace this_thread {
/// Return the thread ID of the calling thread.
/// Return the thread ID of the calling thread.