diff --git a/libstdc++-v3/include/bits/atomic_futex.h b/libstdc++-v3/include/bits/atomic_futex.h index 5f95adeb361..aa137a7b64e 100644 --- a/libstdc++-v3/include/bits/atomic_futex.h +++ b/libstdc++-v3/include/bits/atomic_futex.h @@ -219,8 +219,9 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION _M_load_when_equal_for(unsigned __val, memory_order __mo, const chrono::duration<_Rep, _Period>& __rtime) { + using __dur = typename __clock_t::duration; return _M_load_when_equal_until(__val, __mo, - __clock_t::now() + __rtime); + __clock_t::now() + chrono::__detail::ceil<__dur>(__rtime)); } // Returns false iff a timeout occurred. @@ -233,7 +234,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION do { const __clock_t::time_point __s_entry = __clock_t::now(); const auto __delta = __atime - __c_entry; - const auto __s_atime = __s_entry + __delta; + const auto __s_atime = __s_entry + + chrono::__detail::ceil<_Duration>(__delta); if (_M_load_when_equal_until(__val, __mo, __s_atime)) return true; __c_entry = _Clock::now(); diff --git a/libstdc++-v3/include/std/chrono b/libstdc++-v3/include/std/chrono index 9b9fd2bd42d..893d1f6b2c9 100644 --- a/libstdc++-v3/include/std/chrono +++ b/libstdc++-v3/include/std/chrono @@ -329,6 +329,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION #endif #endif // C++20 + // We want to use ceil even when compiling for earlier standards versions + namespace __detail + { + template + constexpr __enable_if_is_duration<_ToDur> + ceil(const duration<_Rep, _Period>& __d) + { + auto __to = chrono::duration_cast<_ToDur>(__d); + if (__to < __d) + return __to + _ToDur{1}; + return __to; + } + } + #if __cplusplus >= 201703L # define __cpp_lib_chrono 201611 @@ -346,10 +360,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION constexpr __enable_if_is_duration<_ToDur> ceil(const duration<_Rep, _Period>& __d) { - auto __to = chrono::duration_cast<_ToDur>(__d); - if (__to < __d) - return __to + _ToDur{1}; - return __to; + return __detail::ceil<_ToDur>(__d); } template diff --git a/libstdc++-v3/testsuite/30_threads/async/async.cc b/libstdc++-v3/testsuite/30_threads/async/async.cc index 31e9686fab2..46f8d2f327d 100644 --- a/libstdc++-v3/testsuite/30_threads/async/async.cc +++ b/libstdc++-v3/testsuite/30_threads/async/async.cc @@ -157,6 +157,20 @@ void test04() } } +void test_pr91486() +{ + future f1 = async(launch::async, []() { + std::this_thread::sleep_for(std::chrono::seconds(1)); + }); + + std::chrono::duration const wait_time = std::chrono::seconds(1); + auto const start_steady = chrono::steady_clock::now(); + auto status = f1.wait_for(wait_time); + auto const elapsed_steady = chrono::steady_clock::now() - start_steady; + + VERIFY( elapsed_steady >= std::chrono::seconds(1) ); +} + int main() { test01(); @@ -165,5 +179,6 @@ int main() test03(); test03(); test04(); + test_pr91486(); return 0; }