Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r86084 - in trunk/boost/sync/detail: . event
From: andrey.semashev_at_[hidden]
Date: 2013-09-30 15:23:49


Author: andysem
Date: 2013-09-30 15:23:49 EDT (Mon, 30 Sep 2013)
New Revision: 86084
URL: http://svn.boost.org/trac/boost/changeset/86084

Log:
Fixed compilation on Linux.

Text files modified:
   trunk/boost/sync/detail/event/event_futex.hpp | 93 ++++++++++++++++++++-------------------
   trunk/boost/sync/detail/futex.hpp | 4
   2 files changed, 50 insertions(+), 47 deletions(-)

Modified: trunk/boost/sync/detail/event/event_futex.hpp
==============================================================================
--- trunk/boost/sync/detail/event/event_futex.hpp Mon Sep 30 13:53:03 2013 (r86083)
+++ trunk/boost/sync/detail/event/event_futex.hpp 2013-09-30 15:23:49 EDT (Mon, 30 Sep 2013) (r86084)
@@ -6,20 +6,18 @@
 // accompanying file LICENSE_1_0.txt or copy at
 // http://www.boost.org/LICENSE_1_0.txt)
 
-#ifndef BOOST_SYNC_DETAIL_EVENT_EVENT_FUTEX_HPP_INCLUDED
-#define BOOST_SYNC_DETAIL_EVENT_EVENT_FUTEX_HPP_INCLUDED
+#ifndef BOOST_SYNC_DETAIL_EVENT_EVENT_FUTEX_HPP_INCLUDED_
+#define BOOST_SYNC_DETAIL_EVENT_EVENT_FUTEX_HPP_INCLUDED_
 
 #include <errno.h>
-#include <unistd.h>
 #include <sys/time.h>
-#include <sys/syscall.h>
-#include <linux/futex.h>
 
-#include <limits>
 #include <boost/assert.hpp>
+#include <boost/static_assert.hpp>
 #include <boost/sync/detail/config.hpp>
 #include <boost/sync/detail/atomic.hpp>
 #include <boost/sync/detail/pause.hpp>
+#include <boost/sync/detail/futex.hpp>
 
 #include <boost/sync/detail/header.hpp>
 
@@ -27,20 +25,11 @@
 namespace sync {
 BOOST_SYNC_DETAIL_OPEN_ABI_NAMESPACE {
 
-class futex_event_base
+class auto_reset_event
 {
- BOOST_DELETED_FUNCTION(futex_event_base(futex_event_base const&));
- BOOST_DELETED_FUNCTION(futex_event_base& operator=(futex_event_base const&));
+ BOOST_DELETED_FUNCTION(auto_reset_event(auto_reset_event const&));
+ BOOST_DELETED_FUNCTION(auto_reset_event& operator=(auto_reset_event const&));
 
-protected:
- static long futex(void *addr1, int op, int val1, const struct timespec *timeout = NULL, void *addr2 = NULL, int val3 = 0)
- {
- return syscall(SYS_futex, addr1, op, val1, timeout, addr2, val3);
- }
-};
-
-class auto_reset_event : futex_event_base
-{
 public:
     auto_reset_event() BOOST_NOEXCEPT :
         m_state(0)
@@ -49,28 +38,32 @@
     void post() BOOST_NOEXCEPT
     {
         using namespace boost::sync::detail::atomic_ns; // for memory_order
- int32_t old_state = m_state.load();
- if (old_state >= 0) {
- for(;;) {
+ int old_state = m_state.load();
+ if (old_state >= 0)
+ {
+ for(;;)
+ {
                 if (m_state.compare_exchange_weak(old_state, old_state - 1))
                     break;
                 detail::pause();
             }
- futex(&m_state, FUTEX_WAKE_PRIVATE, std::numeric_limits<int>::max() ); // wake all threads
+ 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
- int32_t old_state = m_state.fetch_add(1) + 1;
+ int old_state = m_state.fetch_add(1) + 1;
 
- for (;;) {
- long status = futex(&m_state, FUTEX_WAIT_PRIVATE, old_state);
+ for (;;)
+ {
+ const int status = sync::detail::linux_::futex_wait(reinterpret_cast< int* >(&m_state), old_state);
             if (status == 0)
                 return;
 
- switch (errno) {
+ switch (errno)
+ {
             case EINTR: // signal received
                 continue;
 
@@ -87,16 +80,18 @@
     bool try_wait()
     {
         using namespace boost::sync::detail::atomic_ns; // for memory_order
- int32_t old_state = m_state.load();
+ int old_state = m_state.load();
 
- if (old_state < 0) {
- for(;;) {
- int32_t new_state = old_state + 1;
- bool cas_successful = m_state.compare_exchange_weak(old_state, new_state);
+ 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 a succeeded
+ if (old_state >= 0) // another thread succeeded
                     return false;
+ detail::pause();
             }
         }
         return false;
@@ -119,14 +114,16 @@
     bool do_wait_for(const struct timespec & timeout)
     {
         using namespace boost::sync::detail::atomic_ns; // for memory_order
- int32_t old_state = m_state.fetch_add(1) + 1;
+ int old_state = m_state.fetch_add(1) + 1;
 
- for (;;) {
- long status = futex(&m_state, FUTEX_WAIT_PRIVATE, old_state, &timeout);
+ for (;;)
+ {
+ const int status = sync::detail::linux_::futex_timedwait(reinterpret_cast< int* >(&m_state), old_state, &timeout);
             if (status == 0)
                 return true;
 
- switch (errno) {
+ switch (errno)
+ {
             case ETIMEDOUT:
                 return false;
 
@@ -145,11 +142,16 @@
         return false;
     }
 
- detail::atomic_ns::atomic<int32_t> m_state;
+private:
+ BOOST_STATIC_ASSERT_MSG(sizeof(detail::atomic_ns::atomic<int>) == sizeof(int), "Boost.Sync: unexpected size of atomic<int>");
+ detail::atomic_ns::atomic<int> m_state;
 };
 
-class manual_reset_event: futex_event_base
+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&));
+
 public:
     manual_reset_event() BOOST_NOEXCEPT :
         m_state(0)
@@ -160,7 +162,7 @@
         using namespace boost::sync::detail::atomic_ns; // for memory_order
         int old_state = m_state.exchange(1); // set state
         if (old_state == 0)
- futex(&m_state, FUTEX_WAKE_PRIVATE, std::numeric_limits<int>::max() ); // wake all threads
+ sync::detail::linux_::futex_broadcast(reinterpret_cast< int* >(&m_state)); // wake all threads
     }
 
     void wait() BOOST_NOEXCEPT
@@ -171,7 +173,7 @@
         if ( m_state.load(memory_order_acquire) == 1 )
             return; // fast-path
 
- const long status = futex(&m_state, FUTEX_WAIT_PRIVATE, 0);
+ const int status = sync::detail::linux_::futex_wait(reinterpret_cast< int* >(&m_state), 0);
         if (status == 0)
             return;
 
@@ -223,7 +225,7 @@
         if ( m_state.load(memory_order_acquire) == 1 )
             return true; // fast-path
 
- const long status = futex(&m_state, FUTEX_WAIT_PRIVATE, 0, &timeout);
+ const int status = sync::detail::linux_::futex_timedwait(reinterpret_cast< int* >(&m_state), 0, &timeout);
         if (status == 0)
             return true;
 
@@ -243,10 +245,11 @@
         BOOST_ASSERT(false);
         return false;
     }
- detail::atomic_ns::atomic<int32_t> m_state;
-};
-
 
+private:
+ BOOST_STATIC_ASSERT_MSG(sizeof(detail::atomic_ns::atomic<int>) == sizeof(int), "Boost.Sync: unexpected size of atomic<int>");
+ detail::atomic_ns::atomic<int> m_state;
+};
 
 }
 }
@@ -254,4 +257,4 @@
 
 #include <boost/sync/detail/footer.hpp>
 
-#endif // BOOST_SYNC_DETAIL_EVENT_EVENT_FUTEX_HPP_INCLUDED
+#endif // BOOST_SYNC_DETAIL_EVENT_EVENT_FUTEX_HPP_INCLUDED_

Modified: trunk/boost/sync/detail/futex.hpp
==============================================================================
--- trunk/boost/sync/detail/futex.hpp Mon Sep 30 13:53:03 2013 (r86083)
+++ trunk/boost/sync/detail/futex.hpp 2013-09-30 15:23:49 EDT (Mon, 30 Sep 2013) (r86084)
@@ -37,7 +37,7 @@
 
 namespace detail {
 
-namespace linux {
+namespace linux_ {
 
 //! Invokes an operation on the futex
 BOOST_FORCEINLINE int futex_invoke(int* addr1, int op, int val1, const struct ::timespec* timeout = NULL, int* addr2 = NULL, int val3 = 0) BOOST_NOEXCEPT
@@ -106,7 +106,7 @@
     );
 }
 
-} // namespace linux
+} // namespace linux_
 
 } // namespace detail
 


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