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

Commit 2ab4604

Browse files
authored
Merge pull request #1217 from lukaszstolarczuk/atomic_pa_ptr_tests
Add pmreorder tests for atomic persistent-aware ptr
2 parents f8ea4db + 8e78fcb commit 2ab4604

File tree

5 files changed

+244
-0
lines changed

5 files changed

+244
-0
lines changed

tests/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,16 @@ if(TEST_SELF_RELATIVE_POINTER)
321321

322322
build_test(atomic_persistent_aware_ptr_pmem ptr/atomic_persistent_aware_ptr_pmem.cpp)
323323
add_test_generic(NAME atomic_persistent_aware_ptr_pmem TRACERS none memcheck pmemcheck drd helgrind)
324+
325+
if(PMREORDER_SUPPORTED)
326+
build_test(atomic_persistent_aware_ptr_pmreorder ptr/atomic_persistent_aware_ptr_pmreorder.cpp)
327+
add_test_generic(NAME atomic_persistent_aware_ptr_pmreorder CASE 0 TRACERS none
328+
SCRIPT ptr/atomic_pmreorder_0.cmake)
329+
add_test_generic(NAME atomic_persistent_aware_ptr_pmreorder CASE 1 TRACERS none
330+
SCRIPT ptr/atomic_pmreorder_1.cmake)
331+
add_test_generic(NAME atomic_persistent_aware_ptr_pmreorder CASE 2 TRACERS none
332+
SCRIPT ptr/atomic_pmreorder_2.cmake)
333+
endif()
324334
endif()
325335

326336
add_subdirectory(external)
Lines changed: 197 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
/* Copyright 2021, Intel Corporation */
3+
4+
/*
5+
* atomic_persistent_aware_ptr_pmreorder.cpp.cpp -- self_relative_ptr test under
6+
* pmreorder. One thread is storing the data in the atomic pointer, and the
7+
* other one is trying to load it (and save it on pmem). No matter how stores
8+
* happen values should equal or the read value should have initial value
9+
* (nullptr). Negative case is added using special mock class, not persisting
10+
* data properly.
11+
*/
12+
13+
#include "thread_helpers.hpp"
14+
#include "unittest.hpp"
15+
16+
#include <libpmemobj++/experimental/atomic_persistent_aware_ptr.hpp>
17+
#include <libpmemobj++/persistent_ptr.hpp>
18+
#include <libpmemobj++/pool.hpp>
19+
20+
#define LAYOUT "pmreorder"
21+
22+
/* data (for self_relative_ptr) has to be aligned to 2B */
23+
static int TEST_DATA = 0xACDC;
24+
static std::function<void(void)> sync_func;
25+
26+
/* mock prepared to check negative case (simulate wrong implementation) */
27+
template <typename T>
28+
class mock_atomic_self_relative_ptr {
29+
public:
30+
using value_type = pmem::obj::experimental::self_relative_ptr<T>;
31+
32+
void
33+
store(value_type val)
34+
{
35+
ptr.store(val);
36+
/* sync other thread to stat reading now */
37+
sync_func();
38+
/* wait for other thread to finish reading */
39+
sync_func();
40+
pmem::obj::pool_by_vptr(this).persist(&ptr, sizeof(ptr));
41+
}
42+
43+
value_type
44+
load()
45+
{
46+
return ptr.load();
47+
}
48+
49+
mock_atomic_self_relative_ptr &
50+
operator=(value_type const &r)
51+
{
52+
ptr = r;
53+
return *this;
54+
}
55+
56+
private:
57+
std::atomic<pmem::obj::experimental::self_relative_ptr<T>> ptr;
58+
};
59+
60+
namespace nvobj = pmem::obj;
61+
template <typename T>
62+
using self_relative_ptr = nvobj::experimental::self_relative_ptr<T>;
63+
template <typename T, typename ReadOptimized>
64+
using atomic_ptr =
65+
nvobj::experimental::atomic_persistent_aware_ptr<T, ReadOptimized>;
66+
67+
struct root {
68+
/* read-optimized */
69+
atomic_ptr<int, std::true_type> ptr_r;
70+
/* write-optimized */
71+
atomic_ptr<int, std::false_type> ptr_w;
72+
/* mock for negative case */
73+
mock_atomic_self_relative_ptr<int> ptr_neg;
74+
75+
self_relative_ptr<int> read_r;
76+
self_relative_ptr<int> read_w;
77+
self_relative_ptr<int> read_neg;
78+
};
79+
80+
template <typename PtrA, typename PtrR>
81+
void
82+
insert_and_read(nvobj::pool<root> &pop, PtrA &ptr_atomic, PtrR &ptr_read)
83+
{
84+
parallel_xexec(
85+
2,
86+
[&](size_t thread_id, std::function<void(void)> syncthreads) {
87+
syncthreads();
88+
89+
if (thread_id == 0) {
90+
VALGRIND_PMC_EMIT_LOG("PMREORDER_MARKER.BEGIN");
91+
}
92+
syncthreads();
93+
94+
if (thread_id == 0) {
95+
/* save globalally for mock class to use */
96+
sync_func = syncthreads;
97+
98+
/* insert test data into atomic ptr's */
99+
ptr_atomic.store(
100+
reinterpret_cast<int *>(TEST_DATA));
101+
} else {
102+
/* read test data into self relative ptr's */
103+
if (std::is_same<PtrA,
104+
mock_atomic_self_relative_ptr<
105+
int>>::value) {
106+
/* negative case have to be sync'ed (see
107+
* comments in mock class) */
108+
syncthreads();
109+
ptr_read = ptr_atomic.load();
110+
syncthreads();
111+
} else {
112+
ptr_read = ptr_atomic.load();
113+
}
114+
pop.persist(&ptr_read, sizeof(ptr_read));
115+
}
116+
117+
syncthreads();
118+
if (thread_id == 0) {
119+
VALGRIND_PMC_EMIT_LOG("PMREORDER_MARKER.END");
120+
}
121+
});
122+
}
123+
124+
template <typename PtrL, typename PtrR>
125+
void
126+
check_consistency(nvobj::pool<root> &pop, PtrL &ptr_load, PtrR &ptr_read)
127+
{
128+
/* no matter how it's reordered we either don't have the read_*
129+
* set up yet, or it's properly set to loaded value */
130+
UT_ASSERT(ptr_read == nullptr ||
131+
ptr_load.load().get() == ptr_read.get());
132+
}
133+
134+
static void
135+
test(int argc, char *argv[])
136+
{
137+
if (argc != 3 || strchr("ciomn", argv[1][0]) == nullptr)
138+
UT_FATAL("usage: %s <c|i|o|m|n> file-name", argv[0]);
139+
140+
const char *path = argv[2];
141+
142+
nvobj::pool<root> pop;
143+
144+
try {
145+
if (argv[1][0] == 'c') {
146+
/* just create and init with nulls */
147+
pop = nvobj::pool<root>::create(path, LAYOUT,
148+
PMEMOBJ_MIN_POOL * 20,
149+
S_IWUSR | S_IRUSR);
150+
151+
pmem::obj::transaction::run(pop, [&] {
152+
pop.root()->ptr_r = nullptr;
153+
pop.root()->ptr_w = nullptr;
154+
pop.root()->ptr_neg = nullptr;
155+
pop.root()->read_r = nullptr;
156+
pop.root()->read_w = nullptr;
157+
pop.root()->read_neg = nullptr;
158+
});
159+
160+
} else if (argv[1][0] == 'i') {
161+
/* store and load in parallel */
162+
pop = nvobj::pool<root>::open(path, LAYOUT);
163+
auto r = pop.root();
164+
insert_and_read(pop, r->ptr_r, r->read_r);
165+
insert_and_read(pop, r->ptr_w, r->read_w);
166+
167+
} else if (argv[1][0] == 'o') {
168+
/* re-open at the end, for consistency check */
169+
pop = nvobj::pool<root>::open(path, LAYOUT);
170+
auto r = pop.root();
171+
check_consistency(pop, r->ptr_r, r->read_r);
172+
check_consistency(pop, r->ptr_w, r->read_w);
173+
174+
} else if (argv[1][0] == 'm') {
175+
/* mock store and load in parallel */
176+
pop = nvobj::pool<root>::open(path, LAYOUT);
177+
auto r = pop.root();
178+
insert_and_read(pop, r->ptr_neg, r->read_neg);
179+
180+
} else if (argv[1][0] == 'n') {
181+
/* re-open at the end, for negative consistency check */
182+
pop = nvobj::pool<root>::open(path, LAYOUT);
183+
auto r = pop.root();
184+
check_consistency(pop, r->ptr_neg, r->read_neg);
185+
}
186+
} catch (pmem::pool_error &pe) {
187+
UT_FATAL("!pool::create: %s %s", pe.what(), path);
188+
}
189+
190+
pop.close();
191+
}
192+
193+
int
194+
main(int argc, char *argv[])
195+
{
196+
return run_test([&] { test(argc, argv); });
197+
}

tests/ptr/atomic_pmreorder_0.cmake

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# SPDX-License-Identifier: BSD-3-Clause
2+
# Copyright 2019-2021, Intel Corporation
3+
4+
include(${SRC_DIR}/../helpers.cmake)
5+
6+
setup()
7+
8+
execute(${TEST_EXECUTABLE} c ${DIR}/testfile)
9+
pmreorder_create_store_log(${DIR}/testfile ${TEST_EXECUTABLE} m ${DIR}/testfile)
10+
# negative test, should fail, uses mock of atomic_self_relative_ptr
11+
pmreorder_execute(false NoReorderNoCheck PMREORDER_MARKER=ReorderReverseAccumulative ${TEST_EXECUTABLE} n)
12+
13+
finish()

tests/ptr/atomic_pmreorder_1.cmake

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# SPDX-License-Identifier: BSD-3-Clause
2+
# Copyright 2019-2021, Intel Corporation
3+
4+
include(${SRC_DIR}/../helpers.cmake)
5+
6+
setup()
7+
8+
execute(${TEST_EXECUTABLE} c ${DIR}/testfile)
9+
pmreorder_create_store_log(${DIR}/testfile ${TEST_EXECUTABLE} i ${DIR}/testfile)
10+
pmreorder_execute(true NoReorderNoCheck PMREORDER_MARKER=ReorderAccumulative ${TEST_EXECUTABLE} o)
11+
12+
finish()

tests/ptr/atomic_pmreorder_2.cmake

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# SPDX-License-Identifier: BSD-3-Clause
2+
# Copyright 2019-2021, Intel Corporation
3+
4+
include(${SRC_DIR}/../helpers.cmake)
5+
6+
setup()
7+
8+
execute(${TEST_EXECUTABLE} c ${DIR}/testfile)
9+
pmreorder_create_store_log(${DIR}/testfile ${TEST_EXECUTABLE} i ${DIR}/testfile)
10+
pmreorder_execute(true NoReorderNoCheck PMREORDER_MARKER=ReorderReverseAccumulative ${TEST_EXECUTABLE} o)
11+
12+
finish()

0 commit comments

Comments
 (0)