Chris@16: #ifndef BOOST_WIN32_THREAD_PRIMITIVES_HPP Chris@16: #define BOOST_WIN32_THREAD_PRIMITIVES_HPP Chris@16: Chris@16: // win32_thread_primitives.hpp Chris@16: // Chris@16: // (C) Copyright 2005-7 Anthony Williams Chris@16: // (C) Copyright 2007 David Deakins Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See Chris@16: // accompanying file LICENSE_1_0.txt or copy at Chris@16: // http://www.boost.org/LICENSE_1_0.txt) Chris@16: Chris@16: #include Chris@101: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: //#include Chris@16: #include Chris@16: Chris@101: #if BOOST_PLAT_WINDOWS_RUNTIME Chris@101: #include Chris@16: #endif Chris@16: Chris@16: #if defined( BOOST_USE_WINDOWS_H ) Chris@16: # include Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: namespace detail Chris@16: { Chris@16: namespace win32 Chris@16: { Chris@16: typedef HANDLE handle; Chris@101: typedef SYSTEM_INFO system_info; Chris@101: typedef unsigned __int64 ticks_type; Chris@16: unsigned const infinite=INFINITE; Chris@16: unsigned const timeout=WAIT_TIMEOUT; Chris@16: handle const invalid_handle_value=INVALID_HANDLE_VALUE; Chris@16: unsigned const event_modify_state=EVENT_MODIFY_STATE; Chris@16: unsigned const synchronize=SYNCHRONIZE; Chris@16: unsigned const wait_abandoned=WAIT_ABANDONED; Chris@101: unsigned const create_event_initial_set = 0x00000002; Chris@101: unsigned const create_event_manual_reset = 0x00000001; Chris@101: unsigned const event_all_access = EVENT_ALL_ACCESS; Chris@101: unsigned const semaphore_all_access = SEMAPHORE_ALL_ACCESS; Chris@101: Chris@16: Chris@16: # ifdef BOOST_NO_ANSI_APIS Chris@101: # if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA Chris@16: using ::CreateMutexW; Chris@16: using ::CreateEventW; Chris@101: using ::CreateSemaphoreW; Chris@101: # else Chris@101: using ::CreateMutexExW; Chris@101: using ::CreateEventExW; Chris@101: using ::CreateSemaphoreExW; Chris@101: # endif Chris@16: using ::OpenEventW; Chris@16: # else Chris@16: using ::CreateMutexA; Chris@16: using ::CreateEventA; Chris@16: using ::OpenEventA; Chris@16: using ::CreateSemaphoreA; Chris@16: # endif Chris@101: #if BOOST_PLAT_WINDOWS_RUNTIME Chris@101: using ::GetNativeSystemInfo; Chris@101: using ::GetTickCount64; Chris@101: #else Chris@101: using ::GetSystemInfo; Chris@101: #endif Chris@16: using ::CloseHandle; Chris@16: using ::ReleaseMutex; Chris@16: using ::ReleaseSemaphore; Chris@16: using ::SetEvent; Chris@16: using ::ResetEvent; Chris@101: using ::WaitForMultipleObjectsEx; Chris@101: using ::WaitForSingleObjectEx; Chris@16: using ::GetCurrentProcessId; Chris@16: using ::GetCurrentThreadId; Chris@16: using ::GetCurrentThread; Chris@16: using ::GetCurrentProcess; Chris@16: using ::DuplicateHandle; Chris@101: #if !BOOST_PLAT_WINDOWS_RUNTIME Chris@16: using ::SleepEx; Chris@16: using ::Sleep; Chris@16: using ::QueueUserAPC; Chris@101: #endif Chris@16: } Chris@16: } Chris@16: } Chris@16: #elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) Chris@16: Chris@16: # ifdef UNDER_CE Chris@16: # ifndef WINAPI Chris@16: # ifndef _WIN32_WCE_EMULATION Chris@16: # define WINAPI __cdecl // Note this doesn't match the desktop definition Chris@16: # else Chris@16: # define WINAPI __stdcall Chris@16: # endif Chris@16: # endif Chris@16: Chris@16: # ifdef __cplusplus Chris@16: extern "C" { Chris@16: # endif Chris@16: typedef int BOOL; Chris@16: typedef unsigned long DWORD; Chris@16: typedef void* HANDLE; Chris@16: # include Chris@16: # ifdef __cplusplus Chris@16: } Chris@16: # endif Chris@16: # endif Chris@16: Chris@101: # ifdef __cplusplus Chris@101: extern "C" { Chris@101: # endif Chris@101: struct _SYSTEM_INFO; Chris@101: # ifdef __cplusplus Chris@101: } Chris@101: #endif Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: namespace detail Chris@16: { Chris@16: namespace win32 Chris@16: { Chris@16: # ifdef _WIN64 Chris@16: typedef unsigned __int64 ulong_ptr; Chris@16: # else Chris@16: typedef unsigned long ulong_ptr; Chris@16: # endif Chris@16: typedef void* handle; Chris@101: typedef _SYSTEM_INFO system_info; Chris@101: typedef unsigned __int64 ticks_type; Chris@16: unsigned const infinite=~0U; Chris@16: unsigned const timeout=258U; Chris@16: handle const invalid_handle_value=(handle)(-1); Chris@16: unsigned const event_modify_state=2; Chris@16: unsigned const synchronize=0x100000u; Chris@16: unsigned const wait_abandoned=0x00000080u; Chris@101: unsigned const create_event_initial_set = 0x00000002; Chris@101: unsigned const create_event_manual_reset = 0x00000001; Chris@101: unsigned const event_all_access = 0x1F0003; Chris@101: unsigned const semaphore_all_access = 0x1F0003; Chris@16: Chris@16: extern "C" Chris@16: { Chris@16: struct _SECURITY_ATTRIBUTES; Chris@16: # ifdef BOOST_NO_ANSI_APIS Chris@101: # if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA Chris@16: __declspec(dllimport) void* __stdcall CreateMutexW(_SECURITY_ATTRIBUTES*,int,wchar_t const*); Chris@16: __declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*); Chris@16: __declspec(dllimport) void* __stdcall CreateEventW(_SECURITY_ATTRIBUTES*,int,int,wchar_t const*); Chris@101: # else Chris@101: __declspec(dllimport) void* __stdcall CreateMutexExW(_SECURITY_ATTRIBUTES*,wchar_t const*,unsigned long,unsigned long); Chris@101: __declspec(dllimport) void* __stdcall CreateEventExW(_SECURITY_ATTRIBUTES*,wchar_t const*,unsigned long,unsigned long); Chris@101: __declspec(dllimport) void* __stdcall CreateSemaphoreExW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*,unsigned long,unsigned long); Chris@101: # endif Chris@16: __declspec(dllimport) void* __stdcall OpenEventW(unsigned long,int,wchar_t const*); Chris@16: # else Chris@16: __declspec(dllimport) void* __stdcall CreateMutexA(_SECURITY_ATTRIBUTES*,int,char const*); Chris@16: __declspec(dllimport) void* __stdcall CreateSemaphoreA(_SECURITY_ATTRIBUTES*,long,long,char const*); Chris@16: __declspec(dllimport) void* __stdcall CreateEventA(_SECURITY_ATTRIBUTES*,int,int,char const*); Chris@16: __declspec(dllimport) void* __stdcall OpenEventA(unsigned long,int,char const*); Chris@16: # endif Chris@101: #if BOOST_PLAT_WINDOWS_RUNTIME Chris@101: __declspec(dllimport) void __stdcall GetNativeSystemInfo(_SYSTEM_INFO*); Chris@101: __declspec(dllimport) ticks_type __stdcall GetTickCount64(); Chris@101: #else Chris@101: __declspec(dllimport) void __stdcall GetSystemInfo(_SYSTEM_INFO*); Chris@101: #endif Chris@16: __declspec(dllimport) int __stdcall CloseHandle(void*); Chris@16: __declspec(dllimport) int __stdcall ReleaseMutex(void*); Chris@101: __declspec(dllimport) unsigned long __stdcall WaitForSingleObjectEx(void*,unsigned long,int); Chris@101: __declspec(dllimport) unsigned long __stdcall WaitForMultipleObjectsEx(unsigned long nCount,void* const * lpHandles,int bWaitAll,unsigned long dwMilliseconds,int bAlertable); Chris@16: __declspec(dllimport) int __stdcall ReleaseSemaphore(void*,long,long*); Chris@16: __declspec(dllimport) int __stdcall DuplicateHandle(void*,void*,void*,void**,unsigned long,int,unsigned long); Chris@101: #if !BOOST_PLAT_WINDOWS_RUNTIME Chris@16: __declspec(dllimport) unsigned long __stdcall SleepEx(unsigned long,int); Chris@16: __declspec(dllimport) void __stdcall Sleep(unsigned long); Chris@16: typedef void (__stdcall *queue_user_apc_callback_function)(ulong_ptr); Chris@16: __declspec(dllimport) unsigned long __stdcall QueueUserAPC(queue_user_apc_callback_function,void*,ulong_ptr); Chris@101: #endif Chris@16: Chris@16: # ifndef UNDER_CE Chris@16: __declspec(dllimport) unsigned long __stdcall GetCurrentProcessId(); Chris@16: __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(); Chris@16: __declspec(dllimport) void* __stdcall GetCurrentThread(); Chris@16: __declspec(dllimport) void* __stdcall GetCurrentProcess(); Chris@16: __declspec(dllimport) int __stdcall SetEvent(void*); Chris@16: __declspec(dllimport) int __stdcall ResetEvent(void*); Chris@16: # else Chris@16: using ::GetCurrentProcessId; Chris@16: using ::GetCurrentThreadId; Chris@16: using ::GetCurrentThread; Chris@16: using ::GetCurrentProcess; Chris@16: using ::SetEvent; Chris@16: using ::ResetEvent; Chris@16: # endif Chris@16: } Chris@16: } Chris@16: } Chris@16: } Chris@16: #else Chris@16: # error "Win32 functions not available" Chris@16: #endif Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: namespace detail Chris@16: { Chris@16: namespace win32 Chris@16: { Chris@101: namespace detail { typedef int (__stdcall *farproc_t)(); typedef ticks_type (__stdcall *gettickcount64_t)(); } Chris@101: #if !BOOST_PLAT_WINDOWS_RUNTIME Chris@101: extern "C" Chris@101: { Chris@101: __declspec(dllimport) detail::farproc_t __stdcall GetProcAddress(void *, const char *); Chris@101: #if !defined(BOOST_NO_ANSI_APIS) Chris@101: __declspec(dllimport) void * __stdcall GetModuleHandleA(const char *); Chris@101: #else Chris@101: __declspec(dllimport) void * __stdcall GetModuleHandleW(const wchar_t *); Chris@101: #endif Chris@101: __declspec(dllimport) unsigned long __stdcall GetTickCount(); Chris@101: #ifdef _MSC_VER Chris@101: long _InterlockedCompareExchange(long volatile *, long, long); Chris@101: #pragma intrinsic(_InterlockedCompareExchange) Chris@101: #elif defined(__MINGW64_VERSION_MAJOR) Chris@101: long _InterlockedCompareExchange(long volatile *, long, long); Chris@101: #else Chris@101: // Mingw doesn't provide intrinsics Chris@101: #define _InterlockedCompareExchange InterlockedCompareExchange Chris@101: #endif Chris@101: } Chris@101: // Borrowed from https://stackoverflow.com/questions/8211820/userland-interrupt-timer-access-such-as-via-kequeryinterrupttime-or-similar Chris@101: inline ticks_type __stdcall GetTickCount64emulation() Chris@101: { Chris@101: static volatile long count = 0xFFFFFFFF; Chris@101: unsigned long previous_count, current_tick32, previous_count_zone, current_tick32_zone; Chris@101: ticks_type current_tick64; Chris@101: Chris@101: previous_count = (unsigned long) _InterlockedCompareExchange(&count, 0, 0); Chris@101: current_tick32 = GetTickCount(); Chris@101: Chris@101: if(previous_count == 0xFFFFFFFF) Chris@101: { Chris@101: // count has never been written Chris@101: unsigned long initial_count; Chris@101: initial_count = current_tick32 >> 28; Chris@101: previous_count = (unsigned long) _InterlockedCompareExchange(&count, initial_count, 0xFFFFFFFF); Chris@101: Chris@101: current_tick64 = initial_count; Chris@101: current_tick64 <<= 28; Chris@101: current_tick64 += current_tick32 & 0x0FFFFFFF; Chris@101: return current_tick64; Chris@101: } Chris@101: Chris@101: previous_count_zone = previous_count & 15; Chris@101: current_tick32_zone = current_tick32 >> 28; Chris@101: Chris@101: if(current_tick32_zone == previous_count_zone) Chris@101: { Chris@101: // The top four bits of the 32-bit tick count haven't changed since count was last written. Chris@101: current_tick64 = previous_count; Chris@101: current_tick64 <<= 28; Chris@101: current_tick64 += current_tick32 & 0x0FFFFFFF; Chris@101: return current_tick64; Chris@101: } Chris@101: Chris@101: if(current_tick32_zone == previous_count_zone + 1 || (current_tick32_zone == 0 && previous_count_zone == 15)) Chris@101: { Chris@101: // The top four bits of the 32-bit tick count have been incremented since count was last written. Chris@101: _InterlockedCompareExchange(&count, previous_count + 1, previous_count); Chris@101: current_tick64 = previous_count + 1; Chris@101: current_tick64 <<= 28; Chris@101: current_tick64 += current_tick32 & 0x0FFFFFFF; Chris@101: return current_tick64; Chris@101: } Chris@101: Chris@101: // Oops, we weren't called often enough, we're stuck Chris@101: return 0xFFFFFFFF; Chris@101: } Chris@101: #endif Chris@101: inline detail::gettickcount64_t GetTickCount64_() Chris@101: { Chris@101: static detail::gettickcount64_t gettickcount64impl; Chris@101: if(gettickcount64impl) Chris@101: return gettickcount64impl; Chris@101: Chris@101: // GetTickCount and GetModuleHandle are not allowed in the Windows Runtime, Chris@101: // and kernel32 isn't used in Windows Phone. Chris@101: #if BOOST_PLAT_WINDOWS_RUNTIME Chris@101: gettickcount64impl = &GetTickCount64; Chris@101: #else Chris@101: detail::farproc_t addr=GetProcAddress( Chris@101: #if !defined(BOOST_NO_ANSI_APIS) Chris@101: GetModuleHandleA("KERNEL32.DLL"), Chris@101: #else Chris@101: GetModuleHandleW(L"KERNEL32.DLL"), Chris@101: #endif Chris@101: "GetTickCount64"); Chris@101: if(addr) Chris@101: gettickcount64impl=(detail::gettickcount64_t) addr; Chris@101: else Chris@101: gettickcount64impl=&GetTickCount64emulation; Chris@101: #endif Chris@101: return gettickcount64impl; Chris@101: } Chris@101: Chris@16: enum event_type Chris@16: { Chris@16: auto_reset_event=false, Chris@16: manual_reset_event=true Chris@16: }; Chris@16: Chris@16: enum initial_event_state Chris@16: { Chris@16: event_initially_reset=false, Chris@16: event_initially_set=true Chris@16: }; Chris@16: Chris@101: inline handle create_event( Chris@101: #if !defined(BOOST_NO_ANSI_APIS) Chris@101: const char *mutex_name, Chris@101: #else Chris@101: const wchar_t *mutex_name, Chris@101: #endif Chris@101: event_type type, Chris@101: initial_event_state state) Chris@101: { Chris@101: #if !defined(BOOST_NO_ANSI_APIS) Chris@101: handle const res = win32::CreateEventA(0, type, state, mutex_name); Chris@101: #elif BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA Chris@101: handle const res = win32::CreateEventW(0, type, state, mutex_name); Chris@101: #else Chris@101: handle const res = win32::CreateEventExW( Chris@101: 0, Chris@101: mutex_name, Chris@101: type ? create_event_manual_reset : 0 | state ? create_event_initial_set : 0, Chris@101: event_all_access); Chris@101: #endif Chris@101: return res; Chris@101: } Chris@101: Chris@16: inline handle create_anonymous_event(event_type type,initial_event_state state) Chris@16: { Chris@101: handle const res = create_event(0, type, state); Chris@16: if(!res) Chris@16: { Chris@16: boost::throw_exception(thread_resource_error()); Chris@16: } Chris@16: return res; Chris@16: } Chris@16: Chris@101: inline handle create_anonymous_semaphore_nothrow(long initial_count,long max_count) Chris@101: { Chris@101: #if !defined(BOOST_NO_ANSI_APIS) Chris@101: handle const res=win32::CreateSemaphoreA(0,initial_count,max_count,0); Chris@101: #else Chris@101: #if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA Chris@101: handle const res=win32::CreateSemaphoreEx(0,initial_count,max_count,0,0); Chris@101: #else Chris@101: handle const res=win32::CreateSemaphoreExW(0,initial_count,max_count,0,0,semaphore_all_access); Chris@101: #endif Chris@101: #endif Chris@101: return res; Chris@101: } Chris@101: Chris@16: inline handle create_anonymous_semaphore(long initial_count,long max_count) Chris@16: { Chris@101: handle const res=create_anonymous_semaphore_nothrow(initial_count,max_count); Chris@16: if(!res) Chris@16: { Chris@16: boost::throw_exception(thread_resource_error()); Chris@16: } Chris@16: return res; Chris@16: } Chris@16: Chris@16: inline handle duplicate_handle(handle source) Chris@16: { Chris@16: handle const current_process=GetCurrentProcess(); Chris@16: long const same_access_flag=2; Chris@16: handle new_handle=0; Chris@16: bool const success=DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0; Chris@16: if(!success) Chris@16: { Chris@16: boost::throw_exception(thread_resource_error()); Chris@16: } Chris@16: return new_handle; Chris@16: } Chris@16: Chris@16: inline void release_semaphore(handle semaphore,long count) Chris@16: { Chris@16: BOOST_VERIFY(ReleaseSemaphore(semaphore,count,0)!=0); Chris@16: } Chris@101: Chris@101: inline void get_system_info(system_info *info) Chris@101: { Chris@101: #if BOOST_PLAT_WINDOWS_RUNTIME Chris@101: win32::GetNativeSystemInfo(info); Chris@101: #else Chris@101: win32::GetSystemInfo(info); Chris@101: #endif Chris@101: } Chris@101: Chris@101: inline void sleep(unsigned long milliseconds) Chris@101: { Chris@101: if(milliseconds == 0) Chris@101: { Chris@101: #if BOOST_PLAT_WINDOWS_RUNTIME Chris@101: std::this_thread::yield(); Chris@101: #else Chris@101: ::boost::detail::win32::Sleep(0); Chris@101: #endif Chris@101: } Chris@101: else Chris@101: { Chris@101: #if BOOST_PLAT_WINDOWS_RUNTIME Chris@101: ::boost::detail::win32::WaitForSingleObjectEx(::boost::detail::win32::GetCurrentThread(), milliseconds, 0); Chris@101: #else Chris@101: ::boost::detail::win32::Sleep(milliseconds); Chris@101: #endif Chris@101: } Chris@101: } Chris@101: Chris@101: #if BOOST_PLAT_WINDOWS_RUNTIME Chris@101: class BOOST_THREAD_DECL scoped_winrt_thread Chris@101: { Chris@101: public: Chris@101: scoped_winrt_thread() : m_completionHandle(invalid_handle_value) Chris@101: {} Chris@16: Chris@101: ~scoped_winrt_thread() Chris@101: { Chris@101: if (m_completionHandle != ::boost::detail::win32::invalid_handle_value) Chris@101: { Chris@101: CloseHandle(m_completionHandle); Chris@101: } Chris@101: } Chris@101: Chris@101: typedef unsigned(__stdcall * thread_func)(void *); Chris@101: bool start(thread_func address, void *parameter, unsigned int *thrdId); Chris@101: Chris@101: handle waitable_handle() const Chris@101: { Chris@101: BOOST_ASSERT(m_completionHandle != ::boost::detail::win32::invalid_handle_value); Chris@101: return m_completionHandle; Chris@101: } Chris@101: Chris@101: private: Chris@101: handle m_completionHandle; Chris@101: }; Chris@101: #endif Chris@16: class BOOST_THREAD_DECL handle_manager Chris@16: { Chris@16: private: Chris@16: handle handle_to_manage; Chris@16: handle_manager(handle_manager&); Chris@16: handle_manager& operator=(handle_manager&); Chris@16: Chris@16: void cleanup() Chris@16: { Chris@16: if(handle_to_manage && handle_to_manage!=invalid_handle_value) Chris@16: { Chris@16: BOOST_VERIFY(CloseHandle(handle_to_manage)); Chris@16: } Chris@16: } Chris@16: Chris@16: public: Chris@16: explicit handle_manager(handle handle_to_manage_): Chris@16: handle_to_manage(handle_to_manage_) Chris@16: {} Chris@16: handle_manager(): Chris@16: handle_to_manage(0) Chris@16: {} Chris@16: Chris@16: handle_manager& operator=(handle new_handle) Chris@16: { Chris@16: cleanup(); Chris@16: handle_to_manage=new_handle; Chris@16: return *this; Chris@16: } Chris@16: Chris@16: operator handle() const Chris@16: { Chris@16: return handle_to_manage; Chris@16: } Chris@16: Chris@16: handle duplicate() const Chris@16: { Chris@16: return duplicate_handle(handle_to_manage); Chris@16: } Chris@16: Chris@16: void swap(handle_manager& other) Chris@16: { Chris@16: std::swap(handle_to_manage,other.handle_to_manage); Chris@16: } Chris@16: Chris@16: handle release() Chris@16: { Chris@16: handle const res=handle_to_manage; Chris@16: handle_to_manage=0; Chris@16: return res; Chris@16: } Chris@16: Chris@16: bool operator!() const Chris@16: { Chris@16: return !handle_to_manage; Chris@16: } Chris@16: Chris@16: ~handle_manager() Chris@16: { Chris@16: cleanup(); Chris@16: } Chris@16: }; Chris@16: } Chris@16: } Chris@16: } Chris@16: Chris@16: #if defined(BOOST_MSVC) && (_MSC_VER>=1400) && !defined(UNDER_CE) Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: namespace detail Chris@16: { Chris@16: namespace win32 Chris@16: { Chris@16: #if _MSC_VER==1400 Chris@16: extern "C" unsigned char _interlockedbittestandset(long *a,long b); Chris@16: extern "C" unsigned char _interlockedbittestandreset(long *a,long b); Chris@16: #else Chris@16: extern "C" unsigned char _interlockedbittestandset(volatile long *a,long b); Chris@16: extern "C" unsigned char _interlockedbittestandreset(volatile long *a,long b); Chris@16: #endif Chris@16: Chris@16: #pragma intrinsic(_interlockedbittestandset) Chris@16: #pragma intrinsic(_interlockedbittestandreset) Chris@16: Chris@16: inline bool interlocked_bit_test_and_set(long* x,long bit) Chris@16: { Chris@16: return _interlockedbittestandset(x,bit)!=0; Chris@16: } Chris@16: Chris@16: inline bool interlocked_bit_test_and_reset(long* x,long bit) Chris@16: { Chris@16: return _interlockedbittestandreset(x,bit)!=0; Chris@16: } Chris@16: Chris@16: } Chris@16: } Chris@16: } Chris@16: #define BOOST_THREAD_BTS_DEFINED Chris@16: #elif (defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)) && defined(_M_IX86) Chris@16: namespace boost Chris@16: { Chris@16: namespace detail Chris@16: { Chris@16: namespace win32 Chris@16: { Chris@16: inline bool interlocked_bit_test_and_set(long* x,long bit) Chris@16: { Chris@16: #ifndef BOOST_INTEL_CXX_VERSION Chris@16: __asm { Chris@16: mov eax,bit; Chris@16: mov edx,x; Chris@16: lock bts [edx],eax; Chris@16: setc al; Chris@16: }; Chris@16: #else Chris@16: bool ret; Chris@16: __asm { Chris@16: mov eax,bit Chris@16: mov edx,x Chris@16: lock bts [edx],eax Chris@16: setc al Chris@16: mov ret, al Chris@16: }; Chris@16: return ret; Chris@16: Chris@16: #endif Chris@16: } Chris@16: Chris@16: inline bool interlocked_bit_test_and_reset(long* x,long bit) Chris@16: { Chris@16: #ifndef BOOST_INTEL_CXX_VERSION Chris@16: __asm { Chris@16: mov eax,bit; Chris@16: mov edx,x; Chris@16: lock btr [edx],eax; Chris@16: setc al; Chris@16: }; Chris@16: #else Chris@16: bool ret; Chris@16: __asm { Chris@16: mov eax,bit Chris@16: mov edx,x Chris@16: lock btr [edx],eax Chris@16: setc al Chris@16: mov ret, al Chris@16: }; Chris@16: return ret; Chris@16: Chris@16: #endif Chris@16: } Chris@16: Chris@16: } Chris@16: } Chris@16: } Chris@16: #define BOOST_THREAD_BTS_DEFINED Chris@16: #endif Chris@16: Chris@16: #ifndef BOOST_THREAD_BTS_DEFINED Chris@16: Chris@16: namespace boost Chris@16: { Chris@16: namespace detail Chris@16: { Chris@16: namespace win32 Chris@16: { Chris@16: inline bool interlocked_bit_test_and_set(long* x,long bit) Chris@16: { Chris@16: long const value=1< Chris@16: Chris@16: #endif