]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
libstdc++: Fix time_point conversion in atomic timed waits
authorJonathan Wakely <jwakely@redhat.com>
Fri, 17 Jan 2025 22:16:08 +0000 (22:16 +0000)
committerJonathan Wakely <redi@gcc.gnu.org>
Fri, 30 May 2025 09:02:27 +0000 (10:02 +0100)
Even if a time_point already uses the right clock, we might still need
to convert it to use the expected duration. Calling __to_wait_clock will
perform that conversion, so use that even when the clock is correct.

libstdc++-v3/ChangeLog:

* include/bits/atomic_timed_wait.h (__to_wait_clock): Do not use
chrono::ceil if clock and duration are already correct type.
(__wait_until): Always call __to_wait_clock.

libstdc++-v3/include/bits/atomic_timed_wait.h

index 9fc28f3d26968feaf514da6660e9e7b212dd669d..a916c10879b79d29794e41ce7c04c3a8a4af957a 100644 (file)
@@ -70,7 +70,10 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
                                               _Dur>& __atime) noexcept
       {
        using __w_dur = typename __wait_clock_t::duration;
-       return chrono::ceil<__w_dur>(__atime);
+       if constexpr (is_same_v<__w_dur, _Dur>)
+         return __atime;
+       else
+         return chrono::ceil<__w_dur>(__atime);
       }
 
 #ifdef _GLIBCXX_HAVE_LINUX_FUTEX
@@ -222,22 +225,19 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       __wait_until(const __platform_wait_t* __addr, const __wait_args_base& __args,
                   const chrono::time_point<_Clock, _Dur>& __atime) noexcept
       {
-       if constexpr (is_same_v<__wait_clock_t, _Clock>)
-         return __detail::__wait_until_impl(__addr, __args, __atime);
-       else
-         {
-           auto __res = __detail::__wait_until_impl(__addr, __args,
-                                                    __to_wait_clock(__atime));
-           if (!__res.first)
-             {
-               // We got a timeout when measured against __clock_t but
-               // we need to check against the caller-supplied clock
-               // to tell whether we should return a timeout.
-               if (_Clock::now() < __atime)
-                 __res.first = true;
-             }
-           return __res;
-         }
+       auto __at = __detail::__to_wait_clock(__atime);
+       auto __res = __detail::__wait_until_impl(__addr, __args, __at);
+
+       if constexpr (!is_same_v<__wait_clock_t, _Clock>)
+         if (!__res.first)
+           {
+             // We got a timeout when measured against __clock_t but
+             // we need to check against the caller-supplied clock
+             // to tell whether we should return a timeout.
+             if (_Clock::now() < __atime)
+               __res.first = true;
+           }
+       return __res;
       }
 
     // Returns {true, val} if wait ended before a timeout.