mirror of
				https://github.com/boostorg/unordered.git
				synced 2025-11-04 01:31:41 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			156 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			156 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// 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()
 | 
						|
  {
 | 
						|
    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) {
 | 
						|
      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();
 | 
						|
}
 |