mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-02 21:11:25 +12:00
Busy waiting added
This commit is contained in:
parent
b637bd3866
commit
b1aa87b515
7 changed files with 196 additions and 373 deletions
|
@ -9,8 +9,7 @@ class shared_mutex final
|
|||
enum : s64
|
||||
{
|
||||
c_one = 1ull << 31, // Fixed-point 1.0 value (one writer)
|
||||
c_min = 0x00000002, // Fixed-point 1.0/max_readers value
|
||||
c_sig = 0x00000001,
|
||||
c_min = 0x00000001, // Fixed-point 1.0/max_readers value
|
||||
c_max = c_one
|
||||
};
|
||||
|
||||
|
@ -18,7 +17,7 @@ class shared_mutex final
|
|||
|
||||
void imp_lock_shared(s64 _old);
|
||||
void imp_unlock_shared(s64 _old);
|
||||
|
||||
void imp_wait(s64 _old);
|
||||
void imp_lock(s64 _old);
|
||||
void imp_unlock(s64 _old);
|
||||
|
||||
|
@ -56,8 +55,8 @@ public:
|
|||
|
||||
void lock()
|
||||
{
|
||||
// Unconditional decrement
|
||||
const s64 value = m_value.fetch_sub(c_one);
|
||||
// Try to lock
|
||||
const s64 value = m_value.compare_and_swap(c_one, 0);
|
||||
|
||||
if (value != c_one)
|
||||
{
|
||||
|
@ -80,7 +79,6 @@ public:
|
|||
|
||||
void lock_upgrade()
|
||||
{
|
||||
// TODO
|
||||
if (!m_value.compare_and_swap_test(c_one - c_min, 0))
|
||||
{
|
||||
imp_lock_upgrade();
|
||||
|
@ -91,7 +89,6 @@ public:
|
|||
|
||||
void lock_degrade()
|
||||
{
|
||||
// TODO
|
||||
if (!m_value.compare_and_swap_test(0, c_one - c_min))
|
||||
{
|
||||
imp_lock_degrade();
|
||||
|
@ -103,15 +100,16 @@ public:
|
|||
class reader_lock final
|
||||
{
|
||||
shared_mutex& m_mutex;
|
||||
bool m_upgraded = false;
|
||||
|
||||
void lock()
|
||||
{
|
||||
m_mutex.lock_shared();
|
||||
m_upgraded ? m_mutex.lock() : m_mutex.lock_shared();
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
m_mutex.unlock_shared();
|
||||
m_upgraded ? m_mutex.unlock() : m_mutex.unlock_shared();
|
||||
}
|
||||
|
||||
friend class cond_variable;
|
||||
|
@ -125,6 +123,16 @@ public:
|
|||
lock();
|
||||
}
|
||||
|
||||
// One-way lock upgrade
|
||||
void upgrade()
|
||||
{
|
||||
if (!m_upgraded)
|
||||
{
|
||||
m_mutex.lock_upgrade();
|
||||
m_upgraded = true;
|
||||
}
|
||||
}
|
||||
|
||||
~reader_lock()
|
||||
{
|
||||
unlock();
|
||||
|
@ -136,95 +144,29 @@ class writer_lock final
|
|||
{
|
||||
shared_mutex& m_mutex;
|
||||
|
||||
void lock()
|
||||
{
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
||||
void unlock()
|
||||
{
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
friend class cond_variable;
|
||||
|
||||
public:
|
||||
writer_lock(const writer_lock&) = delete;
|
||||
|
||||
explicit writer_lock(shared_mutex& mutex)
|
||||
: m_mutex(mutex)
|
||||
{
|
||||
m_mutex.lock();
|
||||
lock();
|
||||
}
|
||||
|
||||
~writer_lock()
|
||||
{
|
||||
m_mutex.unlock();
|
||||
}
|
||||
};
|
||||
|
||||
// Exclusive (writer) lock in the scope of shared (reader) lock (experimental).
|
||||
class upgraded_lock final
|
||||
{
|
||||
shared_mutex& m_mutex;
|
||||
|
||||
public:
|
||||
upgraded_lock(const writer_lock&) = delete;
|
||||
|
||||
explicit upgraded_lock(shared_mutex& mutex)
|
||||
: m_mutex(mutex)
|
||||
{
|
||||
m_mutex.lock_upgrade();
|
||||
}
|
||||
|
||||
~upgraded_lock()
|
||||
{
|
||||
m_mutex.lock_degrade();
|
||||
}
|
||||
};
|
||||
|
||||
// Normal mutex with owner registration.
|
||||
class owned_mutex
|
||||
{
|
||||
atomic_t<u32> m_value{0};
|
||||
atomic_t<u32> m_owner{0};
|
||||
|
||||
protected:
|
||||
// Thread id
|
||||
static thread_local const u32 g_tid;
|
||||
|
||||
public:
|
||||
constexpr owned_mutex() = default;
|
||||
|
||||
// Returns false if current thread already owns the mutex.
|
||||
bool lock() noexcept;
|
||||
|
||||
// Returns false if locked by any thread.
|
||||
bool try_lock() noexcept;
|
||||
|
||||
// Returns false if current thread doesn't own the mutex.
|
||||
bool unlock() noexcept;
|
||||
|
||||
// Check state.
|
||||
bool is_locked() const { return m_value != 0; }
|
||||
|
||||
// Check owner.
|
||||
bool is_owned() const { return m_owner == g_tid; }
|
||||
};
|
||||
|
||||
// Recursive lock for owned_mutex (experimental).
|
||||
class recursive_lock final
|
||||
{
|
||||
owned_mutex& m_mutex;
|
||||
const bool m_first;
|
||||
|
||||
public:
|
||||
recursive_lock(const recursive_lock&) = delete;
|
||||
|
||||
explicit recursive_lock(owned_mutex& mutex)
|
||||
: m_mutex(mutex)
|
||||
, m_first(mutex.lock())
|
||||
{
|
||||
}
|
||||
|
||||
// Check whether the lock "owns" the mutex
|
||||
explicit operator bool() const
|
||||
{
|
||||
return m_first;
|
||||
}
|
||||
|
||||
~recursive_lock()
|
||||
{
|
||||
if (m_first && !m_mutex.unlock())
|
||||
{
|
||||
}
|
||||
unlock();
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue