diff options
Diffstat (limited to 'src/uscxml/concurrency/tinythread.h')
-rw-r--r-- | src/uscxml/concurrency/tinythread.h | 773 |
1 files changed, 373 insertions, 400 deletions
diff --git a/src/uscxml/concurrency/tinythread.h b/src/uscxml/concurrency/tinythread.h index aed7b58..2e5caa0 100644 --- a/src/uscxml/concurrency/tinythread.h +++ b/src/uscxml/concurrency/tinythread.h @@ -57,30 +57,30 @@ freely, subject to the following restrictions: // Which platform are we on? #if !defined(_TTHREAD_PLATFORM_DEFINED_) - #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__) - #define _TTHREAD_WIN32_ - #else - #define _TTHREAD_POSIX_ - #endif - #define _TTHREAD_PLATFORM_DEFINED_ +#if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__) +#define _TTHREAD_WIN32_ +#else +#define _TTHREAD_POSIX_ +#endif +#define _TTHREAD_PLATFORM_DEFINED_ #endif // Platform specific includes #if defined(_TTHREAD_WIN32_) - #ifndef WIN32_LEAN_AND_MEAN - #define WIN32_LEAN_AND_MEAN - #define __UNDEF_LEAN_AND_MEAN - #endif - #include <windows.h> - #ifdef __UNDEF_LEAN_AND_MEAN - #undef WIN32_LEAN_AND_MEAN - #undef __UNDEF_LEAN_AND_MEAN - #endif +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#define __UNDEF_LEAN_AND_MEAN +#endif +#include <windows.h> +#ifdef __UNDEF_LEAN_AND_MEAN +#undef WIN32_LEAN_AND_MEAN +#undef __UNDEF_LEAN_AND_MEAN +#endif #else - #include <pthread.h> - #include <signal.h> - #include <sched.h> - #include <unistd.h> +#include <pthread.h> +#include <signal.h> +#include <sched.h> +#include <unistd.h> #endif // Generic includes @@ -95,21 +95,21 @@ freely, subject to the following restrictions: // Do we have a fully featured C++11 compiler? #if (__cplusplus > 199711L) || (defined(__STDCXX_VERSION__) && (__STDCXX_VERSION__ >= 201001L)) - #define _TTHREAD_CPP11_ +#define _TTHREAD_CPP11_ #endif // ...at least partial C++11? #if defined(_TTHREAD_CPP11_) || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__GXX_EXPERIMENTAL_CPP0X__) - #define _TTHREAD_CPP11_PARTIAL_ +#define _TTHREAD_CPP11_PARTIAL_ #endif // Macro for disabling assignments of objects. #ifdef _TTHREAD_CPP11_PARTIAL_ - #define _TTHREAD_DISABLE_ASSIGNMENT(name) \ +#define _TTHREAD_DISABLE_ASSIGNMENT(name) \ name(const name&) = delete; \ name& operator=(const name&) = delete; #else - #define _TTHREAD_DISABLE_ASSIGNMENT(name) \ +#define _TTHREAD_DISABLE_ASSIGNMENT(name) \ name(const name&); \ name& operator=(const name&); #endif @@ -136,11 +136,11 @@ freely, subject to the following restrictions: /// @hideinitializer #if !defined(_TTHREAD_CPP11_) && !defined(thread_local) - #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__) - #define thread_local __thread - #else - #define thread_local __declspec(thread) - #endif +#if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__) +#define thread_local __thread +#else +#define thread_local __declspec(thread) +#endif #endif @@ -157,89 +157,84 @@ namespace tthread { /// on that object). /// @see recursive_mutex class mutex { - public: - /// Constructor. - mutex() +public: + /// Constructor. + mutex() #if defined(_TTHREAD_WIN32_) - : mAlreadyLocked(false) + : mAlreadyLocked(false) #endif - { + { #if defined(_TTHREAD_WIN32_) - InitializeCriticalSection(&mHandle); + InitializeCriticalSection(&mHandle); #else - pthread_mutex_init(&mHandle, NULL); + pthread_mutex_init(&mHandle, NULL); #endif - } + } - /// Destructor. - ~mutex() - { + /// Destructor. + ~mutex() { #if defined(_TTHREAD_WIN32_) - DeleteCriticalSection(&mHandle); + DeleteCriticalSection(&mHandle); #else - pthread_mutex_destroy(&mHandle); + pthread_mutex_destroy(&mHandle); #endif - } + } - /// Lock the mutex. - /// 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. - /// @see lock_guard - inline void lock() - { + /// Lock the mutex. + /// 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. + /// @see lock_guard + inline void lock() { #if defined(_TTHREAD_WIN32_) - EnterCriticalSection(&mHandle); - while(mAlreadyLocked) Sleep(1000); // Simulate deadlock... - mAlreadyLocked = true; + EnterCriticalSection(&mHandle); + while(mAlreadyLocked) Sleep(1000); // Simulate deadlock... + mAlreadyLocked = true; #else - pthread_mutex_lock(&mHandle); + pthread_mutex_lock(&mHandle); #endif - } - - /// Try to lock the mutex. - /// The method will try to lock the mutex. If it fails, the function will - /// return immediately (non-blocking). - /// @return @c true if the lock was acquired, or @c false if the lock could - /// not be acquired. - inline bool try_lock() - { + } + + /// Try to lock the mutex. + /// The method will try to lock the mutex. If it fails, the function will + /// return immediately (non-blocking). + /// @return @c true if the lock was acquired, or @c false if the lock could + /// not be acquired. + inline bool try_lock() { #if defined(_TTHREAD_WIN32_) - bool ret = (TryEnterCriticalSection(&mHandle) ? true : false); - if(ret && mAlreadyLocked) - { - LeaveCriticalSection(&mHandle); - ret = false; - } - return ret; + bool ret = (TryEnterCriticalSection(&mHandle) ? true : false); + if(ret && mAlreadyLocked) { + LeaveCriticalSection(&mHandle); + ret = false; + } + return ret; #else - return (pthread_mutex_trylock(&mHandle) == 0) ? true : false; + return (pthread_mutex_trylock(&mHandle) == 0) ? true : false; #endif - } + } - /// Unlock the mutex. - /// If any threads are waiting for the lock on this mutex, one of them will - /// be unblocked. - inline void unlock() - { + /// Unlock the mutex. + /// If any threads are waiting for the lock on this mutex, one of them will + /// be unblocked. + inline void unlock() { #if defined(_TTHREAD_WIN32_) - mAlreadyLocked = false; - LeaveCriticalSection(&mHandle); + mAlreadyLocked = false; + LeaveCriticalSection(&mHandle); #else - pthread_mutex_unlock(&mHandle); + pthread_mutex_unlock(&mHandle); #endif - } + } - _TTHREAD_DISABLE_ASSIGNMENT(mutex) + _TTHREAD_DISABLE_ASSIGNMENT(mutex) - private: +private: #if defined(_TTHREAD_WIN32_) - CRITICAL_SECTION mHandle; - bool mAlreadyLocked; + CRITICAL_SECTION mHandle; + bool mAlreadyLocked; #else - pthread_mutex_t mHandle; + pthread_mutex_t mHandle; #endif - friend class condition_variable; + friend class condition_variable; }; /// Recursive mutex class. @@ -249,79 +244,74 @@ class mutex { /// number of times). /// @see mutex class recursive_mutex { - public: - /// Constructor. - recursive_mutex() - { +public: + /// Constructor. + recursive_mutex() { #if defined(_TTHREAD_WIN32_) - InitializeCriticalSection(&mHandle); + InitializeCriticalSection(&mHandle); #else - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - pthread_mutex_init(&mHandle, &attr); + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(&mHandle, &attr); #endif - } + } - /// Destructor. - ~recursive_mutex() - { + /// Destructor. + ~recursive_mutex() { #if defined(_TTHREAD_WIN32_) - DeleteCriticalSection(&mHandle); + DeleteCriticalSection(&mHandle); #else - pthread_mutex_destroy(&mHandle); + pthread_mutex_destroy(&mHandle); #endif - } + } - /// Lock the mutex. - /// 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. - /// @see lock_guard - inline void lock() - { + /// Lock the mutex. + /// 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. + /// @see lock_guard + inline void lock() { #if defined(_TTHREAD_WIN32_) - EnterCriticalSection(&mHandle); + EnterCriticalSection(&mHandle); #else - pthread_mutex_lock(&mHandle); + pthread_mutex_lock(&mHandle); #endif - } - - /// Try to lock the mutex. - /// The method will try to lock the mutex. If it fails, the function will - /// return immediately (non-blocking). - /// @return @c true if the lock was acquired, or @c false if the lock could - /// not be acquired. - inline bool try_lock() - { + } + + /// Try to lock the mutex. + /// The method will try to lock the mutex. If it fails, the function will + /// return immediately (non-blocking). + /// @return @c true if the lock was acquired, or @c false if the lock could + /// not be acquired. + inline bool try_lock() { #if defined(_TTHREAD_WIN32_) - return TryEnterCriticalSection(&mHandle) ? true : false; + return TryEnterCriticalSection(&mHandle) ? true : false; #else - return (pthread_mutex_trylock(&mHandle) == 0) ? true : false; + return (pthread_mutex_trylock(&mHandle) == 0) ? true : false; #endif - } + } - /// Unlock the mutex. - /// If any threads are waiting for the lock on this mutex, one of them will - /// be unblocked. - inline void unlock() - { + /// Unlock the mutex. + /// If any threads are waiting for the lock on this mutex, one of them will + /// be unblocked. + inline void unlock() { #if defined(_TTHREAD_WIN32_) - LeaveCriticalSection(&mHandle); + LeaveCriticalSection(&mHandle); #else - pthread_mutex_unlock(&mHandle); + pthread_mutex_unlock(&mHandle); #endif - } + } - _TTHREAD_DISABLE_ASSIGNMENT(recursive_mutex) + _TTHREAD_DISABLE_ASSIGNMENT(recursive_mutex) - private: +private: #if defined(_TTHREAD_WIN32_) - CRITICAL_SECTION mHandle; + CRITICAL_SECTION mHandle; #else - pthread_mutex_t mHandle; + pthread_mutex_t mHandle; #endif - friend class condition_variable; + friend class condition_variable; }; /// Lock guard class. @@ -341,27 +331,25 @@ class recursive_mutex { template <class T> class lock_guard { - public: - typedef T mutex_type; - - lock_guard() : mMutex(0) {} - - /// The constructor locks the mutex. - explicit lock_guard(mutex_type &aMutex) - { - mMutex = &aMutex; - mMutex->lock(); - } - - /// The destructor unlocks the mutex. - ~lock_guard() - { - if(mMutex) - mMutex->unlock(); - } - - private: - mutex_type * mMutex; +public: + typedef T mutex_type; + + lock_guard() : mMutex(0) {} + + /// The constructor locks the mutex. + explicit lock_guard(mutex_type &aMutex) { + mMutex = &aMutex; + mMutex->lock(); + } + + /// The destructor unlocks the mutex. + ~lock_guard() { + if(mMutex) + mMutex->unlock(); + } + +private: + mutex_type * mMutex; }; /// Condition variable class. @@ -390,179 +378,173 @@ class lock_guard { /// } /// @endcode class condition_variable { - public: - /// Constructor. +public: + /// Constructor. #if defined(_TTHREAD_WIN32_) - condition_variable(); + condition_variable(); #else - condition_variable() - { - pthread_cond_init(&mHandle, NULL); - } + condition_variable() { + pthread_cond_init(&mHandle, NULL); + } #endif - /// Destructor. + /// Destructor. #if defined(_TTHREAD_WIN32_) - ~condition_variable(); + ~condition_variable(); #else - ~condition_variable() - { - pthread_cond_destroy(&mHandle); - } -#endif - - /// Wait for the condition. - /// 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. - /// @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. - template <class _mutexT> - inline void wait(_mutexT &aMutex) - { + ~condition_variable() { + pthread_cond_destroy(&mHandle); + } +#endif + + /// Wait for the condition. + /// 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. + /// @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. + template <class _mutexT> + inline void wait(_mutexT &aMutex) { #if defined(_TTHREAD_WIN32_) - // Increment number of waiters - EnterCriticalSection(&mWaitersCountLock); - ++ mWaitersCount; - LeaveCriticalSection(&mWaitersCountLock); - - // Release the mutex while waiting for the condition (will decrease - // the number of waiters when done)... - aMutex.unlock(); - _wait(); - aMutex.lock(); + // Increment number of waiters + EnterCriticalSection(&mWaitersCountLock); + ++ mWaitersCount; + LeaveCriticalSection(&mWaitersCountLock); + + // Release the mutex while waiting for the condition (will decrease + // the number of waiters when done)... + aMutex.unlock(); + _wait(); + aMutex.lock(); #else - pthread_cond_wait(&mHandle, &aMutex.mHandle); + pthread_cond_wait(&mHandle, &aMutex.mHandle); #endif - } + } - /// Notify one thread that is waiting for the condition. - /// If at least one thread is blocked waiting for this condition variable, - /// one will be woken up. - /// @note Only threads that started waiting prior to this call will be - /// woken up. + /// Notify one thread that is waiting for the condition. + /// If at least one thread is blocked waiting for this condition variable, + /// one will be woken up. + /// @note Only threads that started waiting prior to this call will be + /// woken up. #if defined(_TTHREAD_WIN32_) - void notify_one(); + void notify_one(); #else - inline void notify_one() - { - pthread_cond_signal(&mHandle); - } + inline void notify_one() { + pthread_cond_signal(&mHandle); + } #endif - /// Notify all threads that are waiting for the condition. - /// All threads that are blocked waiting for this condition variable will - /// be woken up. - /// @note Only threads that started waiting prior to this call will be - /// woken up. + /// Notify all threads that are waiting for the condition. + /// All threads that are blocked waiting for this condition variable will + /// be woken up. + /// @note Only threads that started waiting prior to this call will be + /// woken up. #if defined(_TTHREAD_WIN32_) - void notify_all(); + void notify_all(); #else - inline void notify_all() - { - pthread_cond_broadcast(&mHandle); - } + inline void notify_all() { + pthread_cond_broadcast(&mHandle); + } #endif - _TTHREAD_DISABLE_ASSIGNMENT(condition_variable) + _TTHREAD_DISABLE_ASSIGNMENT(condition_variable) - private: +private: #if defined(_TTHREAD_WIN32_) - void _wait(); - HANDLE mEvents[2]; ///< Signal and broadcast event HANDLEs. - unsigned int mWaitersCount; ///< Count of the number of waiters. - CRITICAL_SECTION mWaitersCountLock; ///< Serialize access to mWaitersCount. + void _wait(); + HANDLE mEvents[2]; ///< Signal and broadcast event HANDLEs. + unsigned int mWaitersCount; ///< Count of the number of waiters. + CRITICAL_SECTION mWaitersCountLock; ///< Serialize access to mWaitersCount. #else - pthread_cond_t mHandle; + pthread_cond_t mHandle; #endif }; /// Thread class. class thread { - public: +public: #if defined(_TTHREAD_WIN32_) - typedef HANDLE native_handle_type; + typedef HANDLE native_handle_type; #else - typedef pthread_t native_handle_type; + typedef pthread_t native_handle_type; #endif - class id; + class id; - /// Default constructor. - /// Construct a @c thread object without an associated thread of execution - /// (i.e. non-joinable). - thread() : mHandle(0), mNotAThread(true) + /// Default constructor. + /// Construct a @c thread object without an associated thread of execution + /// (i.e. non-joinable). + thread() : mHandle(0), mNotAThread(true) #if defined(_TTHREAD_WIN32_) - , mWin32ThreadID(0) -#endif - {} - - /// Thread starting constructor. - /// Construct a @c thread object with a new thread of execution. - /// @param[in] aFunction A function pointer to a function of type: - /// <tt>void fun(void * arg)</tt> - /// @param[in] aArg Argument to the thread function. - /// @note This constructor is not fully compatible with the standard C++ - /// thread class. It is more similar to the pthread_create() (POSIX) and - /// CreateThread() (Windows) functions. - thread(void (*aFunction)(void *), void * aArg); - - /// Destructor. - /// @note If the thread is joinable upon destruction, @c std::terminate() - /// will be called, which terminates the process. It is always wise to do - /// @c join() before deleting a thread object. - ~thread(); - - /// 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(); - - /// Check if the thread is joinable. - /// A thread object is joinable if it has an associated thread of execution. - 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. - id get_id() const; - - /// Get the native handle for this thread. - /// @note Under Windows, this is a @c HANDLE, and under POSIX systems, this - /// is a @c pthread_t. - inline native_handle_type native_handle() - { - return mHandle; - } - - /// Determine the number of threads which can possibly execute concurrently. - /// This function is useful for determining the optimal number of threads to - /// use for a task. - /// @return The number of hardware thread contexts in the system. - /// @note If this value is not defined, the function returns zero (0). - static unsigned hardware_concurrency(); - - _TTHREAD_DISABLE_ASSIGNMENT(thread) - - private: - native_handle_type mHandle; ///< Thread handle. - mutable mutex mDataMutex; ///< Serializer for access to the thread private data. - bool mNotAThread; ///< True if this object is not a thread of execution. + , mWin32ThreadID(0) +#endif + {} + + /// Thread starting constructor. + /// Construct a @c thread object with a new thread of execution. + /// @param[in] aFunction A function pointer to a function of type: + /// <tt>void fun(void * arg)</tt> + /// @param[in] aArg Argument to the thread function. + /// @note This constructor is not fully compatible with the standard C++ + /// thread class. It is more similar to the pthread_create() (POSIX) and + /// CreateThread() (Windows) functions. + thread(void (*aFunction)(void *), void * aArg); + + /// Destructor. + /// @note If the thread is joinable upon destruction, @c std::terminate() + /// will be called, which terminates the process. It is always wise to do + /// @c join() before deleting a thread object. + ~thread(); + + /// 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(); + + /// Check if the thread is joinable. + /// A thread object is joinable if it has an associated thread of execution. + 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. + id get_id() const; + + /// Get the native handle for this thread. + /// @note Under Windows, this is a @c HANDLE, and under POSIX systems, this + /// is a @c pthread_t. + inline native_handle_type native_handle() { + return mHandle; + } + + /// Determine the number of threads which can possibly execute concurrently. + /// This function is useful for determining the optimal number of threads to + /// use for a task. + /// @return The number of hardware thread contexts in the system. + /// @note If this value is not defined, the function returns zero (0). + static unsigned hardware_concurrency(); + + _TTHREAD_DISABLE_ASSIGNMENT(thread) + +private: + native_handle_type mHandle; ///< Thread handle. + mutable mutex mDataMutex; ///< Serializer for access to the thread private data. + bool mNotAThread; ///< True if this object is not a thread of execution. #if defined(_TTHREAD_WIN32_) - unsigned int mWin32ThreadID; ///< Unique thread ID (filled out by _beginthreadex). + unsigned int mWin32ThreadID; ///< Unique thread ID (filled out by _beginthreadex). #endif - // This is the internal thread wrapper function. + // This is the internal thread wrapper function. #if defined(_TTHREAD_WIN32_) - static unsigned WINAPI wrapper_function(void * aArg); + static unsigned WINAPI wrapper_function(void * aArg); #else - static void * wrapper_function(void * aArg); + static void * wrapper_function(void * aArg); #endif }; @@ -570,60 +552,52 @@ class thread { /// The thread ID is a unique identifier for each thread. /// @see thread::get_id() class thread::id { - public: - /// Default constructor. - /// The default constructed ID is that of thread without a thread of - /// execution. - id() : mId(0) {}; - - id(unsigned long int aId) : mId(aId) {}; - - id(const id& aId) : mId(aId.mId) {}; - - inline id & operator=(const id &aId) - { - mId = aId.mId; - return *this; - } - - inline friend bool operator==(const id &aId1, const id &aId2) - { - return (aId1.mId == aId2.mId); - } - - inline friend bool operator!=(const id &aId1, const id &aId2) - { - return (aId1.mId != aId2.mId); - } - - inline friend bool operator<=(const id &aId1, const id &aId2) - { - return (aId1.mId <= aId2.mId); - } - - inline friend bool operator<(const id &aId1, const id &aId2) - { - return (aId1.mId < aId2.mId); - } - - inline friend bool operator>=(const id &aId1, const id &aId2) - { - return (aId1.mId >= aId2.mId); - } - - inline friend bool operator>(const id &aId1, const id &aId2) - { - return (aId1.mId > aId2.mId); - } - - inline friend std::ostream& operator <<(std::ostream &os, const id &obj) - { - os << obj.mId; - return os; - } - - private: - unsigned long int mId; +public: + /// Default constructor. + /// The default constructed ID is that of thread without a thread of + /// execution. + id() : mId(0) {}; + + id(unsigned long int aId) : mId(aId) {}; + + id(const id& aId) : mId(aId.mId) {}; + + inline id & operator=(const id &aId) { + mId = aId.mId; + return *this; + } + + inline friend bool operator==(const id &aId1, const id &aId2) { + return (aId1.mId == aId2.mId); + } + + inline friend bool operator!=(const id &aId1, const id &aId2) { + return (aId1.mId != aId2.mId); + } + + inline friend bool operator<=(const id &aId1, const id &aId2) { + return (aId1.mId <= aId2.mId); + } + + inline friend bool operator<(const id &aId1, const id &aId2) { + return (aId1.mId < aId2.mId); + } + + inline friend bool operator>=(const id &aId1, const id &aId2) { + return (aId1.mId >= aId2.mId); + } + + inline friend bool operator>(const id &aId1, const id &aId2) { + return (aId1.mId > aId2.mId); + } + + inline friend std::ostream& operator <<(std::ostream &os, const id &obj) { + os << obj.mId; + return os; + } + +private: + unsigned long int mId; }; @@ -633,77 +607,76 @@ typedef long long __intmax_t; /// Minimal implementation of the @c ratio class. This class provides enough /// functionality to implement some basic @c chrono classes. template <__intmax_t N, __intmax_t D = 1> class ratio { - public: - static double _as_double() { return double(N) / double(D); } +public: + static double _as_double() { + return double(N) / double(D); + } }; /// Minimal implementation of the @c chrono namespace. /// The @c chrono namespace provides types for specifying time intervals. namespace chrono { - /// Duration template class. This class provides enough functionality to - /// implement @c this_thread::sleep_for(). - template <class _Rep, class _Period = ratio<1> > class duration { - private: - _Rep rep_; - public: - typedef _Rep rep; - typedef _Period period; - - /// Construct a duration object with the given duration. - template <class _Rep2> - explicit duration(const _Rep2& r) : rep_(r) {}; - - /// Return the value of the duration object. - rep count() const - { - return rep_; - } - }; - - // Standard duration types. - typedef duration<__intmax_t, ratio<1, 1000000000> > nanoseconds; ///< Duration with the unit nanoseconds. - typedef duration<__intmax_t, ratio<1, 1000000> > microseconds; ///< Duration with the unit microseconds. - typedef duration<__intmax_t, ratio<1, 1000> > milliseconds; ///< Duration with the unit milliseconds. - typedef duration<__intmax_t> seconds; ///< Duration with the unit seconds. - typedef duration<__intmax_t, ratio<60> > minutes; ///< Duration with the unit minutes. - typedef duration<__intmax_t, ratio<3600> > hours; ///< Duration with the unit hours. +/// Duration template class. This class provides enough functionality to +/// implement @c this_thread::sleep_for(). +template <class _Rep, class _Period = ratio<1> > class duration { +private: + _Rep rep_; +public: + typedef _Rep rep; + typedef _Period period; + + /// Construct a duration object with the given duration. + template <class _Rep2> + explicit duration(const _Rep2& r) : rep_(r) {}; + + /// Return the value of the duration object. + rep count() const { + return rep_; + } +}; + +// Standard duration types. +typedef duration<__intmax_t, ratio<1, 1000000000> > nanoseconds; ///< Duration with the unit nanoseconds. +typedef duration<__intmax_t, ratio<1, 1000000> > microseconds; ///< Duration with the unit microseconds. +typedef duration<__intmax_t, ratio<1, 1000> > milliseconds; ///< Duration with the unit milliseconds. +typedef duration<__intmax_t> seconds; ///< Duration with the unit seconds. +typedef duration<__intmax_t, ratio<60> > minutes; ///< Duration with the unit minutes. +typedef duration<__intmax_t, ratio<3600> > hours; ///< Duration with the unit hours. } /// The namespace @c this_thread provides methods for dealing with the /// calling thread. namespace this_thread { - /// Return the thread ID of the calling thread. - thread::id get_id(); - - /// Yield execution to another thread. - /// Offers the operating system the opportunity to schedule another thread - /// that is ready to run on the current processor. - inline void yield() - { +/// Return the thread ID of the calling thread. +thread::id get_id(); + +/// Yield execution to another thread. +/// Offers the operating system the opportunity to schedule another thread +/// that is ready to run on the current processor. +inline void yield() { #if defined(_TTHREAD_WIN32_) - Sleep(0); + Sleep(0); #else - sched_yield(); -#endif - } - - /// Blocks the calling thread for a period of time. - /// @param[in] aTime Minimum time to put the thread to sleep. - /// Example usage: - /// @code - /// // Sleep for 100 milliseconds - /// this_thread::sleep_for(chrono::milliseconds(100)); - /// @endcode - /// @note Supported duration types are: nanoseconds, microseconds, - /// milliseconds, seconds, minutes and hours. - template <class _Rep, class _Period> void sleep_for(const chrono::duration<_Rep, _Period>& aTime) - { + sched_yield(); +#endif +} + +/// Blocks the calling thread for a period of time. +/// @param[in] aTime Minimum time to put the thread to sleep. +/// Example usage: +/// @code +/// // Sleep for 100 milliseconds +/// this_thread::sleep_for(chrono::milliseconds(100)); +/// @endcode +/// @note Supported duration types are: nanoseconds, microseconds, +/// milliseconds, seconds, minutes and hours. +template <class _Rep, class _Period> void sleep_for(const chrono::duration<_Rep, _Period>& aTime) { #if defined(_TTHREAD_WIN32_) - Sleep(int(double(aTime.count()) * (1000.0 * _Period::_as_double()) + 0.5)); + Sleep(int(double(aTime.count()) * (1000.0 * _Period::_as_double()) + 0.5)); #else - usleep(int(double(aTime.count()) * (1000000.0 * _Period::_as_double()) + 0.5)); + usleep(int(double(aTime.count()) * (1000000.0 * _Period::_as_double()) + 0.5)); #endif - } +} } } |