9 #ifndef LIBPMEMOBJ_CPP_ATOMIC_SELF_RELATIVE_PTR_HPP
10 #define LIBPMEMOBJ_CPP_ATOMIC_SELF_RELATIVE_PTR_HPP
28 struct atomic<
pmem::obj::experimental::self_relative_ptr<T>> {
31 std::atomic<std::ptrdiff_t>>;
33 std::atomic<std::ptrdiff_t>>;
36 using this_type = atomic;
44 constexpr atomic() noexcept =
default;
49 atomic(
const atomic &) =
delete;
53 std::memory_order order = std::memory_order_seq_cst) noexcept
55 auto offset = accessor::pointer_to_offset(ptr, desired.
get());
56 LIBPMEMOBJ_CPP_ANNOTATE_HAPPENS_BEFORE(order, &ptr);
57 accessor::get_offset(ptr).store(offset, order);
61 load(std::memory_order order = std::memory_order_seq_cst)
const noexcept
63 auto offset = accessor::get_offset(ptr).load(order);
64 LIBPMEMOBJ_CPP_ANNOTATE_HAPPENS_AFTER(order, &ptr);
65 auto pointer = accessor::offset_to_pointer<T>(offset, ptr);
71 std::memory_order order = std::memory_order_seq_cst) noexcept
74 accessor::pointer_to_offset(ptr, desired.
get());
76 accessor::get_offset(ptr).exchange(new_offset, order);
78 accessor::offset_to_pointer<T>(old_offset, ptr)};
83 std::memory_order success,
84 std::memory_order failure) noexcept
86 auto expected_offset =
87 accessor::pointer_to_offset(ptr, expected.
get());
89 accessor::pointer_to_offset(ptr, desired.
get());
91 bool result = accessor::get_offset(ptr).compare_exchange_weak(
92 expected_offset, desired_offset, success, failure);
95 expected = accessor::offset_to_pointer<T>(
96 expected_offset, ptr);
105 compare_exchange_weak(
107 std::memory_order order = std::memory_order_seq_cst) noexcept
109 auto expected_offset =
110 accessor::pointer_to_offset(ptr, expected.
get());
111 auto desired_offset =
112 accessor::pointer_to_offset(ptr, desired.
get());
114 bool result = accessor::get_offset(ptr).compare_exchange_weak(
115 expected_offset, desired_offset, order);
118 expected = accessor::offset_to_pointer<T>(
119 expected_offset, ptr);
129 std::memory_order success,
130 std::memory_order failure) noexcept
132 auto expected_offset =
133 accessor::pointer_to_offset(ptr, expected.
get());
134 auto desired_offset =
135 accessor::pointer_to_offset(ptr, desired.
get());
137 bool result = accessor::get_offset(ptr).compare_exchange_strong(
138 expected_offset, desired_offset, success, failure);
141 expected = accessor::offset_to_pointer<T>(
142 expected_offset, ptr);
151 compare_exchange_strong(
153 std::memory_order order = std::memory_order_seq_cst) noexcept
155 auto expected_offset =
156 accessor::pointer_to_offset(ptr, expected.
get());
157 auto desired_offset =
158 accessor::pointer_to_offset(ptr, desired.
get());
160 bool result = accessor::get_offset(ptr).compare_exchange_strong(
161 expected_offset, desired_offset, order);
164 expected = accessor::offset_to_pointer<T>(
165 expected_offset, ptr);
174 fetch_add(difference_type val,
175 std::memory_order order = std::memory_order_seq_cst) noexcept
177 auto offset = accessor::get_offset(ptr).fetch_add(
178 val *
static_cast<difference_type
>(
sizeof(T)), order);
179 return value_type{accessor::offset_to_pointer<T>(offset, ptr)};
183 fetch_sub(difference_type val,
184 std::memory_order order = std::memory_order_seq_cst) noexcept
186 auto offset = accessor::get_offset(ptr).fetch_sub(
187 val *
static_cast<difference_type
>(
sizeof(T)), order);
188 return value_type{accessor::offset_to_pointer<T>(offset, ptr)};
192 is_lock_free()
const noexcept
194 return accessor::get_offset(ptr).is_lock_free();
206 atomic &operator=(
const atomic &) =
delete;
207 atomic &operator=(
const atomic &)
volatile =
delete;
217 operator++() noexcept
220 return this->fetch_add(1) + 1;
229 operator++(
int) noexcept
231 return this->fetch_add(1);
235 operator--() noexcept
238 return this->fetch_sub(1) - 1;
247 operator--(
int) noexcept
249 return this->fetch_sub(1);
253 operator+=(difference_type diff) noexcept
256 return this->fetch_add(diff) + diff;
265 operator-=(difference_type diff) noexcept
268 return this->fetch_sub(diff) - diff;
294 template <
typename T>
297 static constexpr
bool value =
sizeof(std::atomic<snapshot_type>) ==
298 sizeof(
typename snapshot_type::offset_type);
300 "std::atomic<self_relative_ptr> should be the same size");
Static class accessor to self_relative_ptr_base.
Definition: self_relative_ptr_base_impl.hpp:296
Persistent self-relative pointer class.
Definition: self_relative_ptr.hpp:82
element_type * get() const noexcept
Get the direct pointer.
Definition: self_relative_ptr.hpp:197
typename base_type::difference_type difference_type
The self_relative_ptr difference type.
Definition: self_relative_ptr.hpp:100
Commonly used functionality.
Persistent memory namespace.
Definition: allocation_flag.hpp:15
Persistent self-relative smart pointer.
Base class for self_relative_ptr.
A structure that checks if it is possible to snapshot the specified memory.
Definition: transaction.hpp:41
C++ pmemobj transactions.