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/libs/thread/src/pthread | |
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/libs/thread/src/pthread')
-rw-r--r-- | 3rdParty/Boost/src/libs/thread/src/pthread/once.cpp | 51 | ||||
-rw-r--r-- | 3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp | 232 | ||||
-rw-r--r-- | 3rdParty/Boost/src/libs/thread/src/pthread/timeconv.inl | 17 |
3 files changed, 216 insertions, 84 deletions
diff --git a/3rdParty/Boost/src/libs/thread/src/pthread/once.cpp b/3rdParty/Boost/src/libs/thread/src/pthread/once.cpp index 6e3722a..d5fd656 100644 --- a/3rdParty/Boost/src/libs/thread/src/pthread/once.cpp +++ b/3rdParty/Boost/src/libs/thread/src/pthread/once.cpp @@ -1,6 +1,6 @@ // Copyright (C) 2007 Anthony Williams // -// Distributed under the Boost Software License, Version 1.0. (See accompanying +// 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) #define __STDC_CONSTANT_MACROS @@ -8,12 +8,13 @@ #include <boost/assert.hpp> #include <pthread.h> #include <stdlib.h> +#include <memory> namespace boost { namespace detail { - BOOST_THREAD_DECL boost::uintmax_t once_global_epoch=UINTMAX_C(~0); + BOOST_THREAD_DECL thread_detail::uintmax_atomic_t once_global_epoch=BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C; BOOST_THREAD_DECL pthread_mutex_t once_epoch_mutex=PTHREAD_MUTEX_INITIALIZER; BOOST_THREAD_DECL pthread_cond_t once_epoch_cv = PTHREAD_COND_INITIALIZER; @@ -21,31 +22,51 @@ namespace boost { pthread_key_t epoch_tss_key; pthread_once_t epoch_tss_key_flag=PTHREAD_ONCE_INIT; - - extern "C" void delete_epoch_tss_data(void* data) + + extern "C" { - free(data); + static void delete_epoch_tss_data(void* data) + { + free(data); + } + + static void create_epoch_tss_key() + { + BOOST_VERIFY(!pthread_key_create(&epoch_tss_key,delete_epoch_tss_data)); + } } - extern "C" void create_epoch_tss_key() +#if defined BOOST_THREAD_PATCH + const pthread_once_t pthread_once_init_value=PTHREAD_ONCE_INIT; + struct BOOST_THREAD_DECL delete_epoch_tss_key_on_dlclose_t { - BOOST_VERIFY(!pthread_key_create(&epoch_tss_key,delete_epoch_tss_data)); - } - + delete_epoch_tss_key_on_dlclose_t() + { + } + ~delete_epoch_tss_key_on_dlclose_t() + { + if(memcmp(&epoch_tss_key_flag, &pthread_once_init_value, sizeof(pthread_once_t))) + { + pthread_key_delete(epoch_tss_key); + } + } + }; + delete_epoch_tss_key_on_dlclose_t delete_epoch_tss_key_on_dlclose; +#endif } - - boost::uintmax_t& get_once_per_thread_epoch() + + thread_detail::uintmax_atomic_t& get_once_per_thread_epoch() { BOOST_VERIFY(!pthread_once(&epoch_tss_key_flag,create_epoch_tss_key)); void* data=pthread_getspecific(epoch_tss_key); if(!data) { - data=malloc(sizeof(boost::uintmax_t)); + data=malloc(sizeof(thread_detail::uintmax_atomic_t)); BOOST_VERIFY(!pthread_setspecific(epoch_tss_key,data)); - *static_cast<boost::uintmax_t*>(data)=UINTMAX_C(~0); + *static_cast<thread_detail::uintmax_atomic_t*>(data)=BOOST_THREAD_DETAIL_UINTMAX_ATOMIC_MAX_C; } - return *static_cast<boost::uintmax_t*>(data); + return *static_cast<thread_detail::uintmax_atomic_t*>(data); } } - + } diff --git a/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp b/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp index 187c024..c83eac1 100644 --- a/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp +++ b/3rdParty/Boost/src/libs/thread/src/pthread/thread.cpp @@ -1,20 +1,22 @@ // Copyright (C) 2001-2003 // William E. Kempf // Copyright (C) 2007-8 Anthony Williams +// (C) Copyright 2011 Vicente J. Botet Escriba // -// Distributed under the Boost Software License, Version 1.0. (See accompanying +// 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/thread/thread.hpp> #include <boost/thread/xtime.hpp> -#include <boost/thread/condition.hpp> +#include <boost/thread/condition_variable.hpp> #include <boost/thread/locks.hpp> #include <boost/thread/once.hpp> #include <boost/thread/tss.hpp> #include <boost/throw_exception.hpp> -#ifdef __linux__ + +#ifdef __GLIBC__ #include <sys/sysinfo.h> #elif defined(__APPLE__) || defined(__FreeBSD__) #include <sys/types.h> @@ -23,14 +25,25 @@ #include <unistd.h> #endif -#include "timeconv.inl" +#include "./timeconv.inl" + +#pragma GCC diagnostic ignored "-Wreturn-type" namespace boost { namespace detail { thread_data_base::~thread_data_base() - {} + { + { + for (notify_list_t::iterator i = notify.begin(), e = notify.end(); + i != e; ++i) + { + i->second->unlock(); + i->first->notify_all(); + } + } + } struct thread_exit_callback_node { @@ -45,12 +58,16 @@ namespace boost namespace { +#ifdef BOOST_THREAD_PROVIDES_ONCE_CXX11 + boost::once_flag current_thread_tls_init_flag; +#else boost::once_flag current_thread_tls_init_flag=BOOST_ONCE_INIT; +#endif pthread_key_t current_thread_tls_key; extern "C" { - void tls_destructor(void* data) + static void tls_destructor(void* data) { boost::detail::thread_data_base* thread_info=static_cast<boost::detail::thread_data_base*>(data); if(thread_info) @@ -86,14 +103,31 @@ namespace boost } } } - + +#if defined BOOST_THREAD_PATCH + + struct delete_current_thread_tls_key_on_dlclose_t + { + delete_current_thread_tls_key_on_dlclose_t() + { + } + ~delete_current_thread_tls_key_on_dlclose_t() + { + if (current_thread_tls_init_flag.epoch!=BOOST_ONCE_INITIAL_FLAG_VALUE) + { + pthread_key_delete(current_thread_tls_key); + } + } + }; + delete_current_thread_tls_key_on_dlclose_t delete_current_thread_tls_key_on_dlclose; +#endif void create_current_thread_tls_key() { BOOST_VERIFY(!pthread_key_create(¤t_thread_tls_key,&tls_destructor)); } } - + boost::detail::thread_data_base* get_current_thread_data() { boost::call_once(current_thread_tls_init_flag,create_current_thread_tls_key); @@ -106,26 +140,27 @@ namespace boost BOOST_VERIFY(!pthread_setspecific(current_thread_tls_key,new_data)); } } - + namespace { extern "C" { - void* thread_proxy(void* param) + static void* thread_proxy(void* param) { boost::detail::thread_data_ptr thread_info = static_cast<boost::detail::thread_data_base*>(param)->self; thread_info->self.reset(); detail::set_current_thread_data(thread_info.get()); - try + BOOST_TRY { thread_info->run(); } - catch(thread_interrupted const&) + BOOST_CATCH (thread_interrupted const&) { } + BOOST_CATCH_END // Removed as it stops the debugger identifying the cause of the exception // Unhandled exceptions still cause the application to terminate -// catch(...) +// BOOST_CATCH(...) // { // std::terminate(); // } @@ -146,9 +181,11 @@ namespace boost { interrupt_enabled=false; } - + void run() {} + void notify_all_at_thread_exit(condition_variable*, mutex*) + {} private: externally_launched_thread(externally_launched_thread&); @@ -177,7 +214,7 @@ namespace boost } - thread::thread() + thread::thread() BOOST_NOEXCEPT {} void thread::start_thread() @@ -187,15 +224,47 @@ namespace boost if (res != 0) { thread_info->self.reset(); - boost::throw_exception(thread_resource_error()); + boost::throw_exception(thread_resource_error(res, "boost thread: failed in pthread_create")); } } - thread::~thread() + void thread::start_thread(const attributes& attr) { - detach(); + thread_info->self=thread_info; + const attributes::native_handle_type* h = attr.native_handle(); + int res = pthread_create(&thread_info->thread_handle, h, &thread_proxy, thread_info.get()); + if (res != 0) + { + thread_info->self.reset(); + boost::throw_exception(thread_resource_error()); + } + int detached_state; + res = pthread_attr_getdetachstate(h, &detached_state); + if (res != 0) + { + thread_info->self.reset(); + boost::throw_exception(thread_resource_error()); + } + if (PTHREAD_CREATE_DETACHED==detached_state) + { + detail::thread_data_ptr local_thread_info; + thread_info.swap(local_thread_info); + + if(local_thread_info) + { + //lock_guard<mutex> lock(local_thread_info->data_mutex); + if(!local_thread_info->join_started) + { + //BOOST_VERIFY(!pthread_detach(local_thread_info->thread_handle)); + local_thread_info->join_started=true; + local_thread_info->joined=true; + } + } + } } + + detail::thread_data_ptr thread::get_thread_info BOOST_PREVENT_MACRO_SUBSTITUTION () const { return thread_info; @@ -203,11 +272,15 @@ namespace boost void thread::join() { + if (this_thread::get_id() == get_id()) + { + boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself")); + } detail::thread_data_ptr const local_thread_info=(get_thread_info)(); if(local_thread_info) { bool do_join=false; - + { unique_lock<mutex> lock(local_thread_info->data_mutex); while(!local_thread_info->done) @@ -215,7 +288,7 @@ namespace boost local_thread_info->done_condition.wait(lock); } do_join=!local_thread_info->join_started; - + if(do_join) { local_thread_info->join_started=true; @@ -236,32 +309,42 @@ namespace boost local_thread_info->joined=true; local_thread_info->done_condition.notify_all(); } - + if(thread_info==local_thread_info) { thread_info.reset(); } } + else + { +#ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED + boost::throw_exception(thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable")); +#endif + } } - bool thread::timed_join(system_time const& wait_until) + bool thread::do_try_join_until(struct timespec const &timeout) { + if (this_thread::get_id() == get_id()) + { + boost::throw_exception(thread_resource_error(system::errc::resource_deadlock_would_occur, "boost thread: trying joining itself")); + } detail::thread_data_ptr const local_thread_info=(get_thread_info)(); if(local_thread_info) { bool do_join=false; - + { unique_lock<mutex> lock(local_thread_info->data_mutex); while(!local_thread_info->done) { - if(!local_thread_info->done_condition.timed_wait(lock,wait_until)) + if(!local_thread_info->done_condition.do_timed_wait(lock,timeout)) { return false; } } do_join=!local_thread_info->join_started; - + if(do_join) { local_thread_info->join_started=true; @@ -282,16 +365,22 @@ namespace boost local_thread_info->joined=true; local_thread_info->done_condition.notify_all(); } - + if(thread_info==local_thread_info) { thread_info.reset(); } + return true; + } + else + { +#ifdef BOOST_THREAD_THROW_IF_PRECONDITION_NOT_SATISFIED + boost::throw_exception(thread_resource_error(system::errc::invalid_argument, "boost thread: thread not joinable")); +#endif } - return true; } - bool thread::joinable() const + bool thread::joinable() const BOOST_NOEXCEPT { return (get_thread_info)(); } @@ -301,7 +390,7 @@ namespace boost { detail::thread_data_ptr local_thread_info; thread_info.swap(local_thread_info); - + if(local_thread_info) { lock_guard<mutex> lock(local_thread_info->data_mutex); @@ -316,20 +405,24 @@ namespace boost namespace this_thread { - + +#ifdef __DECXXX + /// Workaround of DECCXX issue of incorrect template substitution + template<> +#endif void sleep(const system_time& st) { detail::thread_data_base* const thread_info=detail::get_current_thread_data(); - + if(thread_info) { unique_lock<mutex> lk(thread_info->sleep_mutex); - while(thread_info->sleep_condition.timed_wait(lk,st)); + while(thread_info->sleep_condition.timed_wait(lk,st)) {} } else { xtime const xt=get_xtime(st); - + for (int foo=0; foo < 5; ++foo) { # if defined(BOOST_HAS_PTHREAD_DELAY_NP) @@ -339,7 +432,7 @@ namespace boost # elif defined(BOOST_HAS_NANOSLEEP) timespec ts; to_timespec_duration(xt, ts); - + // nanosleep takes a timespec that is an offset, not // an absolute time. nanosleep(&ts, 0); @@ -350,14 +443,14 @@ namespace boost cond.timed_wait(lock, xt); # endif xtime cur; - xtime_get(&cur, TIME_UTC); + xtime_get(&cur, TIME_UTC_); if (xtime_cmp(xt, cur) <= 0) return; } } } - void yield() + void yield() BOOST_NOEXCEPT { # if defined(BOOST_HAS_SCHED_YIELD) BOOST_VERIFY(!sched_yield()); @@ -365,13 +458,12 @@ namespace boost BOOST_VERIFY(!pthread_yield()); # else xtime xt; - xtime_get(&xt, TIME_UTC); + xtime_get(&xt, TIME_UTC_); sleep(xt); # endif } } - - unsigned thread::hardware_concurrency() + unsigned thread::hardware_concurrency() BOOST_NOEXCEPT { #if defined(PTW32_VERSION) || defined(__hpux) return pthread_num_processors_np(); @@ -382,15 +474,19 @@ namespace boost #elif defined(BOOST_HAS_UNISTD_H) && defined(_SC_NPROCESSORS_ONLN) int const count=sysconf(_SC_NPROCESSORS_ONLN); return (count>0)?count:0; -#elif defined(_GNU_SOURCE) +#elif defined(__GLIBC__) return get_nprocs(); #else return 0; #endif } - thread::id thread::get_id() const + thread::id thread::get_id() const BOOST_NOEXCEPT { + #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID + //return local_thread_info->thread_handle; + return const_cast<thread*>(this)->native_handle(); + #else detail::thread_data_ptr const local_thread_info=(get_thread_info)(); if(local_thread_info) { @@ -398,8 +494,9 @@ namespace boost } else { - return id(); + return id(); } + #endif } void thread::interrupt() @@ -417,7 +514,7 @@ namespace boost } } - bool thread::interruption_requested() const + bool thread::interruption_requested() const BOOST_NOEXCEPT { detail::thread_data_ptr const local_thread_info=(get_thread_info)(); if(local_thread_info) @@ -444,19 +541,24 @@ namespace boost return pthread_t(); } } - - + + namespace this_thread { - thread::id get_id() + thread::id get_id() BOOST_NOEXCEPT { + #if defined BOOST_THREAD_PROVIDES_BASIC_THREAD_ID + return pthread_self(); + #else boost::detail::thread_data_base* const thread_info=get_or_make_current_thread_data(); return thread::id(thread_info?thread_info->shared_from_this():detail::thread_data_ptr()); + #endif } void interruption_point() { +#ifndef BOOST_NO_EXCEPTIONS boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data(); if(thread_info && thread_info->interrupt_enabled) { @@ -467,15 +569,16 @@ namespace boost throw thread_interrupted(); } } +#endif } - - bool interruption_enabled() + + bool interruption_enabled() BOOST_NOEXCEPT { boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data(); return thread_info && thread_info->interrupt_enabled; } - - bool interruption_requested() + + bool interruption_requested() BOOST_NOEXCEPT { boost::detail::thread_data_base* const thread_info=detail::get_current_thread_data(); if(!thread_info) @@ -489,7 +592,7 @@ namespace boost } } - disable_interruption::disable_interruption(): + disable_interruption::disable_interruption() BOOST_NOEXCEPT: interruption_was_enabled(interruption_enabled()) { if(interruption_was_enabled) @@ -497,8 +600,8 @@ namespace boost detail::get_current_thread_data()->interrupt_enabled=false; } } - - disable_interruption::~disable_interruption() + + disable_interruption::~disable_interruption() BOOST_NOEXCEPT { if(detail::get_current_thread_data()) { @@ -506,15 +609,15 @@ namespace boost } } - restore_interruption::restore_interruption(disable_interruption& d) + restore_interruption::restore_interruption(disable_interruption& d) BOOST_NOEXCEPT { if(d.interruption_was_enabled) { detail::get_current_thread_data()->interrupt_enabled=true; } } - - restore_interruption::~restore_interruption() + + restore_interruption::~restore_interruption() BOOST_NOEXCEPT { if(detail::get_current_thread_data()) { @@ -545,7 +648,7 @@ namespace boost return ¤t_node->second; } } - return NULL; + return 0; } void* get_tss_data(void const* key) @@ -554,7 +657,7 @@ namespace boost { return current_node->value; } - return NULL; + return 0; } void add_new_tss_node(void const* key, @@ -570,7 +673,7 @@ namespace boost detail::thread_data_base* const current_thread_data(get_or_make_current_thread_data()); current_thread_data->tss_data.erase(key); } - + void set_tss_data(void const* key, boost::shared_ptr<tss_cleanup_function> func, void* tss_data,bool cleanup_existing) @@ -591,12 +694,21 @@ namespace boost erase_tss_node(key); } } - else + else if(func || (tss_data!=0)) { add_new_tss_node(key,func,tss_data); } } } + BOOST_THREAD_DECL void notify_all_at_thread_exit(condition_variable& cond, unique_lock<mutex> lk) + { + detail::thread_data_base* const current_thread_data(detail::get_current_thread_data()); + if(current_thread_data) + { + current_thread_data->notify_all_at_thread_exit(&cond, lk.release()); + } + } + } diff --git a/3rdParty/Boost/src/libs/thread/src/pthread/timeconv.inl b/3rdParty/Boost/src/libs/thread/src/pthread/timeconv.inl index b75a135..cab7c55 100644 --- a/3rdParty/Boost/src/libs/thread/src/pthread/timeconv.inl +++ b/3rdParty/Boost/src/libs/thread/src/pthread/timeconv.inl @@ -20,8 +20,8 @@ const int NANOSECONDS_PER_MICROSECOND = 1000; inline void to_time(int milliseconds, boost::xtime& xt) { int res = 0; - res = boost::xtime_get(&xt, boost::TIME_UTC); - BOOST_ASSERT(res == boost::TIME_UTC); + res = boost::xtime_get(&xt, boost::TIME_UTC_); + BOOST_ASSERT(res == boost::TIME_UTC_); (void)res; xt.sec += (milliseconds / MILLISECONDS_PER_SECOND); xt.nsec += ((milliseconds % MILLISECONDS_PER_SECOND) * @@ -33,7 +33,6 @@ inline void to_time(int milliseconds, boost::xtime& xt) xt.nsec -= NANOSECONDS_PER_SECOND; } } - #if defined(BOOST_HAS_PTHREADS) inline void to_timespec(const boost::xtime& xt, timespec& ts) { @@ -57,8 +56,8 @@ inline void to_timespec_duration(const boost::xtime& xt, timespec& ts) { boost::xtime cur; int res = 0; - res = boost::xtime_get(&cur, boost::TIME_UTC); - BOOST_ASSERT(res == boost::TIME_UTC); + res = boost::xtime_get(&cur, boost::TIME_UTC_); + BOOST_ASSERT(res == boost::TIME_UTC_); (void)res; if (boost::xtime_cmp(xt, cur) <= 0) { @@ -88,8 +87,8 @@ inline void to_duration(boost::xtime xt, int& milliseconds) { boost::xtime cur; int res = 0; - res = boost::xtime_get(&cur, boost::TIME_UTC); - BOOST_ASSERT(res == boost::TIME_UTC); + res = boost::xtime_get(&cur, boost::TIME_UTC_); + BOOST_ASSERT(res == boost::TIME_UTC_); (void)res; if (boost::xtime_cmp(xt, cur) <= 0) milliseconds = 0; @@ -110,8 +109,8 @@ inline void to_microduration(boost::xtime xt, int& microseconds) { boost::xtime cur; int res = 0; - res = boost::xtime_get(&cur, boost::TIME_UTC); - BOOST_ASSERT(res == boost::TIME_UTC); + res = boost::xtime_get(&cur, boost::TIME_UTC_); + BOOST_ASSERT(res == boost::TIME_UTC_); (void)res; if (boost::xtime_cmp(xt, cur) <= 0) microseconds = 0; |