1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
|
#include <aocommon/threadpool.h>
#include <boost/test/unit_test.hpp>
#include <set>
#include <vector>
using aocommon::ThreadPool;
BOOST_AUTO_TEST_SUITE(thread_pool)
BOOST_AUTO_TEST_CASE(restart_threads) {
ThreadPool pool;
BOOST_CHECK_EQUAL(pool.NThreads(), 1);
pool.SetNThreads(4);
BOOST_CHECK_EQUAL(pool.NThreads(), 4);
pool.SetNThreads(1);
BOOST_CHECK_EQUAL(pool.NThreads(), 1);
}
BOOST_AUTO_TEST_CASE(single_threaded) {
ThreadPool pool;
pool.SetNThreads(1);
size_t run_count = 0;
std::thread::id executing_thread_id;
auto run = [&](size_t thread_index) {
BOOST_CHECK_EQUAL(thread_index, 0);
++run_count;
executing_thread_id = std::this_thread::get_id();
};
pool.ExecuteInParallel(run);
BOOST_CHECK_EQUAL(run_count, 1);
BOOST_CHECK(executing_thread_id == std::this_thread::get_id());
executing_thread_id = std::thread::id();
pool.ExecuteInParallel(run);
BOOST_CHECK_EQUAL(run_count, 2);
BOOST_CHECK(executing_thread_id == std::this_thread::get_id());
}
BOOST_AUTO_TEST_CASE(multi_threaded) {
ThreadPool pool;
constexpr size_t kNThreads = 10;
pool.SetNThreads(kNThreads);
std::vector<int> run_counts(kNThreads, 0);
std::set<std::thread::id> thread_ids;
std::mutex mutex;
auto run = [&](size_t thread_index) {
std::lock_guard lock(mutex);
thread_ids.insert(std::this_thread::get_id());
++run_counts[thread_index];
};
pool.ExecuteInParallel(run);
const std::vector<int> ref_a(kNThreads, 1);
BOOST_CHECK_EQUAL_COLLECTIONS(run_counts.begin(), run_counts.end(),
ref_a.begin(), ref_a.end());
BOOST_CHECK_EQUAL(thread_ids.size(), kNThreads);
thread_ids.clear();
pool.ExecuteInParallel(run);
const std::vector<int> ref_b(kNThreads, 2);
BOOST_CHECK_EQUAL_COLLECTIONS(run_counts.begin(), run_counts.end(),
ref_b.begin(), ref_b.end());
BOOST_CHECK_EQUAL(thread_ids.size(), kNThreads);
}
BOOST_AUTO_TEST_CASE(non_blocking_single_threaded) {
ThreadPool pool;
pool.SetNThreads(1);
bool is_executed = false;
// With only one thread, the function should never be executed
pool.StartParallelExecution([&](size_t) {
is_executed = true;
while (true)
;
});
BOOST_CHECK(!is_executed);
pool.FinishParallelExecution();
BOOST_CHECK(!is_executed);
}
BOOST_AUTO_TEST_CASE(non_blocking_multi_threaded) {
ThreadPool pool;
constexpr size_t kNThreads = 10;
pool.SetNThreads(kNThreads);
std::vector<int> run_counts(kNThreads, 0);
std::set<std::thread::id> thread_ids;
std::mutex mutex;
auto run = [&](size_t thread_index) {
std::lock_guard lock(mutex);
thread_ids.insert(std::this_thread::get_id());
++run_counts[thread_index];
};
pool.StartParallelExecution(run);
pool.FinishParallelExecution();
std::vector<int> ref_a(kNThreads, 1);
ref_a[0] = 0;
BOOST_CHECK_EQUAL_COLLECTIONS(run_counts.begin(), run_counts.end(),
ref_a.begin(), ref_a.end());
BOOST_CHECK_EQUAL(thread_ids.size(), kNThreads - 1);
thread_ids.clear();
pool.StartParallelExecution(run);
pool.FinishParallelExecution();
std::vector<int> ref_b(kNThreads, 2);
ref_b[0] = 0;
BOOST_CHECK_EQUAL_COLLECTIONS(run_counts.begin(), run_counts.end(),
ref_b.begin(), ref_b.end());
BOOST_CHECK_EQUAL(thread_ids.size(), kNThreads - 1);
}
BOOST_AUTO_TEST_SUITE_END()
|