Use atomic wait in shared_mutex and semaphore

This commit is contained in:
Nekotekina 2019-07-27 17:08:45 +03:00
parent f63e89f9b4
commit 8886414013
2 changed files with 19 additions and 28 deletions

View File

@ -1,7 +1,4 @@
#include "mutex.h"
#include "sync.h"
#include <climits>
void shared_mutex::imp_lock_shared(u32 val)
{
@ -122,24 +119,32 @@ void shared_mutex::imp_unlock_vip(u32 old)
void shared_mutex::imp_wait()
{
while (!balanced_wait_until(m_value, -1, [&](u32& value, auto...)
while (true)
{
if (value >= c_sig)
const auto [old, ok] = m_value.fetch_op([](u32& value)
{
value -= c_sig;
return true;
if (value >= c_sig)
{
value -= c_sig;
return true;
}
return false;
});
if (ok)
{
break;
}
return false;
}))
{
m_value.wait(old);
}
}
void shared_mutex::imp_signal()
{
m_value += c_sig;
balanced_awaken(m_value, 1);
m_value.notify_one();
}
void shared_mutex::imp_lock(u32 val)

View File

@ -1,5 +1,4 @@
#include "sema.h"
#include "sync.h"
void semaphore_base::imp_wait()
{
@ -15,14 +14,6 @@ void semaphore_base::imp_wait()
}
}
#ifdef _WIN32
const s32 value = m_value.fetch_sub(1);
if (value <= 0)
{
NtWaitForKeyedEvent(nullptr, &m_value, false, nullptr);
}
#else
while (true)
{
// Try hard way
@ -51,24 +42,19 @@ void semaphore_base::imp_wait()
if (value >= 0)
{
// Signal other waiter to wake up or to restore sign bit
futex(&m_value, FUTEX_WAKE_PRIVATE, 1);
m_value.notify_one();
return;
}
futex(&m_value, FUTEX_WAIT_PRIVATE, value);
m_value.wait(value);
}
#endif
}
void semaphore_base::imp_post(s32 _old)
{
verify("semaphore_base: overflow" HERE), _old < 0;
#ifdef _WIN32
NtReleaseKeyedEvent(nullptr, &m_value, false, nullptr);
#else
futex(&m_value, FUTEX_WAKE_PRIVATE, 1);
#endif
m_value.notify_one();
}
bool semaphore_base::try_post(s32 _max)