mirror of
https://github.com/RGBCube/serenity
synced 2025-07-28 10:17:34 +00:00
AK+Kernel: Make automatically locking RefPtr & co a kernel-only thing
Some time ago, automatic locking was added to the AK smart pointers to paper over various race conditions in the kernel. Until we've actually solved the issues in the kernel, we're stuck with the locking. However, we don't need to punish single-threaded userspace programs with the high cost of locking. This patch moves the thread-safe variants of RefPtr, NonnullRefPtr, WeakPtr and RefCounted into Kernel/Library/.
This commit is contained in:
parent
ca060d8566
commit
5b1f697460
8 changed files with 1418 additions and 470 deletions
|
@ -6,12 +6,15 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/Atomic.h>
|
||||
#include <AK/Checked.h>
|
||||
#include <AK/Noncopyable.h>
|
||||
#include <AK/Platform.h>
|
||||
#include <AK/StdLibExtras.h>
|
||||
#ifdef KERNEL
|
||||
# include <Kernel/Library/ThreadSafeRefCounted.h>
|
||||
#else
|
||||
|
||||
# include <AK/Assertions.h>
|
||||
# include <AK/Checked.h>
|
||||
# include <AK/Noncopyable.h>
|
||||
# include <AK/Platform.h>
|
||||
# include <AK/StdLibExtras.h>
|
||||
|
||||
namespace AK {
|
||||
|
||||
|
@ -49,43 +52,32 @@ public:
|
|||
|
||||
void ref() const
|
||||
{
|
||||
auto old_ref_count = m_ref_count.fetch_add(1, AK::MemoryOrder::memory_order_relaxed);
|
||||
VERIFY(old_ref_count > 0);
|
||||
VERIFY(!Checked<RefCountType>::addition_would_overflow(old_ref_count, 1));
|
||||
VERIFY(m_ref_count > 0);
|
||||
VERIFY(!Checked<RefCountType>::addition_would_overflow(m_ref_count, 1));
|
||||
++m_ref_count;
|
||||
}
|
||||
|
||||
[[nodiscard]] bool try_ref() const
|
||||
{
|
||||
RefCountType expected = m_ref_count.load(AK::MemoryOrder::memory_order_relaxed);
|
||||
for (;;) {
|
||||
if (expected == 0)
|
||||
return false;
|
||||
VERIFY(!Checked<RefCountType>::addition_would_overflow(expected, 1));
|
||||
if (m_ref_count.compare_exchange_strong(expected, expected + 1, AK::MemoryOrder::memory_order_acquire))
|
||||
return true;
|
||||
}
|
||||
if (m_ref_count == 0)
|
||||
return false;
|
||||
ref();
|
||||
return true;
|
||||
}
|
||||
|
||||
[[nodiscard]] RefCountType ref_count() const
|
||||
{
|
||||
return m_ref_count.load(AK::MemoryOrder::memory_order_relaxed);
|
||||
}
|
||||
[[nodiscard]] RefCountType ref_count() const { return m_ref_count; }
|
||||
|
||||
protected:
|
||||
RefCountedBase() = default;
|
||||
~RefCountedBase()
|
||||
{
|
||||
VERIFY(m_ref_count.load(AK::MemoryOrder::memory_order_relaxed) == 0);
|
||||
}
|
||||
~RefCountedBase() { VERIFY(!m_ref_count); }
|
||||
|
||||
RefCountType deref_base() const
|
||||
{
|
||||
auto old_ref_count = m_ref_count.fetch_sub(1, AK::MemoryOrder::memory_order_acq_rel);
|
||||
VERIFY(old_ref_count > 0);
|
||||
return old_ref_count - 1;
|
||||
VERIFY(m_ref_count);
|
||||
return --m_ref_count;
|
||||
}
|
||||
|
||||
mutable Atomic<RefCountType> m_ref_count { 1 };
|
||||
RefCountType mutable m_ref_count { 1 };
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
|
@ -109,3 +101,5 @@ public:
|
|||
|
||||
using AK::RefCounted;
|
||||
using AK::RefCountedBase;
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue