LLVM: include/llvm/ADT/LazyAtomicPointer.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9#ifndef LLVM_ADT_LAZYATOMICPOINTER_H
10#define LLVM_ADT_LAZYATOMICPOINTER_H
11
14#include <assert.h>
15#include
16
17namespace llvm {
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
35 static constexpr uintptr_t getNull() { return 0; }
36 static constexpr uintptr_t getBusy() { return UINTPTR_MAX; }
37
38 static T *makePointer(uintptr_t Value) {
40 return Value ? reinterpret_cast<T *>(Value) : nullptr;
41 }
42 static uintptr_t makeRaw(T *Value) {
43 uintptr_t Raw = Value ? reinterpret_cast<uintptr_t>(Value) : getNull();
44 assert(Raw != getBusy());
45 return Raw;
46 }
47
48public:
49
51
52
53
55
56
57 T *Old = nullptr;
59 }
60 return Old;
61 }
62
63
64
66 uintptr_t RawExistingValue = makeRaw(ExistingValue);
67 if (Storage.compare_exchange_weak(RawExistingValue, makeRaw(NewValue)))
68 return true;
69
70
71 if (RawExistingValue == getBusy())
72 ExistingValue = nullptr;
73 else
74 ExistingValue = makePointer(RawExistingValue);
75 return false;
76 }
77
78
79
81 uintptr_t RawExistingValue = makeRaw(ExistingValue);
82 const uintptr_t OriginalRawExistingValue = RawExistingValue;
83 if (Storage.compare_exchange_strong(RawExistingValue, makeRaw(NewValue)))
84 return true;
85
86
87 if (LLVM_UNLIKELY(RawExistingValue == getBusy())) {
88 while (RawExistingValue == getBusy()) {
89 RawExistingValue = OriginalRawExistingValue;
90 if (Storage.compare_exchange_weak(RawExistingValue, makeRaw(NewValue)))
91 return true;
92 }
93 }
94 ExistingValue = makePointer(RawExistingValue);
95 return false;
96 }
97
98
99
101 uintptr_t RawValue = Storage.load();
102 return RawValue == getBusy() ? nullptr : makePointer(RawValue);
103 }
104
105
106
107
108
110
111 uintptr_t Raw = Storage.load();
112 if (Raw != getNull() && Raw != getBusy())
113 return *makePointer(Raw);
114
115
117 Storage.compare_exchange_strong(Raw, getBusy()))) {
118 Raw = makeRaw(Generator());
119 assert(Raw != getNull() && "Expected non-null from generator");
120 Storage.store(Raw);
121 return *makePointer(Raw);
122 }
123
124
125 while (Raw == getBusy())
126 Raw = Storage.load();
127 assert(Raw != getNull() && "Expected non-null from competing generator");
128 return *makePointer(Raw);
129 }
130
131 explicit operator bool() const { return load(); }
132 operator T *() const { return load(); }
133
136 assert(P && "Unexpected null dereference");
137 return *P;
138 }
140
145 : Storage(makeRaw(RHS.load())) {}
146
159
160private:
161 std::atomic<uintptr_t> Storage;
162};
163
164}
165
166#endif
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_UNLIKELY(EXPR)
#define LLVM_LIKELY(EXPR)
void store(T *Value)
Store a value. Waits for concurrent loadOrGenerate() calls.
Definition LazyAtomicPointer.h:50
LazyAtomicPointer & operator=(T *RHS)
Definition LazyAtomicPointer.h:151
bool compare_exchange_strong(T *&ExistingValue, T *NewValue)
Compare-exchange.
Definition LazyAtomicPointer.h:80
T * load() const
Return the current stored value.
Definition LazyAtomicPointer.h:100
T * operator->() const
Definition LazyAtomicPointer.h:139
LazyAtomicPointer(const LazyAtomicPointer &RHS)
Definition LazyAtomicPointer.h:144
LazyAtomicPointer(std::nullptr_t)
Definition LazyAtomicPointer.h:142
LazyAtomicPointer & operator=(const LazyAtomicPointer &RHS)
Definition LazyAtomicPointer.h:155
T & operator*() const
Definition LazyAtomicPointer.h:134
LazyAtomicPointer & operator=(std::nullptr_t)
Definition LazyAtomicPointer.h:147
bool compare_exchange_weak(T *&ExistingValue, T *NewValue)
Compare-exchange.
Definition LazyAtomicPointer.h:65
T & loadOrGenerate(function_ref< T *()> Generator)
Get the current value, or call Generator to generate a value.
Definition LazyAtomicPointer.h:109
LazyAtomicPointer()
Definition LazyAtomicPointer.h:141
T * exchange(T *Value)
Set a value.
Definition LazyAtomicPointer.h:54
LazyAtomicPointer(T *Value)
Definition LazyAtomicPointer.h:143
LLVM Value Representation.
An efficient, type-erasing, non-owning reference to a callable.
This is an optimization pass for GlobalISel generic memory operations.