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"
// 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++)
{
busy_wait();
if (try_lock_shared())
{
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
@ -75,11 +88,24 @@ void shared_mutex::imp_lock(u32 val)
{
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++)
{
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;
}

View file

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