From c58738807e205fdbeb1a8b988f76d72f1da9e5eb Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Fri, 17 Nov 2017 22:20:46 +0300 Subject: [PATCH] Fix cond_variable timeout Thanks @Farseer2 for debugging --- Utilities/Thread.cpp | 2 +- Utilities/cond.cpp | 7 ++++--- Utilities/cond.h | 2 ++ 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Utilities/Thread.cpp b/Utilities/Thread.cpp index ac77041b50..d75c1b03f7 100644 --- a/Utilities/Thread.cpp +++ b/Utilities/Thread.cpp @@ -1768,7 +1768,7 @@ bool thread_ctrl::_wait_for(u64 usec) } } } - while (_this->m_cond.wait(_lock, std::exchange(usec, usec == -1 ? -1 : 0))); + while (_this->m_cond.wait(_lock, std::exchange(usec, usec > cond_variable::max_timeout ? -1 : 0))); // Timeout return false; diff --git a/Utilities/cond.cpp b/Utilities/cond.cpp index cd574b077a..e3ecf847bd 100644 --- a/Utilities/cond.cpp +++ b/Utilities/cond.cpp @@ -10,12 +10,13 @@ bool cond_variable::imp_wait(u32 _old, u64 _timeout) noexcept { verify(HERE), _old != -1; // Very unlikely: it requires 2^32 distinct threads to wait simultaneously + const bool is_inf = _timeout > max_timeout; #ifdef _WIN32 LARGE_INTEGER timeout; timeout.QuadPart = _timeout * -10; - if (HRESULT rc = NtWaitForKeyedEvent(nullptr, &m_value, false, _timeout == -1 ? nullptr : &timeout)) + if (HRESULT rc = NtWaitForKeyedEvent(nullptr, &m_value, false, is_inf ? nullptr : &timeout)) { verify(HERE), rc == WAIT_TIMEOUT; @@ -37,12 +38,12 @@ bool cond_variable::imp_wait(u32 _old, u64 _timeout) noexcept for (u32 value = _old + 1;; value = m_value) { - const int err = futex((int*)&m_value.raw(), FUTEX_WAIT_PRIVATE, value, _timeout == -1 ? nullptr : &timeout, nullptr, 0) == 0 + const int err = futex((int*)&m_value.raw(), FUTEX_WAIT_PRIVATE, value, is_inf ? nullptr : &timeout, nullptr, 0) == 0 ? 0 : errno; // Normal or timeout wakeup - if (!err || (_timeout != -1 && err == ETIMEDOUT)) + if (!err || (!is_inf && err == ETIMEDOUT)) { // Cleanup (remove waiter) verify(HERE), m_value--; diff --git a/Utilities/cond.h b/Utilities/cond.h index e63a2331a4..74dad2d741 100644 --- a/Utilities/cond.h +++ b/Utilities/cond.h @@ -47,4 +47,6 @@ public: imp_wake(-1); } } + + static constexpr u64 max_timeout = u64{UINT32_MAX} / 1000 * 1000000; };