|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r86367 - in trunk: boost/sync/detail boost/sync/detail/condition_variables boost/sync/detail/events boost/sync/detail/mutexes boost/sync/detail/semaphore libs/sync/test/run
From: andrey.semashev_at_[hidden]
Date: 2013-10-20 09:54:27
Author: andysem
Date: 2013-10-20 09:54:27 EDT (Sun, 20 Oct 2013)
New Revision: 86367
URL: http://svn.boost.org/trac/boost/changeset/86367
Log:
Made timed_mutex incompatible with condition variable when mutex_timedwait is not available. The test had to be disabled for now because it requires condition_variable_any.
Text files modified:
trunk/boost/sync/detail/condition_variables/condition_variable_posix.hpp | 8 ++--
trunk/boost/sync/detail/events/auto_reset_event_futex.hpp | 69 +++++++++++++++------------------------
trunk/boost/sync/detail/events/manual_reset_event_futex.hpp | 2 -
trunk/boost/sync/detail/mutexes/timed_mutex_posix.hpp | 26 ++++++++++----
trunk/boost/sync/detail/mutexes/timed_mutex_windows.hpp | 6 +-
trunk/boost/sync/detail/pthread.hpp | 26 +++++++++++----
trunk/boost/sync/detail/pthread_mutex_locks.hpp | 8 ++--
trunk/boost/sync/detail/semaphore/basic_semaphore_mach.hpp | 12 +++---
trunk/libs/sync/test/run/mutex_test.cpp | 2
trunk/libs/sync/test/run/utils.hpp | 8 ++--
10 files changed, 85 insertions(+), 82 deletions(-)
Modified: trunk/boost/sync/detail/condition_variables/condition_variable_posix.hpp
==============================================================================
--- trunk/boost/sync/detail/condition_variables/condition_variable_posix.hpp Sat Oct 19 19:03:09 2013 (r86366)
+++ trunk/boost/sync/detail/condition_variables/condition_variable_posix.hpp 2013-10-20 09:54:27 EDT (Sun, 20 Oct 2013) (r86367)
@@ -75,13 +75,13 @@
{
int const res = pthread_cond_init(&m_cond, NULL);
if (res)
- BOOST_SYNC_DETAIL_THROW(resource_error, (res)("boost::sync::condition_variable constructor failed in pthread_cond_init"));
+ BOOST_SYNC_DETAIL_THROW(resource_error, (res)("condition_variable constructor failed in pthread_cond_init"));
}
#endif // defined(PTHREAD_COND_INITIALIZER)
~condition_variable()
{
- BOOST_VERIFY(::pthread_cond_destroy(&m_cond) == 0);
+ BOOST_VERIFY(sync::detail::posix::pthread_cond_destroy(&m_cond) == 0);
}
void notify_one() BOOST_NOEXCEPT
@@ -205,7 +205,7 @@
{
int const res = sync::detail::posix::pthread_cond_wait(&m_cond, mtx);
if (res != 0)
- BOOST_SYNC_DETAIL_THROW(wait_error, (res)("boost::sync::condition_variable::wait failed in pthread_cond_wait"));
+ BOOST_SYNC_DETAIL_THROW(wait_error, (res)("condition_variable::wait failed in pthread_cond_wait"));
}
template< typename Mutex >
@@ -221,7 +221,7 @@
if (res == ETIMEDOUT)
return sync::cv_status::timeout;
else if (res != 0)
- BOOST_SYNC_DETAIL_THROW(wait_error, (res)("boost::sync::condition_variable timedwait failed in pthread_cond_timedwait"));
+ BOOST_SYNC_DETAIL_THROW(wait_error, (res)("condition_variable::timed_wait failed in pthread_cond_timedwait"));
return sync::cv_status::no_timeout;
}
Modified: trunk/boost/sync/detail/events/auto_reset_event_futex.hpp
==============================================================================
--- trunk/boost/sync/detail/events/auto_reset_event_futex.hpp Sat Oct 19 19:03:09 2013 (r86366)
+++ trunk/boost/sync/detail/events/auto_reset_event_futex.hpp 2013-10-20 09:54:27 EDT (Sun, 20 Oct 2013) (r86367)
@@ -171,7 +171,7 @@
again:
sync::detail::system_duration::native_type time_left = (abs_timeout - sync::detail::system_time_point::now()).get();
if (time_left <= 0)
- goto timeout;
+ return on_wait_timed_out();
const int status = sync::detail::linux_::futex_timedwait(reinterpret_cast< int* >(&m_state), old_state, time_left);
if (status != 0)
{
@@ -179,8 +179,7 @@
switch (err)
{
case ETIMEDOUT:
- old_state = m_state.load(detail::atomic_ns::memory_order_acquire);
- goto timeout;
+ return on_wait_timed_out();
case EINTR: // signal received
goto again;
@@ -205,26 +204,6 @@
}
return true;
-
- timeout:
- while (true)
- {
- const unsigned int posts = old_state >> post_count_lowest_bit;
- if (posts == 0)
- {
- // Remove one waiter
- if (m_state.compare_exchange_weak(old_state, old_state - 1u, detail::atomic_ns::memory_order_acquire, detail::atomic_ns::memory_order_release))
- return false;
- }
- else
- {
- // Remove one post and one waiter from the counters
- if (m_state.compare_exchange_weak(old_state, old_state - (post_count_one + 1u), detail::atomic_ns::memory_order_acquire, detail::atomic_ns::memory_order_release))
- return true;
- }
-
- detail::pause();
- }
}
bool priv_timed_wait(sync::detail::system_duration dur)
@@ -252,26 +231,7 @@
switch (err)
{
case ETIMEDOUT:
- old_state = m_state.load(detail::atomic_ns::memory_order_acquire);
- while (true)
- {
- posts = old_state >> post_count_lowest_bit;
- if (posts == 0)
- {
- // Remove one waiter
- if (m_state.compare_exchange_weak(old_state, old_state - 1u, detail::atomic_ns::memory_order_acquire, detail::atomic_ns::memory_order_release))
- return false;
- }
- else
- {
- // Remove one post and one waiter from the counters
- if (m_state.compare_exchange_weak(old_state, old_state - (post_count_one + 1u), detail::atomic_ns::memory_order_acquire, detail::atomic_ns::memory_order_release))
- return true;
- }
-
- detail::pause();
- }
- break;
+ return on_wait_timed_out();
case EINTR: // signal received
goto again;
@@ -316,6 +276,29 @@
return false;
}
+ bool on_wait_timed_out()
+ {
+ unsigned int old_state = m_state.load(detail::atomic_ns::memory_order_acquire);
+ while (true)
+ {
+ unsigned int posts = old_state >> post_count_lowest_bit;
+ if (posts == 0)
+ {
+ // Remove one waiter
+ if (m_state.compare_exchange_weak(old_state, old_state - 1u, detail::atomic_ns::memory_order_acquire, detail::atomic_ns::memory_order_release))
+ return false;
+ }
+ else
+ {
+ // Remove one post and one waiter from the counters
+ if (m_state.compare_exchange_weak(old_state, old_state - (post_count_one + 1u), detail::atomic_ns::memory_order_acquire, detail::atomic_ns::memory_order_release))
+ return true;
+ }
+
+ detail::pause();
+ }
+ }
+
private:
BOOST_STATIC_ASSERT_MSG(sizeof(detail::atomic_ns::atomic< unsigned int >) == sizeof(int), "Boost.Sync: unexpected size of atomic< unsigned int >");
detail::atomic_ns::atomic< unsigned int > m_state;
Modified: trunk/boost/sync/detail/events/manual_reset_event_futex.hpp
==============================================================================
--- trunk/boost/sync/detail/events/manual_reset_event_futex.hpp Sat Oct 19 19:03:09 2013 (r86366)
+++ trunk/boost/sync/detail/events/manual_reset_event_futex.hpp 2013-10-20 09:54:27 EDT (Sun, 20 Oct 2013) (r86367)
@@ -111,7 +111,6 @@
// Check that system time resolution is nanoseconds
BOOST_STATIC_ASSERT(sync::detail::system_duration::subsecond_fraction == 1000000000u);
- // Note that futex timeout must be relative
const int status = sync::detail::linux_::futex_timedwait(reinterpret_cast< int* >(&m_state), 0, time_left);
if (status == 0)
break;
@@ -145,7 +144,6 @@
BOOST_STATIC_ASSERT(sync::detail::system_duration::subsecond_fraction == 1000000000u);
do
{
- // Note that futex timeout must be relative
const int status = sync::detail::linux_::futex_timedwait(reinterpret_cast< int* >(&m_state), 0, time_left);
if (status == 0)
break;
Modified: trunk/boost/sync/detail/mutexes/timed_mutex_posix.hpp
==============================================================================
--- trunk/boost/sync/detail/mutexes/timed_mutex_posix.hpp Sat Oct 19 19:03:09 2013 (r86366)
+++ trunk/boost/sync/detail/mutexes/timed_mutex_posix.hpp 2013-10-20 09:54:27 EDT (Sun, 20 Oct 2013) (r86367)
@@ -17,6 +17,7 @@
#ifndef BOOST_SYNC_DETAIL_MUTEXES_TIMED_MUTEX_POSIX_HPP_INCLUDED_
#define BOOST_SYNC_DETAIL_MUTEXES_TIMED_MUTEX_POSIX_HPP_INCLUDED_
+#include <errno.h>
#include <cstddef>
#include <boost/assert.hpp>
#include <boost/utility/enable_if.hpp>
@@ -47,7 +48,9 @@
class timed_mutex
{
public:
+#if defined(BOOST_SYNC_DETAIL_PTHREAD_HAS_TIMEDLOCK)
typedef void _is_condition_variable_compatible;
+#endif
typedef pthread_mutex_t* native_handle_type;
@@ -91,12 +94,12 @@
{
int const res = pthread_mutex_init(&m_mutex, NULL);
if (res)
- BOOST_SYNC_DETAIL_THROW(resource_error, (res)("boost:: timed_mutex constructor failed in pthread_mutex_init"));
+ BOOST_SYNC_DETAIL_THROW(resource_error, (res)("timed_mutex constructor failed in pthread_mutex_init"));
#if !defined(BOOST_SYNC_DETAIL_PTHREAD_HAS_TIMEDLOCK)
int const res2 = pthread_cond_init(&m_cond, NULL);
if (res2)
- BOOST_SYNC_DETAIL_THROW(resource_error, (res2)("boost:: timed_mutex constructor failed in pthread_cond_init"));
+ BOOST_SYNC_DETAIL_THROW(resource_error, (res2)("timed_mutex constructor failed in pthread_cond_init"));
m_is_locked = false;
#endif
}
@@ -106,7 +109,7 @@
{
BOOST_VERIFY(sync::detail::posix::pthread_mutex_destroy(&m_mutex) == 0);
#if !defined(BOOST_SYNC_DETAIL_PTHREAD_HAS_TIMEDLOCK)
- BOOST_VERIFY(::pthread_cond_destroy(&m_cond) == 0);
+ BOOST_VERIFY(sync::detail::posix::pthread_cond_destroy(&m_cond) == 0);
#endif
}
@@ -116,7 +119,7 @@
{
int const res = sync::detail::posix::pthread_mutex_lock(&m_mutex);
if (res)
- BOOST_SYNC_DETAIL_THROW(lock_error, (res)("boost: timed_mutex lock failed in pthread_mutex_lock"));
+ BOOST_SYNC_DETAIL_THROW(lock_error, (res)("timed_mutex lock failed in pthread_mutex_lock"));
}
void unlock() BOOST_NOEXCEPT
@@ -131,7 +134,7 @@
if (res == 0)
return true;
else if (res != EBUSY)
- BOOST_SYNC_DETAIL_THROW(lock_error, (res)("boost: timed_mutex trylock failed in pthread_mutex_trylock"));
+ BOOST_SYNC_DETAIL_THROW(lock_error, (res)("timed_mutex try_lock failed in pthread_mutex_trylock"));
return false;
}
@@ -206,7 +209,7 @@
if (res == 0)
return true;
else if (res != ETIMEDOUT)
- BOOST_SYNC_DETAIL_THROW(lock_error, (res)("boost: timed_mutex timedlock failed in pthread_mutex_timedlock"));
+ BOOST_SYNC_DETAIL_THROW(lock_error, (res)("timed_mutex timed_lock failed in pthread_mutex_timedlock"));
return false;
#else // defined(BOOST_SYNC_DETAIL_PTHREAD_HAS_TIMEDLOCK)
@@ -216,9 +219,16 @@
{
int const cond_res = sync::detail::posix::pthread_cond_timedwait(&m_cond, &m_mutex, &t.get());
if (cond_res == ETIMEDOUT)
- return false;
+ {
+ if (!m_is_locked)
+ break;
+ else
+ return false;
+ }
else if (cond_res != 0)
- BOOST_SYNC_DETAIL_THROW(lock_error, (cond_res)("boost: timed_mutex timedlock failed in pthread_cond_timedwait"));
+ {
+ BOOST_SYNC_DETAIL_THROW(lock_error, (cond_res)("timed_mutex timed_lock failed in pthread_cond_timedwait"));
+ }
}
m_is_locked = true;
return true;
Modified: trunk/boost/sync/detail/mutexes/timed_mutex_windows.hpp
==============================================================================
--- trunk/boost/sync/detail/mutexes/timed_mutex_windows.hpp Sat Oct 19 19:03:09 2013 (r86366)
+++ trunk/boost/sync/detail/mutexes/timed_mutex_windows.hpp 2013-10-20 09:54:27 EDT (Sun, 20 Oct 2013) (r86367)
@@ -122,7 +122,7 @@
if (!boost::detail::winapi::SetWaitableTimer(handles[1], reinterpret_cast< const boost::detail::winapi::LARGE_INTEGER_* >(&t.get()), 0, NULL, NULL, false))
{
const boost::detail::winapi::DWORD_ err = boost::detail::winapi::GetLastError();
- BOOST_SYNC_DETAIL_THROW(lock_error, (err)("timed_mutex::timedlock failed to set a timeout"));
+ BOOST_SYNC_DETAIL_THROW(lock_error, (err)("timed_mutex::timed_lock failed to set a timeout"));
}
while (true)
@@ -131,7 +131,7 @@
if (res == boost::detail::winapi::wait_failed)
{
const boost::detail::winapi::DWORD_ err = boost::detail::winapi::GetLastError();
- BOOST_SYNC_DETAIL_THROW(lock_error, (err)("timed_mutex::timedlock failed in WaitForMultipleObjects"));
+ BOOST_SYNC_DETAIL_THROW(lock_error, (err)("timed_mutex::timed_lock failed in WaitForMultipleObjects"));
}
switch (res)
@@ -189,7 +189,7 @@
default:
{
const boost::detail::winapi::DWORD_ err = boost::detail::winapi::GetLastError();
- BOOST_SYNC_DETAIL_THROW(lock_error, (err)("timed_mutex::timedlock failed in WaitForSingleObject"));
+ BOOST_SYNC_DETAIL_THROW(lock_error, (err)("timed_mutex::timed_lock failed in WaitForSingleObject"));
}
}
}
Modified: trunk/boost/sync/detail/pthread.hpp
==============================================================================
--- trunk/boost/sync/detail/pthread.hpp Sat Oct 19 19:03:09 2013 (r86366)
+++ trunk/boost/sync/detail/pthread.hpp 2013-10-20 09:54:27 EDT (Sun, 20 Oct 2013) (r86367)
@@ -53,6 +53,7 @@
using ::pthread_mutex_timedlock;
#endif
using ::pthread_mutex_unlock;
+using ::pthread_cond_destroy;
using ::pthread_cond_wait;
using ::pthread_cond_timedwait;
@@ -60,7 +61,7 @@
// Workaround for https://svn.boost.org/trac/boost/ticket/6200
-BOOST_FORCEINLINE int pthread_mutex_destroy(pthread_mutex_t* m)
+BOOST_FORCEINLINE int pthread_mutex_destroy(pthread_mutex_t* m) BOOST_NOEXCEPT
{
int ret;
do
@@ -71,7 +72,7 @@
return ret;
}
-BOOST_FORCEINLINE int pthread_mutex_lock(pthread_mutex_t* m)
+BOOST_FORCEINLINE int pthread_mutex_lock(pthread_mutex_t* m) BOOST_NOEXCEPT
{
int ret;
do
@@ -82,7 +83,7 @@
return ret;
}
-BOOST_FORCEINLINE int pthread_mutex_trylock(pthread_mutex_t* m)
+BOOST_FORCEINLINE int pthread_mutex_trylock(pthread_mutex_t* m) BOOST_NOEXCEPT
{
int ret;
do
@@ -94,7 +95,7 @@
}
#if defined(BOOST_SYNC_DETAIL_PTHREAD_HAS_TIMEDLOCK)
-BOOST_FORCEINLINE int pthread_mutex_timedlock(pthread_mutex_t* m, const struct ::timespec* t)
+BOOST_FORCEINLINE int pthread_mutex_timedlock(pthread_mutex_t* m, const struct ::timespec* t) BOOST_NOEXCEPT
{
int ret;
do
@@ -106,7 +107,7 @@
}
#endif
-BOOST_FORCEINLINE int pthread_mutex_unlock(pthread_mutex_t* m)
+BOOST_FORCEINLINE int pthread_mutex_unlock(pthread_mutex_t* m) BOOST_NOEXCEPT
{
int ret;
do
@@ -117,7 +118,18 @@
return ret;
}
-BOOST_FORCEINLINE int pthread_cond_wait(pthread_cond_t* c, pthread_mutex_t* m)
+BOOST_FORCEINLINE int pthread_cond_destroy(pthread_cond_t* c) BOOST_NOEXCEPT
+{
+ int ret;
+ do
+ {
+ ret = ::pthread_cond_destroy(c);
+ }
+ while (ret == EINTR);
+ return ret;
+}
+
+BOOST_FORCEINLINE int pthread_cond_wait(pthread_cond_t* c, pthread_mutex_t* m) BOOST_NOEXCEPT
{
int ret;
do
@@ -128,7 +140,7 @@
return ret;
}
-BOOST_FORCEINLINE int pthread_cond_timedwait(pthread_cond_t* c, pthread_mutex_t* m, const struct ::timespec* t)
+BOOST_FORCEINLINE int pthread_cond_timedwait(pthread_cond_t* c, pthread_mutex_t* m, const struct ::timespec* t) BOOST_NOEXCEPT
{
int ret;
do
Modified: trunk/boost/sync/detail/pthread_mutex_locks.hpp
==============================================================================
--- trunk/boost/sync/detail/pthread_mutex_locks.hpp Sat Oct 19 19:03:09 2013 (r86366)
+++ trunk/boost/sync/detail/pthread_mutex_locks.hpp 2013-10-20 09:54:27 EDT (Sun, 20 Oct 2013) (r86367)
@@ -40,12 +40,12 @@
public:
explicit pthread_mutex_lock_guard(pthread_mutex_t& m) BOOST_NOEXCEPT : m_mutex(&m)
{
- BOOST_VERIFY(pthread_mutex_lock(m_mutex) == 0);
+ BOOST_VERIFY(sync::detail::posix::pthread_mutex_lock(m_mutex) == 0);
}
~pthread_mutex_lock_guard()
{
- BOOST_VERIFY(pthread_mutex_unlock(m_mutex) == 0);
+ BOOST_VERIFY(sync::detail::posix::pthread_mutex_unlock(m_mutex) == 0);
}
BOOST_DELETED_FUNCTION(pthread_mutex_lock_guard(pthread_mutex_lock_guard const&))
@@ -59,12 +59,12 @@
public:
explicit pthread_mutex_unlock_guard(pthread_mutex_t& m) BOOST_NOEXCEPT : m_mutex(&m)
{
- BOOST_VERIFY(pthread_mutex_unlock(m_mutex) == 0);
+ BOOST_VERIFY(sync::detail::posix::pthread_mutex_unlock(m_mutex) == 0);
}
~pthread_mutex_unlock_guard()
{
- BOOST_VERIFY(pthread_mutex_lock(m_mutex) == 0);
+ BOOST_VERIFY(sync::detail::posix::pthread_mutex_lock(m_mutex) == 0);
}
BOOST_DELETED_FUNCTION(pthread_mutex_unlock_guard(pthread_mutex_unlock_guard const&))
Modified: trunk/boost/sync/detail/semaphore/basic_semaphore_mach.hpp
==============================================================================
--- trunk/boost/sync/detail/semaphore/basic_semaphore_mach.hpp Sat Oct 19 19:03:09 2013 (r86366)
+++ trunk/boost/sync/detail/semaphore/basic_semaphore_mach.hpp 2013-10-20 09:54:27 EDT (Sun, 20 Oct 2013) (r86367)
@@ -97,21 +97,21 @@
sync::detail::system_duration::native_type time_left = dur.get();
if (time_left < 0)
time_left = 0;
- sync::detail::system_duration::native_type time_left_sec = time_left / system_duration::subsecond_fraction;
- sync::detail::system_duration::native_type time_left_subsec = time_left % system_duration::subsecond_fraction;
+ sync::detail::system_duration::native_type time_left_sec = time_left / sync::detail::system_duration::subsecond_fraction;
+ sync::detail::system_duration::native_type time_left_subsec = time_left % sync::detail::system_duration::subsecond_fraction;
enum
{
nanoseconds_fraction = 1000000000u,
- conversion_ratio = static_cast< uint64_t >(nanoseconds_fraction) >= system_duration::subsecond_fraction ?
- nanoseconds_fraction / system_duration::subsecond_fraction :
- system_duration::subsecond_fraction / nanoseconds_fraction
+ conversion_ratio = static_cast< uint64_t >(nanoseconds_fraction) >= sync::detail::system_duration::subsecond_fraction ?
+ nanoseconds_fraction / sync::detail::system_duration::subsecond_fraction :
+ sync::detail::system_duration::subsecond_fraction / nanoseconds_fraction
};
const mach_timespec_t wait_time =
{
time_left_sec,
- static_cast< uint64_t >(nanoseconds_fraction) >= system_duration::subsecond_fraction ?
+ static_cast< uint64_t >(nanoseconds_fraction) >= sync::detail::system_duration::subsecond_fraction ?
time_left_subsec / conversion_ratio : time_left_subsec * conversion_ratio
};
Modified: trunk/libs/sync/test/run/mutex_test.cpp
==============================================================================
--- trunk/libs/sync/test/run/mutex_test.cpp Sat Oct 19 19:03:09 2013 (r86366)
+++ trunk/libs/sync/test/run/mutex_test.cpp 2013-10-20 09:54:27 EDT (Sun, 20 Oct 2013) (r86367)
@@ -284,6 +284,7 @@
timed_test(&do_test_try_mutex, 3);
}
+/*
void do_test_timed_mutex()
{
test_lock<boost::sync::timed_mutex>()();
@@ -296,7 +297,6 @@
timed_test(&do_test_timed_mutex, 3);
}
-/*
void do_test_recursive_mutex()
{
test_lock<boost::recursive_mutex>()();
Modified: trunk/libs/sync/test/run/utils.hpp
==============================================================================
--- trunk/libs/sync/test/run/utils.hpp Sat Oct 19 19:03:09 2013 (r86366)
+++ trunk/libs/sync/test/run/utils.hpp 2013-10-20 09:54:27 EDT (Sun, 20 Oct 2013) (r86367)
@@ -2,7 +2,7 @@
// William E. Kempf
// Copyright (C) 2007-8 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)
#ifndef BOOST_SYNC_LIBS_TEST_UTILS_HPP_INCLUDED_
@@ -150,7 +150,7 @@
}
// boostinspect:nounnamed
-namespace
+namespace
{
template <typename F>
@@ -191,7 +191,7 @@
}
// boostinspect:nounnamed
-namespace
+namespace
{
template <typename F, typename T>
inline thread_detail_anon::thread_binder<F, T> bind(const F& func, const T& param)
@@ -226,7 +226,7 @@
}
// boostinspect:nounnamed
-namespace
+namespace
{
template <typename R, typename T>
inline thread_detail_anon::thread_member_binder<R, T> bind(R (T::*func)(), T& param)
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk