diff options
author | Andreas Kling <kling@serenityos.org> | 2020-04-13 12:29:41 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2020-04-13 12:33:42 +0200 |
commit | 94647fa4abebd187e1abd7f0d01681dd9d08ea9b (patch) | |
tree | 267b002579c4e90386baaa4230371cd06c2d6ea9 /Libraries/LibThread/Lock.h | |
parent | 02e0fab19af9cf892ee651e5916c9895703cefdd (diff) | |
download | serenity-94647fa4abebd187e1abd7f0d01681dd9d08ea9b.zip |
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.
Diffstat (limited to 'Libraries/LibThread/Lock.h')
-rw-r--r-- | Libraries/LibThread/Lock.h | 42 |
1 files changed, 15 insertions, 27 deletions
diff --git a/Libraries/LibThread/Lock.h b/Libraries/LibThread/Lock.h index 2ae3def054..dd3b6e55f1 100644 --- a/Libraries/LibThread/Lock.h +++ b/Libraries/LibThread/Lock.h @@ -44,9 +44,8 @@ public: void unlock(); private: - AK::Atomic<bool> m_lock { false }; + Atomic<int> m_holder { 0 }; u32 m_level { 0 }; - int m_holder { -1 }; }; class Locker { @@ -67,16 +66,16 @@ private: [[gnu::always_inline]] inline void Lock::lock() { int tid = gettid(); + if (m_holder == tid) { + ++m_level; + return; + } for (;;) { - 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_lock.store(false, AK::memory_order_release); - return; - } - m_lock.store(false, AK::memory_order_release); + 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); } @@ -84,22 +83,11 @@ private: 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_level); - --m_level; - if (m_level) { - m_lock.store(false, AK::memory_order_release); - return; - } - m_holder = -1; - m_lock.store(false, AK::memory_order_release); - return; - } - donate(m_holder); - } + ASSERT(m_holder == gettid()); + ASSERT(m_level); + --m_level; + if (!m_level) + m_holder.store(0, AK::memory_order_release); } #define LOCKER(lock) LibThread::Locker locker(lock) |