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

shared_mutex: Optimize busy-waiting by detecting waiters and try to steal the notifying bit

Add an unused has_waiters() method.
This commit is contained in:
Eladash 2022-08-07 17:48:14 +03:00 committed by Ivan
parent 26e731b487
commit 2ec039365f
2 changed files with 34 additions and 3 deletions

View File

@ -6,14 +6,27 @@ void shared_mutex::imp_lock_shared(u32 val)
{ {
ensure(val < c_err); // "shared_mutex underflow" ensure(val < c_err); // "shared_mutex underflow"
// Try to steal the notification bit
if (val & c_sig && m_value.compare_exchange(val, val - c_sig + 1))
{
return;
}
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
{ {
busy_wait();
if (try_lock_shared()) if (try_lock_shared())
{ {
return; return;
} }
const u32 old = m_value;
if (old & c_sig && m_value.compare_and_swap_test(old, old - c_sig + 1))
{
return;
}
busy_wait();
} }
// Acquire writer lock and downgrade // Acquire writer lock and downgrade
@ -75,11 +88,24 @@ void shared_mutex::imp_lock(u32 val)
{ {
ensure(val < c_err); // "shared_mutex underflow" ensure(val < c_err); // "shared_mutex underflow"
// Try to steal the notification bit
if (val & c_sig && m_value.compare_exchange(val, val - c_sig + c_one))
{
return;
}
for (int i = 0; i < 10; i++) for (int i = 0; i < 10; i++)
{ {
busy_wait(); busy_wait();
if (!m_value && try_lock()) const u32 old = m_value;
if (!old && try_lock())
{
return;
}
if (old & c_sig && m_value.compare_and_swap_test(old, old - c_sig + c_one))
{ {
return; return;
} }

View File

@ -171,6 +171,11 @@ public:
{ {
return m_value.load() < c_one - 1; return m_value.load() < c_one - 1;
} }
bool has_waiters() const
{
return m_value.load() > c_one;
}
}; };
// Simplified shared (reader) lock implementation. // Simplified shared (reader) lock implementation.