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

Add cond_variable::wait_unlock

This commit is contained in:
Nekotekina 2018-10-02 17:50:22 +03:00
parent 4bef0f8dab
commit bc87c5808c
2 changed files with 11 additions and 18 deletions

View File

@ -1736,22 +1736,6 @@ bool thread_ctrl::_wait_for(u64 usec)
{
auto _this = g_tls_this_thread;
struct half_lock
{
shared_mutex& ref;
void lock()
{
// Used to avoid additional lock + unlock
}
void unlock()
{
ref.unlock();
}
}
_lock{_this->m_mutex};
do
{
// Mutex is unlocked at the start and after the waiting
@ -1772,7 +1756,6 @@ bool thread_ctrl::_wait_for(u64 usec)
return false;
}
// Lock (semaphore)
_this->m_mutex.lock();
// Double-check the value
@ -1791,7 +1774,7 @@ bool thread_ctrl::_wait_for(u64 usec)
}
}
}
while (_this->m_cond.wait(_lock, std::exchange(usec, usec > cond_variable::max_timeout ? -1 : 0)));
while (_this->m_cond.wait_unlock(std::exchange(usec, usec > cond_variable::max_timeout ? -1 : 0), _this->m_mutex));
// Timeout
return false;

View File

@ -2,6 +2,7 @@
#include "types.h"
#include "Atomic.h"
#include <shared_mutex>
// Lightweight condition variable
class cond_variable
@ -32,6 +33,15 @@ public:
return res;
}
// Unlock all specified objects but don't lock them again
template <typename... Locks>
bool wait_unlock(u64 usec_timeout, Locks&&... locks)
{
const u32 _old = m_value.fetch_add(1); // Increment waiter counter
(..., std::forward<Locks>(locks).unlock());
return imp_wait(_old, usec_timeout);
}
// Wake one thread
void notify_one() noexcept
{