Boost logo

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