Files
unordered/test/cfoa/latch_tests.cpp

156 lines
2.6 KiB
C++
Raw Normal View History

// Copyright (C) 2023 Christian Mazakas
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
#define BOOST_ENABLE_ASSERT_HANDLER
#include "latch.hpp"
#include <boost/core/lightweight_test.hpp>
#include <thread>
#include <vector>
struct exception
{
};
namespace boost {
void assertion_failed(
char const* expr, char const* function, char const* file, long line)
{
(void)expr;
(void)function;
(void)file;
(void)line;
throw exception{};
}
} // namespace boost
namespace {
void test_max() { BOOST_TEST_EQ(boost::latch::max(), INT_MAX); }
void test_constructor()
{
{
auto const f = [] {
boost::latch l(-1);
(void)l;
};
BOOST_TEST_THROWS(f(), exception);
}
{
std::ptrdiff_t n = 0;
boost::latch l(n);
BOOST_TEST(l.try_wait());
}
{
std::ptrdiff_t n = 16;
boost::latch l(n);
BOOST_TEST_NOT(l.try_wait());
l.count_down(16);
BOOST_TEST(l.try_wait());
}
#if PTRDIFF_MAX > INT_MAX
{
auto const f = [] {
std::ptrdiff_t n = INT_MAX;
n += 10;
boost::latch l(n);
(void)l;
};
BOOST_TEST_THROWS(f(), exception);
}
#endif
}
void test_count_down_and_wait()
{
constexpr std::ptrdiff_t n = 1024;
boost::latch l(2 * n);
bool bs[] = {false, false};
std::thread t1([&] {
l.wait();
BOOST_TEST(bs[0]);
BOOST_TEST(bs[1]);
});
std::thread t2([&] {
for (int i = 0; i < n; ++i) {
if (i == (n - 1)) {
bs[0] = true;
} else {
BOOST_TEST_NOT(l.try_wait());
}
l.count_down(1);
}
});
for (int i = 0; i < n; ++i) {
if (i == (n - 1)) {
bs[1] = true;
} else {
BOOST_TEST_NOT(l.try_wait());
}
l.count_down(1);
}
t1.join();
t2.join();
BOOST_TEST(l.try_wait());
}
void test_arrive_and_wait()
{
2023-04-25 13:41:36 -07:00
std::ptrdiff_t const n = 16;
boost::latch l(2 * n);
int xs[n] = {0};
std::vector<std::thread> threads;
for (int i = 0; i < n; ++i) {
2023-04-25 13:41:36 -07:00
threads.emplace_back([&l, &xs, i, n] {
(void)n;
for (int j = 0; j < n; ++j) {
BOOST_TEST_EQ(xs[j], 0);
}
l.arrive_and_wait(2);
xs[i] = 1;
});
}
for (auto& t : threads) {
t.join();
}
for (int i = 0; i < n; ++i) {
BOOST_TEST_EQ(xs[i], 1);
}
}
} // namespace
int main()
{
test_max();
test_constructor();
test_count_down_and_wait();
test_arrive_and_wait();
return boost::report_errors();
}