diff options
author | Remko Tronçon <git@el-tramo.be> | 2010-03-28 15:46:49 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2010-03-28 15:46:49 (GMT) |
commit | f53a1ef582494458301b97bf6e546be52d7ff7e8 (patch) | |
tree | 7571b5cbcbd8a8f1dd1c966c9045b6cb69f0e295 /3rdParty/Boost/src/boost/thread/win32 | |
parent | 638345680d72ca6acaf123f2c8c1c391f696e371 (diff) | |
download | swift-contrib-f53a1ef582494458301b97bf6e546be52d7ff7e8.zip swift-contrib-f53a1ef582494458301b97bf6e546be52d7ff7e8.tar.bz2 |
Moving submodule contents back.
Diffstat (limited to '3rdParty/Boost/src/boost/thread/win32')
11 files changed, 2600 insertions, 0 deletions
diff --git a/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp new file mode 100644 index 0000000..05eb8d7 --- /dev/null +++ b/3rdParty/Boost/src/boost/thread/win32/basic_recursive_mutex.hpp @@ -0,0 +1,120 @@ +#ifndef BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP +#define BOOST_BASIC_RECURSIVE_MUTEX_WIN32_HPP + +// basic_recursive_mutex.hpp +// +// (C) Copyright 2006-8 Anthony Williams +// +// 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 "thread_primitives.hpp" +#include "basic_timed_mutex.hpp" + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + namespace detail + { + template<typename underlying_mutex_type> + struct basic_recursive_mutex_impl + { + long recursion_count; + long locking_thread_id; + underlying_mutex_type mutex; + + void initialize() + { + recursion_count=0; + locking_thread_id=0; + mutex.initialize(); + } + + void destroy() + { + mutex.destroy(); + } + + bool try_lock() + { + long const current_thread_id=win32::GetCurrentThreadId(); + return try_recursive_lock(current_thread_id) || try_basic_lock(current_thread_id); + } + + void lock() + { + long const current_thread_id=win32::GetCurrentThreadId(); + if(!try_recursive_lock(current_thread_id)) + { + mutex.lock(); + BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); + recursion_count=1; + } + } + bool timed_lock(::boost::system_time const& target) + { + long const current_thread_id=win32::GetCurrentThreadId(); + return try_recursive_lock(current_thread_id) || try_timed_lock(current_thread_id,target); + } + template<typename Duration> + bool timed_lock(Duration const& timeout) + { + return timed_lock(get_system_time()+timeout); + } + + void unlock() + { + if(!--recursion_count) + { + BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,0); + mutex.unlock(); + } + } + + private: + bool try_recursive_lock(long current_thread_id) + { + if(::boost::detail::interlocked_read_acquire(&locking_thread_id)==current_thread_id) + { + ++recursion_count; + return true; + } + return false; + } + + bool try_basic_lock(long current_thread_id) + { + if(mutex.try_lock()) + { + BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); + recursion_count=1; + return true; + } + return false; + } + + bool try_timed_lock(long current_thread_id,::boost::system_time const& target) + { + if(mutex.timed_lock(target)) + { + BOOST_INTERLOCKED_EXCHANGE(&locking_thread_id,current_thread_id); + recursion_count=1; + return true; + } + return false; + } + + }; + + typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_mutex; + typedef basic_recursive_mutex_impl<basic_timed_mutex> basic_recursive_timed_mutex; + } +} + +#define BOOST_BASIC_RECURSIVE_MUTEX_INITIALIZER {0} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp new file mode 100644 index 0000000..751bdbd --- /dev/null +++ b/3rdParty/Boost/src/boost/thread/win32/basic_timed_mutex.hpp @@ -0,0 +1,178 @@ +#ifndef BOOST_BASIC_TIMED_MUTEX_WIN32_HPP +#define BOOST_BASIC_TIMED_MUTEX_WIN32_HPP + +// basic_timed_mutex_win32.hpp +// +// (C) Copyright 2006-8 Anthony Williams +// +// 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/assert.hpp> +#include "thread_primitives.hpp" +#include "interlocked_read.hpp" +#include <boost/thread/thread_time.hpp> +#include <boost/thread/xtime.hpp> +#include <boost/detail/interlocked.hpp> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + namespace detail + { + struct basic_timed_mutex + { + BOOST_STATIC_CONSTANT(unsigned char,lock_flag_bit=31); + BOOST_STATIC_CONSTANT(unsigned char,event_set_flag_bit=30); + BOOST_STATIC_CONSTANT(long,lock_flag_value=1<<lock_flag_bit); + BOOST_STATIC_CONSTANT(long,event_set_flag_value=1<<event_set_flag_bit); + long active_count; + void* event; + + void initialize() + { + active_count=0; + event=0; + } + + void destroy() + { +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4312) +#endif + void* const old_event=BOOST_INTERLOCKED_EXCHANGE_POINTER(&event,0); +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + if(old_event) + { + win32::CloseHandle(old_event); + } + } + + + bool try_lock() + { + return !win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit); + } + + void lock() + { + BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel())); + } + bool timed_lock(::boost::system_time const& wait_until) + { + if(!win32::interlocked_bit_test_and_set(&active_count,lock_flag_bit)) + { + return true; + } + long old_count=active_count; + for(;;) + { + long const new_count=(old_count&lock_flag_value)?(old_count+1):(old_count|lock_flag_value); + long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count); + if(current==old_count) + { + break; + } + old_count=current; + } + + if(old_count&lock_flag_value) + { + bool lock_acquired=false; + void* const sem=get_event(); + + do + { + if(win32::WaitForSingleObject(sem,::boost::detail::get_milliseconds_until(wait_until))!=0) + { + BOOST_INTERLOCKED_DECREMENT(&active_count); + return false; + } + old_count&=~lock_flag_value; + old_count|=event_set_flag_value; + for(;;) + { + long const new_count=((old_count&lock_flag_value)?old_count:((old_count-1)|lock_flag_value))&~event_set_flag_value; + long const current=BOOST_INTERLOCKED_COMPARE_EXCHANGE(&active_count,new_count,old_count); + if(current==old_count) + { + break; + } + old_count=current; + } + lock_acquired=!(old_count&lock_flag_value); + } + while(!lock_acquired); + } + return true; + } + + template<typename Duration> + bool timed_lock(Duration const& timeout) + { + return timed_lock(get_system_time()+timeout); + } + + bool timed_lock(boost::xtime const& timeout) + { + return timed_lock(system_time(timeout)); + } + + void unlock() + { + long const offset=lock_flag_value; + long const old_count=BOOST_INTERLOCKED_EXCHANGE_ADD(&active_count,lock_flag_value); + if(!(old_count&event_set_flag_value) && (old_count>offset)) + { + if(!win32::interlocked_bit_test_and_set(&active_count,event_set_flag_bit)) + { + win32::SetEvent(get_event()); + } + } + } + + private: + void* get_event() + { + void* current_event=::boost::detail::interlocked_read_acquire(&event); + + if(!current_event) + { + void* const new_event=win32::create_anonymous_event(win32::auto_reset_event,win32::event_initially_reset); +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4311) +#pragma warning(disable:4312) +#endif + void* const old_event=BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(&event,new_event,0); +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + if(old_event!=0) + { + win32::CloseHandle(new_event); + return old_event; + } + else + { + return new_event; + } + } + return current_event; + } + + }; + + } +} + +#define BOOST_BASIC_TIMED_MUTEX_INITIALIZER {0} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp b/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp new file mode 100644 index 0000000..6e676b4 --- /dev/null +++ b/3rdParty/Boost/src/boost/thread/win32/condition_variable.hpp @@ -0,0 +1,418 @@ +#ifndef BOOST_THREAD_CONDITION_VARIABLE_WIN32_HPP +#define BOOST_THREAD_CONDITION_VARIABLE_WIN32_HPP +// 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) +// (C) Copyright 2007-8 Anthony Williams + +#include <boost/thread/mutex.hpp> +#include "thread_primitives.hpp" +#include <limits.h> +#include <boost/assert.hpp> +#include <algorithm> +#include <boost/thread/thread.hpp> +#include <boost/thread/thread_time.hpp> +#include "interlocked_read.hpp" +#include <boost/thread/xtime.hpp> +#include <vector> +#include <boost/intrusive_ptr.hpp> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + namespace detail + { + class basic_cv_list_entry; + void intrusive_ptr_add_ref(basic_cv_list_entry * p); + void intrusive_ptr_release(basic_cv_list_entry * p); + + class basic_cv_list_entry + { + private: + detail::win32::handle_manager semaphore; + detail::win32::handle_manager wake_sem; + long waiters; + bool notified; + long references; + + basic_cv_list_entry(basic_cv_list_entry&); + void operator=(basic_cv_list_entry&); + + public: + explicit basic_cv_list_entry(detail::win32::handle_manager const& wake_sem_): + semaphore(detail::win32::create_anonymous_semaphore(0,LONG_MAX)), + wake_sem(wake_sem_.duplicate()), + waiters(1),notified(false),references(0) + {} + + static bool no_waiters(boost::intrusive_ptr<basic_cv_list_entry> const& entry) + { + return !detail::interlocked_read_acquire(&entry->waiters); + } + + void add_waiter() + { + BOOST_INTERLOCKED_INCREMENT(&waiters); + } + + void remove_waiter() + { + BOOST_INTERLOCKED_DECREMENT(&waiters); + } + + void release(unsigned count_to_release) + { + notified=true; + detail::win32::ReleaseSemaphore(semaphore,count_to_release,0); + } + + void release_waiters() + { + release(detail::interlocked_read_acquire(&waiters)); + } + + bool is_notified() const + { + return notified; + } + + bool wait(timeout wait_until) + { + return this_thread::interruptible_wait(semaphore,wait_until); + } + + bool woken() + { + unsigned long const woken_result=detail::win32::WaitForSingleObject(wake_sem,0); + BOOST_ASSERT((woken_result==detail::win32::timeout) || (woken_result==0)); + return woken_result==0; + } + + friend void intrusive_ptr_add_ref(basic_cv_list_entry * p); + friend void intrusive_ptr_release(basic_cv_list_entry * p); + }; + + inline void intrusive_ptr_add_ref(basic_cv_list_entry * p) + { + BOOST_INTERLOCKED_INCREMENT(&p->references); + } + + inline void intrusive_ptr_release(basic_cv_list_entry * p) + { + if(!BOOST_INTERLOCKED_DECREMENT(&p->references)) + { + delete p; + } + } + + class basic_condition_variable + { + boost::mutex internal_mutex; + long total_count; + unsigned active_generation_count; + + typedef basic_cv_list_entry list_entry; + + typedef boost::intrusive_ptr<list_entry> entry_ptr; + typedef std::vector<entry_ptr> generation_list; + + generation_list generations; + detail::win32::handle_manager wake_sem; + + void wake_waiters(long count_to_wake) + { + detail::interlocked_write_release(&total_count,total_count-count_to_wake); + detail::win32::ReleaseSemaphore(wake_sem,count_to_wake,0); + } + + template<typename lock_type> + struct relocker + { + lock_type& lock; + bool unlocked; + + relocker(lock_type& lock_): + lock(lock_),unlocked(false) + {} + void unlock() + { + lock.unlock(); + unlocked=true; + } + ~relocker() + { + if(unlocked) + { + lock.lock(); + } + + } + private: + relocker(relocker&); + void operator=(relocker&); + }; + + + entry_ptr get_wait_entry() + { + boost::lock_guard<boost::mutex> internal_lock(internal_mutex); + + if(!wake_sem) + { + wake_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX); + BOOST_ASSERT(wake_sem); + } + + detail::interlocked_write_release(&total_count,total_count+1); + if(generations.empty() || generations.back()->is_notified()) + { + entry_ptr new_entry(new list_entry(wake_sem)); + generations.push_back(new_entry); + return new_entry; + } + else + { + generations.back()->add_waiter(); + return generations.back(); + } + } + + struct entry_manager + { + entry_ptr const entry; + + entry_manager(entry_ptr const& entry_): + entry(entry_) + {} + + ~entry_manager() + { + entry->remove_waiter(); + } + + list_entry* operator->() + { + return entry.get(); + } + + private: + void operator=(entry_manager&); + entry_manager(entry_manager&); + }; + + + protected: + template<typename lock_type> + bool do_wait(lock_type& lock,timeout wait_until) + { + relocker<lock_type> locker(lock); + + entry_manager entry(get_wait_entry()); + + locker.unlock(); + + bool woken=false; + while(!woken) + { + if(!entry->wait(wait_until)) + { + return false; + } + + woken=entry->woken(); + } + return woken; + } + + template<typename lock_type,typename predicate_type> + bool do_wait(lock_type& m,timeout const& wait_until,predicate_type pred) + { + while (!pred()) + { + if(!do_wait(m, wait_until)) + return pred(); + } + return true; + } + + basic_condition_variable(const basic_condition_variable& other); + basic_condition_variable& operator=(const basic_condition_variable& other); + + public: + basic_condition_variable(): + total_count(0),active_generation_count(0),wake_sem(0) + {} + + ~basic_condition_variable() + {} + + void notify_one() + { + if(detail::interlocked_read_acquire(&total_count)) + { + boost::lock_guard<boost::mutex> internal_lock(internal_mutex); + if(!total_count) + { + return; + } + wake_waiters(1); + + for(generation_list::iterator it=generations.begin(), + end=generations.end(); + it!=end;++it) + { + (*it)->release(1); + } + generations.erase(std::remove_if(generations.begin(),generations.end(),&basic_cv_list_entry::no_waiters),generations.end()); + } + } + + void notify_all() + { + if(detail::interlocked_read_acquire(&total_count)) + { + boost::lock_guard<boost::mutex> internal_lock(internal_mutex); + if(!total_count) + { + return; + } + wake_waiters(total_count); + for(generation_list::iterator it=generations.begin(), + end=generations.end(); + it!=end;++it) + { + (*it)->release_waiters(); + } + generations.clear(); + wake_sem=detail::win32::handle(0); + } + } + + }; + } + + class condition_variable: + private detail::basic_condition_variable + { + private: + condition_variable(condition_variable&); + void operator=(condition_variable&); + public: + condition_variable() + {} + + using detail::basic_condition_variable::notify_one; + using detail::basic_condition_variable::notify_all; + + void wait(unique_lock<mutex>& m) + { + do_wait(m,detail::timeout::sentinel()); + } + + template<typename predicate_type> + void wait(unique_lock<mutex>& m,predicate_type pred) + { + while(!pred()) wait(m); + } + + + bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until) + { + return do_wait(m,wait_until); + } + + bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until) + { + return do_wait(m,system_time(wait_until)); + } + template<typename duration_type> + bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration) + { + return do_wait(m,wait_duration.total_milliseconds()); + } + + template<typename predicate_type> + bool timed_wait(unique_lock<mutex>& m,boost::system_time const& wait_until,predicate_type pred) + { + return do_wait(m,wait_until,pred); + } + template<typename predicate_type> + bool timed_wait(unique_lock<mutex>& m,boost::xtime const& wait_until,predicate_type pred) + { + return do_wait(m,system_time(wait_until),pred); + } + template<typename duration_type,typename predicate_type> + bool timed_wait(unique_lock<mutex>& m,duration_type const& wait_duration,predicate_type pred) + { + return do_wait(m,wait_duration.total_milliseconds(),pred); + } + }; + + class condition_variable_any: + private detail::basic_condition_variable + { + private: + condition_variable_any(condition_variable_any&); + void operator=(condition_variable_any&); + public: + condition_variable_any() + {} + + using detail::basic_condition_variable::notify_one; + using detail::basic_condition_variable::notify_all; + + template<typename lock_type> + void wait(lock_type& m) + { + do_wait(m,detail::timeout::sentinel()); + } + + template<typename lock_type,typename predicate_type> + void wait(lock_type& m,predicate_type pred) + { + while(!pred()) wait(m); + } + + template<typename lock_type> + bool timed_wait(lock_type& m,boost::system_time const& wait_until) + { + return do_wait(m,wait_until); + } + + template<typename lock_type> + bool timed_wait(lock_type& m,boost::xtime const& wait_until) + { + return do_wait(m,system_time(wait_until)); + } + + template<typename lock_type,typename duration_type> + bool timed_wait(lock_type& m,duration_type const& wait_duration) + { + return do_wait(m,wait_duration.total_milliseconds()); + } + + template<typename lock_type,typename predicate_type> + bool timed_wait(lock_type& m,boost::system_time const& wait_until,predicate_type pred) + { + return do_wait(m,wait_until,pred); + } + + template<typename lock_type,typename predicate_type> + bool timed_wait(lock_type& m,boost::xtime const& wait_until,predicate_type pred) + { + return do_wait(m,system_time(wait_until),pred); + } + + template<typename lock_type,typename duration_type,typename predicate_type> + bool timed_wait(lock_type& m,duration_type const& wait_duration,predicate_type pred) + { + return do_wait(m,wait_duration.total_milliseconds(),pred); + } + }; + +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/src/boost/thread/win32/interlocked_read.hpp b/3rdParty/Boost/src/boost/thread/win32/interlocked_read.hpp new file mode 100644 index 0000000..133fb6f --- /dev/null +++ b/3rdParty/Boost/src/boost/thread/win32/interlocked_read.hpp @@ -0,0 +1,80 @@ +#ifndef BOOST_THREAD_DETAIL_INTERLOCKED_READ_WIN32_HPP +#define BOOST_THREAD_DETAIL_INTERLOCKED_READ_WIN32_HPP + +// interlocked_read_win32.hpp +// +// (C) Copyright 2005-8 Anthony Williams +// +// 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/detail/interlocked.hpp> + +#include <boost/config/abi_prefix.hpp> + +#ifdef BOOST_MSVC + +extern "C" void _ReadWriteBarrier(void); +#pragma intrinsic(_ReadWriteBarrier) + +namespace boost +{ + namespace detail + { + inline long interlocked_read_acquire(long volatile* x) + { + long const res=*x; + _ReadWriteBarrier(); + return res; + } + inline void* interlocked_read_acquire(void* volatile* x) + { + void* const res=*x; + _ReadWriteBarrier(); + return res; + } + + inline void interlocked_write_release(long volatile* x,long value) + { + _ReadWriteBarrier(); + *x=value; + } + inline void interlocked_write_release(void* volatile* x,void* value) + { + _ReadWriteBarrier(); + *x=value; + } + } +} + +#else + +namespace boost +{ + namespace detail + { + inline long interlocked_read_acquire(long volatile* x) + { + return BOOST_INTERLOCKED_COMPARE_EXCHANGE(x,0,0); + } + inline void* interlocked_read_acquire(void* volatile* x) + { + return BOOST_INTERLOCKED_COMPARE_EXCHANGE_POINTER(x,0,0); + } + inline void interlocked_write_release(long volatile* x,long value) + { + BOOST_INTERLOCKED_EXCHANGE(x,value); + } + inline void interlocked_write_release(void* volatile* x,void* value) + { + BOOST_INTERLOCKED_EXCHANGE_POINTER(x,value); + } + } +} + +#endif + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/src/boost/thread/win32/mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/mutex.hpp new file mode 100644 index 0000000..efe6241 --- /dev/null +++ b/3rdParty/Boost/src/boost/thread/win32/mutex.hpp @@ -0,0 +1,65 @@ +#ifndef BOOST_THREAD_WIN32_MUTEX_HPP +#define BOOST_THREAD_WIN32_MUTEX_HPP +// (C) Copyright 2005-7 Anthony Williams +// 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 "basic_timed_mutex.hpp" +#include <boost/utility.hpp> +#include <boost/thread/exceptions.hpp> +#include <boost/thread/locks.hpp> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + namespace detail + { + typedef ::boost::detail::basic_timed_mutex underlying_mutex; + } + + class mutex: + boost::noncopyable, + public ::boost::detail::underlying_mutex + { + public: + mutex() + { + initialize(); + } + ~mutex() + { + destroy(); + } + + typedef unique_lock<mutex> scoped_lock; + typedef detail::try_lock_wrapper<mutex> scoped_try_lock; + }; + + typedef mutex try_mutex; + + class timed_mutex: + boost::noncopyable, + public ::boost::detail::basic_timed_mutex + { + public: + timed_mutex() + { + initialize(); + } + + ~timed_mutex() + { + destroy(); + } + + typedef unique_lock<timed_mutex> scoped_timed_lock; + typedef detail::try_lock_wrapper<timed_mutex> scoped_try_lock; + typedef scoped_timed_lock scoped_lock; + }; +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/src/boost/thread/win32/once.hpp b/3rdParty/Boost/src/boost/thread/win32/once.hpp new file mode 100644 index 0000000..a6fcc94 --- /dev/null +++ b/3rdParty/Boost/src/boost/thread/win32/once.hpp @@ -0,0 +1,136 @@ +#ifndef BOOST_THREAD_WIN32_ONCE_HPP +#define BOOST_THREAD_WIN32_ONCE_HPP + +// once.hpp +// +// (C) Copyright 2005-7 Anthony Williams +// (C) Copyright 2005 John Maddock +// +// 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 <cstring> +#include <cstddef> +#include <boost/assert.hpp> +#include <boost/static_assert.hpp> +#include <boost/detail/interlocked.hpp> +#include <boost/thread/win32/thread_primitives.hpp> +#include <boost/thread/win32/interlocked_read.hpp> + +#include <boost/config/abi_prefix.hpp> + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std +{ + using ::memcpy; + using ::ptrdiff_t; +} +#endif + +namespace boost +{ + typedef long once_flag; + +#define BOOST_ONCE_INIT 0 + + namespace detail + { + struct win32_mutex_scoped_lock + { + void* const mutex_handle; + explicit win32_mutex_scoped_lock(void* mutex_handle_): + mutex_handle(mutex_handle_) + { + BOOST_VERIFY(!win32::WaitForSingleObject(mutex_handle,win32::infinite)); + } + ~win32_mutex_scoped_lock() + { + BOOST_VERIFY(win32::ReleaseMutex(mutex_handle)!=0); + } + private: + void operator=(win32_mutex_scoped_lock&); + }; + +#ifdef BOOST_NO_ANSI_APIS + template <class I> + void int_to_string(I p, wchar_t* buf) + { + for(unsigned i=0; i < sizeof(I)*2; ++i,++buf) + { + *buf = L'A' + static_cast<wchar_t>((p >> (i*4)) & 0x0f); + } + *buf = 0; + } +#else + template <class I> + void int_to_string(I p, char* buf) + { + for(unsigned i=0; i < sizeof(I)*2; ++i,++buf) + { + *buf = 'A' + static_cast<char>((p >> (i*4)) & 0x0f); + } + *buf = 0; + } +#endif + + // create a named mutex. It doesn't really matter what this name is + // as long as it is unique both to this process, and to the address of "flag": + inline void* create_once_mutex(void* flag_address) + { + +#ifdef BOOST_NO_ANSI_APIS + typedef wchar_t char_type; + static const char_type fixed_mutex_name[]=L"{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag"; +#else + typedef char char_type; + static const char_type fixed_mutex_name[]="{C15730E2-145C-4c5e-B005-3BC753F42475}-once-flag"; +#endif + unsigned const once_mutex_name_fixed_buffer_size=sizeof(fixed_mutex_name)/sizeof(char_type); + unsigned const once_mutex_name_fixed_length=once_mutex_name_fixed_buffer_size-1; + unsigned const once_mutex_name_length=once_mutex_name_fixed_buffer_size+sizeof(void*)*2+sizeof(unsigned long)*2; + char_type mutex_name[once_mutex_name_length]; + + std::memcpy(mutex_name,fixed_mutex_name,sizeof(fixed_mutex_name)); + + BOOST_STATIC_ASSERT(sizeof(void*) == sizeof(std::ptrdiff_t)); + detail::int_to_string(reinterpret_cast<std::ptrdiff_t>(flag_address), mutex_name + once_mutex_name_fixed_length); + detail::int_to_string(win32::GetCurrentProcessId(), mutex_name + once_mutex_name_fixed_length + sizeof(void*)*2); + +#ifdef BOOST_NO_ANSI_APIS + return win32::CreateMutexW(0, 0, mutex_name); +#else + return win32::CreateMutexA(0, 0, mutex_name); +#endif + } + + + } + + + template<typename Function> + void call_once(once_flag& flag,Function f) + { + // Try for a quick win: if the procedure has already been called + // just skip through: + long const function_complete_flag_value=0xc15730e2; + + if(::boost::detail::interlocked_read_acquire(&flag)!=function_complete_flag_value) + { + void* const mutex_handle(::boost::detail::create_once_mutex(&flag)); + BOOST_ASSERT(mutex_handle); + detail::win32::handle_manager const closer(mutex_handle); + detail::win32_mutex_scoped_lock const lock(mutex_handle); + + if(flag!=function_complete_flag_value) + { + f(); + BOOST_INTERLOCKED_EXCHANGE(&flag,function_complete_flag_value); + } + } + } +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp new file mode 100644 index 0000000..2360a92 --- /dev/null +++ b/3rdParty/Boost/src/boost/thread/win32/recursive_mutex.hpp @@ -0,0 +1,64 @@ +#ifndef BOOST_RECURSIVE_MUTEX_WIN32_HPP +#define BOOST_RECURSIVE_MUTEX_WIN32_HPP + +// recursive_mutex.hpp +// +// (C) Copyright 2006-7 Anthony Williams +// +// 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/utility.hpp> +#include "basic_recursive_mutex.hpp" +#include <boost/thread/exceptions.hpp> +#include <boost/thread/locks.hpp> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + class recursive_mutex: + boost::noncopyable, + public ::boost::detail::basic_recursive_mutex + { + public: + recursive_mutex() + { + ::boost::detail::basic_recursive_mutex::initialize(); + } + ~recursive_mutex() + { + ::boost::detail::basic_recursive_mutex::destroy(); + } + + typedef unique_lock<recursive_mutex> scoped_lock; + typedef detail::try_lock_wrapper<recursive_mutex> scoped_try_lock; + }; + + typedef recursive_mutex recursive_try_mutex; + + class recursive_timed_mutex: + boost::noncopyable, + public ::boost::detail::basic_recursive_timed_mutex + { + public: + recursive_timed_mutex() + { + ::boost::detail::basic_recursive_timed_mutex::initialize(); + } + ~recursive_timed_mutex() + { + ::boost::detail::basic_recursive_timed_mutex::destroy(); + } + + typedef unique_lock<recursive_timed_mutex> scoped_timed_lock; + typedef detail::try_lock_wrapper<recursive_timed_mutex> scoped_try_lock; + typedef scoped_timed_lock scoped_lock; + }; +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp b/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp new file mode 100644 index 0000000..58e8093 --- /dev/null +++ b/3rdParty/Boost/src/boost/thread/win32/shared_mutex.hpp @@ -0,0 +1,566 @@ +#ifndef BOOST_THREAD_WIN32_SHARED_MUTEX_HPP +#define BOOST_THREAD_WIN32_SHARED_MUTEX_HPP + +// (C) Copyright 2006-8 Anthony Williams +// +// 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/assert.hpp> +#include <boost/detail/interlocked.hpp> +#include <boost/thread/win32/thread_primitives.hpp> +#include <boost/static_assert.hpp> +#include <limits.h> +#include <boost/utility.hpp> +#include <boost/thread/thread_time.hpp> + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + class shared_mutex: + private boost::noncopyable + { + private: + struct state_data + { + unsigned shared_count:11, + shared_waiting:11, + exclusive:1, + upgrade:1, + exclusive_waiting:7, + exclusive_waiting_blocked:1; + + friend bool operator==(state_data const& lhs,state_data const& rhs) + { + return *reinterpret_cast<unsigned const*>(&lhs)==*reinterpret_cast<unsigned const*>(&rhs); + } + }; + + + template<typename T> + T interlocked_compare_exchange(T* target,T new_value,T comparand) + { + BOOST_STATIC_ASSERT(sizeof(T)==sizeof(long)); + long const res=BOOST_INTERLOCKED_COMPARE_EXCHANGE(reinterpret_cast<long*>(target), + *reinterpret_cast<long*>(&new_value), + *reinterpret_cast<long*>(&comparand)); + return *reinterpret_cast<T const*>(&res); + } + + state_data state; + detail::win32::handle semaphores[2]; + detail::win32::handle &unlock_sem; + detail::win32::handle &exclusive_sem; + detail::win32::handle upgrade_sem; + + void release_waiters(state_data old_state) + { + if(old_state.exclusive_waiting) + { + BOOST_VERIFY(detail::win32::ReleaseSemaphore(exclusive_sem,1,0)!=0); + } + + if(old_state.shared_waiting || old_state.exclusive_waiting) + { + BOOST_VERIFY(detail::win32::ReleaseSemaphore(unlock_sem,old_state.shared_waiting + (old_state.exclusive_waiting?1:0),0)!=0); + } + } + + + public: + shared_mutex(): + unlock_sem(semaphores[0]), + exclusive_sem(semaphores[1]) + { + unlock_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX); + exclusive_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX); + upgrade_sem=detail::win32::create_anonymous_semaphore(0,LONG_MAX); + state_data state_={0}; + state=state_; + } + + ~shared_mutex() + { + detail::win32::CloseHandle(upgrade_sem); + detail::win32::CloseHandle(unlock_sem); + detail::win32::CloseHandle(exclusive_sem); + } + + bool try_lock_shared() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + if(!new_state.exclusive && !new_state.exclusive_waiting_blocked) + { + ++new_state.shared_count; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + return !(old_state.exclusive| old_state.exclusive_waiting_blocked); + } + + void lock_shared() + { + BOOST_VERIFY(timed_lock_shared(::boost::detail::get_system_time_sentinel())); + } + + template<typename TimeDuration> + bool timed_lock_shared(TimeDuration const & relative_time) + { + return timed_lock_shared(get_system_time()+relative_time); + } + + bool timed_lock_shared(boost::system_time const& wait_until) + { + for(;;) + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + if(new_state.exclusive || new_state.exclusive_waiting_blocked) + { + ++new_state.shared_waiting; + } + else + { + ++new_state.shared_count; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + + if(!(old_state.exclusive| old_state.exclusive_waiting_blocked)) + { + return true; + } + + unsigned long const res=detail::win32::WaitForSingleObject(unlock_sem,::boost::detail::get_milliseconds_until(wait_until)); + if(res==detail::win32::timeout) + { + for(;;) + { + state_data new_state=old_state; + if(new_state.exclusive || new_state.exclusive_waiting_blocked) + { + if(new_state.shared_waiting) + { + --new_state.shared_waiting; + } + } + else + { + ++new_state.shared_count; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + + if(!(old_state.exclusive| old_state.exclusive_waiting_blocked)) + { + return true; + } + return false; + } + + BOOST_ASSERT(res==0); + } + } + + void unlock_shared() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + bool const last_reader=!--new_state.shared_count; + + if(last_reader) + { + if(new_state.upgrade) + { + new_state.upgrade=false; + new_state.exclusive=true; + } + else + { + if(new_state.exclusive_waiting) + { + --new_state.exclusive_waiting; + new_state.exclusive_waiting_blocked=false; + } + new_state.shared_waiting=0; + } + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + if(last_reader) + { + if(old_state.upgrade) + { + BOOST_VERIFY(detail::win32::ReleaseSemaphore(upgrade_sem,1,0)!=0); + } + else + { + release_waiters(old_state); + } + } + break; + } + old_state=current_state; + } + } + + void lock() + { + BOOST_VERIFY(timed_lock(::boost::detail::get_system_time_sentinel())); + } + + template<typename TimeDuration> + bool timed_lock(TimeDuration const & relative_time) + { + return timed_lock(get_system_time()+relative_time); + } + + bool try_lock() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + if(new_state.shared_count || new_state.exclusive) + { + return false; + } + else + { + new_state.exclusive=true; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + return true; + } + + + bool timed_lock(boost::system_time const& wait_until) + { + for(;;) + { + state_data old_state=state; + + for(;;) + { + state_data new_state=old_state; + if(new_state.shared_count || new_state.exclusive) + { + ++new_state.exclusive_waiting; + new_state.exclusive_waiting_blocked=true; + } + else + { + new_state.exclusive=true; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + + if(!old_state.shared_count && !old_state.exclusive) + { + return true; + } + unsigned long const wait_res=detail::win32::WaitForMultipleObjects(2,semaphores,true,::boost::detail::get_milliseconds_until(wait_until)); + if(wait_res==detail::win32::timeout) + { + for(;;) + { + state_data new_state=old_state; + if(new_state.shared_count || new_state.exclusive) + { + if(new_state.exclusive_waiting) + { + if(!--new_state.exclusive_waiting) + { + new_state.exclusive_waiting_blocked=false; + } + } + } + else + { + new_state.exclusive=true; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + if(!old_state.shared_count && !old_state.exclusive) + { + return true; + } + return false; + } + BOOST_ASSERT(wait_res<2); + } + } + + void unlock() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + new_state.exclusive=false; + if(new_state.exclusive_waiting) + { + --new_state.exclusive_waiting; + new_state.exclusive_waiting_blocked=false; + } + new_state.shared_waiting=0; + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + release_waiters(old_state); + } + + void lock_upgrade() + { + for(;;) + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade) + { + ++new_state.shared_waiting; + } + else + { + ++new_state.shared_count; + new_state.upgrade=true; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + + if(!(old_state.exclusive|| old_state.exclusive_waiting_blocked|| old_state.upgrade)) + { + return; + } + + BOOST_VERIFY(!detail::win32::WaitForSingleObject(unlock_sem,detail::win32::infinite)); + } + } + + bool try_lock_upgrade() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + if(new_state.exclusive || new_state.exclusive_waiting_blocked || new_state.upgrade) + { + return false; + } + else + { + ++new_state.shared_count; + new_state.upgrade=true; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + return true; + } + + void unlock_upgrade() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + new_state.upgrade=false; + bool const last_reader=!--new_state.shared_count; + + if(last_reader) + { + if(new_state.exclusive_waiting) + { + --new_state.exclusive_waiting; + new_state.exclusive_waiting_blocked=false; + } + new_state.shared_waiting=0; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + if(last_reader) + { + release_waiters(old_state); + } + break; + } + old_state=current_state; + } + } + + void unlock_upgrade_and_lock() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + bool const last_reader=!--new_state.shared_count; + + if(last_reader) + { + new_state.upgrade=false; + new_state.exclusive=true; + } + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + if(!last_reader) + { + BOOST_VERIFY(!detail::win32::WaitForSingleObject(upgrade_sem,detail::win32::infinite)); + } + break; + } + old_state=current_state; + } + } + + void unlock_and_lock_upgrade() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + new_state.exclusive=false; + new_state.upgrade=true; + ++new_state.shared_count; + if(new_state.exclusive_waiting) + { + --new_state.exclusive_waiting; + new_state.exclusive_waiting_blocked=false; + } + new_state.shared_waiting=0; + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + release_waiters(old_state); + } + + void unlock_and_lock_shared() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + new_state.exclusive=false; + ++new_state.shared_count; + if(new_state.exclusive_waiting) + { + --new_state.exclusive_waiting; + new_state.exclusive_waiting_blocked=false; + } + new_state.shared_waiting=0; + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + release_waiters(old_state); + } + + void unlock_upgrade_and_lock_shared() + { + state_data old_state=state; + for(;;) + { + state_data new_state=old_state; + new_state.upgrade=false; + if(new_state.exclusive_waiting) + { + --new_state.exclusive_waiting; + new_state.exclusive_waiting_blocked=false; + } + new_state.shared_waiting=0; + + state_data const current_state=interlocked_compare_exchange(&state,new_state,old_state); + if(current_state==old_state) + { + break; + } + old_state=current_state; + } + release_waiters(old_state); + } + + }; +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp new file mode 100644 index 0000000..1a6a1e0 --- /dev/null +++ b/3rdParty/Boost/src/boost/thread/win32/thread_data.hpp @@ -0,0 +1,178 @@ +#ifndef BOOST_THREAD_PTHREAD_THREAD_DATA_HPP +#define BOOST_THREAD_PTHREAD_THREAD_DATA_HPP +// 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) +// (C) Copyright 2008 Anthony Williams + +#include <boost/thread/detail/config.hpp> +#include <boost/intrusive_ptr.hpp> +#include <boost/thread/thread_time.hpp> +#include "thread_primitives.hpp" +#include "thread_heap_alloc.hpp" + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + namespace detail + { + struct thread_exit_callback_node; + struct tss_data_node; + + struct thread_data_base; + void intrusive_ptr_add_ref(thread_data_base * p); + void intrusive_ptr_release(thread_data_base * p); + + struct thread_data_base + { + long count; + detail::win32::handle_manager thread_handle; + detail::win32::handle_manager interruption_handle; + boost::detail::thread_exit_callback_node* thread_exit_callbacks; + boost::detail::tss_data_node* tss_data; + bool interruption_enabled; + unsigned id; + + thread_data_base(): + count(0),thread_handle(detail::win32::invalid_handle_value), + interruption_handle(create_anonymous_event(detail::win32::manual_reset_event,detail::win32::event_initially_reset)), + thread_exit_callbacks(0),tss_data(0), + interruption_enabled(true), + id(0) + {} + virtual ~thread_data_base() + {} + + friend void intrusive_ptr_add_ref(thread_data_base * p) + { + BOOST_INTERLOCKED_INCREMENT(&p->count); + } + + friend void intrusive_ptr_release(thread_data_base * p) + { + if(!BOOST_INTERLOCKED_DECREMENT(&p->count)) + { + detail::heap_delete(p); + } + } + + void interrupt() + { + BOOST_VERIFY(detail::win32::SetEvent(interruption_handle)!=0); + } + + typedef detail::win32::handle native_handle_type; + + virtual void run()=0; + }; + + typedef boost::intrusive_ptr<detail::thread_data_base> thread_data_ptr; + + struct timeout + { + unsigned long start; + uintmax_t milliseconds; + bool relative; + boost::system_time abs_time; + + static unsigned long const max_non_infinite_wait=0xfffffffe; + + timeout(uintmax_t milliseconds_): + start(win32::GetTickCount()), + milliseconds(milliseconds_), + relative(true), + abs_time(boost::get_system_time()) + {} + + timeout(boost::system_time const& abs_time_): + start(win32::GetTickCount()), + milliseconds(0), + relative(false), + abs_time(abs_time_) + {} + + struct remaining_time + { + bool more; + unsigned long milliseconds; + + remaining_time(uintmax_t remaining): + more(remaining>max_non_infinite_wait), + milliseconds(more?max_non_infinite_wait:(unsigned long)remaining) + {} + }; + + remaining_time remaining_milliseconds() const + { + if(is_sentinel()) + { + return remaining_time(win32::infinite); + } + else if(relative) + { + unsigned long const now=win32::GetTickCount(); + unsigned long const elapsed=now-start; + return remaining_time((elapsed<milliseconds)?(milliseconds-elapsed):0); + } + else + { + system_time const now=get_system_time(); + if(abs_time<=now) + { + return remaining_time(0); + } + return remaining_time((abs_time-now).total_milliseconds()+1); + } + } + + bool is_sentinel() const + { + return milliseconds==~uintmax_t(0); + } + + + static timeout sentinel() + { + return timeout(sentinel_type()); + } + private: + struct sentinel_type + {}; + + explicit timeout(sentinel_type): + start(0),milliseconds(~uintmax_t(0)),relative(true) + {} + }; + } + + namespace this_thread + { + void BOOST_THREAD_DECL yield(); + + bool BOOST_THREAD_DECL interruptible_wait(detail::win32::handle handle_to_wait_for,detail::timeout target_time); + inline void interruptible_wait(unsigned long milliseconds) + { + interruptible_wait(detail::win32::invalid_handle_value,milliseconds); + } + inline void interruptible_wait(system_time const& abs_time) + { + interruptible_wait(detail::win32::invalid_handle_value,abs_time); + } + + template<typename TimeDuration> + inline void sleep(TimeDuration const& rel_time) + { + interruptible_wait(static_cast<unsigned long>(rel_time.total_milliseconds())); + } + inline void sleep(system_time const& abs_time) + { + interruptible_wait(abs_time); + } + } + +} + +#include <boost/config/abi_suffix.hpp> + +#endif diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp new file mode 100644 index 0000000..9f8186f --- /dev/null +++ b/3rdParty/Boost/src/boost/thread/win32/thread_heap_alloc.hpp @@ -0,0 +1,397 @@ +// 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) +// (C) Copyright 2007 Anthony Williams +#ifndef THREAD_HEAP_ALLOC_HPP +#define THREAD_HEAP_ALLOC_HPP +#include <new> +#include "thread_primitives.hpp" +#include <stdexcept> +#include <boost/assert.hpp> + +#if defined( BOOST_USE_WINDOWS_H ) +# include <windows.h> + +namespace boost +{ + namespace detail + { + namespace win32 + { + using ::GetProcessHeap; + using ::HeapAlloc; + using ::HeapFree; + } + } +} + +#else + +# ifdef HeapAlloc +# undef HeapAlloc +# endif + +namespace boost +{ + namespace detail + { + namespace win32 + { + extern "C" + { + __declspec(dllimport) handle __stdcall GetProcessHeap(); + __declspec(dllimport) void* __stdcall HeapAlloc(handle,unsigned long,ulong_ptr); + __declspec(dllimport) int __stdcall HeapFree(handle,unsigned long,void*); + } + } + } +} + +#endif + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + namespace detail + { + inline BOOST_THREAD_DECL void* allocate_raw_heap_memory(unsigned size) + { + void* const heap_memory=detail::win32::HeapAlloc(detail::win32::GetProcessHeap(),0,size); + if(!heap_memory) + { + throw std::bad_alloc(); + } + return heap_memory; + } + + inline BOOST_THREAD_DECL void free_raw_heap_memory(void* heap_memory) + { + BOOST_VERIFY(detail::win32::HeapFree(detail::win32::GetProcessHeap(),0,heap_memory)!=0); + } + + template<typename T> + inline T* heap_new() + { + void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); + try + { + T* const data=new (heap_memory) T(); + return data; + } + catch(...) + { + free_raw_heap_memory(heap_memory); + throw; + } + } + +#ifdef BOOST_HAS_RVALUE_REFS + template<typename T,typename A1> + inline T* heap_new(A1&& a1) + { + void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); + try + { + T* const data=new (heap_memory) T(static_cast<A1&&>(a1)); + return data; + } + catch(...) + { + free_raw_heap_memory(heap_memory); + throw; + } + } + template<typename T,typename A1,typename A2> + inline T* heap_new(A1&& a1,A2&& a2) + { + void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); + try + { + T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2)); + return data; + } + catch(...) + { + free_raw_heap_memory(heap_memory); + throw; + } + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1&& a1,A2&& a2,A3&& a3) + { + void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); + try + { + T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2), + static_cast<A3&&>(a3)); + return data; + } + catch(...) + { + free_raw_heap_memory(heap_memory); + throw; + } + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1&& a1,A2&& a2,A3&& a3,A4&& a4) + { + void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); + try + { + T* const data=new (heap_memory) T(static_cast<A1&&>(a1),static_cast<A2&&>(a2), + static_cast<A3&&>(a3),static_cast<A4&&>(a4)); + return data; + } + catch(...) + { + free_raw_heap_memory(heap_memory); + throw; + } + } +#else + template<typename T,typename A1> + inline T* heap_new_impl(A1 a1) + { + void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); + try + { + T* const data=new (heap_memory) T(a1); + return data; + } + catch(...) + { + free_raw_heap_memory(heap_memory); + throw; + } + } + + template<typename T,typename A1,typename A2> + inline T* heap_new_impl(A1 a1,A2 a2) + { + void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); + try + { + T* const data=new (heap_memory) T(a1,a2); + return data; + } + catch(...) + { + free_raw_heap_memory(heap_memory); + throw; + } + } + + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new_impl(A1 a1,A2 a2,A3 a3) + { + void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); + try + { + T* const data=new (heap_memory) T(a1,a2,a3); + return data; + } + catch(...) + { + free_raw_heap_memory(heap_memory); + throw; + } + } + + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new_impl(A1 a1,A2 a2,A3 a3,A4 a4) + { + void* const heap_memory=allocate_raw_heap_memory(sizeof(T)); + try + { + T* const data=new (heap_memory) T(a1,a2,a3,a4); + return data; + } + catch(...) + { + free_raw_heap_memory(heap_memory); + throw; + } + } + + + template<typename T,typename A1> + inline T* heap_new(A1 const& a1) + { + return heap_new_impl<T,A1 const&>(a1); + } + template<typename T,typename A1> + inline T* heap_new(A1& a1) + { + return heap_new_impl<T,A1&>(a1); + } + + template<typename T,typename A1,typename A2> + inline T* heap_new(A1 const& a1,A2 const& a2) + { + return heap_new_impl<T,A1 const&,A2 const&>(a1,a2); + } + template<typename T,typename A1,typename A2> + inline T* heap_new(A1& a1,A2 const& a2) + { + return heap_new_impl<T,A1&,A2 const&>(a1,a2); + } + template<typename T,typename A1,typename A2> + inline T* heap_new(A1 const& a1,A2& a2) + { + return heap_new_impl<T,A1 const&,A2&>(a1,a2); + } + template<typename T,typename A1,typename A2> + inline T* heap_new(A1& a1,A2& a2) + { + return heap_new_impl<T,A1&,A2&>(a1,a2); + } + + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3) + { + return heap_new_impl<T,A1 const&,A2 const&,A3 const&>(a1,a2,a3); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3) + { + return heap_new_impl<T,A1&,A2 const&,A3 const&>(a1,a2,a3); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3) + { + return heap_new_impl<T,A1 const&,A2&,A3 const&>(a1,a2,a3); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1& a1,A2& a2,A3 const& a3) + { + return heap_new_impl<T,A1&,A2&,A3 const&>(a1,a2,a3); + } + + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3) + { + return heap_new_impl<T,A1 const&,A2 const&,A3&>(a1,a2,a3); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1& a1,A2 const& a2,A3& a3) + { + return heap_new_impl<T,A1&,A2 const&,A3&>(a1,a2,a3); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1 const& a1,A2& a2,A3& a3) + { + return heap_new_impl<T,A1 const&,A2&,A3&>(a1,a2,a3); + } + template<typename T,typename A1,typename A2,typename A3> + inline T* heap_new(A1& a1,A2& a2,A3& a3) + { + return heap_new_impl<T,A1&,A2&,A3&>(a1,a2,a3); + } + + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4 const& a4) + { + return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4 const& a4) + { + return heap_new_impl<T,A1&,A2 const&,A3 const&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4 const& a4) + { + return heap_new_impl<T,A1 const&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4 const& a4) + { + return heap_new_impl<T,A1&,A2&,A3 const&,A4 const&>(a1,a2,a3,a4); + } + + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4 const& a4) + { + return heap_new_impl<T,A1 const&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4 const& a4) + { + return heap_new_impl<T,A1&,A2 const&,A3&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4 const& a4) + { + return heap_new_impl<T,A1 const&,A2&,A3&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2& a2,A3& a3,A4 const& a4) + { + return heap_new_impl<T,A1&,A2&,A3&,A4 const&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2 const& a2,A3 const& a3,A4& a4) + { + return heap_new_impl<T,A1 const&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2 const& a2,A3 const& a3,A4& a4) + { + return heap_new_impl<T,A1&,A2 const&,A3 const&,A4&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2& a2,A3 const& a3,A4& a4) + { + return heap_new_impl<T,A1 const&,A2&,A3 const&,A4&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2& a2,A3 const& a3,A4& a4) + { + return heap_new_impl<T,A1&,A2&,A3 const&,A4&>(a1,a2,a3,a4); + } + + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2 const& a2,A3& a3,A4& a4) + { + return heap_new_impl<T,A1 const&,A2 const&,A3&,A4&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2 const& a2,A3& a3,A4& a4) + { + return heap_new_impl<T,A1&,A2 const&,A3&,A4&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1 const& a1,A2& a2,A3& a3,A4& a4) + { + return heap_new_impl<T,A1 const&,A2&,A3&,A4&>(a1,a2,a3,a4); + } + template<typename T,typename A1,typename A2,typename A3,typename A4> + inline T* heap_new(A1& a1,A2& a2,A3& a3,A4& a4) + { + return heap_new_impl<T,A1&,A2&,A3&,A4&>(a1,a2,a3,a4); + } + +#endif + template<typename T> + inline void heap_delete(T* data) + { + data->~T(); + free_raw_heap_memory(data); + } + + template<typename T> + struct do_heap_delete + { + void operator()(T* data) const + { + detail::heap_delete(data); + } + }; + } +} + +#include <boost/config/abi_suffix.hpp> + + +#endif diff --git a/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp b/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp new file mode 100644 index 0000000..67a1bc3 --- /dev/null +++ b/3rdParty/Boost/src/boost/thread/win32/thread_primitives.hpp @@ -0,0 +1,398 @@ +#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/config.hpp> +#include <boost/assert.hpp> +#include <boost/thread/exceptions.hpp> +#include <boost/detail/interlocked.hpp> +#include <algorithm> + +#if defined( BOOST_USE_WINDOWS_H ) +# include <windows.h> + +namespace boost +{ + namespace detail + { + namespace win32 + { + typedef ULONG_PTR ulong_ptr; + typedef HANDLE handle; + unsigned const infinite=INFINITE; + unsigned const timeout=WAIT_TIMEOUT; + handle const invalid_handle_value=INVALID_HANDLE_VALUE; + +# ifdef BOOST_NO_ANSI_APIS + using ::CreateMutexW; + using ::CreateEventW; + using ::CreateSemaphoreW; +# else + using ::CreateMutexA; + using ::CreateEventA; + using ::CreateSemaphoreA; +# endif + using ::CloseHandle; + using ::ReleaseMutex; + using ::ReleaseSemaphore; + using ::SetEvent; + using ::ResetEvent; + using ::WaitForMultipleObjects; + using ::WaitForSingleObject; + using ::GetCurrentProcessId; + using ::GetCurrentThreadId; + using ::GetCurrentThread; + using ::GetCurrentProcess; + using ::DuplicateHandle; + using ::SleepEx; + using ::Sleep; + using ::QueueUserAPC; + using ::GetTickCount; + } + } +} +#elif defined( WIN32 ) || defined( _WIN32 ) || defined( __WIN32__ ) + +# ifdef UNDER_CE +# ifndef WINAPI +# ifndef _WIN32_WCE_EMULATION +# define WINAPI __cdecl // Note this doesn't match the desktop definition +# else +# define WINAPI __stdcall +# endif +# endif + +# ifdef __cplusplus +extern "C" { +# endif +typedef int BOOL; +typedef unsigned long DWORD; +typedef void* HANDLE; + +# include <kfuncs.h> +# ifdef __cplusplus +} +# endif +# endif + +namespace boost +{ + namespace detail + { + namespace win32 + { + +# ifdef _WIN64 + typedef unsigned __int64 ulong_ptr; +# else + typedef unsigned long ulong_ptr; +# endif + typedef void* handle; + unsigned const infinite=~0U; + unsigned const timeout=258U; + handle const invalid_handle_value=(handle)(-1); + + extern "C" + { + struct _SECURITY_ATTRIBUTES; +# ifdef BOOST_NO_ANSI_APIS + __declspec(dllimport) void* __stdcall CreateMutexW(_SECURITY_ATTRIBUTES*,int,wchar_t const*); + __declspec(dllimport) void* __stdcall CreateSemaphoreW(_SECURITY_ATTRIBUTES*,long,long,wchar_t const*); + __declspec(dllimport) void* __stdcall CreateEventW(_SECURITY_ATTRIBUTES*,int,int,wchar_t const*); +# else + __declspec(dllimport) void* __stdcall CreateMutexA(_SECURITY_ATTRIBUTES*,int,char const*); + __declspec(dllimport) void* __stdcall CreateSemaphoreA(_SECURITY_ATTRIBUTES*,long,long,char const*); + __declspec(dllimport) void* __stdcall CreateEventA(_SECURITY_ATTRIBUTES*,int,int,char const*); +# endif + __declspec(dllimport) int __stdcall CloseHandle(void*); + __declspec(dllimport) int __stdcall ReleaseMutex(void*); + __declspec(dllimport) unsigned long __stdcall WaitForSingleObject(void*,unsigned long); + __declspec(dllimport) unsigned long __stdcall WaitForMultipleObjects(unsigned long nCount,void* const * lpHandles,int bWaitAll,unsigned long dwMilliseconds); + __declspec(dllimport) int __stdcall ReleaseSemaphore(void*,long,long*); + __declspec(dllimport) int __stdcall DuplicateHandle(void*,void*,void*,void**,unsigned long,int,unsigned long); + __declspec(dllimport) unsigned long __stdcall SleepEx(unsigned long,int); + __declspec(dllimport) void __stdcall Sleep(unsigned long); + typedef void (__stdcall *queue_user_apc_callback_function)(ulong_ptr); + __declspec(dllimport) unsigned long __stdcall QueueUserAPC(queue_user_apc_callback_function,void*,ulong_ptr); + + __declspec(dllimport) unsigned long __stdcall GetTickCount(); + +# ifndef UNDER_CE + __declspec(dllimport) unsigned long __stdcall GetCurrentProcessId(); + __declspec(dllimport) unsigned long __stdcall GetCurrentThreadId(); + __declspec(dllimport) void* __stdcall GetCurrentThread(); + __declspec(dllimport) void* __stdcall GetCurrentProcess(); + __declspec(dllimport) int __stdcall SetEvent(void*); + __declspec(dllimport) int __stdcall ResetEvent(void*); +# else + using ::GetCurrentProcessId; + using ::GetCurrentThreadId; + using ::GetCurrentThread; + using ::GetCurrentProcess; + using ::SetEvent; + using ::ResetEvent; +# endif + } + } + } +} +#else +# error "Win32 functions not available" +#endif + +#include <boost/config/abi_prefix.hpp> + +namespace boost +{ + namespace detail + { + namespace win32 + { + 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_anonymous_event(event_type type,initial_event_state state) + { +#if !defined(BOOST_NO_ANSI_APIS) + handle const res=win32::CreateEventA(0,type,state,0); +#else + handle const res=win32::CreateEventW(0,type,state,0); +#endif + if(!res) + { + throw thread_resource_error(); + } + return res; + } + + inline handle create_anonymous_semaphore(long initial_count,long max_count) + { +#if !defined(BOOST_NO_ANSI_APIS) + handle const res=CreateSemaphoreA(0,initial_count,max_count,0); +#else + handle const res=CreateSemaphoreW(0,initial_count,max_count,0); +#endif + if(!res) + { + throw thread_resource_error(); + } + return res; + } + + inline handle duplicate_handle(handle source) + { + handle const current_process=GetCurrentProcess(); + long const same_access_flag=2; + handle new_handle=0; + bool const success=DuplicateHandle(current_process,source,current_process,&new_handle,0,false,same_access_flag)!=0; + if(!success) + { + throw thread_resource_error(); + } + return new_handle; + } + + inline void release_semaphore(handle semaphore,long count) + { + BOOST_VERIFY(ReleaseSemaphore(semaphore,count,0)!=0); + } + + class 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(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) + { + __asm { + mov eax,bit; + mov edx,x; + lock bts [edx],eax; + setc al; + }; + } + + inline bool interlocked_bit_test_and_reset(long* x,long bit) + { + __asm { + mov eax,bit; + mov edx,x; + lock btr [edx],eax; + setc al; + }; + } + + } + } +} +#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 |