Convert the specified duration to the target clock's duration type before adding it to the current time. This avoids the situation described in PR libstdc++/68519 when the specified duration type lacks sufficient precision. --- libstdc++-v3/include/bits/atomic_futex.h | 6 +++++- libstdc++-v3/testsuite/30_threads/async/async.cc | 15 +++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-)
This change depends on the some of the changes in the series I posted yesterday. See https://gcc.gnu.org/ml/libstdc++/2018-08/msg00001.html diff --git a/libstdc++-v3/include/bits/atomic_futex.h b/libstdc++-v3/include/bits/atomic_futex.h index b7ffb7fb191..9703d752981 100644 --- a/libstdc++-v3/include/bits/atomic_futex.h +++ b/libstdc++-v3/include/bits/atomic_futex.h @@ -219,8 +219,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_load_when_equal_for(unsigned __val, memory_order __mo, const chrono::duration<_Rep, _Period>& __rtime) { + using __dur = typename __clock_t::duration; + auto __reltime = chrono::duration_cast<__dur>(__rtime); + if (__reltime < __rtime) + ++__reltime; return _M_load_when_equal_until(__val, __mo, - __clock_t::now() + __rtime); + __clock_t::now() + __reltime); } // Returns false iff a timeout occurred. diff --git a/libstdc++-v3/testsuite/30_threads/async/async.cc b/libstdc++-v3/testsuite/30_threads/async/async.cc index 755c95cbea6..cd5113d5010 100644 --- a/libstdc++-v3/testsuite/30_threads/async/async.cc +++ b/libstdc++-v3/testsuite/30_threads/async/async.cc @@ -157,6 +157,20 @@ void test04() } } +void test_pr36827() +{ + future<void> f1 = async(launch::async, []() { + std::this_thread::sleep_for(std::chrono::seconds(1)); + }); + + std::chrono::duration<float> const wait_time = std::chrono::seconds(1); + auto const start_steady = chrono::steady_clock::now(); + auto status = f1.wait_for(wait_time); + auto const elapsed_steady = chrono::steady_clock::now() - start_steady; + + VERIFY( elapsed_steady >= std::chrono::seconds(1) ); +} + int main() { test01(); @@ -165,5 +179,6 @@ int main() test03<std::chrono::steady_clock>(); test03<steady_clock_copy>(); test04(); + test_pr36827(); return 0; } -- 2.11.0