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

Commit 02f3745

Browse files
committed
tests: split radix_concurrent test
and enable overwrite tests (since runtime_initialize_mt is available).
1 parent 3065a34 commit 02f3745

4 files changed

Lines changed: 142 additions & 124 deletions

File tree

tests/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -969,6 +969,9 @@ if(TEST_RADIX_TREE)
969969
build_test_ext(NAME radix_concurrent SRC_FILES radix_tree/radix_concurrent.cpp)
970970
add_test_generic(NAME radix_concurrent TRACERS none memcheck pmemcheck drd helgrind)
971971

972+
build_test_ext(NAME radix_concurrent_overwrite SRC_FILES radix_tree/radix_concurrent_overwrite.cpp)
973+
add_test_generic(NAME radix_concurrent_overwrite TRACERS none memcheck pmemcheck drd helgrind)
974+
972975
build_test_ext(NAME radix_ctor_exceptions_nopmem SRC_FILES map/map_ctor_exception_nopmem.cpp BUILD_OPTIONS -DLIBPMEMOBJ_CPP_TESTS_RADIX)
973976
add_test_generic(NAME radix_ctor_exceptions_nopmem TRACERS none memcheck pmemcheck)
974977

tests/radix_tree/radix.hpp

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

44
#include "transaction_helpers.hpp"
55
#include "unittest.hpp"
@@ -141,3 +141,29 @@ verify_elements(nvobj::persistent_ptr<Container> ptr, unsigned count, K&& key_f,
141141
}
142142
}
143143
}
144+
145+
template <typename WriteF, typename ReadF>
146+
static void
147+
parallel_write_read(WriteF writer, std::vector<ReadF> &readers,
148+
size_t n_readers)
149+
{
150+
parallel_exec(n_readers + 1, [&](size_t thread_id) {
151+
if (thread_id == 0) {
152+
writer();
153+
} else {
154+
readers[(thread_id - 1) % readers.size()]();
155+
}
156+
});
157+
}
158+
159+
template <typename Container>
160+
static void
161+
init_container(nvobj::pool<root> &pop, nvobj::persistent_ptr<Container> &ptr, const size_t initial_elements)
162+
{
163+
nvobj::transaction::run(
164+
pop, [&] { ptr = nvobj::make_persistent<Container>(); });
165+
166+
for (size_t i = 0; i < initial_elements; ++i) {
167+
ptr->emplace(key<Container>(i), value<Container>(i));
168+
}
169+
}

tests/radix_tree/radix_concurrent.cpp

Lines changed: 20 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -10,40 +10,17 @@
1010

1111
static size_t INITIAL_ELEMENTS = 256;
1212

13-
template <typename WriteF, typename ReadF>
14-
static void
15-
parallel_write_read(WriteF writer, std::vector<ReadF> &readers,
16-
size_t n_readers)
17-
{
18-
parallel_exec(n_readers + 1, [&](size_t thread_id) {
19-
if (thread_id == 0) {
20-
writer();
21-
} else {
22-
readers[(thread_id - 1) % readers.size()]();
23-
}
24-
});
25-
}
26-
27-
template <typename Container>
28-
static void
29-
init_container(nvobj::pool<root> &pop, nvobj::persistent_ptr<Container> &ptr)
30-
{
31-
nvobj::transaction::run(
32-
pop, [&] { ptr = nvobj::make_persistent<Container>(); });
33-
34-
for (size_t i = 0; i < INITIAL_ELEMENTS; ++i) {
35-
ptr->emplace(key<Container>(i), value<Container>(i));
36-
}
37-
}
38-
3913
template <typename Container>
4014
static void
4115
test_write_find(nvobj::pool<root> &pop, nvobj::persistent_ptr<Container> &ptr)
4216
{
43-
const size_t threads = 16;
17+
size_t threads = 8;
18+
if (On_drd)
19+
threads = 2;
20+
4421
const size_t batch_size = INITIAL_ELEMENTS / threads;
4522

46-
init_container(pop, ptr);
23+
init_container(pop, ptr, INITIAL_ELEMENTS);
4724

4825
auto writer = [&]() {
4926
for (size_t i = INITIAL_ELEMENTS; i < INITIAL_ELEMENTS * 2;
@@ -70,91 +47,20 @@ test_write_find(nvobj::pool<root> &pop, nvobj::persistent_ptr<Container> &ptr)
7047

7148
nvobj::transaction::run(
7249
pop, [&] { nvobj::delete_persistent<Container>(ptr); });
73-
}
74-
75-
// XXX: For now, we cannot concurrently read and overwrite values
76-
#if FALSE
77-
template <typename Container>
78-
static void
79-
test_overwrite_find(nvobj::pool<root> &pop,
80-
nvobj::persistent_ptr<Container> &ptr)
81-
{
82-
const size_t threads = 16;
83-
84-
init_container(pop, ptr);
85-
86-
auto writer = [&]() {
87-
for (size_t i = 0; i < INITIAL_ELEMENTS; ++i) {
88-
ptr->insert_or_assign(key<Container>(i),
89-
value<Container>(i + 1));
90-
}
91-
};
92-
93-
auto readers = std::vector<std::function<void()>>{
94-
[&]() {
95-
for (size_t i = 0; i < INITIAL_ELEMENTS; ++i) {
96-
auto res = ptr->find(key<Container>(i));
97-
UT_ASSERT(res != ptr->end());
98-
UT_ASSERT(res->value() == value<Container>(i) ||
99-
res->value() ==
100-
value<Container>(i + 1));
101-
}
102-
},
103-
};
10450

105-
parallel_write_read(writer, readers, threads);
106-
107-
nvobj::transaction::run(
108-
pop, [&] { nvobj::delete_persistent<Container>(ptr); });
109-
}
110-
111-
static void
112-
test_overwrite_bigger_size_find(
113-
nvobj::pool<root> &pop,
114-
nvobj::persistent_ptr<container_int_string> &ptr)
115-
{
116-
const size_t threads = 16;
117-
const std::string new_val = std::string(100, 'a');
118-
119-
init_container(pop, ptr);
120-
121-
auto writer = [&]() {
122-
for (size_t i = 0; i < INITIAL_ELEMENTS; ++i) {
123-
ptr->insert_or_assign(key<container_int_string>(i),
124-
new_val);
125-
}
126-
};
127-
128-
auto readers = std::vector<std::function<void()>>{
129-
[&]() {
130-
for (size_t i = 0; i < INITIAL_ELEMENTS; ++i) {
131-
auto res =
132-
ptr->find(key<container_int_string>(i));
133-
UT_ASSERT(res != ptr->end());
134-
UT_ASSERT(res->value() ==
135-
value<container_int_string>(
136-
i) ||
137-
res->value() == new_val);
138-
}
139-
},
140-
};
141-
142-
parallel_write_read(writer, readers, threads);
143-
144-
nvobj::transaction::run(pop, [&] {
145-
nvobj::delete_persistent<container_int_string>(ptr);
146-
});
51+
UT_ASSERTeq(num_allocs(pop), 0);
14752
}
148-
#endif
14953

15054
template <typename Container>
15155
static void
15256
test_various_readers(nvobj::pool<root> &pop,
15357
nvobj::persistent_ptr<Container> &ptr)
15458
{
155-
const size_t threads = 12;
59+
size_t threads = 16;
60+
if (On_drd)
61+
threads = 4;
15662

157-
init_container(pop, ptr);
63+
init_container(pop, ptr, INITIAL_ELEMENTS);
15864

15965
auto writer = [&]() {
16066
/* writer thread does nothing in this test */
@@ -189,6 +95,8 @@ test_various_readers(nvobj::pool<root> &pop,
18995

19096
nvobj::transaction::run(
19197
pop, [&] { nvobj::delete_persistent<Container>(ptr); });
98+
99+
UT_ASSERTeq(num_allocs(pop), 0);
192100
}
193101

194102
static void
@@ -210,28 +118,17 @@ test(int argc, char *argv[])
210118
}
211119

212120
test_write_find(pop, pop.root()->radix_int_int);
213-
// test_overwrite_find(pop, pop.root()->radix_int_int);
214121
/* this test only works with int as a value type */
215122
test_various_readers(pop, pop.root()->radix_int_int);
216123

217-
test_write_find(pop, pop.root()->radix_int);
218-
// test_overwrite_find(pop, pop.root()->radix_int);
219-
220-
test_write_find(pop, pop.root()->radix_int_str);
221-
// test_overwrite_find(pop, pop.root()->radix_int_str);
222-
// test_overwrite_bigger_size_find(pop, pop.root()->radix_int_str);
223-
224-
test_write_find(pop, pop.root()->radix_str);
225-
// test_overwrite_find(pop, pop.root()->radix_str);
226-
227-
test_write_find(pop, pop.root()->radix_inline_s_wchart_wchart);
228-
// test_overwrite_find(pop, pop.root()->radix_inline_s_wchart_wchart);
229-
230-
test_write_find(pop, pop.root()->radix_inline_s_wchart);
231-
// test_overwrite_find(pop, pop.root()->radix_inline_s_wchart);
232-
233-
test_write_find(pop, pop.root()->radix_inline_s_u8t);
234-
// test_overwrite_find(pop, pop.root()->radix_inline_s_u8t);
124+
if (!On_drd) {
125+
test_write_find(pop, pop.root()->radix_int);
126+
test_write_find(pop, pop.root()->radix_int_str);
127+
test_write_find(pop, pop.root()->radix_str);
128+
test_write_find(pop, pop.root()->radix_inline_s_wchart_wchart);
129+
test_write_find(pop, pop.root()->radix_inline_s_wchart);
130+
test_write_find(pop, pop.root()->radix_inline_s_u8t);
131+
}
235132

236133
pop.close();
237134
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// SPDX-License-Identifier: BSD-3-Clause
2+
/* Copyright 2021, Intel Corporation */
3+
4+
#include "radix.hpp"
5+
6+
/*
7+
* radix_concurrent_overwrite -- test concurrent overwrite operations on the
8+
* radix_tree.
9+
*/
10+
11+
static size_t INITIAL_ELEMENTS = 256;
12+
13+
static void
14+
test_overwrite_bigger_size_find(
15+
nvobj::pool<root> &pop,
16+
nvobj::persistent_ptr<container_int_string> &ptr)
17+
{
18+
size_t threads = 16;
19+
if (On_drd)
20+
threads = 2;
21+
22+
init_container(pop, ptr, INITIAL_ELEMENTS);
23+
ptr->runtime_initialize_mt();
24+
25+
/* Overwrites initial elements with string(i, 100) */
26+
auto writer = [&]() {
27+
for (size_t i = 0; i < INITIAL_ELEMENTS * 2; ++i) {
28+
auto k = i % INITIAL_ELEMENTS;
29+
ptr->insert_or_assign(
30+
key<container_int_string>(k),
31+
value<container_int_string>(i, 100));
32+
}
33+
};
34+
35+
auto readers = std::vector<std::function<void()>>{
36+
[&]() {
37+
for (size_t i = 0; i < INITIAL_ELEMENTS * 2; ++i) {
38+
auto k = i % INITIAL_ELEMENTS;
39+
auto res =
40+
ptr->find(key<container_int_string>(k));
41+
UT_ASSERT(res != ptr->end());
42+
UT_ASSERT(res->value() ==
43+
value<container_int_string>(
44+
k) ||
45+
res->value() ==
46+
value<container_int_string>(
47+
k, 100) ||
48+
res->value() ==
49+
value<container_int_string>(
50+
k + INITIAL_ELEMENTS,
51+
100));
52+
}
53+
},
54+
};
55+
56+
parallel_write_read(writer, readers, threads);
57+
58+
nvobj::transaction::run(pop, [&] {
59+
nvobj::delete_persistent<container_int_string>(ptr);
60+
});
61+
62+
UT_ASSERTeq(num_allocs(pop), 0);
63+
}
64+
65+
static void
66+
test(int argc, char *argv[])
67+
{
68+
if (argc != 2)
69+
UT_FATAL("usage: %s file-name", argv[0]);
70+
71+
const char *path = argv[1];
72+
73+
nvobj::pool<root> pop;
74+
75+
try {
76+
pop = nvobj::pool<struct root>::create(path, "radix_concurrent",
77+
10 * PMEMOBJ_MIN_POOL,
78+
S_IWUSR | S_IRUSR);
79+
} catch (pmem::pool_error &pe) {
80+
UT_FATAL("!pool::create: %s %s", pe.what(), path);
81+
}
82+
83+
test_overwrite_bigger_size_find(pop, pop.root()->radix_int_str);
84+
85+
pop.close();
86+
}
87+
88+
int
89+
main(int argc, char *argv[])
90+
{
91+
return run_test([&] { test(argc, argv); });
92+
}

0 commit comments

Comments
 (0)