diff options
Diffstat (limited to 'shared/loki/Threads.h')
-rw-r--r-- | shared/loki/Threads.h | 609 |
1 files changed, 0 insertions, 609 deletions
diff --git a/shared/loki/Threads.h b/shared/loki/Threads.h deleted file mode 100644 index 690ca50f..00000000 --- a/shared/loki/Threads.h +++ /dev/null @@ -1,609 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design -// Patterns Applied". Copyright (c) 2001. Addison-Wesley. -// Permission to use, copy, modify, distribute and sell this software 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. -// The author or Addison-Wesley Longman make no representations about the -// suitability of this software for any purpose. It is provided "as is" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -#ifndef LOKI_THREADS_INC_ -#define LOKI_THREADS_INC_ - -// $Id: Threads.h 902 2008-11-10 05:47:06Z rich_sposato $ - - -/// @defgroup ThreadingGroup Threading -/// Policies to for the threading model: -/// -/// - SingleThreaded -/// - ObjectLevelLockable -/// - ClassLevelLockable -/// -/// All classes in Loki have configurable threading model. -/// -/// The macro LOKI_DEFAULT_THREADING selects the default -/// threading model for certain components of Loki -/// (it affects only default template arguments) -/// -/// \par Usage: -/// -/// To use a specific threading model define -/// -/// - nothing, single-theading is default -/// - LOKI_OBJECT_LEVEL_THREADING for object-level-threading -/// - LOKI_CLASS_LEVEL_THREADING for class-level-threading -/// -/// \par Supported platfroms: -/// -/// - Windows (windows.h) -/// - POSIX (pthread.h): -/// No recursive mutex support with pthread. -/// This means: calling Lock() on a Loki::Mutex twice from the -/// same thread before unlocking the mutex deadlocks the system. -/// To avoid this redesign your synchronization. See also: -/// http://sourceforge.net/tracker/index.php?func=detail&aid=1516182&group_id=29557&atid=396647 - - -#include <cassert> - -#if defined(LOKI_CLASS_LEVEL_THREADING) || defined(LOKI_OBJECT_LEVEL_THREADING) - -#define LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL ::Loki::ClassLevelLockable - -#if defined(LOKI_CLASS_LEVEL_THREADING) && !defined(LOKI_OBJECT_LEVEL_THREADING) -#define LOKI_DEFAULT_THREADING ::Loki::ClassLevelLockable -#else -#define LOKI_DEFAULT_THREADING ::Loki::ObjectLevelLockable -#endif - -#if defined(_WIN32) || defined(_WIN64) -#include <windows.h> -#define LOKI_WINDOWS_H -#else -#include <pthread.h> -#define LOKI_PTHREAD_H -#endif - -#else - -#define LOKI_DEFAULT_THREADING ::Loki::SingleThreaded -#define LOKI_DEFAULT_THREADING_NO_OBJ_LEVEL ::Loki::SingleThreaded - -#endif - -#ifndef LOKI_DEFAULT_MUTEX -#define LOKI_DEFAULT_MUTEX ::Loki::Mutex -#endif - -#ifdef LOKI_WINDOWS_H - -#define LOKI_THREADS_MUTEX(x) CRITICAL_SECTION (x); -#define LOKI_THREADS_MUTEX_INIT(x) ::InitializeCriticalSection (x) -#define LOKI_THREADS_MUTEX_DELETE(x) ::DeleteCriticalSection (x) -#define LOKI_THREADS_MUTEX_LOCK(x) ::EnterCriticalSection (x) -#define LOKI_THREADS_MUTEX_UNLOCK(x) ::LeaveCriticalSection (x) -#define LOKI_THREADS_LONG LONG -#define LOKI_THREADS_MUTEX_CTOR(x) - -#define LOKI_THREADS_ATOMIC_FUNCTIONS \ - static IntType AtomicMultiply(volatile IntType& lval, const IntType val) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - lval *= val; \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicDivide(volatile IntType& lval, const IntType val) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - lval /= val; \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicIncrement(volatile IntType& lval) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - ++lval; \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicDecrement(volatile IntType& lval) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - --lval; \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static void AtomicAssign(volatile IntType& lval, const IntType val) \ - { InterlockedExchange(&const_cast<IntType&>(lval), val); } \ - \ - static void AtomicAssign(IntType& lval, volatile const IntType& val) \ - { InterlockedExchange(&lval, val); } \ - \ - static IntType AtomicIncrement(volatile IntType& lval, const IntType compare, bool & matches ) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - ++lval; \ - matches = ( lval == compare ); \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicDecrement(volatile IntType& lval, const IntType compare, bool & matches ) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - --lval; \ - matches = ( lval == compare ); \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicAdd(volatile IntType& lval, const IntType val, const IntType compare, bool & matches ) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - lval += val; \ - matches = ( lval == compare ); \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicSubtract(volatile IntType& lval, const IntType val, const IntType compare, bool & matches ) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - lval -= val; \ - matches = ( lval == compare ); \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicMultiply(volatile IntType& lval, const IntType val, const IntType compare, bool & matches ) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - lval *= val; \ - matches = ( lval == compare ); \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicDivide(volatile IntType& lval, const IntType val, const IntType compare, bool & matches ) \ - { \ - ::EnterCriticalSection( &atomic_mutex_ ); \ - lval /= val; \ - matches = ( lval == compare ); \ - ::LeaveCriticalSection( &atomic_mutex_ ); \ - return lval; \ - } - -#elif defined(LOKI_PTHREAD_H) - - -#define LOKI_THREADS_MUTEX(x) pthread_mutex_t (x); - -#define LOKI_THREADS_MUTEX_INIT(x) ::pthread_mutex_init(x, 0) - -// define to 1 to enable recursive mutex support -#if 0 -// experimental recursive mutex support -#define LOKI_THREADS_MUTEX_CTOR(x) : x(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) -#else -// no recursive mutex support -#define LOKI_THREADS_MUTEX_CTOR(x) -#endif - -#define LOKI_THREADS_MUTEX_DELETE(x) ::pthread_mutex_destroy (x) -#define LOKI_THREADS_MUTEX_LOCK(x) ::pthread_mutex_lock (x) -#define LOKI_THREADS_MUTEX_UNLOCK(x) ::pthread_mutex_unlock (x) -#define LOKI_THREADS_LONG long - -#define LOKI_THREADS_ATOMIC(x) \ - pthread_mutex_lock(&atomic_mutex_); \ - x; \ - pthread_mutex_unlock(&atomic_mutex_) - -#define LOKI_THREADS_ATOMIC_FUNCTIONS \ - private: \ - static pthread_mutex_t atomic_mutex_; \ - public: \ - static IntType AtomicMultiply(volatile IntType& lval, const IntType val) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - lval *= val; \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicDivide(volatile IntType& lval, const IntType val) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - lval /= val; \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicIncrement(volatile IntType& lval) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - ++lval; \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicDecrement(volatile IntType& lval) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - --lval; \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static void AtomicAssign(volatile IntType& lval, const IntType val) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - lval = val; \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static void AtomicAssign(IntType& lval, volatile const IntType& val) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - lval = val; \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicIncrement(volatile IntType& lval, const IntType compare, bool & matches ) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - ++lval; \ - matches = ( compare == lval ); \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicDecrement(volatile IntType& lval, const IntType compare, bool & matches ) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - --lval; \ - matches = ( compare == lval ); \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } \ - static IntType AtomicMultiply(volatile IntType& lval, const IntType val, const IntType compare, bool & matches ) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - lval *= val; \ - matches = ( lval == compare ); \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } \ - \ - static IntType AtomicDivide(volatile IntType& lval, const IntType val, const IntType compare, bool & matches ) \ - { \ - ::pthread_mutex_lock( &atomic_mutex_ ); \ - lval /= val; \ - matches = ( lval == compare ); \ - ::pthread_mutex_unlock( &atomic_mutex_ ); \ - return lval; \ - } - -#else // single threaded - -#define LOKI_THREADS_MUTEX(x) -#define LOKI_THREADS_MUTEX_INIT(x) -#define LOKI_THREADS_MUTEX_DELETE(x) -#define LOKI_THREADS_MUTEX_LOCK(x) -#define LOKI_THREADS_MUTEX_UNLOCK(x) -#define LOKI_THREADS_LONG -#define LOKI_THREADS_MUTEX_CTOR(x) - -#endif - - - -namespace Loki -{ - -//////////////////////////////////////////////////////////////////////////////// -/// \class Mutex -// -/// \ingroup ThreadingGroup -/// A simple and portable Mutex. A default policy class for locking objects. -//////////////////////////////////////////////////////////////////////////////// - -class Mutex -{ -public: - Mutex() LOKI_THREADS_MUTEX_CTOR(mtx_) - { - LOKI_THREADS_MUTEX_INIT(&mtx_); - } - ~Mutex() - { - LOKI_THREADS_MUTEX_DELETE(&mtx_); - } - void Lock() - { - LOKI_THREADS_MUTEX_LOCK(&mtx_); - } - void Unlock() - { - LOKI_THREADS_MUTEX_UNLOCK(&mtx_); - } -private: - /// Copy-constructor not implemented. - Mutex(const Mutex&); - /// Copy-assignement operator not implemented. - Mutex& operator = (const Mutex&); - LOKI_THREADS_MUTEX(mtx_) -}; - - -//////////////////////////////////////////////////////////////////////////////// -/// \class SingleThreaded -/// -/// \ingroup ThreadingGroup -/// Implementation of the ThreadingModel policy used by various classes -/// Implements a single-threaded model; no synchronization -//////////////////////////////////////////////////////////////////////////////// -template <class Host, class MutexPolicy = LOKI_DEFAULT_MUTEX> -class SingleThreaded -{ -public: - /// \struct Lock - /// Dummy Lock class - struct Lock - { - Lock() {} - explicit Lock(const SingleThreaded&) {} - explicit Lock(const SingleThreaded*) {} - }; - - typedef Host VolatileType; - - typedef int IntType; - - static IntType AtomicAdd(volatile IntType& lval, const IntType val) - { return lval += val; } - - static IntType AtomicSubtract(volatile IntType& lval, const IntType val) - { return lval -= val; } - - static IntType AtomicMultiply(volatile IntType& lval, const IntType val) - { return lval *= val; } - - static IntType AtomicDivide(volatile IntType& lval, const IntType val) - { return lval /= val; } - - static IntType AtomicIncrement(volatile IntType& lval) - { return ++lval; } - - static IntType AtomicDecrement(volatile IntType& lval) - { return --lval; } - - static void AtomicAssign(volatile IntType& lval, const IntType val) - { lval = val; } - - static void AtomicAssign(IntType& lval, volatile IntType& val) - { lval = val; } - - static IntType AtomicAdd(volatile IntType& lval, const IntType val, const IntType compare, bool& matches ) - { - lval += val; - matches = ( lval == compare ); - return lval; - } - - static IntType AtomicSubtract(volatile IntType& lval, const IntType val, const IntType compare, bool& matches ) - { - lval -= val; - matches = ( lval == compare ); - return lval; - } - - static IntType AtomicMultiply(volatile IntType& lval, const IntType val, const IntType compare, bool& matches ) - { - lval *= val; - matches = ( lval == compare ); - return lval; - } - - static IntType AtomicDivide(volatile IntType& lval, const IntType val, const IntType compare, bool& matches ) - { - lval /= val; - matches = ( lval == compare ); - return lval; - } - - static IntType AtomicIncrement(volatile IntType& lval, const IntType compare, bool& matches ) - { - ++lval; - matches = ( lval == compare ); - return lval; - } - - static IntType AtomicDecrement(volatile IntType& lval, const IntType compare, bool& matches ) - { - --lval; - matches = ( lval == compare ); - return lval; - } - -}; - - -#if defined(LOKI_WINDOWS_H) || defined(LOKI_PTHREAD_H) - -//////////////////////////////////////////////////////////////////////////////// -/// \class ObjectLevelLockable -/// -/// \ingroup ThreadingGroup -/// Implementation of the ThreadingModel policy used by various classes -/// Implements a object-level locking scheme -//////////////////////////////////////////////////////////////////////////////// -template < class Host, class MutexPolicy = LOKI_DEFAULT_MUTEX > -class ObjectLevelLockable -{ - mutable MutexPolicy mtx_; - -public: - ObjectLevelLockable() : mtx_() {} - - ObjectLevelLockable(const ObjectLevelLockable&) : mtx_() {} - - ~ObjectLevelLockable() {} - - class Lock; - friend class Lock; - - /// \struct Lock - /// Lock class to lock on object level - class Lock - { - public: - - /// Lock object - explicit Lock(const ObjectLevelLockable& host) : host_(host) - { - host_.mtx_.Lock(); - } - - /// Lock object - explicit Lock(const ObjectLevelLockable* host) : host_(*host) - { - host_.mtx_.Lock(); - } - - /// Unlock object - ~Lock() - { - host_.mtx_.Unlock(); - } - - private: - /// private by design of the object level threading - Lock(); - Lock(const Lock&); - Lock& operator=(const Lock&); - const ObjectLevelLockable& host_; - }; - - typedef volatile Host VolatileType; - - typedef LOKI_THREADS_LONG IntType; - - LOKI_THREADS_ATOMIC_FUNCTIONS - -}; - -#ifdef LOKI_PTHREAD_H -template <class Host, class MutexPolicy> -pthread_mutex_t ObjectLevelLockable<Host, MutexPolicy>::atomic_mutex_ = PTHREAD_MUTEX_INITIALIZER; -#endif - -//////////////////////////////////////////////////////////////////////////////// -/// \class ClassLevelLockable -/// -/// \ingroup ThreadingGroup -/// Implementation of the ThreadingModel policy used by various classes -/// Implements a class-level locking scheme -//////////////////////////////////////////////////////////////////////////////// -template <class Host, class MutexPolicy = LOKI_DEFAULT_MUTEX > -class ClassLevelLockable -{ - struct Initializer - { - bool init_; - MutexPolicy mtx_; - - Initializer() : init_(false), mtx_() - { - init_ = true; - } - - ~Initializer() - { - assert(init_); - } - }; - - static Initializer initializer_; - -public: - - class Lock; - friend class Lock; - - /// \struct Lock - /// Lock class to lock on class level - class Lock - { - public: - - /// Lock class - Lock() - { - assert(initializer_.init_); - initializer_.mtx_.Lock(); - } - - /// Lock class - explicit Lock(const ClassLevelLockable&) - { - assert(initializer_.init_); - initializer_.mtx_.Lock(); - } - - /// Lock class - explicit Lock(const ClassLevelLockable*) - { - assert(initializer_.init_); - initializer_.mtx_.Lock(); - } - - /// Unlock class - ~Lock() - { - assert(initializer_.init_); - initializer_.mtx_.Unlock(); - } - - private: - Lock(const Lock&); - Lock& operator=(const Lock&); - }; - - typedef volatile Host VolatileType; - - typedef LOKI_THREADS_LONG IntType; - - LOKI_THREADS_ATOMIC_FUNCTIONS - -}; - -#ifdef LOKI_PTHREAD_H -template <class Host, class MutexPolicy> -pthread_mutex_t ClassLevelLockable<Host, MutexPolicy>::atomic_mutex_ = PTHREAD_MUTEX_INITIALIZER; -#endif - -template < class Host, class MutexPolicy > -typename ClassLevelLockable< Host, MutexPolicy >::Initializer -ClassLevelLockable< Host, MutexPolicy >::initializer_; - -#endif // #if defined(LOKI_WINDOWS_H) || defined(LOKI_PTHREAD_H) - -} // namespace Loki - - -#endif // end file guardian - |