mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 19:27:45 +00:00
LibThread: Simplify the userspace Lock to remove CAS on unlock()
Instead of using a separate synchronization variable, just use the lock holder TID for synchronization. This way, we only need to CAS when first acquiring a lock.
This commit is contained in:
parent
02e0fab19a
commit
94647fa4ab
1 changed files with 15 additions and 27 deletions
|
@ -44,9 +44,8 @@ public:
|
||||||
void unlock();
|
void unlock();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
AK::Atomic<bool> m_lock { false };
|
Atomic<int> m_holder { 0 };
|
||||||
u32 m_level { 0 };
|
u32 m_level { 0 };
|
||||||
int m_holder { -1 };
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class Locker {
|
class Locker {
|
||||||
|
@ -67,16 +66,16 @@ private:
|
||||||
[[gnu::always_inline]] inline void Lock::lock()
|
[[gnu::always_inline]] inline void Lock::lock()
|
||||||
{
|
{
|
||||||
int tid = gettid();
|
int tid = gettid();
|
||||||
for (;;) {
|
if (m_holder == tid) {
|
||||||
bool expected = false;
|
|
||||||
if (m_lock.compare_exchange_strong(expected, true, AK::memory_order_acq_rel)) {
|
|
||||||
if (m_holder == -1 || m_holder == tid) {
|
|
||||||
m_holder = tid;
|
|
||||||
++m_level;
|
++m_level;
|
||||||
m_lock.store(false, AK::memory_order_release);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_lock.store(false, AK::memory_order_release);
|
for (;;) {
|
||||||
|
int expected = 0;
|
||||||
|
if (m_holder.compare_exchange_strong(expected, tid, AK::memory_order_acq_rel)) {
|
||||||
|
m_holder = tid;
|
||||||
|
m_level = 1;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
donate(m_holder);
|
donate(m_holder);
|
||||||
}
|
}
|
||||||
|
@ -84,22 +83,11 @@ private:
|
||||||
|
|
||||||
inline void Lock::unlock()
|
inline void Lock::unlock()
|
||||||
{
|
{
|
||||||
for (;;) {
|
|
||||||
bool expected = false;
|
|
||||||
if (m_lock.compare_exchange_strong(expected, true, AK::memory_order_acq_rel)) {
|
|
||||||
ASSERT(m_holder == gettid());
|
ASSERT(m_holder == gettid());
|
||||||
ASSERT(m_level);
|
ASSERT(m_level);
|
||||||
--m_level;
|
--m_level;
|
||||||
if (m_level) {
|
if (!m_level)
|
||||||
m_lock.store(false, AK::memory_order_release);
|
m_holder.store(0, AK::memory_order_release);
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_holder = -1;
|
|
||||||
m_lock.store(false, AK::memory_order_release);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
donate(m_holder);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LOCKER(lock) LibThread::Locker locker(lock)
|
#define LOCKER(lock) LibThread::Locker locker(lock)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue