123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426 |
- #ifndef BOOST_WIN32_THREAD_PRIMITIVES_HPP
- #define BOOST_WIN32_THREAD_PRIMITIVES_HPP
- // win32_thread_primitives.hpp
- //
- // (C) Copyright 2005-7 Anthony Williams
- // (C) Copyright 2007 David Deakins
- //
- // Distributed under the Boost Software License, Version 1.0. (See
- // accompanying file LICENSE_1_0.txt or copy at
- // http://www.boost.org/LICENSE_1_0.txt)
- #include <boost/thread/detail/config.hpp>
- #include <boost/predef/platform.h>
- #include <boost/throw_exception.hpp>
- #include <boost/assert.hpp>
- #include <boost/thread/exceptions.hpp>
- #include <boost/detail/interlocked.hpp>
- #include <boost/winapi/config.hpp>
- #include <boost/winapi/basic_types.hpp>
- #include <boost/winapi/semaphore.hpp>
- #include <boost/winapi/system.hpp>
- #include <boost/winapi/event.hpp>
- #include <boost/winapi/thread.hpp>
- #include <boost/winapi/get_current_thread.hpp>
- #include <boost/winapi/get_current_thread_id.hpp>
- #include <boost/winapi/get_current_process.hpp>
- #include <boost/winapi/get_current_process_id.hpp>
- #include <boost/winapi/wait.hpp>
- #include <boost/winapi/handles.hpp>
- #include <boost/winapi/access_rights.hpp>
- //#include <boost/winapi/synchronization.hpp>
- #include <boost/thread/win32/interlocked_read.hpp>
- #include <algorithm>
- #if BOOST_PLAT_WINDOWS_RUNTIME
- #include <thread>
- #endif
- namespace boost
- {
- namespace detail
- {
- namespace win32
- {
- typedef ::boost::winapi::HANDLE_ handle;
- typedef ::boost::winapi::SYSTEM_INFO_ system_info;
- typedef ::boost::winapi::ULONGLONG_ ticks_type;
- unsigned const infinite=::boost::winapi::INFINITE_;
- unsigned const timeout=::boost::winapi::WAIT_TIMEOUT_;
- handle const invalid_handle_value=::boost::winapi::INVALID_HANDLE_VALUE_;
- unsigned const event_modify_state=::boost::winapi::EVENT_MODIFY_STATE_;
- unsigned const synchronize=::boost::winapi::SYNCHRONIZE_;
- unsigned const wait_abandoned=::boost::winapi::WAIT_ABANDONED_;
- unsigned const create_event_initial_set = 0x00000002;
- unsigned const create_event_manual_reset = 0x00000001;
- unsigned const event_all_access = ::boost::winapi::EVENT_ALL_ACCESS_;
- unsigned const semaphore_all_access = boost::winapi::SEMAPHORE_ALL_ACCESS_;
- }
- }
- }
- #include <boost/config/abi_prefix.hpp>
- namespace boost
- {
- namespace detail
- {
- namespace win32
- {
- namespace detail { typedef ticks_type (BOOST_WINAPI_WINAPI_CC *gettickcount64_t)(); }
- extern BOOST_THREAD_DECL boost::detail::win32::detail::gettickcount64_t gettickcount64;
- enum event_type
- {
- auto_reset_event=false,
- manual_reset_event=true
- };
- enum initial_event_state
- {
- event_initially_reset=false,
- event_initially_set=true
- };
- inline handle create_event(
- #if !defined(BOOST_NO_ANSI_APIS)
- const char *mutex_name,
- #else
- const wchar_t *mutex_name,
- #endif
- event_type type,
- initial_event_state state)
- {
- #if !defined(BOOST_NO_ANSI_APIS)
- handle const res = ::boost::winapi::CreateEventA(0, type, state, mutex_name);
- #elif BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
- handle const res = ::boost::winapi::CreateEventW(0, type, state, mutex_name);
- #else
- handle const res = ::boost::winapi::CreateEventExW(
- 0,
- mutex_name,
- (type ? create_event_manual_reset : 0) | (state ? create_event_initial_set : 0),
- event_all_access);
- #endif
- return res;
- }
- inline handle create_anonymous_event(event_type type,initial_event_state state)
- {
- handle const res = create_event(0, type, state);
- if(!res)
- {
- boost::throw_exception(thread_resource_error());
- }
- return res;
- }
- inline handle create_anonymous_semaphore_nothrow(long initial_count,long max_count)
- {
- #if !defined(BOOST_NO_ANSI_APIS)
- handle const res=::boost::winapi::CreateSemaphoreA(0,initial_count,max_count,0);
- #else
- #if BOOST_USE_WINAPI_VERSION < BOOST_WINAPI_VERSION_VISTA
- handle const res=::boost::winapi::CreateSemaphoreEx(0,initial_count,max_count,0,0);
- #else
- handle const res=::boost::winapi::CreateSemaphoreExW(0,initial_count,max_count,0,0,semaphore_all_access);
- #endif
- #endif
- return res;
- }
- inline handle create_anonymous_semaphore(long initial_count,long max_count)
- {
- handle const res=create_anonymous_semaphore_nothrow(initial_count,max_count);
- if(!res)
- {
- boost::throw_exception(thread_resource_error());
- }
- return res;
- }
- inline handle duplicate_handle(handle source)
- {
- handle const current_process=::boost::winapi::GetCurrentProcess();
- long const same_access_flag=2;
- handle new_handle=0;
- bool const success=::boost::winapi::DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0;
- if(!success)
- {
- boost::throw_exception(thread_resource_error());
- }
- return new_handle;
- }
- inline void release_semaphore(handle semaphore,long count)
- {
- BOOST_VERIFY(::boost::winapi::ReleaseSemaphore(semaphore,count,0)!=0);
- }
- inline void get_system_info(system_info *info)
- {
- #if BOOST_PLAT_WINDOWS_RUNTIME
- ::boost::winapi::GetNativeSystemInfo(info);
- #else
- ::boost::winapi::GetSystemInfo(info);
- #endif
- }
- inline void sleep(unsigned long milliseconds)
- {
- if(milliseconds == 0)
- {
- #if BOOST_PLAT_WINDOWS_RUNTIME
- std::this_thread::yield();
- #else
- ::boost::winapi::Sleep(0);
- #endif
- }
- else
- {
- #if BOOST_PLAT_WINDOWS_RUNTIME
- ::boost::winapi::WaitForSingleObjectEx(::boost::winapi::GetCurrentThread(), milliseconds, 0);
- #else
- ::boost::winapi::Sleep(milliseconds);
- #endif
- }
- }
- #if BOOST_PLAT_WINDOWS_RUNTIME
- class BOOST_THREAD_DECL scoped_winrt_thread
- {
- public:
- scoped_winrt_thread() : m_completionHandle(invalid_handle_value)
- {}
- ~scoped_winrt_thread()
- {
- if (m_completionHandle != ::boost::detail::win32::invalid_handle_value)
- {
- ::boost::winapi::CloseHandle(m_completionHandle);
- }
- }
- typedef unsigned(__stdcall * thread_func)(void *);
- bool start(thread_func address, void *parameter, unsigned int *thrdId);
- handle waitable_handle() const
- {
- BOOST_ASSERT(m_completionHandle != ::boost::detail::win32::invalid_handle_value);
- return m_completionHandle;
- }
- private:
- handle m_completionHandle;
- };
- #endif
- class BOOST_THREAD_DECL handle_manager
- {
- private:
- handle handle_to_manage;
- handle_manager(handle_manager&);
- handle_manager& operator=(handle_manager&);
- void cleanup()
- {
- if(handle_to_manage && handle_to_manage!=invalid_handle_value)
- {
- BOOST_VERIFY(::boost::winapi::CloseHandle(handle_to_manage));
- }
- }
- public:
- explicit handle_manager(handle handle_to_manage_):
- handle_to_manage(handle_to_manage_)
- {}
- handle_manager():
- handle_to_manage(0)
- {}
- handle_manager& operator=(handle new_handle)
- {
- cleanup();
- handle_to_manage=new_handle;
- return *this;
- }
- operator handle() const
- {
- return handle_to_manage;
- }
- handle duplicate() const
- {
- return duplicate_handle(handle_to_manage);
- }
- void swap(handle_manager& other)
- {
- std::swap(handle_to_manage,other.handle_to_manage);
- }
- handle release()
- {
- handle const res=handle_to_manage;
- handle_to_manage=0;
- return res;
- }
- bool operator!() const
- {
- return !handle_to_manage;
- }
- ~handle_manager()
- {
- cleanup();
- }
- };
- }
- }
- }
- #if defined(BOOST_MSVC) && (_MSC_VER>=1400) && !defined(UNDER_CE)
- namespace boost
- {
- namespace detail
- {
- namespace win32
- {
- #if _MSC_VER==1400
- extern "C" unsigned char _interlockedbittestandset(long *a,long b);
- extern "C" unsigned char _interlockedbittestandreset(long *a,long b);
- #else
- extern "C" unsigned char _interlockedbittestandset(volatile long *a,long b);
- extern "C" unsigned char _interlockedbittestandreset(volatile long *a,long b);
- #endif
- #pragma intrinsic(_interlockedbittestandset)
- #pragma intrinsic(_interlockedbittestandreset)
- inline bool interlocked_bit_test_and_set(long* x,long bit)
- {
- return _interlockedbittestandset(x,bit)!=0;
- }
- inline bool interlocked_bit_test_and_reset(long* x,long bit)
- {
- return _interlockedbittestandreset(x,bit)!=0;
- }
- }
- }
- }
- #define BOOST_THREAD_BTS_DEFINED
- #elif (defined(BOOST_MSVC) || defined(BOOST_INTEL_WIN)) && defined(_M_IX86)
- namespace boost
- {
- namespace detail
- {
- namespace win32
- {
- inline bool interlocked_bit_test_and_set(long* x,long bit)
- {
- #ifndef BOOST_INTEL_CXX_VERSION
- __asm {
- mov eax,bit;
- mov edx,x;
- lock bts [edx],eax;
- setc al;
- };
- #else
- bool ret;
- __asm {
- mov eax,bit
- mov edx,x
- lock bts [edx],eax
- setc al
- mov ret, al
- };
- return ret;
- #endif
- }
- inline bool interlocked_bit_test_and_reset(long* x,long bit)
- {
- #ifndef BOOST_INTEL_CXX_VERSION
- __asm {
- mov eax,bit;
- mov edx,x;
- lock btr [edx],eax;
- setc al;
- };
- #else
- bool ret;
- __asm {
- mov eax,bit
- mov edx,x
- lock btr [edx],eax
- setc al
- mov ret, al
- };
- return ret;
- #endif
- }
- }
- }
- }
- #define BOOST_THREAD_BTS_DEFINED
- #endif
- #ifndef BOOST_THREAD_BTS_DEFINED
- namespace boost
- {
- namespace detail
- {
- namespace win32
- {
- inline bool interlocked_bit_test_and_set(long* x,long bit)
- {
- long const value=1<<bit;
- long old=*x;
- do
- {
- long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old|value,old);
- if(current==old)
- {
- break;
- }
- old=current;
- }
- while(true) ;
- return (old&value)!=0;
- }
- inline bool interlocked_bit_test_and_reset(long* x,long bit)
- {
- long const value=1<<bit;
- long old=*x;
- do
- {
- long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,old&~value,old);
- if(current==old)
- {
- break;
- }
- old=current;
- }
- while(true) ;
- return (old&value)!=0;
- }
- }
- }
- }
- #endif
- #include <boost/config/abi_suffix.hpp>
- #endif
|