diff --git a/include/boost/detail/atomic_count.hpp b/include/boost/detail/atomic_count.hpp index d97fafa..2adb57e 100644 --- a/include/boost/detail/atomic_count.hpp +++ b/include/boost/detail/atomic_count.hpp @@ -91,12 +91,14 @@ typedef long atomic_count; } -#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) -# include -//#elif defined(linux) || defined(__linux) || defined(__linux__) #elif defined(BOOST_USE_ASM_ATOMIC_H) # include +#elif defined(BOOST_AC_USE_PTHREADS) +# include +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) +# include #elif defined(BOOST_HAS_PTHREADS) +# define BOOST_AC_USE_PTHREADS # include #else diff --git a/include/boost/detail/atomic_count_pthreads.hpp b/include/boost/detail/atomic_count_pthreads.hpp index eb1dd97..0f8c663 100644 --- a/include/boost/detail/atomic_count_pthreads.hpp +++ b/include/boost/detail/atomic_count_pthreads.hpp @@ -19,11 +19,9 @@ // inefficiencies. Example: a class with two atomic_count members // can get away with a single mutex. // -// Define a macro so that users can detect the situation and optimize. +// Users can detect this situation by checking BOOST_AC_USE_PTHREADS. // -#define BOOST_ATOMIC_COUNT_USES_PTHREADS - namespace boost { diff --git a/include/boost/detail/atomic_count_win32.hpp b/include/boost/detail/atomic_count_win32.hpp index 163a26d..0482757 100644 --- a/include/boost/detail/atomic_count_win32.hpp +++ b/include/boost/detail/atomic_count_win32.hpp @@ -16,20 +16,14 @@ // warranty, and with no claim as to its suitability for any purpose. // +#include + namespace boost { namespace detail { -// Avoid #including - -namespace win32 -{ -extern "C" __declspec(dllimport) long __stdcall InterlockedIncrement(long volatile *); -extern "C" __declspec(dllimport) long __stdcall InterlockedDecrement(long volatile *); -} - class atomic_count { public: @@ -40,12 +34,12 @@ public: long operator++() { - return win32::InterlockedIncrement(&value_); + return winapi::InterlockedIncrement(&value_); } long operator--() { - return win32::InterlockedDecrement(&value_); + return winapi::InterlockedDecrement(&value_); } operator long() const diff --git a/include/boost/detail/lightweight_mutex.hpp b/include/boost/detail/lightweight_mutex.hpp index d199114..6a74397 100644 --- a/include/boost/detail/lightweight_mutex.hpp +++ b/include/boost/detail/lightweight_mutex.hpp @@ -37,16 +37,28 @@ #include +// +// Note to implementors: if you write a platform-specific lightweight_mutex +// for a platform that supports pthreads, be sure to test its performance +// against the pthreads-based version using smart_ptr_timing_test.cpp and +// smart_ptr_mt_test.cpp. Custom versions are usually not worth the trouble +// _unless_ the performance gains are substantial. +// + #ifndef BOOST_HAS_THREADS # include -#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) -# include -//#elif defined(linux) || defined(__linux) || defined(__linux__) #elif defined(BOOST_USE_ASM_ATOMIC_H) # include +#elif defined(BOOST_LWM_USE_CRITICAL_SECTION) +# include +#elif defined(BOOST_LWM_USE_PTHREADS) +# include +#elif defined(WIN32) || defined(_WIN32) || defined(__WIN32__) +# include #elif defined(__sgi) # include #elif defined(BOOST_HAS_PTHREADS) +# define BOOST_LWM_USE_PTHREADS # include #else # include diff --git a/include/boost/detail/lwm_win32.hpp b/include/boost/detail/lwm_win32.hpp index 3e79198..a54aefc 100644 --- a/include/boost/detail/lwm_win32.hpp +++ b/include/boost/detail/lwm_win32.hpp @@ -16,17 +16,14 @@ // warranty, and with no claim as to its suitability for any purpose. // +#include + namespace boost { namespace detail { -// avoid including - -extern "C" __declspec(dllimport) long __stdcall InterlockedExchange(long volatile *, long); -extern "C" __declspec(dllimport) void __stdcall Sleep(unsigned long); - class lightweight_mutex { private: @@ -58,12 +55,15 @@ public: explicit scoped_lock(lightweight_mutex & m): m_(m) { - while( InterlockedExchange(&m_.l_, 1) ) Sleep(0); + while( winapi::InterlockedExchange(&m_.l_, 1) ) + { + winapi::Sleep(0); + } } ~scoped_lock() { - InterlockedExchange(&m_.l_, 0); + winapi::InterlockedExchange(&m_.l_, 0); // Note: adding a Sleep(0) here will make // the mutex more fair and will increase the overall diff --git a/include/boost/detail/lwm_win32_cs.hpp b/include/boost/detail/lwm_win32_cs.hpp new file mode 100644 index 0000000..3127004 --- /dev/null +++ b/include/boost/detail/lwm_win32_cs.hpp @@ -0,0 +1,78 @@ +#ifndef BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED +#define BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED + +#if _MSC_VER >= 1020 +#pragma once +#endif + +// +// boost/detail/lwm_win32_cs.hpp +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// + +#include + +namespace boost +{ + +namespace detail +{ + +class lightweight_mutex +{ +private: + + winapi::critical_section cs_; + + lightweight_mutex(lightweight_mutex const &); + lightweight_mutex & operator=(lightweight_mutex const &); + +public: + + lightweight_mutex() + { + winapi::InitializeCriticalSection(&cs_); + } + + ~lightweight_mutex() + { + winapi::DeleteCriticalSection(&cs_); + } + + class scoped_lock; + friend class scoped_lock; + + class scoped_lock + { + private: + + lightweight_mutex & m_; + + scoped_lock(scoped_lock const &); + scoped_lock & operator=(scoped_lock const &); + + public: + + explicit scoped_lock(lightweight_mutex & m): m_(m) + { + winapi::EnterCriticalSection(&m_.cs_); + } + + ~scoped_lock() + { + winapi::LeaveCriticalSection(&m_.cs_); + } + }; +}; + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_LWM_WIN32_CS_HPP_INCLUDED diff --git a/include/boost/detail/winapi.hpp b/include/boost/detail/winapi.hpp new file mode 100644 index 0000000..0e9bb72 --- /dev/null +++ b/include/boost/detail/winapi.hpp @@ -0,0 +1,75 @@ +#ifndef BOOST_DETAIL_WINAPI_HPP_INCLUDED +#define BOOST_DETAIL_WINAPI_HPP_INCLUDED + +#if _MSC_VER >= 1020 +#pragma once +#endif + +// +// boost/detail/winapi.hpp - a lightweight version of +// +// Copyright (c) 2002 Peter Dimov and Multi Media Ltd. +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// + +namespace boost +{ + +namespace detail +{ + +namespace winapi +{ + +typedef long long_type; +typedef unsigned long dword_type; +typedef void * handle_type; + +#if defined(_WIN64) + +typedef __int64 int_ptr_type; +typedef unsigned __int64 uint_ptr_type; +typedef __int64 long_ptr_type; +typedef unsigned __int64 ulong_ptr_type; + +#else + +typedef int int_ptr_type; +typedef unsigned int uint_ptr_type; +typedef long long_ptr_type; +typedef unsigned long ulong_ptr_type; + +#endif + +struct critical_section +{ + struct critical_section_debug * DebugInfo; + long_type LockCount; + long_type RecursionCount; + handle_type OwningThread; + handle_type LockSemaphore; + ulong_ptr_type SpinCount; +}; + +extern "C" __declspec(dllimport) long_type __stdcall InterlockedIncrement(long_type volatile *); +extern "C" __declspec(dllimport) long_type __stdcall InterlockedDecrement(long_type volatile *); +extern "C" __declspec(dllimport) long_type __stdcall InterlockedExchange(long_type volatile *, long_type); + +extern "C" __declspec(dllimport) void __stdcall Sleep(dword_type); + +extern "C" __declspec(dllimport) void __stdcall InitializeCriticalSection(critical_section *); +extern "C" __declspec(dllimport) void __stdcall EnterCriticalSection(critical_section *); +extern "C" __declspec(dllimport) void __stdcall LeaveCriticalSection(critical_section *); +extern "C" __declspec(dllimport) void __stdcall DeleteCriticalSection(critical_section *); + +} // namespace winapi + +} // namespace detail + +} // namespace boost + +#endif // #ifndef BOOST_DETAIL_WINAPI_HPP_INCLUDED