[PATCH v5 0/8] std::future::wait_* and std::condition_variable improvements

Mike Crowe mac@mcrowe.com
Fri May 29 06:17:26 GMT 2020


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


More information about the Gcc-patches mailing list