diff options
author | Remko Tronçon <git@el-tramo.be> | 2012-12-23 13:16:26 (GMT) |
---|---|---|
committer | Remko Tronçon <git@el-tramo.be> | 2012-12-23 14:43:26 (GMT) |
commit | 491ddd570a752cf9bda85933bed0c6942e39b1f9 (patch) | |
tree | 10c25c1be8cc08d0497df1dccd56a10fbb30beee /3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp | |
parent | da7d7a0ca71b80281aa9ff2526290b61ccb0cc60 (diff) | |
download | swift-491ddd570a752cf9bda85933bed0c6942e39b1f9.zip swift-491ddd570a752cf9bda85933bed0c6942e39b1f9.tar.bz2 |
Update Boost to 1.52.0.
Change-Id: I1e56bea2600bf2ed9c5b3aba8c4f9d2a0f350e77
Diffstat (limited to '3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp')
-rw-r--r-- | 3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp | 139 |
1 files changed, 127 insertions, 12 deletions
diff --git a/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp b/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp index 1bee28b..db4e09f 100644 --- a/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp +++ b/3rdParty/Boost/src/boost/thread/pthread/thread_data.hpp @@ -4,24 +4,77 @@ // accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) // (C) Copyright 2007 Anthony Williams +// (C) Copyright 2011-2012 Vicente J. Botet Escriba #include <boost/thread/detail/config.hpp> #include <boost/thread/exceptions.hpp> +#include <boost/thread/locks.hpp> +#include <boost/thread/mutex.hpp> +#include <boost/thread/pthread/condition_variable_fwd.hpp> + #include <boost/shared_ptr.hpp> #include <boost/enable_shared_from_this.hpp> -#include <boost/thread/mutex.hpp> #include <boost/optional.hpp> -#include <pthread.h> #include <boost/assert.hpp> -#include "condition_variable_fwd.hpp" +#ifdef BOOST_THREAD_USES_CHRONO +#include <boost/chrono/system_clocks.hpp> +#endif + #include <map> +#include <vector> +#include <utility> + +#include <pthread.h> +#include <unistd.h> #include <boost/config/abi_prefix.hpp> namespace boost { + class thread_attributes { + public: + thread_attributes() BOOST_NOEXCEPT { + int res = pthread_attr_init(&val_); + BOOST_VERIFY(!res && "pthread_attr_init failed"); + } + ~thread_attributes() { + int res = pthread_attr_destroy(&val_); + BOOST_VERIFY(!res && "pthread_attr_destroy failed"); + } + // stack + void set_stack_size(std::size_t size) BOOST_NOEXCEPT { + if (size==0) return; + std::size_t page_size = getpagesize(); +#ifdef PTHREAD_STACK_MIN + if (size<PTHREAD_STACK_MIN) size=PTHREAD_STACK_MIN; +#endif + size = ((size+page_size-1)/page_size)*page_size; + int res = pthread_attr_setstacksize(&val_, size); + BOOST_VERIFY(!res && "pthread_attr_setstacksize failed"); + } + + std::size_t get_stack_size() const BOOST_NOEXCEPT { + std::size_t size; + int res = pthread_attr_getstacksize(&val_, &size); + BOOST_VERIFY(!res && "pthread_attr_getstacksize failed"); + return size; + } +#define BOOST_THREAD_DEFINES_THREAD_ATTRIBUTES_NATIVE_HANDLE + + typedef pthread_attr_t native_handle_type; + native_handle_type* native_handle() BOOST_NOEXCEPT { + return &val_; + } + const native_handle_type* native_handle() const BOOST_NOEXCEPT { + return &val_; + } + + private: + pthread_attr_t val_; + }; + class thread; - + namespace detail { struct tss_cleanup_function; @@ -39,7 +92,7 @@ namespace boost struct thread_data_base; typedef boost::shared_ptr<thread_data_base> thread_data_ptr; - + struct BOOST_THREAD_DECL thread_data_base: enable_shared_from_this<thread_data_base> { @@ -58,19 +111,28 @@ namespace boost bool interrupt_requested; pthread_mutex_t* cond_mutex; pthread_cond_t* current_cond; + typedef std::vector<std::pair<condition_variable*, mutex*> + //, hidden_allocator<std::pair<condition_variable*, mutex*> > + > notify_list_t; + notify_list_t notify; thread_data_base(): done(false),join_started(false),joined(false), thread_exit_callbacks(0), interrupt_enabled(true), interrupt_requested(false), - current_cond(0) + current_cond(0), + notify() {} virtual ~thread_data_base(); typedef pthread_t native_handle_type; virtual void run()=0; + void notify_all_at_thread_exit(condition_variable* cv, mutex* m) + { + notify.push_back(std::pair<condition_variable*, mutex*>(cv, m)); + } }; BOOST_THREAD_DECL thread_data_base* get_current_thread_data(); @@ -83,13 +145,15 @@ namespace boost void check_for_interruption() { +#ifndef BOOST_NO_EXCEPTIONS if(thread_info->interrupt_requested) { thread_info->interrupt_requested=false; - throw thread_interrupted(); + throw thread_interrupted(); // BOOST_NO_EXCEPTIONS protected } +#endif } - + void operator=(interruption_checker&); public: explicit interruption_checker(pthread_mutex_t* cond_mutex,pthread_cond_t* cond): @@ -128,15 +192,66 @@ namespace boost namespace this_thread { - void BOOST_THREAD_DECL yield(); - - void BOOST_THREAD_DECL sleep(system_time const& abs_time); - +#ifdef BOOST_THREAD_USES_CHRONO + inline + void BOOST_SYMBOL_VISIBLE sleep_for(const chrono::nanoseconds& ns) + { + using namespace chrono; + boost::detail::thread_data_base* const thread_info=boost::detail::get_current_thread_data(); + + if(thread_info) + { + unique_lock<mutex> lk(thread_info->sleep_mutex); + while(cv_status::no_timeout==thread_info->sleep_condition.wait_for(lk,ns)) {} + } + else + { + if (ns >= nanoseconds::zero()) + { + + # if defined(BOOST_HAS_PTHREAD_DELAY_NP) + timespec ts; + ts.tv_sec = static_cast<long>(duration_cast<seconds>(ns).count()); + ts.tv_nsec = static_cast<long>((ns - seconds(ts.tv_sec)).count()); + BOOST_VERIFY(!pthread_delay_np(&ts)); + # elif defined(BOOST_HAS_NANOSLEEP) + timespec ts; + ts.tv_sec = static_cast<long>(duration_cast<seconds>(ns).count()); + ts.tv_nsec = static_cast<long>((ns - seconds(ts.tv_sec)).count()); + // nanosleep takes a timespec that is an offset, not + // an absolute time. + nanosleep(&ts, 0); + # else + mutex mx; + mutex::scoped_lock lock(mx); + condition_variable cond; + cond.wait_for(lock, ns); + # endif + } + } + } +#endif + void BOOST_THREAD_DECL yield() BOOST_NOEXCEPT; + +#ifdef __DECXXX + /// Workaround of DECCXX issue of incorrect template substitution template<typename TimeDuration> inline void sleep(TimeDuration const& rel_time) { this_thread::sleep(get_system_time()+rel_time); } + + template<> + void BOOST_THREAD_DECL sleep(system_time const& abs_time); +#else + void BOOST_THREAD_DECL sleep(system_time const& abs_time); + + template<typename TimeDuration> + inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time) + { + this_thread::sleep(get_system_time()+rel_time); + } +#endif } } |