On 32-bit linux the following spins in a tight loop until it times out: #include <future> #include <thread> int main() { std::promise<void> p; auto f = p.get_future(); std::thread t([&p](){ std::this_thread::sleep_for(std::chrono::seconds(10)); p.set_value(); }); f.wait(); t.join(); } strace shows thousands of invalid calls: futex(0x8cf2a24, FUTEX_WAIT, 2147483648, {4289120584, 134527555}) = -1 EINVAL (Invalid argument) It's called from the infinite loop in __atomic_futex_unsigned::_M_load_and_test_until in <bits/atomic_futex.h>
This fixes it: --- a/libstdc++-v3/src/c++11/futex.cc +++ b/libstdc++-v3/src/c++11/futex.cc @@ -52,7 +52,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION // 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); + ret = syscall (SYS_futex, __addr, futex_wait_op, __val, nullptr); _GLIBCXX_DEBUG_ASSERT(ret == 0 || errno == EINTR || errno == EAGAIN); return true; }
(In reply to Jonathan Wakely from comment #1) > This fixes it: > > --- a/libstdc++-v3/src/c++11/futex.cc > +++ b/libstdc++-v3/src/c++11/futex.cc > @@ -52,7 +52,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION > // 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); > + ret = syscall (SYS_futex, __addr, futex_wait_op, __val, nullptr); > _GLIBCXX_DEBUG_ASSERT(ret == 0 || errno == EINTR || errno == EAGAIN); > return true; > } That is correct. futex.2 from draft_futex upstream branch of linux man pages project: ~~~ If the timeout argument is non-NULL, its contents specify a relative timeout for the wait, measured according to the CLOCK_MONOTONIC clock. (This inter‐ val will be rounded up to the system clock granularity, and is guaranteed not to expire early.) If timeout is NULL, the call blocks indefinitely. ~~~ I assume you want to block indefinitely.
LGTM, thanks. Would be nice to backport this.
Author: redi Date: Wed Dec 16 10:40:04 2015 New Revision: 231676 URL: https://gcc.gnu.org/viewcvs?rev=231676&root=gcc&view=rev Log: libstdc++/68921 add timeout argument to futex(2) PR libstdc++/68921 * src/c++11/futex.cc (__atomic_futex_unsigned_base::_M_futex_wait_until): Use null pointer as timeout argument. Modified: trunk/libstdc++-v3/ChangeLog trunk/libstdc++-v3/src/c++11/futex.cc
Author: redi Date: Wed Dec 16 11:48:55 2015 New Revision: 231679 URL: https://gcc.gnu.org/viewcvs?rev=231679&root=gcc&view=rev Log: libstdc++/68921 add timeout argument to futex(2) PR libstdc++/68921 * src/c++11/futex.cc (__atomic_futex_unsigned_base::_M_futex_wait_until): Use null pointer as timeout argument. Modified: branches/gcc-5-branch/libstdc++-v3/ChangeLog branches/gcc-5-branch/libstdc++-v3/src/c++11/futex.cc
Fixed for 5.4