From 3439a479afbb13f28a436b472e150a71c5b3b6ce Mon Sep 17 00:00:00 2001 From: Sergey Bugaev Date: Sun, 25 Aug 2019 23:51:27 +0300 Subject: LibThread: Move CLock to LibThread::Lock And adapt all the code that uses it. --- Libraries/LibC/malloc.cpp | 10 +-- Libraries/LibCore/CEventLoop.cpp | 2 +- Libraries/LibCore/CEventLoop.h | 4 +- Libraries/LibCore/CLock.h | 125 ----------------------------- Libraries/LibThread/BackgroundAction.cpp | 8 +- Libraries/LibThread/BackgroundAction.h | 4 +- Libraries/LibThread/Lock.h | 133 +++++++++++++++++++++++++++++++ Servers/AudioServer/ASMixer.h | 4 +- 8 files changed, 149 insertions(+), 141 deletions(-) delete mode 100644 Libraries/LibCore/CLock.h create mode 100644 Libraries/LibThread/Lock.h diff --git a/Libraries/LibC/malloc.cpp b/Libraries/LibC/malloc.cpp index 7495966366..d5364f5161 100644 --- a/Libraries/LibC/malloc.cpp +++ b/Libraries/LibC/malloc.cpp @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include #include @@ -19,10 +19,10 @@ #define MAGIC_BIGALLOC_HEADER 0x42697267 #define PAGE_ROUND_UP(x) ((((size_t)(x)) + PAGE_SIZE - 1) & (~(PAGE_SIZE - 1))) -static CLock& malloc_lock() +static LibThread::Lock& malloc_lock() { - static u32 lock_storage[sizeof(CLock) / sizeof(u32)]; - return *reinterpret_cast(&lock_storage); + static u32 lock_storage[sizeof(LibThread::Lock) / sizeof(u32)]; + return *reinterpret_cast(&lock_storage); } static const int number_of_chunked_blocks_to_keep_around_per_size_class = 32; @@ -317,7 +317,7 @@ void* realloc(void* ptr, size_t size) void __malloc_init() { - new (&malloc_lock()) CLock(); + new (&malloc_lock()) LibThread::Lock(); if (getenv("LIBC_NOSCRUB_MALLOC")) s_scrub_malloc = false; if (getenv("LIBC_NOSCRUB_FREE")) diff --git a/Libraries/LibCore/CEventLoop.cpp b/Libraries/LibCore/CEventLoop.cpp index ac4b7c6ae0..1d34d7299d 100644 --- a/Libraries/LibCore/CEventLoop.cpp +++ b/Libraries/LibCore/CEventLoop.cpp @@ -5,10 +5,10 @@ #include #include #include -#include #include #include #include +#include #include #include #include diff --git a/Libraries/LibCore/CEventLoop.h b/Libraries/LibCore/CEventLoop.h index aa7777b768..bf8700d779 100644 --- a/Libraries/LibCore/CEventLoop.h +++ b/Libraries/LibCore/CEventLoop.h @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include #include #include @@ -69,7 +69,7 @@ private: static int s_wake_pipe_fds[2]; - CLock m_lock; + LibThread::Lock m_lock; struct EventLoopTimer { int timer_id { 0 }; diff --git a/Libraries/LibCore/CLock.h b/Libraries/LibCore/CLock.h deleted file mode 100644 index 2c31751f92..0000000000 --- a/Libraries/LibCore/CLock.h +++ /dev/null @@ -1,125 +0,0 @@ -#pragma once - -#ifdef __serenity__ - -#include -#include -#include - -#define memory_barrier() asm volatile("" :: \ - : "memory") - -static inline u32 CAS(volatile u32* mem, u32 newval, u32 oldval) -{ - u32 ret; - asm volatile( - "cmpxchgl %2, %1" - : "=a"(ret), "+m"(*mem) - : "r"(newval), "0"(oldval) - : "cc", "memory"); - return ret; -} - -class CLock { -public: - CLock() {} - ~CLock() {} - - void lock(); - void unlock(); - -private: - volatile u32 m_lock { 0 }; - u32 m_level { 0 }; - int m_holder { -1 }; -}; - -class CLocker { -public: - [[gnu::always_inline]] inline explicit CLocker(CLock& l) - : m_lock(l) - { - lock(); - } - [[gnu::always_inline]] inline ~CLocker() { unlock(); } - [[gnu::always_inline]] inline void unlock() { m_lock.unlock(); } - [[gnu::always_inline]] inline void lock() { m_lock.lock(); } - -private: - CLock& m_lock; -}; - -[[gnu::always_inline]] inline void CLock::lock() -{ - int tid = gettid(); - for (;;) { - if (CAS(&m_lock, 1, 0) == 0) { - if (m_holder == -1 || m_holder == tid) { - m_holder = tid; - ++m_level; - memory_barrier(); - m_lock = 0; - return; - } - m_lock = 0; - } - donate(m_holder); - } -} - -inline void CLock::unlock() -{ - for (;;) { - if (CAS(&m_lock, 1, 0) == 0) { - ASSERT(m_holder == gettid()); - ASSERT(m_level); - --m_level; - if (m_level) { - memory_barrier(); - m_lock = 0; - return; - } - m_holder = -1; - memory_barrier(); - m_lock = 0; - return; - } - donate(m_holder); - } -} - -#define LOCKER(lock) CLocker locker(lock) - -template -class CLockable { -public: - CLockable() {} - CLockable(T&& resource) - : m_resource(move(resource)) - { - } - CLock& lock() { return m_lock; } - T& resource() { return m_resource; } - - T lock_and_copy() - { - LOCKER(m_lock); - return m_resource; - } - -private: - T m_resource; - CLock m_lock; -}; - -#else - -class CLock { -public: - CLock() { } - ~CLock() { } -}; - -#define LOCKER(x) - -#endif diff --git a/Libraries/LibThread/BackgroundAction.cpp b/Libraries/LibThread/BackgroundAction.cpp index 0f1ef2046a..bffb784511 100644 --- a/Libraries/LibThread/BackgroundAction.cpp +++ b/Libraries/LibThread/BackgroundAction.cpp @@ -1,9 +1,9 @@ #include #include -#include +#include #include -static CLockable>>* s_all_actions; +static LibThread::Lockable>>* s_all_actions; static LibThread::Thread* s_background_thread; static int background_thread_func() @@ -27,13 +27,13 @@ static int background_thread_func() static void init() { - s_all_actions = new CLockable>>(); + s_all_actions = new LibThread::Lockable>>(); s_background_thread = new LibThread::Thread(background_thread_func); s_background_thread->set_name("Background thread"); s_background_thread->start(); } -CLockable>>& LibThread::BackgroundActionBase::all_actions() +LibThread::Lockable>>& LibThread::BackgroundActionBase::all_actions() { if (s_all_actions == nullptr) init(); diff --git a/Libraries/LibThread/BackgroundAction.h b/Libraries/LibThread/BackgroundAction.h index 965ec7b0bf..67f5d99f4b 100644 --- a/Libraries/LibThread/BackgroundAction.h +++ b/Libraries/LibThread/BackgroundAction.h @@ -6,8 +6,8 @@ #include #include #include -#include #include +#include #include namespace LibThread { @@ -22,7 +22,7 @@ class BackgroundActionBase { private: BackgroundActionBase() {} - static CLockable>>& all_actions(); + static Lockable>>& all_actions(); static Thread& background_thread(); }; diff --git a/Libraries/LibThread/Lock.h b/Libraries/LibThread/Lock.h new file mode 100644 index 0000000000..a3aea5e13b --- /dev/null +++ b/Libraries/LibThread/Lock.h @@ -0,0 +1,133 @@ +#pragma once + +#ifdef __serenity__ + +#include +#include +#include + +#define memory_barrier() asm volatile("" :: \ + : "memory") + +static inline u32 CAS(volatile u32* mem, u32 newval, u32 oldval) +{ + u32 ret; + asm volatile( + "cmpxchgl %2, %1" + : "=a"(ret), "+m"(*mem) + : "r"(newval), "0"(oldval) + : "cc", "memory"); + return ret; +} + +namespace LibThread { + +class Lock { +public: + Lock() {} + ~Lock() {} + + void lock(); + void unlock(); + +private: + volatile u32 m_lock { 0 }; + u32 m_level { 0 }; + int m_holder { -1 }; +}; + +class Locker { +public: + [[gnu::always_inline]] inline explicit Locker(Lock& l) + : m_lock(l) + { + lock(); + } + [[gnu::always_inline]] inline ~Locker() { unlock(); } + [[gnu::always_inline]] inline void unlock() { m_lock.unlock(); } + [[gnu::always_inline]] inline void lock() { m_lock.lock(); } + +private: + Lock& m_lock; +}; + +[[gnu::always_inline]] inline void Lock::lock() +{ + int tid = gettid(); + for (;;) { + if (CAS(&m_lock, 1, 0) == 0) { + if (m_holder == -1 || m_holder == tid) { + m_holder = tid; + ++m_level; + memory_barrier(); + m_lock = 0; + return; + } + m_lock = 0; + } + donate(m_holder); + } +} + +inline void Lock::unlock() +{ + for (;;) { + if (CAS(&m_lock, 1, 0) == 0) { + ASSERT(m_holder == gettid()); + ASSERT(m_level); + --m_level; + if (m_level) { + memory_barrier(); + m_lock = 0; + return; + } + m_holder = -1; + memory_barrier(); + m_lock = 0; + return; + } + donate(m_holder); + } +} + +#define LOCKER(lock) LibThread::Locker locker(lock) + +template +class Lockable { +public: + Lockable() {} + Lockable(T&& resource) + : m_resource(move(resource)) + { + } + Lock& lock() { return m_lock; } + T& resource() { return m_resource; } + + T lock_and_copy() + { + LOCKER(m_lock); + return m_resource; + } + +private: + T m_resource; + Lock m_lock; +}; + +} + +#else + +namespace LibThread { + +class Lock { +public: + Lock() { } + ~Lock() { } +}; + +} + +#define LOCKER(x) + +#endif diff --git a/Servers/AudioServer/ASMixer.h b/Servers/AudioServer/ASMixer.h index 401ee455c3..0f2e869c05 100644 --- a/Servers/AudioServer/ASMixer.h +++ b/Servers/AudioServer/ASMixer.h @@ -7,7 +7,7 @@ #include #include #include -#include +#include #include class ASClientConnection; @@ -64,7 +64,7 @@ private: Vector> m_pending_mixing; CFile m_device; - CLock m_lock; + LibThread::Lock m_lock; LibThread::Thread m_sound_thread; -- cgit v1.2.3