|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r86138 - in trunk/boost/sync/detail: event semaphore
From: andrey.semashev_at_[hidden]
Date: 2013-10-02 15:16:30
Author: andysem
Date: 2013-10-02 15:16:29 EDT (Wed, 02 Oct 2013)
New Revision: 86138
URL: http://svn.boost.org/trac/boost/changeset/86138
Log:
Added namespace qualifiers for atomic symbols. Reworked futex-based auto-reset event.
Text files modified:
trunk/boost/sync/detail/event/event_autoreset_semaphore.hpp | 55 +++++-----
trunk/boost/sync/detail/event/event_futex.hpp | 196 ++++++++++++++++-----------------------
trunk/boost/sync/detail/event/event_mach.hpp | 11 -
trunk/boost/sync/detail/semaphore/semaphore_mach.hpp | 2
4 files changed, 110 insertions(+), 154 deletions(-)
Modified: trunk/boost/sync/detail/event/event_autoreset_semaphore.hpp
==============================================================================
--- trunk/boost/sync/detail/event/event_autoreset_semaphore.hpp Wed Oct 2 15:15:21 2013 (r86137)
+++ trunk/boost/sync/detail/event/event_autoreset_semaphore.hpp 2013-10-02 15:16:29 EDT (Wed, 02 Oct 2013) (r86138)
@@ -11,7 +11,6 @@
#define BOOST_SYNC_DETAIL_EVENT_EVENT_AUTORESET_SEMAPHORE_HPP
#include <cstddef>
-#include <boost/assert.hpp>
#include <boost/cstdint.hpp>
#include <boost/sync/detail/config.hpp>
@@ -19,7 +18,6 @@
#include <boost/sync/detail/pause.hpp>
#include <boost/sync/semaphore.hpp>
-
#include <boost/sync/detail/header.hpp>
namespace boost {
@@ -31,20 +29,23 @@
class auto_reset_event
{
BOOST_DELETED_FUNCTION(auto_reset_event(auto_reset_event const&))
- BOOST_DELETED_FUNCTION(auto_reset_event& operator=(auto_reset_event const&));
+ BOOST_DELETED_FUNCTION(auto_reset_event& operator= (auto_reset_event const&));
public:
- auto_reset_event():
+ auto_reset_event() :
m_state(0)
- {}
+ {
+ }
void post() BOOST_NOEXCEPT
{
- using namespace boost::sync::detail::atomic_ns; // for memory_order
- int32_t old_state = m_state.load(memory_order_acquire);
- if (old_state >= 0) {
- for (;;) {
- if (m_state.compare_exchange_weak( old_state, old_state - 1, memory_order_release, memory_order_acquire)) {
+ int32_t old_state = m_state.load(detail::atomic_ns::memory_order_acquire);
+ if (old_state >= 0)
+ {
+ for (;;)
+ {
+ if (m_state.compare_exchange_weak(old_state, old_state - 1, detail::atomic_ns::memory_order_release, detail::atomic_ns::memory_order_acquire))
+ {
m_sem.post();
return; // avoid unnecessary fence
}
@@ -56,56 +57,50 @@
}
}
- atomic_thread_fence( memory_order_release );
+ detail::atomic_ns::atomic_thread_fence(detail::atomic_ns::memory_order_release);
}
void wait()
{
- m_state.fetch_add(1, memory_order_acquire);
+ m_state.fetch_add(1, detail::atomic_ns::memory_order_acquire);
m_sem.wait();
}
bool try_wait()
{
- using namespace boost::sync::detail::atomic_ns; // for memory_order
-
- m_state.fetch_add(1, memory_order_acquire);
+ m_state.fetch_add(1, detail::atomic_ns::memory_order_acquire);
const bool wait_successful = m_sem.try_wait();
if (wait_successful)
return true;
- m_state.fetch_add(-1, memory_order_relaxed);
+ m_state.fetch_add(-1, detail::atomic_ns::memory_order_relaxed);
return false;
}
template <typename Duration>
bool try_wait_for(const Duration & duration)
{
- using namespace boost::sync::detail::atomic_ns; // for memory_order
+ m_state.fetch_add(1, detail::atomic_ns::memory_order_acquire);
- m_state.fetch_add(1, memory_order_acquire);
-
- const bool wait_successful = m_sem.try_wait_for( duration );
+ const bool wait_successful = m_sem.try_wait_for(duration);
if (wait_successful)
return true;
- m_state.fetch_add(-1, memory_order_relaxed);
+ m_state.fetch_add(-1, detail::atomic_ns::memory_order_relaxed);
return false;
}
template <typename Timepoint>
bool try_wait_until(const Timepoint & timeout )
{
- using namespace boost::sync::detail::atomic_ns; // for memory_order
-
- m_state.fetch_add(1, memory_order_acquire);
+ m_state.fetch_add(1, detail::atomic_ns::memory_order_acquire);
- const bool wait_successful = m_sem.try_wait_until( timeout );
+ const bool wait_successful = m_sem.try_wait_until(timeout);
if (wait_successful)
return true;
- m_state.fetch_add(-1, memory_order_relaxed);
+ m_state.fetch_add(-1, detail::atomic_ns::memory_order_relaxed);
return false;
}
@@ -114,9 +109,11 @@
detail::atomic_ns::atomic<int32_t> m_state;
};
-}
-}
-}
+} // namespace abi
+
+} // namespace sync
+
+} // namespace boost
#include <boost/sync/detail/footer.hpp>
Modified: trunk/boost/sync/detail/event/event_futex.hpp
==============================================================================
--- trunk/boost/sync/detail/event/event_futex.hpp Wed Oct 2 15:15:21 2013 (r86137)
+++ trunk/boost/sync/detail/event/event_futex.hpp 2013-10-02 15:16:29 EDT (Wed, 02 Oct 2013) (r86138)
@@ -28,84 +28,60 @@
class auto_reset_event
{
BOOST_DELETED_FUNCTION(auto_reset_event(auto_reset_event const&));
- BOOST_DELETED_FUNCTION(auto_reset_event& operator=(auto_reset_event const&));
+ BOOST_DELETED_FUNCTION(auto_reset_event& operator= (auto_reset_event const&));
public:
auto_reset_event() BOOST_NOEXCEPT :
m_state(0)
- {}
+ {
+ }
void post() BOOST_NOEXCEPT
{
- using namespace boost::sync::detail::atomic_ns; // for memory_order
- int old_state = m_state.load();
- if (old_state >= 0)
+ if (m_state.exchange(1, detail::atomic_ns::memory_order_release) == 0)
{
- for(;;)
- {
- if (m_state.compare_exchange_weak(old_state, old_state - 1))
- break;
- detail::pause();
- }
- sync::detail::linux_::futex_broadcast(reinterpret_cast< int* >(&m_state)); // wake all threads
+ sync::detail::linux_::futex_signal(reinterpret_cast< int* >(&m_state));
}
}
void wait() BOOST_NOEXCEPT
{
- using namespace boost::sync::detail::atomic_ns; // for memory_order
- int old_state = m_state.fetch_add(1) + 1;
-
- for (;;)
+ while (m_state.exchange(0, detail::atomic_ns::memory_order_acq_rel) == 0)
{
- const int status = sync::detail::linux_::futex_wait(reinterpret_cast< int* >(&m_state), old_state);
- if (status == 0)
- return;
-
- switch (errno)
+ again:
+ const int status = sync::detail::linux_::futex_wait(reinterpret_cast< int* >(&m_state), 0);
+ if (status != 0)
{
- case EINTR: // signal received
- continue;
-
- case EWOULDBLOCK: // another thread changed the state, reread and retry
- old_state = m_state.load();
- continue;
-
- default:
- BOOST_ASSERT(false);
+ const int err = errno;
+ switch (err)
+ {
+ case EINTR: // signal received
+ goto again; // skip xchg
+
+ case EWOULDBLOCK: // another thread changed the state, retry
+ continue;
+
+ default:
+ BOOST_ASSERT(false);
+ }
}
}
}
- bool try_wait()
+ bool try_wait() BOOST_NOEXCEPT
{
- using namespace boost::sync::detail::atomic_ns; // for memory_order
- int old_state = m_state.load();
-
- if (old_state < 0)
- {
- for(;;)
- {
- const bool cas_successful = m_state.compare_exchange_weak(old_state, old_state + 1);
- if (cas_successful) // we succeeded and reset the wait count
- return true;
- if (old_state >= 0) // another thread succeeded
- return false;
- detail::pause();
- }
- }
- return false;
+ return m_state.exchange(0, detail::atomic_ns::memory_order_acq_rel) != 0;
}
template <typename Duration>
bool try_wait_for(const Duration & duration) BOOST_NOEXCEPT
{
- timespec ts = boost::detail::to_timespec( duration );
+ timespec ts = boost::detail::to_timespec(duration);
return do_wait_for(ts);
}
template <class Clock, class Duration>
- bool try_wait_until(const chrono::time_point<Clock, Duration> & timeout ) BOOST_NOEXCEPT
+ bool try_wait_until(const chrono::time_point<Clock, Duration> & timeout) BOOST_NOEXCEPT
{
return try_wait_for( timeout - Clock::now() );
}
@@ -113,33 +89,31 @@
private:
bool do_wait_for(const struct timespec & timeout)
{
- using namespace boost::sync::detail::atomic_ns; // for memory_order
- int old_state = m_state.fetch_add(1) + 1;
-
- for (;;)
+ while (m_state.exchange(0, detail::atomic_ns::memory_order_acq_rel) == 0)
{
- const int status = sync::detail::linux_::futex_timedwait(reinterpret_cast< int* >(&m_state), old_state, &timeout);
- if (status == 0)
- return true;
-
- switch (errno)
+ again:
+ const int status = sync::detail::linux_::futex_timedwait(reinterpret_cast< int* >(&m_state), 0, &timeout);
+ if (status != 0)
{
- case ETIMEDOUT:
- return false;
+ const int err = errno;
+ switch (err)
+ {
+ case ETIMEDOUT:
+ return false;
- case EINTR: // signal received
- continue;
+ case EINTR: // signal received
+ goto again; // skip xchg
- case EWOULDBLOCK: // another thread changed the state, reread and retry
- old_state = m_state.load();
- continue;
+ case EWOULDBLOCK: // another thread changed the state, retry
+ continue;
- default:
- BOOST_ASSERT(false);
+ default:
+ BOOST_ASSERT(false);
+ }
}
}
- BOOST_ASSERT(false);
- return false;
+
+ return true;
}
private:
@@ -150,57 +124,49 @@
class manual_reset_event
{
BOOST_DELETED_FUNCTION(manual_reset_event(manual_reset_event const&));
- BOOST_DELETED_FUNCTION(manual_reset_event& operator=(manual_reset_event const&));
+ BOOST_DELETED_FUNCTION(manual_reset_event& operator= (manual_reset_event const&));
public:
manual_reset_event() BOOST_NOEXCEPT :
m_state(0)
- {}
+ {
+ }
void post() BOOST_NOEXCEPT
{
- using namespace boost::sync::detail::atomic_ns; // for memory_order
- int old_state = m_state.exchange(1); // set state
+ int old_state = m_state.exchange(1, detail::atomic_ns::memory_order_release); // set state
if (old_state == 0)
sync::detail::linux_::futex_broadcast(reinterpret_cast< int* >(&m_state)); // wake all threads
}
void wait() BOOST_NOEXCEPT
{
- using namespace boost::sync::detail::atomic_ns; // for memory_order
- try_again:
-
- if ( m_state.load(memory_order_acquire) == 1 )
- return; // fast-path
+ while (m_state.load(detail::atomic_ns::memory_order_acquire) == 0)
+ {
+ const int status = sync::detail::linux_::futex_wait(reinterpret_cast< int* >(&m_state), 0);
+ if (status == 0)
+ break;
- const int status = sync::detail::linux_::futex_wait(reinterpret_cast< int* >(&m_state), 0);
- if (status == 0)
- return;
+ switch (errno)
+ {
+ case EINTR: // signal received
+ case EWOULDBLOCK: // another thread has reset the event
+ continue;
- switch (errno)
- {
- case EINTR:
- // signal received
- goto try_again;
-
- case EWOULDBLOCK:
- // another thread has reset the event
- goto try_again;
+ default:
+ BOOST_ASSERT(false);
+ }
}
}
bool try_wait()
{
- using namespace boost::sync::detail::atomic_ns; // for memory_order
- if ( m_state.load(memory_order_acquire) == 1 )
- return true; // fast-path
- else
- return false;
+ return m_state.load(detail::atomic_ns::memory_order_acquire) == 1;
}
void reset() BOOST_NOEXCEPT
{
- m_state.store( 0 );
+ m_state.store(0, detail::atomic_ns::memory_order_release);
}
template <typename Duration>
@@ -219,31 +185,27 @@
private:
bool do_wait_for(const struct timespec & timeout)
{
- using namespace boost::sync::detail::atomic_ns; // for memory_order
-
- try_again:
- if ( m_state.load(memory_order_acquire) == 1 )
- return true; // fast-path
+ while (m_state.load(detail::atomic_ns::memory_order_acquire) == 0)
+ {
+ const int status = sync::detail::linux_::futex_timedwait(reinterpret_cast< int* >(&m_state), 0, &timeout);
+ if (status == 0)
+ break;
- const int status = sync::detail::linux_::futex_timedwait(reinterpret_cast< int* >(&m_state), 0, &timeout);
- if (status == 0)
- return true;
+ switch (errno)
+ {
+ case ETIMEDOUT:
+ return false;
- switch (errno)
- {
- case ETIMEDOUT:
- return false;
+ case EINTR: // signal received
+ case EWOULDBLOCK: // another thread has reset the event
+ continue;
- case EINTR:
- // signal received
- goto try_again;
-
- case EWOULDBLOCK:
- // another thread has reset the event
- goto try_again;
+ default:
+ BOOST_ASSERT(false);
+ }
}
- BOOST_ASSERT(false);
- return false;
+
+ return true;
}
private:
Modified: trunk/boost/sync/detail/event/event_mach.hpp
==============================================================================
--- trunk/boost/sync/detail/event/event_mach.hpp Wed Oct 2 15:15:21 2013 (r86137)
+++ trunk/boost/sync/detail/event/event_mach.hpp 2013-10-02 15:16:29 EDT (Wed, 02 Oct 2013) (r86138)
@@ -43,7 +43,7 @@
BOOST_DELETED_FUNCTION(manual_reset_event& operator=(manual_reset_event const&));
public:
- manual_reset_event() BOOST_NOEXCEPT:
+ manual_reset_event() BOOST_NOEXCEPT :
m_state(0)
{
kern_return_t result = semaphore_create(mach_task_self(), &m_sem, SYNC_POLICY_FIFO, 0);
@@ -58,8 +58,7 @@
void post() BOOST_NOEXCEPT
{
- using namespace boost::sync::detail::atomic_ns; // for memory_order
- m_state.store( 1, memory_order_release );
+ m_state.store( 1, detail::atomic_ns::memory_order_release );
semaphore_signal_all( m_sem ); // wake all threads!& reset semaphore count
}
@@ -70,8 +69,7 @@
void wait() BOOST_NOEXCEPT
{
- using namespace boost::sync::detail::atomic_ns; // for memory_order
- if (m_state.load(memory_order_acquire) == 1)
+ if (m_state.load(detail::atomic_ns::memory_order_acquire) == 1)
return;
kern_return_t result = semaphore_wait( m_sem );
@@ -103,8 +101,7 @@
private:
bool do_try_wait_until (const mach_timespec_t & timeout)
{
- using namespace boost::sync::detail::atomic_ns; // for memory_order
- if (m_state.load( memory_order_acquire ) == 1)
+ if (m_state.load( detail::atomic_ns::memory_order_acquire ) == 1)
return true;
kern_return_t result = semaphore_timedwait( m_sem, timeout );
Modified: trunk/boost/sync/detail/semaphore/semaphore_mach.hpp
==============================================================================
--- trunk/boost/sync/detail/semaphore/semaphore_mach.hpp Wed Oct 2 15:15:21 2013 (r86137)
+++ trunk/boost/sync/detail/semaphore/semaphore_mach.hpp 2013-10-02 15:16:29 EDT (Wed, 02 Oct 2013) (r86138)
@@ -46,7 +46,7 @@
public:
explicit semaphore(unsigned int i = 0)
{
- kern_return_t result = semaphore_create(mach_task_self(), &m_sem, SYNC_POLICY_FIFO, 0);
+ kern_return_t result = semaphore_create(mach_task_self(), &m_sem, SYNC_POLICY_FIFO, i);
if (result != KERN_SUCCESS)
BOOST_THROW_EXCEPTION(resource_error(sync::detail::system_ns::errc::not_enough_memory, "boost::sync::semaphore constructor failed in semaphore_create"));
}
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