Skip to content

Commit e632281

Browse files
committed
Move test_concurrent_increment back
Co-authored-by: Klaim (Joël Lamotte) <[email protected]> Signed-off-by: Julien Jerphanion <[email protected]>
1 parent b831d69 commit e632281

File tree

1 file changed

+66
-66
lines changed

1 file changed

+66
-66
lines changed

libmamba/tests/src/util/test_synchronized_value.cpp

Lines changed: 66 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -103,72 +103,6 @@ namespace
103103

104104
using supported_mutex_types = std::tuple<std::mutex, std::shared_mutex, std::recursive_mutex>;
105105

106-
template <mamba::util::Mutex M>
107-
auto test_concurrent_increment(
108-
std::invocable<mamba::util::synchronized_value<ValueType, M>&> auto increment_task
109-
)
110-
{
111-
static constexpr auto arbitrary_number_of_executing_threads = 512;
112-
113-
mamba::util::synchronized_value<ValueType, M> current_value;
114-
static constexpr int expected_result = arbitrary_number_of_executing_threads;
115-
116-
std::atomic<bool> run_tasks = false; // used to launch tasks about the same time, simpler
117-
// than condition_variable
118-
std::vector<std::future<void>> tasks;
119-
120-
// Launch the reading and writing tasks (maybe threads, depends on how async is implemented)
121-
for (int i = 0; i < expected_result * 2; ++i)
122-
{
123-
if (i % 2) // intertwine reading and writing tasks
124-
{
125-
// add writing task
126-
tasks.push_back(std::async(
127-
std::launch::async,
128-
[&, increment_task]
129-
{
130-
// don't actually run until we get the green light
131-
mambatests::wait_condition([&] { return run_tasks == true; });
132-
increment_task(current_value);
133-
}
134-
));
135-
}
136-
else
137-
{
138-
// add reading task
139-
tasks.push_back(std::async(
140-
std::launch::async,
141-
[&]
142-
{
143-
// don't actually run until we get the green light
144-
mambatests::wait_condition([&] { return run_tasks == true; });
145-
const auto& readonly_value = std::as_const(current_value);
146-
static constexpr auto arbitrary_read_count = 100;
147-
long long sum = 0;
148-
for (int c = 0; c < arbitrary_read_count; ++c)
149-
{
150-
sum += readonly_value->x; // TODO: also try to mix reading and writing
151-
// using different kinds of access
152-
std::this_thread::yield(); // for timing randomness and limit
153-
// over-exhaustion
154-
}
155-
REQUIRE(sum != 0); // It is possible but extremely unlikely that all
156-
// reading tasks will read before any writing tasks.
157-
}
158-
));
159-
}
160-
}
161-
162-
run_tasks = true; // green light, tasks will run probably concurrently, worse case in
163-
// unpredictable order
164-
for (auto& task : tasks)
165-
{
166-
task.wait(); // wait all to be finished
167-
}
168-
169-
REQUIRE(current_value->x == expected_result);
170-
}
171-
172106
template <mamba::util::Mutex MutexType>
173107
void test_synchronized_value_basics()
174108
{
@@ -318,6 +252,72 @@ namespace
318252
REQUIRE(values == initial_values);
319253
}
320254

255+
template <mamba::util::Mutex M>
256+
auto test_concurrent_increment(
257+
std::invocable<mamba::util::synchronized_value<ValueType, M>&> auto increment_task
258+
)
259+
{
260+
static constexpr auto arbitrary_number_of_executing_threads = 512;
261+
262+
mamba::util::synchronized_value<ValueType, M> current_value;
263+
static constexpr int expected_result = arbitrary_number_of_executing_threads;
264+
265+
std::atomic<bool> run_tasks = false; // used to launch tasks about the same time, simpler
266+
// than condition_variable
267+
std::vector<std::future<void>> tasks;
268+
269+
// Launch the reading and writing tasks (maybe threads, depends on how async is implemented)
270+
for (int i = 0; i < expected_result * 2; ++i)
271+
{
272+
if (i % 2) // intertwine reading and writing tasks
273+
{
274+
// add writing task
275+
tasks.push_back(std::async(
276+
std::launch::async,
277+
[&, increment_task]
278+
{
279+
// don't actually run until we get the green light
280+
mambatests::wait_condition([&] { return run_tasks == true; });
281+
increment_task(current_value);
282+
}
283+
));
284+
}
285+
else
286+
{
287+
// add reading task
288+
tasks.push_back(std::async(
289+
std::launch::async,
290+
[&]
291+
{
292+
// don't actually run until we get the green light
293+
mambatests::wait_condition([&] { return run_tasks == true; });
294+
const auto& readonly_value = std::as_const(current_value);
295+
static constexpr auto arbitrary_read_count = 100;
296+
long long sum = 0;
297+
for (int c = 0; c < arbitrary_read_count; ++c)
298+
{
299+
sum += readonly_value->x; // TODO: also try to mix reading and writing
300+
// using different kinds of access
301+
std::this_thread::yield(); // for timing randomness and limit
302+
// over-exhaustion
303+
}
304+
REQUIRE(sum != 0); // It is possible but extremely unlikely that all
305+
// reading tasks will read before any writing tasks.
306+
}
307+
));
308+
}
309+
}
310+
311+
run_tasks = true; // green light, tasks will run probably concurrently, worse case in
312+
// unpredictable order
313+
for (auto& task : tasks)
314+
{
315+
task.wait(); // wait all to be finished
316+
}
317+
318+
REQUIRE(current_value->x == expected_result);
319+
}
320+
321321
// Factorized thread-safe direct_access test
322322
template <mamba::util::Mutex MutexType>
323323
void test_synchronized_value_threadsafe_direct_access()

0 commit comments

Comments
 (0)