2
0
mirror of https://github.com/boostorg/sync.git synced 2026-01-19 04:42:12 +00:00
Files
sync/test/run/semaphore_test.cpp
2021-02-05 14:18:41 +01:00

253 lines
6.0 KiB
C++

// Copyright (C) 2013 Tim Blechmann
//
// 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)
#include <boost/core/lightweight_test.hpp>
#include <boost/bind/bind.hpp>
#include <boost/chrono.hpp>
#include <boost/thread/thread.hpp>
#include <boost/thread/thread_time.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>
#include <boost/sync/semaphore.hpp>
#include <boost/sync/support/boost_chrono.hpp>
#include <boost/sync/support/boost_date_time.hpp>
#include <boost/typeof/typeof.hpp>
void test_semaphore_post_wait()
{
boost::sync::semaphore sem;
sem.post();
sem.wait();
}
void test_semaphore_try_wait()
{
boost::sync::semaphore sem;
BOOST_TEST(!sem.try_wait());
sem.post();
BOOST_TEST(sem.try_wait());
}
void test_semaphore_initial_count()
{
boost::sync::semaphore sem(2);
BOOST_TEST(sem.try_wait());
BOOST_TEST(sem.try_wait());
BOOST_TEST(!sem.try_wait());
}
struct semaphore_wait_and_post_test
{
void run()
{
boost::thread post_thread(boost::bind(&semaphore_wait_and_post_test::wait_and_post, this));
sem_.wait();
}
void wait_and_post()
{
boost::this_thread::sleep_for(boost::chrono::seconds(1));
sem_.post();
}
boost::sync::semaphore sem_;
boost::thread thread_;
};
void test_semaphore_wait_and_post()
{
semaphore_wait_and_post_test test;
test.run();
}
void test_semaphore_wait_for()
{
using namespace boost;
boost::sync::semaphore sem;
BOOST_AUTO(start, chrono::system_clock::now());
BOOST_TEST(!sem.wait_for(chrono::milliseconds(500)));
BOOST_AUTO(end, chrono::system_clock::now());
BOOST_AUTO(wait_time, end - start);
// guessing!
BOOST_TEST( wait_time > chrono::milliseconds(450) );
BOOST_TEST( wait_time < chrono::milliseconds(1000) );
sem.post();
BOOST_TEST(sem.wait_for(chrono::milliseconds(500)));
}
void test_semaphore_wait_until()
{
using namespace boost;
boost::sync::semaphore sem;
{
BOOST_AUTO(now, chrono::system_clock::now());
BOOST_AUTO(timeout, now + chrono::milliseconds(500));
BOOST_TEST(!sem.wait_until(timeout));
BOOST_AUTO(end, chrono::system_clock::now());
BOOST_AUTO(timeout_delta, end - timeout);
// guessing!
BOOST_TEST( timeout_delta > chrono::milliseconds(-400) );
BOOST_TEST( timeout_delta < chrono::milliseconds(400) );
}
sem.post();
{
BOOST_AUTO(start, chrono::system_clock::now());
BOOST_AUTO(timeout, start + chrono::milliseconds(500));
BOOST_TEST(sem.wait_until(timeout));
BOOST_AUTO(end, chrono::system_clock::now());
// guessing!
BOOST_TEST( (end - start) < chrono::milliseconds(100) );
}
}
void test_semaphore_timed_wait()
{
using namespace boost;
boost::sync::semaphore sem;
// Relative timeouts
{
BOOST_AUTO(start, chrono::system_clock::now());
BOOST_TEST(!sem.timed_wait(chrono::milliseconds(500)));
BOOST_AUTO(end, chrono::system_clock::now());
BOOST_AUTO(wait_time, end - start);
// guessing!
BOOST_TEST( wait_time > chrono::milliseconds(450) );
BOOST_TEST( wait_time < chrono::milliseconds(1000) );
sem.post();
BOOST_TEST(sem.timed_wait(chrono::milliseconds(500)));
}
{
BOOST_AUTO(start, get_system_time());
BOOST_TEST(!sem.timed_wait(posix_time::milliseconds(500)));
BOOST_AUTO(end, get_system_time());
BOOST_AUTO(wait_time, end - start);
// guessing!
BOOST_TEST( wait_time > posix_time::milliseconds(450) );
BOOST_TEST( wait_time < posix_time::milliseconds(1000) );
sem.post();
BOOST_TEST(sem.timed_wait(posix_time::milliseconds(500)));
}
// Absolute timeouts
{
BOOST_AUTO(now, chrono::system_clock::now());
BOOST_AUTO(timeout, now + chrono::milliseconds(500));
BOOST_TEST(!sem.timed_wait(timeout));
BOOST_AUTO(end, chrono::system_clock::now());
BOOST_AUTO(timeout_delta, end - timeout);
// guessing!
BOOST_TEST( timeout_delta > chrono::milliseconds(-400) );
BOOST_TEST( timeout_delta < chrono::milliseconds(400) );
}
sem.post();
{
BOOST_AUTO(start, chrono::system_clock::now());
BOOST_AUTO(timeout, start + chrono::milliseconds(500));
BOOST_TEST(sem.timed_wait(timeout));
BOOST_AUTO(end, chrono::system_clock::now());
// guessing!
BOOST_TEST( (end - start) < chrono::milliseconds(100) );
}
{
BOOST_AUTO(now, get_system_time());
BOOST_AUTO(timeout, now + posix_time::milliseconds(500));
BOOST_TEST(!sem.timed_wait(timeout));
BOOST_AUTO(end, get_system_time());
BOOST_AUTO(timeout_delta, end - timeout);
// guessing!
BOOST_TEST( timeout_delta > posix_time::milliseconds(-400) );
BOOST_TEST( timeout_delta < posix_time::milliseconds(400) );
}
sem.post();
{
BOOST_AUTO(start, get_system_time());
BOOST_AUTO(timeout, start + posix_time::milliseconds(500));
BOOST_TEST(sem.timed_wait(timeout));
BOOST_AUTO(end, get_system_time());
// guessing!
BOOST_TEST( (end - start) < posix_time::milliseconds(100) );
}
{
// timed wait after timeout
boost::sync::semaphore sema;
using namespace boost::chrono;
BOOST_AUTO(start, steady_clock::now());
BOOST_AUTO(timeout, start + milliseconds(100));
boost::this_thread::sleep_for(milliseconds(500));
sema.post();
BOOST_TEST(sema.wait_until(timeout));
}
}
int main()
{
test_semaphore_post_wait();
test_semaphore_try_wait();
test_semaphore_initial_count();
test_semaphore_wait_and_post();
test_semaphore_wait_for();
test_semaphore_wait_until();
test_semaphore_timed_wait();
return boost::report_errors();
}