On Sun, 14 Sept 2025 at 21:34, Mike Crowe <[email protected]> wrote:
>
> Add tests to show that std::condition_variable::wait_until and
> std::condition_variable::wait_for don't suffer from libstdc++/PR116586.
>
> libstdc++-v3/ChangeLog:
>
>         * testsuite/30_threads/condition_variable/members/116586.c: New test.
>
> Signed-off-by: Mike Crowe <[email protected]>
> ---
>  .../condition_variable/members/116586.cc      | 58 +++++++++++++++++++
>  1 file changed, 58 insertions(+)
>  create mode 100644 
> libstdc++-v3/testsuite/30_threads/condition_variable/members/116586.cc
>
> diff --git 
> a/libstdc++-v3/testsuite/30_threads/condition_variable/members/116586.cc 
> b/libstdc++-v3/testsuite/30_threads/condition_variable/members/116586.cc
> new file mode 100644
> index 00000000000..d10f8036bb6
> --- /dev/null
> +++ b/libstdc++-v3/testsuite/30_threads/condition_variable/members/116586.cc
> @@ -0,0 +1,58 @@
> +// { dg-do run { target c++11 } }
> +
> +#include <chrono>
> +#include <mutex>
> +#include <testsuite_hooks.h>

This is missing <condition_variable> (it works with the default build
config because every test gets the <bits/stdc++.h> PCH included).

Some of the other tests were missing <future>

> +
> +namespace chrono = std::chrono;
> +
> +// thread.timedmutex.requirements.general:
> +//   If abs_time has already passed, the function attempts to obtain
> +//   ownership without blocking (as if by calling try_lock()).
> +
> +template <typename Clock>
> +void
> +test_absolute(chrono::nanoseconds offset)
> +{
> +  std::mutex mtx;
> +  std::condition_variable cv;
> +  chrono::time_point<Clock> tp(offset);
> +  std::unique_lock lock(mtx);

This uses CTAD which isn't valid in C++11 and C++14. One of the tests
used CTAD for std::future too.

(And my suggestion to use chrono literals won't work in this file
either, as I'd forgotten they weren't added until C++14 - bah)


> +  // Doesn't cope with spurious wakeup
> +  VERIFY(cv.wait_until(lock, tp) == std::cv_status::timeout);
> +}
> +
> +// The type of clock used for the actual wait depends on whether
> +// _GLIBCXX_USE_PTHREAD_MUTEX_CLOCKLOCK is defined. We might as well just 
> test
> +// both steady_clock and system_clock.
> +template <typename Clock>
> +void
> +test_relative(chrono::nanoseconds offset)
> +{
> +  std::mutex mtx;
> +  std::condition_variable cv;
> +  const auto d = -Clock::now().time_since_epoch() + offset;
> +  std::unique_lock lock(mtx);
> +  // Doesn't cope with spurious wakeup
> +  VERIFY(cv.wait_for(lock, d) == std::cv_status::timeout);
> +}
> +
> +int main()
> +{
> +  // It's not really possible to arrange for the relative calls to have
> +  // tv_nsec == 0 due to time advancing.
> +  for (const chrono::nanoseconds offset : {
> +      // tv_sec == 0, tv_nsec == 0
> +      chrono::nanoseconds{0},
> +      // tv_sec == 0, tv_nsec < 0
> +      chrono::duration_cast<chrono::nanoseconds>(chrono::milliseconds{-10}),
> +      // tv_sec < 0
> +      chrono::duration_cast<chrono::nanoseconds>(chrono::seconds{-10})
> +    }) {

Apparently this needs <initializer_list> to be included to deduce the
{...} here.

I've made these changes locally when running the tests, so there's no
need for new patches - I'll get these pushed after I've pushed my one
with the utility functions for creating timespec.

> +    test_absolute<chrono::system_clock>(offset);
> +    test_relative<chrono::system_clock>(offset);
> +
> +    test_absolute<chrono::steady_clock>(offset);
> +    test_relative<chrono::steady_clock>(offset);
> +  }
> +}
> --
> 2.39.5
>

Reply via email to