📄 threads.h
字号:
////////////////////////////////////////////////////////////////////////////////// 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)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -