// 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 #include #include 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() { std::ptrdiff_t const n = 16; boost::latch l(2 * n); int xs[n] = {0}; std::vector threads; for (int i = 0; i < n; ++i) { 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(); }