1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 10:42:36 +01:00

Fix cond_variable timeout

Thanks @Farseer2 for debugging
This commit is contained in:
Nekotekina 2017-11-17 22:20:46 +03:00
parent 223f17ac7e
commit c58738807e
3 changed files with 7 additions and 4 deletions

View File

@ -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 // Timeout
return false; return false;

View File

@ -10,12 +10,13 @@
bool cond_variable::imp_wait(u32 _old, u64 _timeout) noexcept 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 verify(HERE), _old != -1; // Very unlikely: it requires 2^32 distinct threads to wait simultaneously
const bool is_inf = _timeout > max_timeout;
#ifdef _WIN32 #ifdef _WIN32
LARGE_INTEGER timeout; LARGE_INTEGER timeout;
timeout.QuadPart = _timeout * -10; 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; 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) 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 ? 0
: errno; : errno;
// Normal or timeout wakeup // Normal or timeout wakeup
if (!err || (_timeout != -1 && err == ETIMEDOUT)) if (!err || (!is_inf && err == ETIMEDOUT))
{ {
// Cleanup (remove waiter) // Cleanup (remove waiter)
verify(HERE), m_value--; verify(HERE), m_value--;

View File

@ -47,4 +47,6 @@ public:
imp_wake(-1); imp_wake(-1);
} }
} }
static constexpr u64 max_timeout = u64{UINT32_MAX} / 1000 * 1000000;
}; };