Skip to content

Commit 53c0038

Browse files
committed
AK: Make Weakable non-atomic
Let's not punish single-threaded workloads with the performance cost of atomic weakables. The kernel keeps using LockWeakable.
1 parent 159f968 commit 53c0038

File tree

1 file changed

+6
-40
lines changed

1 file changed

+6
-40
lines changed

AK/Weakable.h

Lines changed: 6 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@
77
#pragma once
88

99
#include <AK/Assertions.h>
10-
#include <AK/Atomic.h>
1110
#include <AK/RefCounted.h>
1211
#include <AK/RefPtr.h>
1312
#include <AK/StdLibExtras.h>
14-
#include <sched.h>
1513

1614
namespace AK {
1715

@@ -31,59 +29,27 @@ class WeakLink : public RefCounted<WeakLink> {
3129
RefPtr<T> strong_ref() const
3230
requires(IsBaseOf<RefCountedBase, T>)
3331
{
34-
RefPtr<T> ref;
35-
36-
{
37-
if (!(m_consumers.fetch_add(1u << 1, AK::MemoryOrder::memory_order_acquire) & 1u)) {
38-
T* ptr = (T*)m_ptr.load(AK::MemoryOrder::memory_order_acquire);
39-
if (ptr && ptr->try_ref())
40-
ref = adopt_ref(*ptr);
41-
}
42-
m_consumers.fetch_sub(1u << 1, AK::MemoryOrder::memory_order_release);
43-
}
44-
45-
return ref;
32+
return static_cast<T*>(m_ptr);
4633
}
4734

4835
template<typename T>
4936
T* unsafe_ptr() const
5037
{
51-
if (m_consumers.load(AK::MemoryOrder::memory_order_relaxed) & 1u)
52-
return nullptr;
53-
// NOTE: This may return a non-null pointer even if revocation
54-
// has been triggered as there is a possible race! But it's "unsafe"
55-
// anyway because we return a raw pointer without ensuring a
56-
// reference...
57-
return (T*)m_ptr.load(AK::MemoryOrder::memory_order_acquire);
38+
return static_cast<T*>(m_ptr);
5839
}
5940

60-
bool is_null() const
61-
{
62-
return unsafe_ptr<void>() == nullptr;
63-
}
41+
bool is_null() const { return m_ptr == nullptr; }
6442

65-
void revoke()
66-
{
67-
auto current_consumers = m_consumers.fetch_or(1u, AK::MemoryOrder::memory_order_relaxed);
68-
VERIFY(!(current_consumers & 1u));
69-
// We flagged revocation, now wait until everyone trying to obtain
70-
// a strong reference is done
71-
while (current_consumers > 0) {
72-
sched_yield();
73-
current_consumers = m_consumers.load(AK::MemoryOrder::memory_order_acquire) & ~1u;
74-
}
75-
// No one is trying to use it (anymore)
76-
m_ptr.store(nullptr, AK::MemoryOrder::memory_order_release);
77-
}
43+
void revoke() { m_ptr = nullptr; }
7844

7945
private:
8046
template<typename T>
8147
explicit WeakLink(T& weakable)
8248
: m_ptr(&weakable)
8349
{
8450
}
85-
mutable Atomic<void*> m_ptr;
86-
mutable Atomic<unsigned> m_consumers; // LSB indicates revocation in progress
51+
52+
mutable void* m_ptr { nullptr };
8753
};
8854

8955
template<typename T>

0 commit comments

Comments
 (0)