This series ensures that the std::future::wait_* functions use std::chrono::steady_clock when required, introduces std::chrono::__detail::ceil to make that easier to do, and then makes use of that function to simplify and improve the fix for PR68519 in std::condition_variable.
v1 of this series was originally posted back in September 2017 (see https://gcc.gnu.org/ml/libstdc++/2017-09/msg00083.html ) v2 of this series was originally posted back in January 2018 (see https://gcc.gnu.org/ml/libstdc++/2018-01/msg00035.html ) v3 of this series was originally posted back in August 2018 (see https://gcc.gnu.org/ml/libstdc++/2018-08/msg00001.html ) v4 of this series was originally posted back in October 2019 (see https://gcc.gnu.org/legacy-ml/gcc-patches/2019-10/msg01934.html ) Changes since v4: * Expose std::chrono::ceil as std::chrono::__detail::ceil so that it can be used to fix PR91486 in std::future::wait_for (as suggested by John Salmon in PR91486.) * Use std::chrono::__detail::ceil to simplify fix for PR68519 in std::condition_variable::wait_for. * Also fix equivalent of PR68519 in std::condition_variable::wait_until and add test. Changelog: * libstdc++-v3/include/std/condition_variable: (condition_variable::wait_until): Convert delta to steady_clock duration before adding to current steady_clock time to avoid rounding errors described in PR68519. (condition_variable::wait_for): Simplify calculation of absolute time by using chrono::__detail::ceil in both overloads. * libstdc++-v3/testsuite/30_threads/condition_variable/members/68519.cc: (test_wait_for): Renamed from test01. Replace unassigned val variable with constant false. Reduce scope of mx and cv variables to just test_wait_for function. (test_wait_until): Add new test case. * libstdc++-v3/include/std/chrono: (__detail::ceil) Move implementation of std::chrono::ceil into private namespace so that it's available to pre-C++17 code. * libstdc++-v3/include/bits/atomic_futex.h: (__atomic_futex_unsigned::_M_load_when_equal_for, __atomic_futex_unsigned::_M_load_when_equal_until): Use __detail::ceil to convert delta to the reference clock duration type to avoid resolution problems * libstdc++-v3/testsuite/30_threads/async/async.cc: (test_pr91486): New test for __atomic_futex_unsigned::_M_load_when_equal_for. * run test03 with steady_clock_copy, which behaves identically to std::chrono::steady_clock, but isn't std::chrono::steady_clock. This causes the overload of __atomic_futex_unsigned::_M_load_when_equal_until that takes an arbitrary clock to be called. * invent test04 which uses a deliberately slow running clock in order to exercise the looping behaviour o __atomic_futex_unsigned::_M_load_when_equal_until described above. * libstdc++-v3/include/bits/atomic_futex.h: (__atomic_futex_unsigned) Add loop to _M_load_when_equal_until on generic _Clock to check the timeout against _Clock again after _M_load_when_equal_until returns indicating a timeout. * libstdc++-v3/testsuite/30_threads/async/async.cc: Invent slow_clock that runs at an eleventh of steady_clock's speed. Use it to test the user-supplied-clock variant of __atomic_futex_unsigned::_M_load_when_equal_until works generally with test03 and loops correctly when the timeout time hasn't been reached in test04. * libstdc++-v3/include/bits/atomic_futex.h: (__atomic_futex_unsigned): Change __clock_t typedef to use steady_clock so that unknown clocks are synced to it rather than system_clock. Change existing __clock_t overloads of _M_load_and_text_until_impl and _M_load_when_equal_until to use system_clock explicitly. Remove comment about DR 887 since these changes address that problem as best as we currently able. * libstdc++-v3/config/abi/pre/gnu.ver: Update for addition of __atomic_futex_unsigned_base::_M_futex_wait_until_steady. * libstdc++-v3/include/bits/atomic_futex.h (__atomic_futex_unsigned_base): Add comments to clarify that _M_futex_wait_until _M_load_and_test_until use CLOCK_REALTIME. Declare new _M_futex_wait_until_steady and _M_load_and_text_until_steady methods that use CLOCK_MONOTONIC. Add _M_load_and_test_until_impl and _M_load_when_equal_until overloads that accept a steady_clock time_point and use these new methods. * libstdc++-v3/src/c++11/futex.cc: Include headers required for clock_gettime. Add futex_clock_monotonic_flag constant to tell futex to use CLOCK_MONOTONIC to match the existing futex_clock_realtime_flag. Add futex_clock_monotonic_unavailable to store the result of trying to use CLOCK_MONOTONIC. (__atomic_futex_unsigned_base::_M_futex_wait_until_steady): Add new variant of _M_futex_wait_until that uses CLOCK_MONOTONIC to support waiting using steady_clock. * libstdc++-v3/src/c++11/futex.cc: Add new constants for required futex flags. Add futex_clock_realtime_unavailable flag to store result of trying to use FUTEX_CLOCK_REALTIME. (__atomic_futex_unsigned_base::_M_futex_wait_until): Try to use FUTEX_WAIT_BITSET with FUTEX_CLOCK_REALTIME and only fall back to using gettimeofday and FUTEX_WAIT if that's not supported. * libstdc++-v3/testsuite/30_threads/async/async.cc (test02): Test steady_clock with std::future::wait_until. (test03): Add new test templated on clock type waiting for future associated with async to resolve. (main): Call test03 to test both system_clock and steady_clock. Mike Crowe (8): libstdc++: Improve async test libstdc++ futex: Use FUTEX_CLOCK_REALTIME for wait libstdc++ futex: Support waiting on std::chrono::steady_clock directly libstdc++ atomic_futex: Use std::chrono::steady_clock as reference clock libstdc++ futex: Loop when waiting against arbitrary clock libstdc++ atomic_futex: Avoid rounding errors in std::future::wait_* [PR91486] libstdc++ condition_variable: Avoid rounding errors on custom clocks libstdc++: Extra async tests, not for merging libstdc++-v3/config/abi/pre/gnu.ver | 10 ++-- libstdc++-v3/include/bits/atomic_futex.h | 93 +++++++++++++++++++++++++++++++----- libstdc++-v3/include/std/chrono | 19 +++++-- libstdc++-v3/include/std/condition_variable | 18 +++---- libstdc++-v3/src/c++11/futex.cc | 119 ++++++++++++++++++++++++++++++++++++++++++++++- libstdc++-v3/testsuite/30_threads/async/async.cc | 188 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- libstdc++-v3/testsuite/30_threads/condition_variable/members/68519.cc | 61 ++++++++++++++++++++--- 7 files changed, 473 insertions(+), 35 deletions(-) base-commit: 6ce3d791dfcba469e709935aba5743640f7d4959 -- git-series 0.9.1