4#ifndef LIBPMEMOBJ_CPP_ATOMIC_SELF_RELATIVE_PTR_HPP
5#define LIBPMEMOBJ_CPP_ATOMIC_SELF_RELATIVE_PTR_HPP
23struct 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;
212 operator++()
noexcept
215 return this->fetch_add(1) + 1;
224 operator++(
int)
noexcept
226 return this->fetch_add(1);
230 operator--()
noexcept
233 return this->fetch_sub(1) - 1;
242 operator--(
int)
noexcept
244 return this->fetch_sub(1);
248 operator+=(difference_type diff)
noexcept
251 return this->fetch_add(diff) + diff;
260 operator-=(difference_type diff)
noexcept
263 return this->fetch_sub(diff) - diff;
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.
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.