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 <m...@mcrowe.com> --- .../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> + +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); + // 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}) + }) { + 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