mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-05 14:31:24 +12:00
mutex.cpp: minor update
New concept (incomplete)
This commit is contained in:
parent
3907dd0444
commit
beab5291bb
2 changed files with 141 additions and 1 deletions
|
@ -1,7 +1,12 @@
|
||||||
#include "mutex.h"
|
#include "mutex.h"
|
||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
|
|
||||||
#include <limits.h>
|
#include <climits>
|
||||||
|
#include <vector>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
// TLS variable for tracking owned mutexes
|
||||||
|
thread_local std::vector<shared_mutex*> g_tls_locks;
|
||||||
|
|
||||||
void shared_mutex::imp_lock_shared(s64 _old)
|
void shared_mutex::imp_lock_shared(s64 _old)
|
||||||
{
|
{
|
||||||
|
@ -217,12 +222,14 @@ void shared_mutex::imp_unlock(s64 _old)
|
||||||
|
|
||||||
void shared_mutex::imp_lock_upgrade()
|
void shared_mutex::imp_lock_upgrade()
|
||||||
{
|
{
|
||||||
|
// TODO
|
||||||
unlock_shared();
|
unlock_shared();
|
||||||
lock();
|
lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void shared_mutex::imp_lock_degrade()
|
void shared_mutex::imp_lock_degrade()
|
||||||
{
|
{
|
||||||
|
// TODO
|
||||||
unlock();
|
unlock();
|
||||||
lock_shared();
|
lock_shared();
|
||||||
}
|
}
|
||||||
|
@ -250,3 +257,78 @@ bool shared_mutex::try_lock_degrade()
|
||||||
// TODO
|
// TODO
|
||||||
return m_value.compare_and_swap_test(0, c_one - c_min);
|
return m_value.compare_and_swap_test(0, c_one - c_min);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
safe_reader_lock::safe_reader_lock(shared_mutex& mutex)
|
||||||
|
: m_mutex(mutex)
|
||||||
|
, m_is_owned(false)
|
||||||
|
{
|
||||||
|
if (std::count(g_tls_locks.cbegin(), g_tls_locks.cend(), &m_mutex) == 0)
|
||||||
|
{
|
||||||
|
m_is_owned = true;
|
||||||
|
|
||||||
|
if (m_is_owned)
|
||||||
|
{
|
||||||
|
m_mutex.lock_shared();
|
||||||
|
g_tls_locks.emplace_back(&m_mutex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: order locks
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
safe_reader_lock::~safe_reader_lock()
|
||||||
|
{
|
||||||
|
if (m_is_owned)
|
||||||
|
{
|
||||||
|
m_mutex.unlock_shared();
|
||||||
|
g_tls_locks.erase(std::remove(g_tls_locks.begin(), g_tls_locks.end(), &m_mutex), g_tls_locks.cend());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: order locks
|
||||||
|
}
|
||||||
|
|
||||||
|
safe_writer_lock::safe_writer_lock(shared_mutex& mutex)
|
||||||
|
: m_mutex(mutex)
|
||||||
|
, m_is_owned(false)
|
||||||
|
, m_is_upgraded(false)
|
||||||
|
{
|
||||||
|
if (std::count(g_tls_locks.cbegin(), g_tls_locks.cend(), &m_mutex) == 0)
|
||||||
|
{
|
||||||
|
m_is_owned = true;
|
||||||
|
|
||||||
|
if (m_is_owned)
|
||||||
|
{
|
||||||
|
m_mutex.lock_shared();
|
||||||
|
g_tls_locks.emplace_back(&m_mutex);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: order locks
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_mutex.is_reading())
|
||||||
|
{
|
||||||
|
m_is_upgraded = true;
|
||||||
|
m_mutex.lock_upgrade();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
safe_writer_lock::~safe_writer_lock()
|
||||||
|
{
|
||||||
|
if (m_is_upgraded)
|
||||||
|
{
|
||||||
|
m_mutex.lock_degrade();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_is_owned)
|
||||||
|
{
|
||||||
|
m_mutex.unlock();
|
||||||
|
g_tls_locks.erase(std::remove(g_tls_locks.begin(), g_tls_locks.end(), &m_mutex), g_tls_locks.cend());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: order locks
|
||||||
|
}
|
||||||
|
|
|
@ -95,6 +95,11 @@ public:
|
||||||
imp_lock_degrade();
|
imp_lock_degrade();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool is_reading() const
|
||||||
|
{
|
||||||
|
return (m_value.load() % c_one) != 0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Simplified shared (reader) lock implementation.
|
// Simplified shared (reader) lock implementation.
|
||||||
|
@ -171,3 +176,56 @@ public:
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Safe reader lock. Can be recursive above other safe locks (reader or writer).
|
||||||
|
class safe_reader_lock final
|
||||||
|
{
|
||||||
|
shared_mutex& m_mutex;
|
||||||
|
bool m_is_owned;
|
||||||
|
|
||||||
|
void lock()
|
||||||
|
{
|
||||||
|
m_mutex.lock_shared();
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlock()
|
||||||
|
{
|
||||||
|
m_mutex.unlock_shared();
|
||||||
|
}
|
||||||
|
|
||||||
|
friend class cond_variable;
|
||||||
|
|
||||||
|
public:
|
||||||
|
safe_reader_lock(const safe_reader_lock&) = delete;
|
||||||
|
|
||||||
|
explicit safe_reader_lock(shared_mutex& mutex);
|
||||||
|
|
||||||
|
~safe_reader_lock();
|
||||||
|
};
|
||||||
|
|
||||||
|
// Safe writer lock. Can be recursive above other safe locks. Performs upgrade and degrade operations above existing reader lock if necessary.
|
||||||
|
class safe_writer_lock final
|
||||||
|
{
|
||||||
|
shared_mutex& m_mutex;
|
||||||
|
bool m_is_owned;
|
||||||
|
bool m_is_upgraded;
|
||||||
|
|
||||||
|
void lock()
|
||||||
|
{
|
||||||
|
m_mutex.lock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void unlock()
|
||||||
|
{
|
||||||
|
m_mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
friend class cond_variable;
|
||||||
|
|
||||||
|
public:
|
||||||
|
safe_writer_lock(const safe_writer_lock&) = delete;
|
||||||
|
|
||||||
|
explicit safe_writer_lock(shared_mutex& mutex);
|
||||||
|
|
||||||
|
~safe_writer_lock();
|
||||||
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue