4 #ifndef LIBPMEMOBJ_CPP_ATOMIC_SELF_RELATIVE_PTR_HPP
5 #define LIBPMEMOBJ_CPP_ATOMIC_SELF_RELATIVE_PTR_HPP
23 struct atomic<
pmem::obj::experimental::self_relative_ptr<T>> {
26 std::atomic<std::ptrdiff_t>>;
28 std::atomic<std::ptrdiff_t>>;
31 using this_type = atomic;
39 constexpr atomic() noexcept =
default;
44 atomic(
const atomic &) =
delete;
48 std::memory_order order = std::memory_order_seq_cst) noexcept
50 auto offset = accessor::pointer_to_offset(ptr, desired.
get());
51 LIBPMEMOBJ_CPP_ANNOTATE_HAPPENS_BEFORE(order, &ptr);
52 accessor::get_offset(ptr).store(offset, order);
56 load(std::memory_order order = std::memory_order_seq_cst)
const noexcept
58 auto offset = accessor::get_offset(ptr).load(order);
59 LIBPMEMOBJ_CPP_ANNOTATE_HAPPENS_AFTER(order, &ptr);
60 auto pointer = accessor::offset_to_pointer<T>(offset, ptr);
66 std::memory_order order = std::memory_order_seq_cst) noexcept
69 accessor::pointer_to_offset(ptr, desired.
get());
71 accessor::get_offset(ptr).exchange(new_offset, order);
73 accessor::offset_to_pointer<T>(old_offset, ptr)};
78 std::memory_order success,
79 std::memory_order failure) noexcept
81 auto expected_offset =
82 accessor::pointer_to_offset(ptr, expected.
get());
84 accessor::pointer_to_offset(ptr, desired.
get());
86 bool result = accessor::get_offset(ptr).compare_exchange_weak(
87 expected_offset, desired_offset, success, failure);
90 expected = accessor::offset_to_pointer<T>(
91 expected_offset, ptr);
100 compare_exchange_weak(
102 std::memory_order order = std::memory_order_seq_cst) noexcept
104 auto expected_offset =
105 accessor::pointer_to_offset(ptr, expected.
get());
106 auto desired_offset =
107 accessor::pointer_to_offset(ptr, desired.
get());
109 bool result = accessor::get_offset(ptr).compare_exchange_weak(
110 expected_offset, desired_offset, order);
113 expected = accessor::offset_to_pointer<T>(
114 expected_offset, ptr);
124 std::memory_order success,
125 std::memory_order failure) noexcept
127 auto expected_offset =
128 accessor::pointer_to_offset(ptr, expected.
get());
129 auto desired_offset =
130 accessor::pointer_to_offset(ptr, desired.
get());
132 bool result = accessor::get_offset(ptr).compare_exchange_strong(
133 expected_offset, desired_offset, success, failure);
136 expected = accessor::offset_to_pointer<T>(
137 expected_offset, ptr);
146 compare_exchange_strong(
148 std::memory_order order = std::memory_order_seq_cst) noexcept
150 auto expected_offset =
151 accessor::pointer_to_offset(ptr, expected.
get());
152 auto desired_offset =
153 accessor::pointer_to_offset(ptr, desired.
get());
155 bool result = accessor::get_offset(ptr).compare_exchange_strong(
156 expected_offset, desired_offset, order);
159 expected = accessor::offset_to_pointer<T>(
160 expected_offset, ptr);
169 fetch_add(difference_type val,
170 std::memory_order order = std::memory_order_seq_cst) noexcept
172 auto offset = accessor::get_offset(ptr).fetch_add(
173 val *
static_cast<difference_type
>(
sizeof(T)), order);
174 return value_type{accessor::offset_to_pointer<T>(offset, ptr)};
178 fetch_sub(difference_type val,
179 std::memory_order order = std::memory_order_seq_cst) noexcept
181 auto offset = accessor::get_offset(ptr).fetch_sub(
182 val *
static_cast<difference_type
>(
sizeof(T)), order);
183 return value_type{accessor::offset_to_pointer<T>(offset, ptr)};
187 is_lock_free()
const noexcept
189 return accessor::get_offset(ptr).is_lock_free();
201 atomic &operator=(
const atomic &) =
delete;
202 atomic &operator=(
const atomic &)
volatile =
delete;
215 return this->fetch_add(1) + 1;
226 return this->fetch_add(1);
233 return this->fetch_sub(1) - 1;
244 return this->fetch_sub(1);
251 return this->fetch_add(diff) + diff;
263 return this->fetch_sub(diff) - diff;
288 template <
typename T>
291 static constexpr
bool value =
sizeof(std::atomic<snapshot_type>) ==
292 sizeof(
typename snapshot_type::offset_type);
294 "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:81
element_type * get() const noexcept
Get the direct pointer.
Definition: self_relative_ptr.hpp:196
typename base_type::difference_type difference_type
The self_relative_ptr difference type.
Definition: self_relative_ptr.hpp:99
Commonly used functionality.
p< T > & operator+=(p< T > &lhs, const p< Y > &rhs)
Addition assignment operator overload.
Definition: pext.hpp:94
p< T > & operator++(p< T > &pp)
Prefix increment operator overload.
Definition: pext.hpp:48
p< T > & operator--(p< T > &pp)
Prefix decrement operator overload.
Definition: pext.hpp:59
p< T > & operator-=(p< T > &lhs, const p< Y > &rhs)
Subtraction assignment operator overload.
Definition: pext.hpp:116
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:36
C++ pmemobj transactions.