public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [patch libstdc++] Optimize synchronization in std::future if futexes are available.
@ 2015-01-16 17:10 Torvald Riegel
  2015-01-16 18:14 ` Jonathan Wakely
  2015-01-18 15:50 ` Jonathan Wakely
  0 siblings, 2 replies; 17+ messages in thread
From: Torvald Riegel @ 2015-01-16 17:10 UTC (permalink / raw)
  To: GCC Patches, libstdc++; +Cc: Jonathan Wakely

[-- Attachment #1: Type: text/plain, Size: 1661 bytes --]

This patch optimizes synchronization in std::future by using atomic
operations and futexes if the latter are available, instead of the
mutex/condvar combination in the existing code.  That reduces the space
overhead for futexes as well as synchronization runtime overheads.

To do that, the patch introduces an abstraction layer for futexes that
essentially extends an atomic-typed variable with operations that wait
for the variable to (not) have a certain value.  This waiting can then
be implemented internally with a combination of spin-waiting (not
implemented yet) and blocking using OS features such as futexes.  This
approach is similar to what the "synchronic<T>" proposal to ISO C++
(N4195) contains.
The atomic-typed variable is an unsigned int because this is what Linux
futexes currently support as futex variable.

If futexes are not available, the implementation falls back to using a
mutex and condvar.  This leads to very similar code for std::future
compared to the existing code.  The exception is that
_State_baseV2::wait_for and _State_baseV2::wait_until may acquire the
mutex twice if the future is not ready; this may lead to some additional
contention if those functions actually have to wait for the future to
become ready (ie, this is on the slow path).

It would be possible to optimize the space overhead in std::future
further by merging _State_baseV2::_M_retrieved and
_State_baseV2::_M_once into _State_baseV2::_M_status.  This would add
some complexity to the synchronization code, but not a lot.
I'm happy to do this next week if people are interested in this.

Tested on x86_64-linux and the 30_threads/* tests.

OK for trunk?

[-- Attachment #2: future.patch --]
[-- Type: text/x-patch, Size: 24775 bytes --]

commit 4b07d1c0ab807fd0fbedacde1e9fec99a7d75b6d
Author: Torvald Riegel <triegel@redhat.com>
Date:   Sun Nov 16 12:07:22 2014 +0100

    libstdc++: Optimize synchronization in std::future if futexes are available.
    
    	* src/c++11/futex.cc: New file.
    	* include/bits/atomic_futex.h: New file.
    	* include/std/future (__future_base::_State_baseV2): Use
    	atomic_futex_unsigned instead of mutex+condvar.
    	* src/c++11/futex.cc: Likewise.
    	* include/Makefile.am: Add atomic_futex.h.
    	* include/Makefile.in: Likewise.
    	* src/c++11/Makefile.am: Add futex.cc.
    	* src/c++11/Makefile.in: Likewise.

diff --git a/libstdc++-v3/config/abi/pre/gnu.ver b/libstdc++-v3/config/abi/pre/gnu.ver
index 700da18..d8d155f 100644
--- a/libstdc++-v3/config/abi/pre/gnu.ver
+++ b/libstdc++-v3/config/abi/pre/gnu.ver
@@ -1759,6 +1759,11 @@ GLIBCXX_3.4.21 {
     _ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE3getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmPK[cw]SC_;
     _ZNKSt8time_getI[cw]St19istreambuf_iteratorI[cw]St11char_traitsI[cw]EEE6do_getES3_S3_RSt8ios_baseRSt12_Ios_IostateP2tmcc;
 
+    extern "C++"
+    {
+      std::__atomic_futex_unsigned_base*;
+    };
+
 } GLIBCXX_3.4.20;
 
 
diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am
index 08e5d5f..4772950 100644
--- a/libstdc++-v3/include/Makefile.am
+++ b/libstdc++-v3/include/Makefile.am
@@ -83,6 +83,7 @@ bits_headers = \
 	${bits_srcdir}/allocated_ptr.h \
 	${bits_srcdir}/allocator.h \
 	${bits_srcdir}/atomic_base.h \
+	${bits_srcdir}/atomic_futex.h \
 	${bits_srcdir}/basic_ios.h \
 	${bits_srcdir}/basic_ios.tcc \
 	${bits_srcdir}/basic_string.h \
diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in
index 3e5d82e..ebcaa96 100644
--- a/libstdc++-v3/include/Makefile.in
+++ b/libstdc++-v3/include/Makefile.in
@@ -351,6 +351,7 @@ bits_headers = \
 	${bits_srcdir}/allocated_ptr.h \
 	${bits_srcdir}/allocator.h \
 	${bits_srcdir}/atomic_base.h \
+	${bits_srcdir}/atomic_futex.h \
 	${bits_srcdir}/basic_ios.h \
 	${bits_srcdir}/basic_ios.tcc \
 	${bits_srcdir}/basic_string.h \
diff --git a/libstdc++-v3/include/bits/atomic_futex.h b/libstdc++-v3/include/bits/atomic_futex.h
new file mode 100644
index 0000000..9a418d8
--- /dev/null
+++ b/libstdc++-v3/include/bits/atomic_futex.h
@@ -0,0 +1,288 @@
+// -*- C++ -*- header.
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+/** @file bits/atomic_futex.h
+ *  This is an internal header file, included by other library headers.
+ *  Do not attempt to use it directly.
+ */
+
+#ifndef _GLIBCXX_ATOMIC_FUTEX_H
+#define _GLIBCXX_ATOMIC_FUTEX_H 1
+
+#pragma GCC system_header
+
+#include <bits/c++config.h>
+#include <atomic>
+#include <chrono>
+#if !defined(_GLIBCXX_HAVE_LINUX_FUTEX)
+#include <mutex>
+#include <condition_variable>
+#endif
+
+#ifndef _GLIBCXX_ALWAYS_INLINE
+#define _GLIBCXX_ALWAYS_INLINE inline __attribute__((always_inline))
+#endif
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+#if defined(_GLIBCXX_HAVE_LINUX_FUTEX)
+  struct __atomic_futex_unsigned_base
+  {
+    // Returns false iff a timeout occurred.
+    bool
+    _M_futex_wait_until(unsigned *__addr, unsigned __val, bool __has_timeout,
+	chrono::seconds __s, chrono::nanoseconds __ns);
+
+    // This can be executed after the object has been destroyed.
+    static void _M_futex_notify_all(unsigned* __addr);
+  };
+
+  template <unsigned _Waiter_bit = 0x80000000>
+  struct __atomic_futex_unsigned : __atomic_futex_unsigned_base
+  {
+    typedef chrono::system_clock __clock_t;
+
+    // XXX We expect this to be lock-free, and having the payload at offset 0.
+#if ATOMIC_INT_LOCK_FREE < 2
+# error We require lock-free atomic operations on int
+#endif
+    atomic<unsigned> _M_data;
+
+    __atomic_futex_unsigned(unsigned __data) : _M_data(__data)
+    { }
+
+    _GLIBCXX_ALWAYS_INLINE unsigned
+    _M_load(memory_order __mo)
+    {
+      return _M_data.load(__mo) & ~_Waiter_bit;
+    }
+
+  private:
+
+    // If a timeout occurs, returns a current value after the timeout;
+    // otherwise, returns the operand's value if equal is true or a different
+    // value if equal is false.
+    // The assumed value is the caller's assumption about the current value
+    // when making the call.
+    unsigned
+    _M_load_and_test_until(unsigned __assumed, unsigned __operand,
+	bool __equal, memory_order __mo, bool __has_timeout,
+	chrono::seconds __s, chrono::nanoseconds __ns)
+    {
+      for (;;)
+	{
+	  // Don't bother checking the value again because we expect the caller to
+	  // have done it recently.
+	  // memory_order_relaxed is sufficient because we can rely on just the
+	  // modification order (store_notify uses an atomic RMW operation too),
+	  // and the futex syscalls synchronize between themselves.
+	  _M_data.fetch_or(_Waiter_bit, memory_order_relaxed);
+	  bool __ret;
+	  __ret = _M_futex_wait_until((unsigned*)(void*)&_M_data,
+	      __assumed | _Waiter_bit, __has_timeout, __s, __ns);
+	  // Fetch the current value after waiting (clears _Waiter_bit).
+	  __assumed = _M_load(__mo);
+	  if (!__ret || ((__operand == __assumed) == __equal))
+	    return __assumed;
+	  // TODO adapt wait time
+	}
+    }
+
+    // Returns the operand's value if equal is true or a different value if
+    // equal is false.
+    // The assumed value is the caller's assumption about the current value
+    // when making the call.
+    unsigned
+    _M_load_and_test(unsigned __assumed, unsigned __operand,
+	bool __equal, memory_order __mo)
+    {
+      return _M_load_and_test_until(__assumed, __operand, __equal, __mo,
+	  false, chrono::seconds(0), chrono::nanoseconds(0));
+    }
+
+    // If a timeout occurs, returns a current value after the timeout;
+    // otherwise, returns the operand's value if equal is true or a different
+    // value if equal is false.
+    // The assumed value is the caller's assumption about the current value
+    // when making the call.
+    template<typename _Dur>
+    unsigned
+    _M_load_and_test_until_impl(unsigned __assumed, unsigned __operand,
+	bool __equal, memory_order __mo,
+	const chrono::time_point<__clock_t, _Dur>& __atime)
+    {
+      auto __s = chrono::time_point_cast<chrono::seconds>(__atime);
+      auto __ns = chrono::duration_cast<chrono::nanoseconds>(__atime - __s);
+      // XXX correct?
+      return _M_load_and_test_until(__assumed, __operand, __equal, __mo,
+	  true, __s.time_since_epoch(), __ns);
+    }
+
+  public:
+
+    _GLIBCXX_ALWAYS_INLINE unsigned
+    _M_load_when_not_equal(unsigned __val, memory_order __mo)
+    {
+      unsigned __i = _M_load(__mo);
+      if ((__i & ~_Waiter_bit) != __val) return;
+      // TODO Spin-wait first.
+      return _M_load_and_test(__i, __val, false, __mo);
+    }
+
+    _GLIBCXX_ALWAYS_INLINE void
+    _M_load_when_equal(unsigned __val, memory_order __mo)
+    {
+      unsigned __i = _M_load(__mo);
+      if ((__i & ~_Waiter_bit) == __val)
+	return;
+      // TODO Spin-wait first.
+      _M_load_and_test(__i, __val, true, __mo);
+    }
+
+    // Returns false iff a timeout occurred.
+    template<typename _Rep, typename _Period>
+    _GLIBCXX_ALWAYS_INLINE bool
+    _M_load_when_equal_for(unsigned __val, memory_order __mo,
+	const chrono::duration<_Rep, _Period>& __rtime)
+    {
+      return _M_load_when_equal_until(__val, __mo, __clock_t::now() + __rtime);
+    }
+
+    // Returns false iff a timeout occurred.
+    template<typename _Clock, typename _Duration>
+    _GLIBCXX_ALWAYS_INLINE bool
+    _M_load_when_equal_until(unsigned __val, memory_order __mo,
+	const chrono::time_point<_Clock, _Duration>& __atime)
+    {
+      // DR 887 - Sync unknown clock to known clock.
+      const typename _Clock::time_point __c_entry = _Clock::now();
+      const __clock_t::time_point __s_entry = __clock_t::now();
+      const auto __delta = __atime - __c_entry;
+      const auto __s_atime = __s_entry + __delta;
+      return _M_load_when_equal_until(__val, __mo, __s_atime);
+    }
+
+    // Returns false iff a timeout occurred.
+    template<typename _Duration>
+    _GLIBCXX_ALWAYS_INLINE bool
+    _M_load_when_equal_until(unsigned __val, memory_order __mo,
+	const chrono::time_point<__clock_t, _Duration>& __atime)
+    {
+      unsigned __i = _M_load(__mo);
+      if ((__i & ~_Waiter_bit) == __val)
+	return true;
+      // TODO Spin-wait first.  Ignore effect on timeout.
+      __i = _M_load_and_test_until_impl(__i, __val, true, __mo, __atime);
+      return (__i & ~_Waiter_bit) == __val;
+    }
+
+    _GLIBCXX_ALWAYS_INLINE void
+    _M_store_notify_all(unsigned __val, memory_order __mo)
+    {
+      unsigned* __futex = (unsigned *)(void *)&_M_data;
+      if (_M_data.exchange(__val, __mo) & _Waiter_bit)
+	_M_futex_notify_all(__futex);
+    }
+
+  };
+
+#else
+
+  // If futexes are not available, use a mutex and a condvar to wait.
+  // Because we access the data only within critical sections, all accesses
+  // are sequentially consistent; thus, we satisfy any provided memory_order.
+  template <unsigned _Waiter_bit = 0x80000000>
+  struct __atomic_futex_unsigned
+  {
+    typedef chrono::system_clock __clock_t;
+
+    unsigned _M_data;
+    mutex _M_mutex;
+    condition_variable _M_condvar;
+
+    __atomic_futex_unsigned(unsigned __data) : _M_data(__data)
+    { }
+
+    _GLIBCXX_ALWAYS_INLINE unsigned
+    _M_load(memory_order __mo)
+    {
+      unique_lock<mutex> __lock(_M_mutex);
+      return _M_data;
+    }
+
+    _GLIBCXX_ALWAYS_INLINE unsigned
+    _M_load_when_not_equal(unsigned __val, memory_order __mo)
+    {
+      unique_lock<mutex> __lock(_M_mutex);
+      while (_M_data == __val)
+	_M_condvar.wait(__lock);
+      return _M_data;
+    }
+
+    _GLIBCXX_ALWAYS_INLINE void
+    _M_load_when_equal(unsigned __val, memory_order __mo)
+    {
+      unique_lock<mutex> __lock(_M_mutex);
+      while (_M_data != __val)
+	_M_condvar.wait(__lock);
+    }
+
+    template<typename _Rep, typename _Period>
+    _GLIBCXX_ALWAYS_INLINE bool
+    _M_load_when_equal_for(unsigned __val, memory_order __mo,
+	const chrono::duration<_Rep, _Period>& __rtime)
+    {
+      unique_lock<mutex> __lock(_M_mutex);
+      return _M_condvar.wait_for(__lock, __rtime,
+				 [&] { return _M_data == __val;});
+    }
+
+    template<typename _Clock, typename _Duration>
+    _GLIBCXX_ALWAYS_INLINE bool
+    _M_load_when_equal_until(unsigned __val, memory_order __mo,
+	const chrono::time_point<_Clock, _Duration>& __atime)
+    {
+      unique_lock<mutex> __lock(_M_mutex);
+      return _M_condvar.wait_until(__lock, __atime,
+				   [&] { return _M_data == __val;});
+    }
+
+    _GLIBCXX_ALWAYS_INLINE void
+    _M_store_notify_all(unsigned __val, memory_order __mo)
+    {
+      unique_lock<mutex> __lock(_M_mutex);
+      _M_data = __val;
+      _M_condvar.notify_all();
+    }
+
+  };
+
+#endif
+
+_GLIBCXX_END_NAMESPACE_VERSION
+} // namespace std
+
+#endif
diff --git a/libstdc++-v3/include/std/future b/libstdc++-v3/include/std/future
index 2ac6f15..cb0226d 100644
--- a/libstdc++-v3/include/std/future
+++ b/libstdc++-v3/include/std/future
@@ -41,6 +41,7 @@
 #include <condition_variable>
 #include <system_error>
 #include <atomic>
+#include <bits/atomic_futex.h>
 #include <bits/functexcept.h>
 #include <bits/unique_ptr.h>
 #include <bits/shared_ptr.h>
@@ -294,15 +295,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     {
       typedef _Ptr<_Result_base> _Ptr_type;
 
+      enum _Status : unsigned {
+	__not_ready,
+	__ready
+      };
+
       _Ptr_type			_M_result;
-      mutex               	_M_mutex;
-      condition_variable  	_M_cond;
-      atomic_flag		_M_retrieved = ATOMIC_FLAG_INIT;
-      bool			_M_ready = false;
+      __atomic_futex_unsigned<>	_M_status;
+      atomic_flag         	_M_retrieved = ATOMIC_FLAG_INIT;
       once_flag			_M_once;
 
     public:
-      _State_baseV2() noexcept = default;
+      _State_baseV2() noexcept : _M_result(), _M_status(_Status::__not_ready)
+	{ }
       _State_baseV2(const _State_baseV2&) = delete;
       _State_baseV2& operator=(const _State_baseV2&) = delete;
       virtual ~_State_baseV2() = default;
@@ -312,9 +317,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       {
 	// Run any deferred function or join any asynchronous thread:
 	_M_complete_async();
-
-	unique_lock<mutex> __lock(_M_mutex);
-	_M_cond.wait(__lock, [&] { return _M_ready; });
+	// Acquire MO makes sure this synchronizes with the thread that made
+	// the future ready.
+	_M_status._M_load_when_equal(_Status::__ready, memory_order_acquire);
 	return *_M_result;
       }
 
@@ -322,12 +327,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         future_status
         wait_for(const chrono::duration<_Rep, _Period>& __rel)
         {
-	  unique_lock<mutex> __lock(_M_mutex);
-	  if (_M_ready)
+	  // First, check if the future has been made ready.  Use acquire MO
+	  // to synchronize with the thread that made it ready.
+	  if (_M_status._M_load(memory_order_acquire) == _Status::__ready)
 	    return future_status::ready;
-	  if (_M_has_deferred())
+	  if (_M_is_deferred_future())
 	    return future_status::deferred;
-	  if (_M_cond.wait_for(__lock, __rel, [&] { return _M_ready; }))
+	  if (_M_status._M_load_when_equal_for(_Status::__ready,
+	      memory_order_acquire, __rel))
 	    {
 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
 	      // 2100.  timed waiting functions must also join
@@ -349,12 +356,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
         future_status
         wait_until(const chrono::time_point<_Clock, _Duration>& __abs)
         {
-	  unique_lock<mutex> __lock(_M_mutex);
-	  if (_M_ready)
+	  // First, check if the future has been made ready.  Use acquire MO
+	  // to synchronize with the thread that made it ready.
+	  if (_M_status._M_load(memory_order_acquire) == _Status::__ready)
 	    return future_status::ready;
-	  if (_M_has_deferred())
+	  if (_M_is_deferred_future())
 	    return future_status::deferred;
-	  if (_M_cond.wait_until(__lock, __abs, [&] { return _M_ready; }))
+	  if (_M_status._M_load_when_equal_until(_Status::__ready,
+	      memory_order_acquire, __abs))
 	    {
 	      // _GLIBCXX_RESOLVE_LIB_DEFECTS
 	      // 2100.  timed waiting functions must also join
@@ -367,45 +376,37 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	}
 
       // Provide a result to the shared state and make it ready.
-      // Atomically performs:
-      //   if (!_M_ready) {
-      //     _M_result = __res();
-      //     _M_ready = true;
-      //   }
+      // Calls at most once: _M_result = __res();
       void
       _M_set_result(function<_Ptr_type()> __res, bool __ignore_failure = false)
       {
-	unique_lock<mutex> __lock(_M_mutex, defer_lock);
+	bool __did_set = false;
         // all calls to this function are serialized,
         // side-effects of invoking __res only happen once
 	call_once(_M_once, &_State_baseV2::_M_do_set, this,
-		  std::__addressof(__res), std::__addressof(__lock));
-	if (__lock.owns_lock())
-	  {
-	    _M_ready = true;
-	    _M_cond.notify_all();
-	  }
+		  std::__addressof(__res), std::__addressof(__did_set));
+	if (__did_set)
+	  // Use release MO to synchronize with observers of the ready state.
+	  _M_status._M_store_notify_all(_Status::__ready,
+					memory_order_release);
 	else if (!__ignore_failure)
           __throw_future_error(int(future_errc::promise_already_satisfied));
       }
 
       // Provide a result to the shared state but delay making it ready
       // until the calling thread exits.
-      // Atomically performs:
-      //   if (!_M_ready) {
-      //     _M_result = __res();
-      //   }
+      // Calls at most once: _M_result = __res();
       void
       _M_set_delayed_result(function<_Ptr_type()> __res,
 			    weak_ptr<_State_baseV2> __self)
       {
+	bool __did_set = false;
 	unique_ptr<_Make_ready> __mr{new _Make_ready};
-	unique_lock<mutex> __lock(_M_mutex, defer_lock);
         // all calls to this function are serialized,
         // side-effects of invoking __res only happen once
 	call_once(_M_once, &_State_baseV2::_M_do_set, this,
-		  std::__addressof(__res), std::__addressof(__lock));
-	if (!__lock.owns_lock())
+		  std::__addressof(__res), std::__addressof(__did_set));
+	if (!__did_set)
           __throw_future_error(int(future_errc::promise_already_satisfied));
 	__mr->_M_shared_state = std::move(__self);
 	__mr->_M_set();
@@ -424,12 +425,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 	    // provider is abandoning this shared state, so noone can be
 	    // trying to make the shared state ready at the same time, and
 	    // we can access _M_result directly instead of through call_once.
-	    {
-	      lock_guard<mutex> __lock(_M_mutex);
-	      _M_result.swap(__res);
-	      _M_ready = true;
-	    }
-	    _M_cond.notify_all();
+	    _M_result.swap(__res);
+	    // Use release MO to synchronize with observers of the ready state.
+	    _M_status._M_store_notify_all(_Status::__ready,
+					  memory_order_release);
 	  }
       }
 
@@ -523,18 +522,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     private:
       // The function invoked with std::call_once(_M_once, ...).
       void
-      _M_do_set(function<_Ptr_type()>* __f, unique_lock<mutex>* __lock)
+      _M_do_set(function<_Ptr_type()>* __f, bool* __did_set)
       {
-        _Ptr_type __res = (*__f)(); // do not hold lock while running setter
-	__lock->lock();
-        _M_result.swap(__res);
+        _Ptr_type __res = (*__f)();
+        // Notify the caller that we did try to set; if we do not throw an
+        // exception, the caller will be aware that it did set (e.g., see
+        // _M_set_result).
+	*__did_set = true;
+        _M_result.swap(__res); // nothrow
       }
 
       // Wait for completion of async function.
       virtual void _M_complete_async() { }
 
       // Return true if state corresponds to a deferred function.
-      virtual bool _M_has_deferred() const { return false; }
+      virtual bool _M_is_deferred_future() const { return false; }
 
       struct _Make_ready final : __at_thread_exit_elt
       {
@@ -1606,7 +1608,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
       // Caller should check whether the state is ready first, because this
       // function will return true even after the deferred function has run.
-      virtual bool _M_has_deferred() const { return true; }
+      virtual bool _M_is_deferred_future() const { return true; }
     };
 
   // Common functionality hoisted out of the _Async_state_impl template.
diff --git a/libstdc++-v3/src/c++11/Makefile.am b/libstdc++-v3/src/c++11/Makefile.am
index 4cba983..b2a4d1f 100644
--- a/libstdc++-v3/src/c++11/Makefile.am
+++ b/libstdc++-v3/src/c++11/Makefile.am
@@ -59,6 +59,7 @@ sources = \
 	debug.cc \
 	functexcept.cc \
 	functional.cc \
+	futex.cc \
 	future.cc \
 	hash_c++0x.cc \
 	hashtable_c++0x.cc \
diff --git a/libstdc++-v3/src/c++11/Makefile.in b/libstdc++-v3/src/c++11/Makefile.in
index 619bf37..eb439a0 100644
--- a/libstdc++-v3/src/c++11/Makefile.in
+++ b/libstdc++-v3/src/c++11/Makefile.in
@@ -73,7 +73,7 @@ libc__11convenience_la_LIBADD =
 @ENABLE_DUAL_ABI_TRUE@	cxx11-shim_facets.lo cxx11-stdexcept.lo
 am__objects_2 = ctype_configure_char.lo ctype_members.lo
 am__objects_3 = chrono.lo condition_variable.lo cow-stdexcept.lo \
-	ctype.lo debug.lo functexcept.lo functional.lo future.lo \
+	ctype.lo debug.lo functexcept.lo functional.lo futex.lo future.lo \
 	hash_c++0x.lo hashtable_c++0x.lo ios.lo limits.lo mutex.lo \
 	placeholders.lo random.lo regex.lo shared_ptr.lo \
 	snprintf_lite.lo system_error.lo thread.lo $(am__objects_1) \
@@ -350,6 +350,7 @@ sources = \
 	debug.cc \
 	functexcept.cc \
 	functional.cc \
+	futex.cc \
 	future.cc \
 	hash_c++0x.cc \
 	hashtable_c++0x.cc \
diff --git a/libstdc++-v3/src/c++11/futex.cc b/libstdc++-v3/src/c++11/futex.cc
new file mode 100644
index 0000000..ad766c8
--- /dev/null
+++ b/libstdc++-v3/src/c++11/futex.cc
@@ -0,0 +1,97 @@
+// futex -*- C++ -*-
+
+// Copyright (C) 2015 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library.  This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+
+// Under Section 7 of GPL version 3, you are granted additional
+// permissions described in the GCC Runtime Library Exception, version
+// 3.1, as published by the Free Software Foundation.
+
+// You should have received a copy of the GNU General Public License and
+// a copy of the GCC Runtime Library Exception along with this program;
+// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
+// <http://www.gnu.org/licenses/>.
+
+#include <bits/c++config.h>
+#if defined(_GLIBCXX_HAVE_LINUX_FUTEX)
+#include <bits/atomic_futex.h>
+#include <chrono>
+#include <climits>
+#include <syscall.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <errno.h>
+#include <debug/debug.h>
+
+// Constants for the wait/wake futex syscall operations
+const unsigned futex_wait_op = 0;
+const unsigned futex_wake_op = 1;
+
+namespace std _GLIBCXX_VISIBILITY(default)
+{
+_GLIBCXX_BEGIN_NAMESPACE_VERSION
+
+  bool
+  __atomic_futex_unsigned_base::_M_futex_wait_until(unsigned *__addr,
+      unsigned __val,
+      bool __has_timeout, chrono::seconds __s, chrono::nanoseconds __ns)
+  {
+    if (!__has_timeout)
+      {
+	// Ignore whether we actually succeeded to block because at worst,
+	// we will fall back to spin-waiting.  The only thing we could do
+	// here on errors is abort.
+	int ret __attribute__((unused));
+	ret = syscall (SYS_futex, __addr, futex_wait_op, __val);
+	_GLIBCXX_DEBUG_ASSERT(ret == 0 || errno == EINTR || errno == EAGAIN);
+	return true;
+      }
+    else
+      {
+	struct timeval tv;
+	gettimeofday (&tv, NULL);
+	// Convert the absolute timeout value to a relative timeout
+	struct timespec rt;
+	rt.tv_sec = __s.count() - tv.tv_sec;
+	rt.tv_nsec = __ns.count() - tv.tv_usec * 1000;
+	if (rt.tv_nsec < 0)
+	  {
+	    rt.tv_nsec += 1000000000;
+	    --rt.tv_sec;
+	  }
+	// Did we already time out?
+	if (rt.tv_sec < 0)
+	  return false;
+
+	if (syscall (SYS_futex, __addr, futex_wait_op, __val, &rt) == -1)
+	  {
+	    _GLIBCXX_DEBUG_ASSERT(errno == EINTR || errno == EAGAIN
+				  || errno == ETIMEDOUT);
+	    if (errno == ETIMEDOUT)
+	      return false;
+	  }
+	return true;
+      }
+  }
+
+  void
+  __atomic_futex_unsigned_base::_M_futex_notify_all(unsigned* __addr)
+  {
+    // This syscall can fail for various reasons, including in situations
+    // in which there is no real error.  Thus, we don't bother checking
+    // the error codes.  See the futex documentation and glibc for background.
+    syscall (SYS_futex, __addr, futex_wake_op, INT_MAX);
+  }
+
+}
+#endif
diff --git a/libstdc++-v3/src/c++11/future.cc b/libstdc++-v3/src/c++11/future.cc
index 1502ff6..c711a5f 100644
--- a/libstdc++-v3/src/c++11/future.cc
+++ b/libstdc++-v3/src/c++11/future.cc
@@ -89,11 +89,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     unique_ptr<_Make_ready> mr{static_cast<_Make_ready*>(p)};
     if (auto state = mr->_M_shared_state.lock())
       {
-	{
-	  lock_guard<mutex> __lock{state->_M_mutex};
-	  state->_M_ready = true;
-	}
-	state->_M_cond.notify_all();
+	// Use release MO to synchronize with observers of the ready state.
+	state->_M_status._M_store_notify_all(_Status::__ready,
+	    memory_order_release);
       }
   }
 

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch libstdc++] Optimize synchronization in std::future if futexes are available.
  2015-01-16 17:10 [patch libstdc++] Optimize synchronization in std::future if futexes are available Torvald Riegel
@ 2015-01-16 18:14 ` Jonathan Wakely
  2015-01-18 15:50 ` Jonathan Wakely
  1 sibling, 0 replies; 17+ messages in thread
From: Jonathan Wakely @ 2015-01-16 18:14 UTC (permalink / raw)
  To: Torvald Riegel; +Cc: GCC Patches, libstdc++

On 16/01/15 18:00 +0100, Torvald Riegel wrote:
>OK for trunk?

OK, thanks.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch libstdc++] Optimize synchronization in std::future if futexes are available.
  2015-01-16 17:10 [patch libstdc++] Optimize synchronization in std::future if futexes are available Torvald Riegel
  2015-01-16 18:14 ` Jonathan Wakely
@ 2015-01-18 15:50 ` Jonathan Wakely
  1 sibling, 0 replies; 17+ messages in thread
From: Jonathan Wakely @ 2015-01-18 15:50 UTC (permalink / raw)
  To: Torvald Riegel; +Cc: GCC Patches, libstdc++

On 16/01/15 18:00 +0100, Torvald Riegel wrote:
>+namespace std _GLIBCXX_VISIBILITY(default)
>+{
>+_GLIBCXX_BEGIN_NAMESPACE_VERSION
>+
>+  bool
>+  __atomic_futex_unsigned_base::_M_futex_wait_until(unsigned *__addr,
>+      unsigned __val,
>+      bool __has_timeout, chrono::seconds __s, chrono::nanoseconds __ns)
>+  {
>+    if (!__has_timeout)
>+      {
>+	// Ignore whether we actually succeeded to block because at worst,
>+	// we will fall back to spin-waiting.  The only thing we could do
>+	// here on errors is abort.
>+	int ret __attribute__((unused));
>+	ret = syscall (SYS_futex, __addr, futex_wait_op, __val);
>+	_GLIBCXX_DEBUG_ASSERT(ret == 0 || errno == EINTR || errno == EAGAIN);

I've just noticed these debug assertions in the futex.cc file, which
will never fire because the library isn't build with -D_GLIBCXX_DEBUG
defined. We should decide whether other errors are necessary to handle
and either throw an exception or std::terminate().

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch libstdc++] Optimize synchronization in std::future if futexes are available.
  2015-01-18 15:49                       ` Jonathan Wakely
@ 2015-02-01 15:13                         ` Jonathan Wakely
  0 siblings, 0 replies; 17+ messages in thread
From: Jonathan Wakely @ 2015-02-01 15:13 UTC (permalink / raw)
  To: libstdc++, gcc-patches; +Cc: Torvald Riegel

[-- Attachment #1: Type: text/plain, Size: 136 bytes --]

One more patch to fix the preprocessor conditions, this time to fix
--disable-threads builds.

Tested x86_64-linux, committed to trunk.

[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 730 bytes --]

commit 911783907e5482c09d80fd8a5e3b5aa6d2b891d3
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Sat Jan 31 22:01:43 2015 +0000

    	* src/c++11/futex.cc: Do not define for gthr-single.h targets.

diff --git a/libstdc++-v3/src/c++11/futex.cc b/libstdc++-v3/src/c++11/futex.cc
index 1336779..a7f0200 100644
--- a/libstdc++-v3/src/c++11/futex.cc
+++ b/libstdc++-v3/src/c++11/futex.cc
@@ -23,6 +23,7 @@
 // <http://www.gnu.org/licenses/>.
 
 #include <bits/atomic_futex.h>
+#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
 #if defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1
 #include <chrono>
 #include <climits>
@@ -94,3 +95,4 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 }
 #endif
+#endif

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch libstdc++] Optimize synchronization in std::future if futexes are available.
  2015-01-18 15:32                     ` Jonathan Wakely
  2015-01-18 15:49                       ` Jonathan Wakely
@ 2015-01-29  3:35                       ` Doug Gilmore
  1 sibling, 0 replies; 17+ messages in thread
From: Doug Gilmore @ 2015-01-29  3:35 UTC (permalink / raw)
  To: gcc-patches

[-- Attachment #1: Type: text/plain, Size: 1531 bytes --]

On 01/18/2015 05:19 AM, Jonathan Wakely wrote:
> On 17/01/15 19:51 -0700, Sandra Loosemore wrote:
>> On 01/17/2015 03:58 PM, Jonathan Wakely wrote:
>>>
>>> My fault, this additional chunk is needed alongside the patch I sent
>>> earlier:
>>>
>>> --- a/libstdc++-v3/include/bits/atomic_futex.h
>>> +++ b/libstdc++-v3/include/bits/atomic_futex.h
>>> @@ -35,7 +35,7 @@
>>> #include <bits/c++config.h>
>>> #include <atomic>
>>> #include <chrono>
>>> -#if !defined(_GLIBCXX_HAVE_LINUX_FUTEX)
>>> +#if ! (defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1)
>>> #include <mutex>
>>> #include <condition_variable>
>>> #endif
>>>
>>> What I sent earlier causes your target to use std::mutex and
>>> std::condition_variable, but without the bit above the headers aren't
>>> included.
>>
>> Still no joy:
>> /scratch/sandra/arm-fsf2/src/gcc-mainline/libstdc++-v3/src/c++11/futex.cc:45:3: error: '__atomic_futex_unsigned_base' has not been declared
>>   __atomic_futex_unsigned_base::_M_futex_wait_until(unsigned *__addr,
>>   ^
>> /scratch/sandra/arm-fsf2/src/gcc-mainline/libstdc++-v3/src/c++11/futex.cc:88:3: error: '__atomic_futex_unsigned_base' has not been declared
>>   __atomic_futex_unsigned_base::_M_futex_notify_all(unsigned* __addr)
>>   ^
> 
> futex.cc needs the same change ...
I am still noticing a problem building a native X86_64 ToT compiler on
Ubuntu 12.04.5 LTS.

Attached is a patch where the CPP guards in atomic_futex.h are
reflected in futex.cc, which fixes my build problem.

OK to commit?

Thanks,

Doug


[-- Attachment #2: 0001-CPP-guards-in-futex.cc-should-match-guards-in-futex..patch --]
[-- Type: text/x-patch, Size: 993 bytes --]

From 1debe13da342ac30d905e12a9ca243e30cb61870 Mon Sep 17 00:00:00 2001
From: Doug Gilmore <doug.gilmore@imgtec.com>
Date: Wed, 28 Jan 2015 14:29:14 -0800
Subject: [PATCH] CPP guards in futex.cc should match guards in futex.ii.

---
 libstdc++-v3/src/c++11/futex.cc |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/src/c++11/futex.cc b/libstdc++-v3/src/c++11/futex.cc
index 1336779..5087483 100644
--- a/libstdc++-v3/src/c++11/futex.cc
+++ b/libstdc++-v3/src/c++11/futex.cc
@@ -23,6 +23,7 @@
 // <http://www.gnu.org/licenses/>.
 
 #include <bits/atomic_futex.h>
+#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
 #if defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1
 #include <chrono>
 #include <climits>
@@ -93,4 +94,5 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   }
 
 }
-#endif
+#endif // _GLIBCXX_HAVE_LINUX_FUTEX && ATOMIC_INT_LOCK_FREE > 1
+#endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
-- 
1.7.9.5


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch libstdc++] Optimize synchronization in std::future if futexes are available.
  2015-01-18 15:32                     ` Jonathan Wakely
@ 2015-01-18 15:49                       ` Jonathan Wakely
  2015-02-01 15:13                         ` Jonathan Wakely
  2015-01-29  3:35                       ` Doug Gilmore
  1 sibling, 1 reply; 17+ messages in thread
From: Jonathan Wakely @ 2015-01-18 15:49 UTC (permalink / raw)
  To: Sandra Loosemore
  Cc: Hans-Peter Nilsson, pinskia, David Edelsohn, Torvald Riegel,
	GCC Patches, libstdc++

[-- Attachment #1: Type: text/plain, Size: 1947 bytes --]

On 18/01/15 13:19 +0000, Jonathan Wakely wrote:
>On 17/01/15 19:51 -0700, Sandra Loosemore wrote:
>>On 01/17/2015 03:58 PM, Jonathan Wakely wrote:
>>>
>>>My fault, this additional chunk is needed alongside the patch I sent
>>>earlier:
>>>
>>>--- a/libstdc++-v3/include/bits/atomic_futex.h
>>>+++ b/libstdc++-v3/include/bits/atomic_futex.h
>>>@@ -35,7 +35,7 @@
>>>#include <bits/c++config.h>
>>>#include <atomic>
>>>#include <chrono>
>>>-#if !defined(_GLIBCXX_HAVE_LINUX_FUTEX)
>>>+#if ! (defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1)
>>>#include <mutex>
>>>#include <condition_variable>
>>>#endif
>>>
>>>What I sent earlier causes your target to use std::mutex and
>>>std::condition_variable, but without the bit above the headers aren't
>>>included.
>>
>>Still no joy:
>>/scratch/sandra/arm-fsf2/src/gcc-mainline/libstdc++-v3/src/c++11/futex.cc:45:3: 
>>error: '__atomic_futex_unsigned_base' has not been declared
>>  __atomic_futex_unsigned_base::_M_futex_wait_until(unsigned *__addr,
>>  ^
>>/scratch/sandra/arm-fsf2/src/gcc-mainline/libstdc++-v3/src/c++11/futex.cc:88:3: 
>>error: '__atomic_futex_unsigned_base' has not been declared
>>  __atomic_futex_unsigned_base::_M_futex_notify_all(unsigned* __addr)
>>  ^
>
>futex.cc needs the same change ...

>diff --git a/libstdc++-v3/src/c++11/futex.cc b/libstdc++-v3/src/c++11/futex.cc
>index ad766c8..f24b44e 100644
>--- a/libstdc++-v3/src/c++11/futex.cc
>+++ b/libstdc++-v3/src/c++11/futex.cc
>@@ -23,7 +23,7 @@
> // <http://www.gnu.org/licenses/>.
> 
> #include <bits/c++config.h>
>-#if defined(_GLIBCXX_HAVE_LINUX_FUTEX)
>+#if defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1
> #include <bits/atomic_futex.h>
> #include <chrono>
> #include <climits>

I've committed the attached after succesfully building
arm-none-linux-gnueabi with it and testing on x86_64-linux.

(The other changes in the patch are just whitespace and making the
member variables private.)


[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 7915 bytes --]

commit 07fcc71b616a253ed34b8b6f83e7f8cf6ea08a7a
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Sun Jan 18 14:34:52 2015 +0000

    	* src/c++11/futex.cc: Fix order of includes and preprocessor condition.

diff --git a/libstdc++-v3/src/c++11/futex.cc b/libstdc++-v3/src/c++11/futex.cc
index f24b44e..1336779 100644
--- a/libstdc++-v3/src/c++11/futex.cc
+++ b/libstdc++-v3/src/c++11/futex.cc
@@ -22,9 +22,8 @@
 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 // <http://www.gnu.org/licenses/>.
 
-#include <bits/c++config.h>
-#if defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1
 #include <bits/atomic_futex.h>
+#if defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1
 #include <chrono>
 #include <climits>
 #include <syscall.h>

commit c0b71ac062080887ae2bc072c9db21118155ae22
Author: redi <redi@138bc75d-0d04-0410-961f-82ee72b054a4>
Date:   Sun Jan 18 14:25:22 2015 +0000

    	* include/bits/atomic_futex.h: Use mutex and condition_variable when
    	atomic int is not lock-free. Make member variables private.
    	* src/c++11/futex.cc: Likewise.
    
    git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@219815 138bc75d-0d04-0410-961f-82ee72b054a4

diff --git a/libstdc++-v3/include/bits/atomic_futex.h b/libstdc++-v3/include/bits/atomic_futex.h
index 2673604..51b9c7e 100644
--- a/libstdc++-v3/include/bits/atomic_futex.h
+++ b/libstdc++-v3/include/bits/atomic_futex.h
@@ -35,7 +35,7 @@
 #include <bits/c++config.h>
 #include <atomic>
 #include <chrono>
-#if !defined(_GLIBCXX_HAVE_LINUX_FUTEX)
+#if ! (defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1)
 #include <mutex>
 #include <condition_variable>
 #endif
@@ -49,7 +49,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
 #if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
-#if defined(_GLIBCXX_HAVE_LINUX_FUTEX)
+#if defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1
   struct __atomic_futex_unsigned_base
   {
     // Returns false iff a timeout occurred.
@@ -62,16 +62,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   };
 
   template <unsigned _Waiter_bit = 0x80000000>
-  struct __atomic_futex_unsigned : __atomic_futex_unsigned_base
+  class __atomic_futex_unsigned : __atomic_futex_unsigned_base
   {
     typedef chrono::system_clock __clock_t;
 
-    // XXX We expect this to be lock-free, and having the payload at offset 0.
-#if ATOMIC_INT_LOCK_FREE < 2
-# error We require lock-free atomic operations on int
-#endif
+    // This must be lock-free and at offset 0.
     atomic<unsigned> _M_data;
 
+  public:
+    explicit
     __atomic_futex_unsigned(unsigned __data) : _M_data(__data)
     { }
 
@@ -82,7 +81,6 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
   private:
-
     // If a timeout occurs, returns a current value after the timeout;
     // otherwise, returns the operand's value if equal is true or a different
     // value if equal is false.
@@ -165,26 +163,27 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     // Returns false iff a timeout occurred.
     template<typename _Rep, typename _Period>
-    _GLIBCXX_ALWAYS_INLINE bool
-    _M_load_when_equal_for(unsigned __val, memory_order __mo,
-	const chrono::duration<_Rep, _Period>& __rtime)
-    {
-      return _M_load_when_equal_until(__val, __mo, __clock_t::now() + __rtime);
-    }
+      _GLIBCXX_ALWAYS_INLINE bool
+      _M_load_when_equal_for(unsigned __val, memory_order __mo,
+	  const chrono::duration<_Rep, _Period>& __rtime)
+      {
+	return _M_load_when_equal_until(__val, __mo,
+					__clock_t::now() + __rtime);
+      }
 
     // Returns false iff a timeout occurred.
     template<typename _Clock, typename _Duration>
-    _GLIBCXX_ALWAYS_INLINE bool
-    _M_load_when_equal_until(unsigned __val, memory_order __mo,
-	const chrono::time_point<_Clock, _Duration>& __atime)
-    {
-      // DR 887 - Sync unknown clock to known clock.
-      const typename _Clock::time_point __c_entry = _Clock::now();
-      const __clock_t::time_point __s_entry = __clock_t::now();
-      const auto __delta = __atime - __c_entry;
-      const auto __s_atime = __s_entry + __delta;
-      return _M_load_when_equal_until(__val, __mo, __s_atime);
-    }
+      _GLIBCXX_ALWAYS_INLINE bool
+      _M_load_when_equal_until(unsigned __val, memory_order __mo,
+	  const chrono::time_point<_Clock, _Duration>& __atime)
+      {
+	// DR 887 - Sync unknown clock to known clock.
+	const typename _Clock::time_point __c_entry = _Clock::now();
+	const __clock_t::time_point __s_entry = __clock_t::now();
+	const auto __delta = __atime - __c_entry;
+	const auto __s_atime = __s_entry + __delta;
+	return _M_load_when_equal_until(__val, __mo, __s_atime);
+      }
 
     // Returns false iff a timeout occurred.
     template<typename _Duration>
@@ -207,16 +206,15 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       if (_M_data.exchange(__val, __mo) & _Waiter_bit)
 	_M_futex_notify_all(__futex);
     }
-
   };
 
-#else // !_GLIBCXX_HAVE_LINUX_FUTEX
+#else // ! (_GLIBCXX_HAVE_LINUX_FUTEX && ATOMIC_INT_LOCK_FREE > 1)
 
   // If futexes are not available, use a mutex and a condvar to wait.
   // Because we access the data only within critical sections, all accesses
   // are sequentially consistent; thus, we satisfy any provided memory_order.
   template <unsigned _Waiter_bit = 0x80000000>
-  struct __atomic_futex_unsigned
+  class __atomic_futex_unsigned
   {
     typedef chrono::system_clock __clock_t;
 
@@ -224,6 +222,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     mutex _M_mutex;
     condition_variable _M_condvar;
 
+  public:
+    explicit
     __atomic_futex_unsigned(unsigned __data) : _M_data(__data)
     { }
 
@@ -252,24 +252,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     }
 
     template<typename _Rep, typename _Period>
-    _GLIBCXX_ALWAYS_INLINE bool
-    _M_load_when_equal_for(unsigned __val, memory_order __mo,
-	const chrono::duration<_Rep, _Period>& __rtime)
-    {
-      unique_lock<mutex> __lock(_M_mutex);
-      return _M_condvar.wait_for(__lock, __rtime,
-				 [&] { return _M_data == __val;});
-    }
+      _GLIBCXX_ALWAYS_INLINE bool
+      _M_load_when_equal_for(unsigned __val, memory_order __mo,
+	  const chrono::duration<_Rep, _Period>& __rtime)
+      {
+	unique_lock<mutex> __lock(_M_mutex);
+	return _M_condvar.wait_for(__lock, __rtime,
+				   [&] { return _M_data == __val;});
+      }
 
     template<typename _Clock, typename _Duration>
-    _GLIBCXX_ALWAYS_INLINE bool
-    _M_load_when_equal_until(unsigned __val, memory_order __mo,
-	const chrono::time_point<_Clock, _Duration>& __atime)
-    {
-      unique_lock<mutex> __lock(_M_mutex);
-      return _M_condvar.wait_until(__lock, __atime,
-				   [&] { return _M_data == __val;});
-    }
+      _GLIBCXX_ALWAYS_INLINE bool
+      _M_load_when_equal_until(unsigned __val, memory_order __mo,
+	  const chrono::time_point<_Clock, _Duration>& __atime)
+      {
+	unique_lock<mutex> __lock(_M_mutex);
+	return _M_condvar.wait_until(__lock, __atime,
+				     [&] { return _M_data == __val;});
+      }
 
     _GLIBCXX_ALWAYS_INLINE void
     _M_store_notify_all(unsigned __val, memory_order __mo)
@@ -278,10 +278,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       _M_data = __val;
       _M_condvar.notify_all();
     }
-
   };
 
-#endif // _GLIBCXX_HAVE_LINUX_FUTEX
+#endif // _GLIBCXX_HAVE_LINUX_FUTEX && ATOMIC_INT_LOCK_FREE > 1
 #endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
 
 _GLIBCXX_END_NAMESPACE_VERSION
diff --git a/libstdc++-v3/src/c++11/futex.cc b/libstdc++-v3/src/c++11/futex.cc
index ad766c8..f24b44e 100644
--- a/libstdc++-v3/src/c++11/futex.cc
+++ b/libstdc++-v3/src/c++11/futex.cc
@@ -23,7 +23,7 @@
 // <http://www.gnu.org/licenses/>.
 
 #include <bits/c++config.h>
-#if defined(_GLIBCXX_HAVE_LINUX_FUTEX)
+#if defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1
 #include <bits/atomic_futex.h>
 #include <chrono>
 #include <climits>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch libstdc++] Optimize synchronization in std::future if futexes are available.
  2015-01-18  8:37                   ` Sandra Loosemore
@ 2015-01-18 15:32                     ` Jonathan Wakely
  2015-01-18 15:49                       ` Jonathan Wakely
  2015-01-29  3:35                       ` Doug Gilmore
  0 siblings, 2 replies; 17+ messages in thread
From: Jonathan Wakely @ 2015-01-18 15:32 UTC (permalink / raw)
  To: Sandra Loosemore
  Cc: Hans-Peter Nilsson, pinskia, David Edelsohn, Torvald Riegel,
	GCC Patches, libstdc++

[-- Attachment #1: Type: text/plain, Size: 1195 bytes --]

On 17/01/15 19:51 -0700, Sandra Loosemore wrote:
>On 01/17/2015 03:58 PM, Jonathan Wakely wrote:
>>
>>My fault, this additional chunk is needed alongside the patch I sent
>>earlier:
>>
>>--- a/libstdc++-v3/include/bits/atomic_futex.h
>>+++ b/libstdc++-v3/include/bits/atomic_futex.h
>>@@ -35,7 +35,7 @@
>>#include <bits/c++config.h>
>>#include <atomic>
>>#include <chrono>
>>-#if !defined(_GLIBCXX_HAVE_LINUX_FUTEX)
>>+#if ! (defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1)
>>#include <mutex>
>>#include <condition_variable>
>>#endif
>>
>>What I sent earlier causes your target to use std::mutex and
>>std::condition_variable, but without the bit above the headers aren't
>>included.
>
>Still no joy:
>/scratch/sandra/arm-fsf2/src/gcc-mainline/libstdc++-v3/src/c++11/futex.cc:45:3: 
>error: '__atomic_futex_unsigned_base' has not been declared
>   __atomic_futex_unsigned_base::_M_futex_wait_until(unsigned *__addr,
>   ^
>/scratch/sandra/arm-fsf2/src/gcc-mainline/libstdc++-v3/src/c++11/futex.cc:88:3: 
>error: '__atomic_futex_unsigned_base' has not been declared
>   __atomic_futex_unsigned_base::_M_futex_notify_all(unsigned* __addr)
>   ^

futex.cc needs the same change ...

[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 449 bytes --]

diff --git a/libstdc++-v3/src/c++11/futex.cc b/libstdc++-v3/src/c++11/futex.cc
index ad766c8..f24b44e 100644
--- a/libstdc++-v3/src/c++11/futex.cc
+++ b/libstdc++-v3/src/c++11/futex.cc
@@ -23,7 +23,7 @@
 // <http://www.gnu.org/licenses/>.
 
 #include <bits/c++config.h>
-#if defined(_GLIBCXX_HAVE_LINUX_FUTEX)
+#if defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1
 #include <bits/atomic_futex.h>
 #include <chrono>
 #include <climits>

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch libstdc++] Optimize synchronization in std::future if futexes are available.
  2015-01-18  0:24                 ` Jonathan Wakely
@ 2015-01-18  8:37                   ` Sandra Loosemore
  2015-01-18 15:32                     ` Jonathan Wakely
  0 siblings, 1 reply; 17+ messages in thread
From: Sandra Loosemore @ 2015-01-18  8:37 UTC (permalink / raw)
  To: Jonathan Wakely
  Cc: Hans-Peter Nilsson, pinskia, David Edelsohn, Torvald Riegel,
	GCC Patches, libstdc++

On 01/17/2015 03:58 PM, Jonathan Wakely wrote:
>
> My fault, this additional chunk is needed alongside the patch I sent
> earlier:
>
> --- a/libstdc++-v3/include/bits/atomic_futex.h
> +++ b/libstdc++-v3/include/bits/atomic_futex.h
> @@ -35,7 +35,7 @@
> #include <bits/c++config.h>
> #include <atomic>
> #include <chrono>
> -#if !defined(_GLIBCXX_HAVE_LINUX_FUTEX)
> +#if ! (defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1)
> #include <mutex>
> #include <condition_variable>
> #endif
>
> What I sent earlier causes your target to use std::mutex and
> std::condition_variable, but without the bit above the headers aren't
> included.

Still no joy:
/scratch/sandra/arm-fsf2/src/gcc-mainline/libstdc++-v3/src/c++11/futex.cc:45:3: 
error: '__atomic_futex_unsigned_base' has not been declared
    __atomic_futex_unsigned_base::_M_futex_wait_until(unsigned *__addr,
    ^
/scratch/sandra/arm-fsf2/src/gcc-mainline/libstdc++-v3/src/c++11/futex.cc:88:3: 
error: '__atomic_futex_unsigned_base' has not been declared
    __atomic_futex_unsigned_base::_M_futex_notify_all(unsigned* __addr)
    ^

>>>> Maybe the patch(es) causing all these problems should be reverted
>>>> until the breakage is tracked down and fixed and regression-tested on
>>>> a variety of targets?  It's not really blocking me at the moment, but
>>>> it seems unfortunate that trunk is so unstable as we're entering Stage
>>>> 4.....
>
> Torvald, if the extra change above doesn't fix it (although it should
> do) then maybe it should be reverted until it can be tested more
> widely.

-Sandra


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch libstdc++] Optimize synchronization in std::future if futexes are available.
  2015-01-18  0:08               ` Sandra Loosemore
@ 2015-01-18  0:24                 ` Jonathan Wakely
  2015-01-18  8:37                   ` Sandra Loosemore
  0 siblings, 1 reply; 17+ messages in thread
From: Jonathan Wakely @ 2015-01-18  0:24 UTC (permalink / raw)
  To: Sandra Loosemore
  Cc: Hans-Peter Nilsson, pinskia, David Edelsohn, Torvald Riegel,
	GCC Patches, libstdc++

On 17/01/15 15:54 -0700, Sandra Loosemore wrote:
>On 01/17/2015 03:36 PM, Jonathan Wakely wrote:
>>On 17/01/15 15:22 -0700, Sandra Loosemore wrote:
>>[snip snip]
>>>I'm getting a different series of build errors with this patch --
>>>starting with
>>>
>>>In file included from
>>>/scratch/sandra/arm-fsf2/src/gcc-mainline/libstdc++-v3/src/c++11/futex.cc:27:0:
>>>
>>>/scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_futex.h:221:5:
>>>error: 'mutex' does not name a type
>>>    mutex _M_mutex;
>>>    ^
>>>/scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_futex.h:222:5:
>>>error: 'condition_variable' does not name a type
>>>    condition_variable _M_condvar;
>>>    ^
>>>/scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_futex.h:
>>>In member function 'unsigned int
>>>std::__atomic_futex_unsigned<_Waiter_bit>::_M_load(std::memory_
>>>order)':
>>>/scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_futex.h:230:7:
>>>error: 'unique_lock' was not declared in this scope
>>>      unique_lock<mutex> __lock(_M_mutex);
>>>      ^
>>>and going on for several screenfuls.
>>
>>Odd, that should already be fixed at rev 219799.
>>
>>Are you still at a revision older than that?
>
>My source tree is at r219802 now.

My fault, this additional chunk is needed alongside the patch I sent
earlier:

--- a/libstdc++-v3/include/bits/atomic_futex.h
+++ b/libstdc++-v3/include/bits/atomic_futex.h
@@ -35,7 +35,7 @@
 #include <bits/c++config.h>
 #include <atomic>
 #include <chrono>
-#if !defined(_GLIBCXX_HAVE_LINUX_FUTEX)
+#if ! (defined(_GLIBCXX_HAVE_LINUX_FUTEX) && ATOMIC_INT_LOCK_FREE > 1)
 #include <mutex>
 #include <condition_variable>
 #endif

What I sent earlier causes your target to use std::mutex and
std::condition_variable, but without the bit above the headers aren't
included.

>>>Maybe the patch(es) causing all these problems should be reverted
>>>until the breakage is tracked down and fixed and regression-tested on
>>>a variety of targets?  It's not really blocking me at the moment, but
>>>it seems unfortunate that trunk is so unstable as we're entering Stage
>>>4.....

Torvald, if the extra change above doesn't fix it (although it should
do) then maybe it should be reverted until it can be tested more
widely.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch libstdc++] Optimize synchronization in std::future if futexes are available.
  2015-01-17 22:58             ` Jonathan Wakely
@ 2015-01-18  0:08               ` Sandra Loosemore
  2015-01-18  0:24                 ` Jonathan Wakely
  0 siblings, 1 reply; 17+ messages in thread
From: Sandra Loosemore @ 2015-01-18  0:08 UTC (permalink / raw)
  To: Jonathan Wakely
  Cc: Hans-Peter Nilsson, pinskia, David Edelsohn, Torvald Riegel,
	GCC Patches, libstdc++

On 01/17/2015 03:36 PM, Jonathan Wakely wrote:
> On 17/01/15 15:22 -0700, Sandra Loosemore wrote:
> [snip snip]
>> I'm getting a different series of build errors with this patch --
>> starting with
>>
>> In file included from
>> /scratch/sandra/arm-fsf2/src/gcc-mainline/libstdc++-v3/src/c++11/futex.cc:27:0:
>>
>> /scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_futex.h:221:5:
>> error: 'mutex' does not name a type
>>     mutex _M_mutex;
>>     ^
>> /scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_futex.h:222:5:
>> error: 'condition_variable' does not name a type
>>     condition_variable _M_condvar;
>>     ^
>> /scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_futex.h:
>> In member function 'unsigned int
>> std::__atomic_futex_unsigned<_Waiter_bit>::_M_load(std::memory_
>> order)':
>> /scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_futex.h:230:7:
>> error: 'unique_lock' was not declared in this scope
>>       unique_lock<mutex> __lock(_M_mutex);
>>       ^
>> and going on for several screenfuls.
>
> Odd, that should already be fixed at rev 219799.
>
> Are you still at a revision older than that?

My source tree is at r219802 now.
>
>> Maybe the patch(es) causing all these problems should be reverted
>> until the breakage is tracked down and fixed and regression-tested on
>> a variety of targets?  It's not really blocking me at the moment, but
>> it seems unfortunate that trunk is so unstable as we're entering Stage
>> 4.....

-Sandra


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch libstdc++] Optimize synchronization in std::future if futexes are available.
  2015-01-17 22:54           ` Sandra Loosemore
@ 2015-01-17 22:58             ` Jonathan Wakely
  2015-01-18  0:08               ` Sandra Loosemore
  0 siblings, 1 reply; 17+ messages in thread
From: Jonathan Wakely @ 2015-01-17 22:58 UTC (permalink / raw)
  To: Sandra Loosemore
  Cc: Hans-Peter Nilsson, pinskia, David Edelsohn, Torvald Riegel,
	GCC Patches, libstdc++

On 17/01/15 15:22 -0700, Sandra Loosemore wrote:
>On 01/17/2015 01:23 PM, Jonathan Wakely wrote:
>>On 17/01/15 12:59 -0700, Sandra Loosemore wrote:
>>>Re:
>>>
>>>>On 17/01/15 01:45 -0500, Hans-Peter Nilsson wrote:
>>>>>On Fri, 16 Jan 2015, pinskia@gmail.com wrote:
>>>>>>>On Jan 16, 2015, at 9:57 PM, David Edelsohn <dje.gcc@gmail.com>
>>>>>>>wrote:
>>>>>>>
>>>>>>>This patch has broken bootstrap on AIX
>>>>>>>
>>>>>>>May I mention that this really should have been tested on systems
>>>>>>>other than x86 Linux.
>>>>>>
>>>>>>It also broke all newlib targets too. So you could have tested one
>>>>>>listed in the sim-test web page.
>>>>>
>>>>>For those interested, PR64638.
>>>>
>>>>Should be fixed in trunk now, by this patch.
>>>
>>>I'm now getting this error in an arm-none-linux-gnueabi cross build:
>>>
>>>
>>>In file included from
>>>/scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/future:44:0,
>>>
>>>                from
>>>/scratch/sandra/arm-fsf2/src/gcc-mainline/libstdc++-v3/src/c++11/functexcept.cc:34:
>>>
>>>/scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_futex.h:71:3:
>>>error: #error We require lock-free atomic operations on int
>>># error We require lock-free atomic operations on int
>>>  ^
>>>
>>>It used to work a few days ago....  nothing changed in my build
>>>environment except that I did "svn up" in my gcc source directory....
>>
>>Well that file didn't exist until yesterday :-)
>>
>>Does the attached patch fix it?
>>
>>The new __atomic_futex_unsigned type is only used in <future> when
>>ATOMIC_LOCK_FREE > 1, so there's no point trying to define it and
>>then failing if int is not lock-free, as the type isn't going to be
>>used anyway.
>
>I'm getting a different series of build errors with this patch -- 
>starting with
>
>In file included from /scratch/sandra/arm-fsf2/src/gcc-mainline/libstdc++-v3/src/c++11/futex.cc:27:0:
>/scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_futex.h:221:5: 
>error: 'mutex' does not name a type
>     mutex _M_mutex;
>     ^
>/scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_futex.h:222:5: 
>error: 'condition_variable' does not name a type
>     condition_variable _M_condvar;
>     ^
>/scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_futex.h: 
>In member function 'unsigned int 
>std::__atomic_futex_unsigned<_Waiter_bit>::_M_load(std::memory_
>order)':
>/scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_futex.h:230:7: 
>error: 'unique_lock' was not declared in this scope
>       unique_lock<mutex> __lock(_M_mutex);
>       ^
>and going on for several screenfuls.

Odd, that should already be fixed at rev 219799.

Are you still at a revision older than that?

>Maybe the patch(es) causing all these problems should be reverted 
>until the breakage is tracked down and fixed and regression-tested on 
>a variety of targets?  It's not really blocking me at the moment, but 
>it seems unfortunate that trunk is so unstable as we're entering Stage 
>4.....


^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch libstdc++] Optimize synchronization in std::future if futexes are available.
  2015-01-17 21:13         ` Jonathan Wakely
@ 2015-01-17 22:54           ` Sandra Loosemore
  2015-01-17 22:58             ` Jonathan Wakely
  0 siblings, 1 reply; 17+ messages in thread
From: Sandra Loosemore @ 2015-01-17 22:54 UTC (permalink / raw)
  To: Jonathan Wakely
  Cc: Hans-Peter Nilsson, pinskia, David Edelsohn, Torvald Riegel,
	GCC Patches, libstdc++

On 01/17/2015 01:23 PM, Jonathan Wakely wrote:
> On 17/01/15 12:59 -0700, Sandra Loosemore wrote:
>> Re:
>>
>>> On 17/01/15 01:45 -0500, Hans-Peter Nilsson wrote:
>>>> On Fri, 16 Jan 2015, pinskia@gmail.com wrote:
>>>>>> On Jan 16, 2015, at 9:57 PM, David Edelsohn <dje.gcc@gmail.com>
>>>>>> wrote:
>>>>>>
>>>>>> This patch has broken bootstrap on AIX
>>>>>>
>>>>>> May I mention that this really should have been tested on systems
>>>>>> other than x86 Linux.
>>>>>
>>>>> It also broke all newlib targets too. So you could have tested one
>>>>> listed in the sim-test web page.
>>>>
>>>> For those interested, PR64638.
>>>
>>> Should be fixed in trunk now, by this patch.
>>
>> I'm now getting this error in an arm-none-linux-gnueabi cross build:
>>
>>
>> In file included from
>> /scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/future:44:0,
>>
>>                 from
>> /scratch/sandra/arm-fsf2/src/gcc-mainline/libstdc++-v3/src/c++11/functexcept.cc:34:
>>
>> /scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_futex.h:71:3:
>> error: #error We require lock-free atomic operations on int
>> # error We require lock-free atomic operations on int
>>   ^
>>
>> It used to work a few days ago....  nothing changed in my build
>> environment except that I did "svn up" in my gcc source directory....
>
> Well that file didn't exist until yesterday :-)
>
> Does the attached patch fix it?
>
> The new __atomic_futex_unsigned type is only used in <future> when
> ATOMIC_LOCK_FREE > 1, so there's no point trying to define it and
> then failing if int is not lock-free, as the type isn't going to be
> used anyway.

I'm getting a different series of build errors with this patch -- 
starting with

In file included from 
/scratch/sandra/arm-fsf2/src/gcc-mainline/libstdc++-v3/src/c++11/futex.cc:27:0:
/scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_futex.h:221:5: 
error: 'mutex' does not name a type
      mutex _M_mutex;
      ^
/scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_futex.h:222:5: 
error: 'condition_variable' does not name a type
      condition_variable _M_condvar;
      ^
/scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_futex.h: 
In member function 'unsigned int 
std::__atomic_futex_unsigned<_Waiter_bit>::_M_load(std::memory_
order)':
/scratch/sandra/arm-fsf2/obj/gcc-mainline-0-arm-none-linux-gnueabi-i686-pc-linux-gnu/arm-none-linux-gnueabi/libstdc++-v3/include/bits/atomic_futex.h:230:7: 
error: 'unique_lock' was not declared in this scope
        unique_lock<mutex> __lock(_M_mutex);
        ^
and going on for several screenfuls.

Maybe the patch(es) causing all these problems should be reverted until 
the breakage is tracked down and fixed and regression-tested on a 
variety of targets?  It's not really blocking me at the moment, but it 
seems unfortunate that trunk is so unstable as we're entering Stage 4.....

-Sandra

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch libstdc++] Optimize synchronization in std::future if futexes are available.
  2015-01-17  8:06   ` Hans-Peter Nilsson
  2015-01-17 11:00     ` Jonathan Wakely
@ 2015-01-17 14:30     ` Jonathan Wakely
  2015-01-17 20:55       ` Sandra Loosemore
  1 sibling, 1 reply; 17+ messages in thread
From: Jonathan Wakely @ 2015-01-17 14:30 UTC (permalink / raw)
  To: Hans-Peter Nilsson
  Cc: pinskia, David Edelsohn, Torvald Riegel, GCC Patches, libstdc++

[-- Attachment #1: Type: text/plain, Size: 513 bytes --]

On 17/01/15 01:45 -0500, Hans-Peter Nilsson wrote:
>On Fri, 16 Jan 2015, pinskia@gmail.com wrote:
>> > On Jan 16, 2015, at 9:57 PM, David Edelsohn <dje.gcc@gmail.com> wrote:
>> >
>> > This patch has broken bootstrap on AIX
>> >
>> > May I mention that this really should have been tested on systems
>> > other than x86 Linux.
>>
>> It also broke all newlib targets too. So you could have tested one listed in the sim-test web page.
>
>For those interested, PR64638.

Should be fixed in trunk now, by this patch.


[-- Attachment #2: patch.txt --]
[-- Type: text/x-patch, Size: 1257 bytes --]

commit a0fe2162e3b10f6d35e4ea73bae209081bf2e9c2
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Sat Jan 17 13:29:17 2015 +0000

    	PR libstdc++/64638
    	* include/bits/atomic_futex.h: Use appropriate config macros for
    	availability of std::mutex, std::condition and std::chrono.

diff --git a/libstdc++-v3/include/bits/atomic_futex.h b/libstdc++-v3/include/bits/atomic_futex.h
index 9a418d8..2673604 100644
--- a/libstdc++-v3/include/bits/atomic_futex.h
+++ b/libstdc++-v3/include/bits/atomic_futex.h
@@ -48,6 +48,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
+#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1)
 #if defined(_GLIBCXX_HAVE_LINUX_FUTEX)
   struct __atomic_futex_unsigned_base
   {
@@ -209,7 +210,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   };
 
-#else
+#else // !_GLIBCXX_HAVE_LINUX_FUTEX
 
   // If futexes are not available, use a mutex and a condvar to wait.
   // Because we access the data only within critical sections, all accesses
@@ -280,7 +281,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
   };
 
-#endif
+#endif // _GLIBCXX_HAVE_LINUX_FUTEX
+#endif // _GLIBCXX_HAS_GTHREADS && _GLIBCXX_USE_C99_STDINT_TR1
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace std

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch libstdc++] Optimize synchronization in std::future if futexes are available.
  2015-01-17  8:06   ` Hans-Peter Nilsson
@ 2015-01-17 11:00     ` Jonathan Wakely
  2015-01-17 14:30     ` Jonathan Wakely
  1 sibling, 0 replies; 17+ messages in thread
From: Jonathan Wakely @ 2015-01-17 11:00 UTC (permalink / raw)
  To: Hans-Peter Nilsson
  Cc: Andrew Pinski, David Edelsohn, Torvald Riegel, GCC Patches,
	libstdc++,
	Jonathan Wakely

On 17 January 2015 at 06:45, Hans-Peter Nilsson <hp@bitrange.com> wrote:
> On Fri, 16 Jan 2015, pinskia@gmail.com wrote:
>> > On Jan 16, 2015, at 9:57 PM, David Edelsohn <dje.gcc@gmail.com> wrote:
>> >
>> > This patch has broken bootstrap on AIX
>> >
>> > May I mention that this really should have been tested on systems
>> > other than x86 Linux.
>>
>> It also broke all newlib targets too. So you could have tested one listed in the sim-test web page.
>
> For those interested, PR64638.

I'll fix it later today if Torvald doesn't beat me to it.

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch libstdc++] Optimize synchronization in std::future if futexes are available.
  2015-01-17  7:24 ` pinskia
@ 2015-01-17  8:06   ` Hans-Peter Nilsson
  2015-01-17 11:00     ` Jonathan Wakely
  2015-01-17 14:30     ` Jonathan Wakely
  0 siblings, 2 replies; 17+ messages in thread
From: Hans-Peter Nilsson @ 2015-01-17  8:06 UTC (permalink / raw)
  To: pinskia
  Cc: David Edelsohn, Torvald Riegel, GCC Patches, libstdc++, Jonathan Wakely

On Fri, 16 Jan 2015, pinskia@gmail.com wrote:
> > On Jan 16, 2015, at 9:57 PM, David Edelsohn <dje.gcc@gmail.com> wrote:
> >
> > This patch has broken bootstrap on AIX
> >
> > May I mention that this really should have been tested on systems
> > other than x86 Linux.
>
> It also broke all newlib targets too. So you could have tested one listed in the sim-test web page.

For those interested, PR64638.

brgds, H-P

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch libstdc++] Optimize synchronization in std::future if futexes are available.
  2015-01-17  6:45 David Edelsohn
@ 2015-01-17  7:24 ` pinskia
  2015-01-17  8:06   ` Hans-Peter Nilsson
  0 siblings, 1 reply; 17+ messages in thread
From: pinskia @ 2015-01-17  7:24 UTC (permalink / raw)
  To: David Edelsohn; +Cc: Torvald Riegel, GCC Patches, libstdc++, Jonathan Wakely





> On Jan 16, 2015, at 9:57 PM, David Edelsohn <dje.gcc@gmail.com> wrote:
> 
> This patch has broken bootstrap on AIX
> 
> May I mention that this really should have been tested on systems
> other than x86 Linux.

It also broke all newlib targets too. So you could have tested one listed in the sim-test web page. 

Thanks,
Andrew

> 
> In file included from /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/
> future:44:0,
>                 from
> /nasfarm/edelsohn/src/src/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc:30:
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:223:5:
> error: 'mutex' does not name a type
>     mutex _M_mutex;
>     ^
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:224:5:
> error: 'condition_variable' does not name a type
>     condition_variable _M_condvar;
>     ^
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:
> In member function 'unsigned int
> std::__atomic_futex_unsigned<_Waiter_bit>::_M_load(std::memory_order)':
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:232:19:
> error: 'mutex' was not declared in this scope
>       unique_lock<mutex> __lock(_M_mutex);
>                   ^
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:232:24:
> error: template argument 1 is invalid
>       unique_lock<mutex> __lock(_M_mutex);
>                        ^
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:232:33:
> error: '_M_mutex' was not declared in this scope
>       unique_lock<mutex> __lock(_M_mutex);
> 
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:
> In member function 'unsigned int
> std::__atomic_futex_unsigned<_Waiter_bit>::_M_load_when_not_equal(unsigned
> int, std::memory_order)':
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:239:19:
> error: 'mutex' was not declared in this scope
>       unique_lock<mutex> __lock(_M_mutex);
>                   ^
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:239:24:
> error: template argument 1 is invalid
>       unique_lock<mutex> __lock(_M_mutex);
>                        ^
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:239:33:
> error: '_M_mutex' was not declared in this scope
>       unique_lock<mutex> __lock(_M_mutex);
>                                 ^
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:241:2:
> error: '_M_condvar' was not declared in this scope
>  _M_condvar.wait(__lock);
>  ^
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:
> In member function 'void
> std::__atomic_futex_unsigned<_Waiter_bit>::_M_load_when_equal(unsigned
> int, std::memory_order)':
> 
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:248:19:
> error: 'mutex' was not declared in this scope
>       unique_lock<mutex> __lock(_M_mutex);
>                   ^
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:248:24:
> error: template argument 1 is invalid
>       unique_lock<mutex> __lock(_M_mutex);
> 
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:248:33:
> error: '_M_mutex' was not declared in this scope
>       unique_lock<mutex> __lock(_M_mutex);
>                                 ^
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:250:2:
> error: '_M_condvar' was not declared in this scope
>  _M_condvar.wait(__lock);
>  ^
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:
> In member function 'bool
> std::__atomic_futex_unsigned<_Waiter_bit>::_M_load_when_equal_for(unsigned
> int, std::memory_order, const std::chrono::duration<_Rep, _Period>&)':
> 
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:258:19:
> error: 'mutex' was not declared in this scope
>       unique_lock<mutex> __lock(_M_mutex);
>                   ^
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:258:24:
> error: template argument 1 is invalid
>       unique_lock<mutex> __lock(_M_mutex);
>                        ^
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:258:33:
> error: '_M_mutex' was not declared in this scope
>       unique_lock<mutex> __lock(_M_mutex);
>                                 ^
> /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:259:14:
> error: '_M_condvar' was not declared in this scope
>       return _M_condvar.wait_for(__lock, __rtime,
>              ^
> 
> etc.
> 
> - David

^ permalink raw reply	[flat|nested] 17+ messages in thread

* Re: [patch libstdc++] Optimize synchronization in std::future if futexes are available.
@ 2015-01-17  6:45 David Edelsohn
  2015-01-17  7:24 ` pinskia
  0 siblings, 1 reply; 17+ messages in thread
From: David Edelsohn @ 2015-01-17  6:45 UTC (permalink / raw)
  To: Torvald Riegel; +Cc: GCC Patches, libstdc++, Jonathan Wakely

This patch has broken bootstrap on AIX

May I mention that this really should have been tested on systems
other than x86 Linux.

In file included from /tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/
future:44:0,
                 from
/nasfarm/edelsohn/src/src/libstdc++-v3/src/c++11/compatibility-thread-c++0x.cc:30:
/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:223:5:
error: 'mutex' does not name a type
     mutex _M_mutex;
     ^
/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:224:5:
error: 'condition_variable' does not name a type
     condition_variable _M_condvar;
     ^
/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:
In member function 'unsigned int
std::__atomic_futex_unsigned<_Waiter_bit>::_M_load(std::memory_order)':
/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:232:19:
error: 'mutex' was not declared in this scope
       unique_lock<mutex> __lock(_M_mutex);
                   ^
/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:232:24:
error: template argument 1 is invalid
       unique_lock<mutex> __lock(_M_mutex);
                        ^
/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:232:33:
error: '_M_mutex' was not declared in this scope
       unique_lock<mutex> __lock(_M_mutex);

/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:
In member function 'unsigned int
std::__atomic_futex_unsigned<_Waiter_bit>::_M_load_when_not_equal(unsigned
int, std::memory_order)':
/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:239:19:
error: 'mutex' was not declared in this scope
       unique_lock<mutex> __lock(_M_mutex);
                   ^
/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:239:24:
error: template argument 1 is invalid
       unique_lock<mutex> __lock(_M_mutex);
                        ^
/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:239:33:
error: '_M_mutex' was not declared in this scope
       unique_lock<mutex> __lock(_M_mutex);
                                 ^
/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:241:2:
error: '_M_condvar' was not declared in this scope
  _M_condvar.wait(__lock);
  ^
/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:
In member function 'void
std::__atomic_futex_unsigned<_Waiter_bit>::_M_load_when_equal(unsigned
int, std::memory_order)':

/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:248:19:
error: 'mutex' was not declared in this scope
       unique_lock<mutex> __lock(_M_mutex);
                   ^
/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:248:24:
error: template argument 1 is invalid
       unique_lock<mutex> __lock(_M_mutex);

/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:248:33:
error: '_M_mutex' was not declared in this scope
       unique_lock<mutex> __lock(_M_mutex);
                                 ^
/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:250:2:
error: '_M_condvar' was not declared in this scope
  _M_condvar.wait(__lock);
  ^
/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:
In member function 'bool
std::__atomic_futex_unsigned<_Waiter_bit>::_M_load_when_equal_for(unsigned
int, std::memory_order, const std::chrono::duration<_Rep, _Period>&)':

/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:258:19:
error: 'mutex' was not declared in this scope
       unique_lock<mutex> __lock(_M_mutex);
                   ^
/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:258:24:
error: template argument 1 is invalid
       unique_lock<mutex> __lock(_M_mutex);
                        ^
/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:258:33:
error: '_M_mutex' was not declared in this scope
       unique_lock<mutex> __lock(_M_mutex);
                                 ^
/tmp/20150117/powerpc-ibm-aix7.1.0.0/libstdc++-v3/include/bits/atomic_futex.h:259:14:
error: '_M_condvar' was not declared in this scope
       return _M_condvar.wait_for(__lock, __rtime,
              ^

etc.

- David

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2015-02-01 15:13 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-01-16 17:10 [patch libstdc++] Optimize synchronization in std::future if futexes are available Torvald Riegel
2015-01-16 18:14 ` Jonathan Wakely
2015-01-18 15:50 ` Jonathan Wakely
2015-01-17  6:45 David Edelsohn
2015-01-17  7:24 ` pinskia
2015-01-17  8:06   ` Hans-Peter Nilsson
2015-01-17 11:00     ` Jonathan Wakely
2015-01-17 14:30     ` Jonathan Wakely
2015-01-17 20:55       ` Sandra Loosemore
2015-01-17 21:13         ` Jonathan Wakely
2015-01-17 22:54           ` Sandra Loosemore
2015-01-17 22:58             ` Jonathan Wakely
2015-01-18  0:08               ` Sandra Loosemore
2015-01-18  0:24                 ` Jonathan Wakely
2015-01-18  8:37                   ` Sandra Loosemore
2015-01-18 15:32                     ` Jonathan Wakely
2015-01-18 15:49                       ` Jonathan Wakely
2015-02-01 15:13                         ` Jonathan Wakely
2015-01-29  3:35                       ` Doug Gilmore

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).