Skip to content
This repository was archived by the owner on Mar 22, 2023. It is now read-only.

Commit e8de081

Browse files
committed
radix_tree: use std::atomic<tagged_pointer>
1 parent fb442bb commit e8de081

7 files changed

Lines changed: 500 additions & 171 deletions

File tree

doc/libpmemobj++.Doxyfile.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,6 @@ HTML_TIMESTAMP = NO
229229
# recursively expanded use the := operator instead of the = operator.
230230
# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
231231

232-
PREDEFINED = __cpp_lib_uncaught_exceptions _WIN32
232+
PREDEFINED = __cpp_lib_uncaught_exceptions _WIN32 DOXYGEN_SHOULD_SKIP_THIS
233233

234234
WARN_AS_ERROR = @DOXYGEN_WARN_AS_ERROR@

include/libpmemobj++/detail/common.hpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// SPDX-License-Identifier: BSD-3-Clause
2-
/* Copyright 2016-2020, Intel Corporation */
2+
/* Copyright 2016-2021, Intel Corporation */
33

44
/**
55
* @file
@@ -65,6 +65,29 @@
6565
#include <drd.h>
6666
#endif
6767

68+
#if LIBPMEMOBJ_CPP_VG_HELGRIND_ENABLED
69+
70+
#define LIBPMEMOBJ_CPP_ANNOTATE_HAPPENS_BEFORE(order, ptr) \
71+
if (order == std::memory_order_release || \
72+
order == std::memory_order_acq_rel || \
73+
order == std::memory_order_seq_cst) { \
74+
ANNOTATE_HAPPENS_BEFORE(ptr); \
75+
}
76+
77+
#define LIBPMEMOBJ_CPP_ANNOTATE_HAPPENS_AFTER(order, ptr) \
78+
if (order == std::memory_order_consume || \
79+
order == std::memory_order_acquire || \
80+
order == std::memory_order_acq_rel || \
81+
order == std::memory_order_seq_cst) { \
82+
ANNOTATE_HAPPENS_AFTER(ptr); \
83+
}
84+
#else
85+
86+
#define LIBPMEMOBJ_CPP_ANNOTATE_HAPPENS_BEFORE(order, ptr)
87+
#define LIBPMEMOBJ_CPP_ANNOTATE_HAPPENS_AFTER(order, ptr)
88+
89+
#endif
90+
6891
/*
6992
* Workaround for missing "is_trivially_copyable" in gcc < 5.0.
7093
* Be aware of a difference between __has_trivial_copy and is_trivially_copyable

include/libpmemobj++/detail/tagged_ptr.hpp

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
#include <cassert>
88

9+
#include <libpmemobj++/detail/common.hpp>
910
#include <libpmemobj++/experimental/atomic_self_relative_ptr.hpp>
1011
#include <libpmemobj++/experimental/self_relative_ptr.hpp>
1112
#include <libpmemobj++/persistent_ptr.hpp>
@@ -25,6 +26,10 @@ struct tagged_ptr_impl {
2526
assert(!(bool)*this);
2627
}
2728

29+
tagged_ptr_impl(const PointerType &ptr) : ptr(ptr)
30+
{
31+
}
32+
2833
tagged_ptr_impl(const obj::persistent_ptr<P1> &ptr)
2934
: ptr(add_tag(ptr.get()))
3035
{
@@ -157,6 +162,11 @@ struct tagged_ptr_impl {
157162
}
158163

159164
PointerType ptr;
165+
166+
#ifndef DOXYGEN_SHOULD_SKIP_THIS
167+
friend std::atomic<tagged_ptr_impl<
168+
P1, P2, obj::experimental::self_relative_ptr<void>>>;
169+
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
160170
};
161171

162172
template <typename P1, typename P2>
@@ -174,36 +184,68 @@ struct atomic<pmem::detail::tagged_ptr<P1, P2>> {
174184
private:
175185
using ptr_type = pmem::detail::tagged_ptr_impl<
176186
P1, P2,
177-
std::atomic<pmem::obj::experimental::self_relative_ptr<void>>>;
178-
179-
public:
180-
using this_type = atomic;
187+
atomic<pmem::obj::experimental::self_relative_ptr<void>>>;
181188
using value_type = pmem::detail::tagged_ptr<P1, P2>;
182189

190+
public:
183191
/*
184192
* Constructors
185193
*/
186194
constexpr atomic() noexcept = default;
195+
187196
atomic(value_type value) : ptr()
188197
{
189198
store(value);
190199
}
200+
191201
atomic(const atomic &) = delete;
192202

193203
void
194204
store(value_type desired,
195205
std::memory_order order = std::memory_order_seq_cst) noexcept
196206
{
197-
LIBPMEMOBJ_CPP_ANNOTATE_HAPPENS_BEFORE(order, &ptr);
198-
ptr.store(desired, order);
207+
LIBPMEMOBJ_CPP_ANNOTATE_HAPPENS_BEFORE(order, &ptr.ptr);
208+
ptr.ptr.store(desired.ptr, order);
209+
}
210+
211+
void
212+
store_with_snapshot(value_type desired,
213+
std::memory_order order = std::memory_order_seq_cst)
214+
{
215+
LIBPMEMOBJ_CPP_ANNOTATE_HAPPENS_BEFORE(order, &ptr.ptr);
216+
pmem::obj::transaction::snapshot(&ptr.ptr);
217+
ptr.ptr.store(desired.ptr, order);
218+
}
219+
220+
void
221+
store_with_snapshot_release(value_type desired)
222+
{
223+
store_with_snapshot(desired, std::memory_order_release);
199224
}
200225

201226
value_type
202227
load(std::memory_order order = std::memory_order_seq_cst) const noexcept
203228
{
204-
auto ptr = this->ptr.load(order);
205-
LIBPMEMOBJ_CPP_ANNOTATE_HAPPENS_AFTER(order, &ptr);
206-
return ptr;
229+
#if LIBPMEMOBJ_CPP_VG_HELGRIND_ENABLED
230+
VALGRIND_HG_DISABLE_CHECKING(&ptr.ptr, sizeof(ptr.ptr));
231+
#endif
232+
auto ret = this->ptr.ptr.load(order);
233+
LIBPMEMOBJ_CPP_ANNOTATE_HAPPENS_AFTER(order, &ptr.ptr);
234+
return value_type(ret);
235+
}
236+
237+
value_type
238+
load_acquire() const noexcept
239+
{
240+
return load(std::memory_order_acquire);
241+
}
242+
243+
void
244+
swap(atomic<pmem::detail::tagged_ptr<P1, P2>> &rhs)
245+
{
246+
auto tmp = rhs.load();
247+
rhs.store_with_snapshot(this->load());
248+
this->store_with_snapshot(tmp);
207249
}
208250

209251
private:

include/libpmemobj++/experimental/atomic_self_relative_ptr.hpp

Lines changed: 2 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,16 @@
11
// SPDX-License-Identifier: BSD-3-Clause
2-
/* Copyright 2020, Intel Corporation */
2+
/* Copyright 2020-2021, Intel Corporation */
33

44
#ifndef LIBPMEMOBJ_CPP_ATOMIC_SELF_RELATIVE_PTR_HPP
55
#define LIBPMEMOBJ_CPP_ATOMIC_SELF_RELATIVE_PTR_HPP
66

7+
#include <libpmemobj++/detail/common.hpp>
78
#include <libpmemobj++/detail/self_relative_ptr_base_impl.hpp>
89
#include <libpmemobj++/experimental/self_relative_ptr.hpp>
910
#include <libpmemobj++/transaction.hpp>
1011

1112
#include <atomic>
1213

13-
#if LIBPMEMOBJ_CPP_VG_HELGRIND_ENABLED
14-
15-
#define LIBPMEMOBJ_CPP_ANNOTATE_HAPPENS_BEFORE(order, ptr) \
16-
if (order == std::memory_order_release || \
17-
order == std::memory_order_acq_rel || \
18-
order == std::memory_order_seq_cst) { \
19-
ANNOTATE_HAPPENS_BEFORE(ptr); \
20-
}
21-
22-
#define LIBPMEMOBJ_CPP_ANNOTATE_HAPPENS_AFTER(order, ptr) \
23-
if (order == std::memory_order_consume || \
24-
order == std::memory_order_acquire || \
25-
order == std::memory_order_acq_rel || \
26-
order == std::memory_order_seq_cst) { \
27-
ANNOTATE_HAPPENS_AFTER(ptr); \
28-
}
29-
#else
30-
31-
#define LIBPMEMOBJ_CPP_ANNOTATE_HAPPENS_BEFORE(order, ptr)
32-
#define LIBPMEMOBJ_CPP_ANNOTATE_HAPPENS_AFTER(order, ptr)
33-
34-
#endif
35-
3614
namespace std
3715
{
3816
/**
@@ -252,9 +230,6 @@ struct atomic<pmem::obj::experimental::self_relative_ptr<T>> {
252230

253231
} /* namespace std */
254232

255-
#undef LIBPMEMOBJ_CPP_ANNOTATE_HAPPENS_BEFORE
256-
#undef LIBPMEMOBJ_CPP_ANNOTATE_HAPPENS_AFTER
257-
258233
namespace pmem
259234
{
260235

0 commit comments

Comments
 (0)