mirror of
https://github.com/boostorg/atomic.git
synced 2026-01-19 04:02:09 +00:00
Removed chrono workarounds for older compilers.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
// Copyright (c) 2011 Helge Bahmann
|
||||
// Copyright (c) 2025 Andrey Semashev
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -36,7 +37,6 @@
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include "test_config.hpp"
|
||||
#include "test_clock.hpp"
|
||||
|
||||
/* helper class to let two instances of a function race against each
|
||||
other, with configurable timeout and early abort on detection of error */
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
/* concurrently run the function in two threads, until either timeout
|
||||
or one of the functions returns "false"; returns true if timeout
|
||||
was reached, or false if early abort and updates timeout accordingly */
|
||||
static bool execute(std::function< bool (std::size_t) > const& fn, steady_clock::duration& timeout)
|
||||
static bool execute(std::function< bool (std::size_t) > const& fn, std::chrono::steady_clock::duration& timeout)
|
||||
{
|
||||
concurrent_runner runner(fn);
|
||||
runner.wait_finish(timeout);
|
||||
@@ -60,10 +60,10 @@ public:
|
||||
second_thread_ = std::thread([this, fn]() { thread_function(fn, 1); });
|
||||
}
|
||||
|
||||
void wait_finish(steady_clock::duration& timeout)
|
||||
void wait_finish(std::chrono::steady_clock::duration& timeout)
|
||||
{
|
||||
steady_clock::time_point start = steady_clock::now();
|
||||
steady_clock::time_point end = start + timeout;
|
||||
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
|
||||
std::chrono::steady_clock::time_point end = start + timeout;
|
||||
|
||||
{
|
||||
std::unique_lock< std::mutex > guard(m_);
|
||||
@@ -79,7 +79,7 @@ public:
|
||||
first_thread_.join();
|
||||
second_thread_.join();
|
||||
|
||||
steady_clock::duration duration = steady_clock::now() - start;
|
||||
std::chrono::steady_clock::duration duration = std::chrono::steady_clock::now() - start;
|
||||
if (duration < timeout)
|
||||
timeout = duration;
|
||||
}
|
||||
@@ -152,7 +152,7 @@ double estimate_avg_race_time(void)
|
||||
/* take 10 samples */
|
||||
for (std::size_t n = 0; n < 10; ++n)
|
||||
{
|
||||
steady_clock::duration timeout = std::chrono::seconds(10);
|
||||
std::chrono::steady_clock::duration timeout = std::chrono::seconds(10);
|
||||
|
||||
volatile unsigned int value(0);
|
||||
bool success = concurrent_runner::execute(
|
||||
@@ -249,14 +249,14 @@ int main(int, char *[])
|
||||
double avg_race_time = estimate_avg_race_time();
|
||||
|
||||
/* 5.298 = 0.995 quantile of exponential distribution */
|
||||
const steady_clock::duration timeout = std::chrono::microseconds(static_cast< std::chrono::microseconds::rep >(5.298 * avg_race_time));
|
||||
const std::chrono::steady_clock::duration timeout = std::chrono::microseconds(static_cast< std::chrono::microseconds::rep >(5.298 * avg_race_time));
|
||||
|
||||
{
|
||||
boost::atomic<unsigned int> value(0);
|
||||
|
||||
/* testing two different operations in this loop, therefore
|
||||
enlarge timeout */
|
||||
steady_clock::duration tmp(timeout * 2);
|
||||
std::chrono::steady_clock::duration tmp(timeout * 2);
|
||||
|
||||
bool success = concurrent_runner::execute(
|
||||
[&value](std::size_t instance) { return test_arithmetic< unsigned int, 0 >(value, instance); },
|
||||
@@ -271,7 +271,7 @@ int main(int, char *[])
|
||||
|
||||
/* testing three different operations in this loop, therefore
|
||||
enlarge timeout */
|
||||
steady_clock::duration tmp(timeout * 3);
|
||||
std::chrono::steady_clock::duration tmp(timeout * 3);
|
||||
|
||||
bool success = concurrent_runner::execute(
|
||||
[&value](std::size_t instance) { return test_bitops< unsigned int, 0 >(value, instance); },
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2020 Andrey Semashev
|
||||
// Copyright (c) 2020-2025 Andrey Semashev
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -40,7 +40,6 @@
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include "test_config.hpp"
|
||||
#include "test_clock.hpp"
|
||||
|
||||
/* helper class to let two instances of a function race against each
|
||||
other, with configurable timeout and early abort on detection of error */
|
||||
@@ -50,7 +49,7 @@ public:
|
||||
/* concurrently run the function in two threads, until either timeout
|
||||
or one of the functions returns "false"; returns true if timeout
|
||||
was reached, or false if early abort and updates timeout accordingly */
|
||||
static bool execute(std::function< bool (std::size_t) > const& fn, steady_clock::duration& timeout)
|
||||
static bool execute(std::function< bool (std::size_t) > const& fn, std::chrono::steady_clock::duration& timeout)
|
||||
{
|
||||
concurrent_runner runner(fn);
|
||||
runner.wait_finish(timeout);
|
||||
@@ -64,10 +63,10 @@ public:
|
||||
second_thread_ = std::thread([this, fn]() { thread_function(fn, 1); });
|
||||
}
|
||||
|
||||
void wait_finish(steady_clock::duration& timeout)
|
||||
void wait_finish(std::chrono::steady_clock::duration& timeout)
|
||||
{
|
||||
steady_clock::time_point start = steady_clock::now();
|
||||
steady_clock::time_point end = start + timeout;
|
||||
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
|
||||
std::chrono::steady_clock::time_point end = start + timeout;
|
||||
|
||||
{
|
||||
std::unique_lock< std::mutex > guard(m_);
|
||||
@@ -83,7 +82,7 @@ public:
|
||||
first_thread_.join();
|
||||
second_thread_.join();
|
||||
|
||||
steady_clock::duration duration = steady_clock::now() - start;
|
||||
std::chrono::steady_clock::duration duration = std::chrono::steady_clock::now() - start;
|
||||
if (duration < timeout)
|
||||
timeout = duration;
|
||||
}
|
||||
@@ -156,7 +155,7 @@ double estimate_avg_race_time(void)
|
||||
/* take 10 samples */
|
||||
for (std::size_t n = 0; n < 10; ++n)
|
||||
{
|
||||
steady_clock::duration timeout = std::chrono::seconds(10);
|
||||
std::chrono::steady_clock::duration timeout = std::chrono::seconds(10);
|
||||
|
||||
volatile unsigned int value(0);
|
||||
bool success = concurrent_runner::execute(
|
||||
@@ -255,14 +254,14 @@ int main(int, char *[])
|
||||
double avg_race_time = estimate_avg_race_time();
|
||||
|
||||
/* 5.298 = 0.995 quantile of exponential distribution */
|
||||
const steady_clock::duration timeout = std::chrono::microseconds(static_cast< std::chrono::microseconds::rep >(5.298 * avg_race_time));
|
||||
const std::chrono::steady_clock::duration timeout = std::chrono::microseconds(static_cast< std::chrono::microseconds::rep >(5.298 * avg_race_time));
|
||||
|
||||
{
|
||||
unsigned int value = 0;
|
||||
|
||||
/* testing two different operations in this loop, therefore
|
||||
enlarge timeout */
|
||||
steady_clock::duration tmp(timeout * 2);
|
||||
std::chrono::steady_clock::duration tmp(timeout * 2);
|
||||
|
||||
bool success = concurrent_runner::execute(
|
||||
[&value](std::size_t instance) { return test_arithmetic< unsigned int, 0 >(value, instance); },
|
||||
@@ -277,7 +276,7 @@ int main(int, char *[])
|
||||
|
||||
/* testing three different operations in this loop, therefore
|
||||
enlarge timeout */
|
||||
steady_clock::duration tmp(timeout * 3);
|
||||
std::chrono::steady_clock::duration tmp(timeout * 3);
|
||||
|
||||
bool success = concurrent_runner::execute(
|
||||
[&value](std::size_t instance) { return test_bitops< unsigned int, 0 >(value, instance); },
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2020-2023 Andrey Semashev
|
||||
// Copyright (c) 2020-2025 Andrey Semashev
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -17,10 +17,10 @@
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
#include <type_traits>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/atomic/capabilities.hpp>
|
||||
#include <boost/atomic/ipc_atomic_flag.hpp>
|
||||
#include <boost/type_traits/integral_constant.hpp>
|
||||
#include "atomic_wrapper.hpp"
|
||||
#include "lightweight_test_stream.hpp"
|
||||
#include "test_clock.hpp"
|
||||
@@ -28,7 +28,7 @@
|
||||
#include "test_barrier.hpp"
|
||||
|
||||
//! Since some of the tests below are allowed to fail, we retry up to this many times to pass the test
|
||||
BOOST_CONSTEXPR_OR_CONST unsigned int test_retry_count = 5u;
|
||||
constexpr unsigned int test_retry_count = 5u;
|
||||
|
||||
//! The test verifies that the wait operation returns immediately if the passed value does not match the atomic value
|
||||
template< template< typename > class Wrapper, typename T >
|
||||
@@ -92,22 +92,22 @@ public:
|
||||
|
||||
test_clock::time_point start_time = test_clock::now();
|
||||
|
||||
std::this_thread::sleep_until(start_time + chrono::milliseconds(200));
|
||||
std::this_thread::sleep_until(start_time + std::chrono::milliseconds(200));
|
||||
|
||||
m_wrapper.a.store(m_value2, boost::memory_order_release);
|
||||
m_wrapper.a.notify_one();
|
||||
|
||||
std::this_thread::sleep_until(start_time + chrono::milliseconds(400));
|
||||
std::this_thread::sleep_until(start_time + std::chrono::milliseconds(400));
|
||||
|
||||
m_wrapper.a.store(m_value3, boost::memory_order_release);
|
||||
m_wrapper.a.notify_one();
|
||||
|
||||
if (!thread1.try_join_for(chrono::seconds(3)))
|
||||
if (!thread1.try_join_for(std::chrono::seconds(3)))
|
||||
{
|
||||
BOOST_ERROR("Thread 1 failed to join");
|
||||
std::abort();
|
||||
}
|
||||
if (!thread2.try_join_for(chrono::seconds(3)))
|
||||
if (!thread2.try_join_for(std::chrono::seconds(3)))
|
||||
{
|
||||
BOOST_ERROR("Thread 2 failed to join");
|
||||
std::abort();
|
||||
@@ -120,21 +120,24 @@ public:
|
||||
|
||||
if (m_wrapper.a.has_native_wait_notify())
|
||||
{
|
||||
if ((first_state->m_wakeup_time - start_time) < chrono::milliseconds(200))
|
||||
if ((first_state->m_wakeup_time - start_time) < std::chrono::milliseconds(200))
|
||||
{
|
||||
std::cout << "notify_one_test: first thread woke up too soon: " << chrono::duration_cast< chrono::milliseconds >(first_state->m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
std::cout << "notify_one_test: first thread woke up too soon: "
|
||||
<< std::chrono::duration_cast< std::chrono::milliseconds >(first_state->m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((first_state->m_wakeup_time - start_time) >= chrono::milliseconds(400))
|
||||
if ((first_state->m_wakeup_time - start_time) >= std::chrono::milliseconds(400))
|
||||
{
|
||||
std::cout << "notify_one_test: first thread woke up too late: " << chrono::duration_cast< chrono::milliseconds >(first_state->m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
std::cout << "notify_one_test: first thread woke up too late: "
|
||||
<< std::chrono::duration_cast< std::chrono::milliseconds >(first_state->m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((second_state->m_wakeup_time - start_time) < chrono::milliseconds(400))
|
||||
if ((second_state->m_wakeup_time - start_time) < std::chrono::milliseconds(400))
|
||||
{
|
||||
std::cout << "notify_one_test: second thread woke up too soon: " << chrono::duration_cast< chrono::milliseconds >(second_state->m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
std::cout << "notify_one_test: second thread woke up too soon: "
|
||||
<< std::chrono::duration_cast< std::chrono::milliseconds >(second_state->m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -226,17 +229,17 @@ public:
|
||||
|
||||
test_clock::time_point start_time = test_clock::now();
|
||||
|
||||
std::this_thread::sleep_until(start_time + chrono::milliseconds(200));
|
||||
std::this_thread::sleep_until(start_time + std::chrono::milliseconds(200));
|
||||
|
||||
m_wrapper.a.store(m_value2, boost::memory_order_release);
|
||||
m_wrapper.a.notify_all();
|
||||
|
||||
if (!thread1.try_join_for(chrono::seconds(3)))
|
||||
if (!thread1.try_join_for(std::chrono::seconds(3)))
|
||||
{
|
||||
BOOST_ERROR("Thread 1 failed to join");
|
||||
std::abort();
|
||||
}
|
||||
if (!thread2.try_join_for(chrono::seconds(3)))
|
||||
if (!thread2.try_join_for(std::chrono::seconds(3)))
|
||||
{
|
||||
BOOST_ERROR("Thread 2 failed to join");
|
||||
std::abort();
|
||||
@@ -244,15 +247,17 @@ public:
|
||||
|
||||
if (m_wrapper.a.has_native_wait_notify())
|
||||
{
|
||||
if ((m_thread1_state.m_wakeup_time - start_time) < chrono::milliseconds(200))
|
||||
if ((m_thread1_state.m_wakeup_time - start_time) < std::chrono::milliseconds(200))
|
||||
{
|
||||
std::cout << "notify_all_test: first thread woke up too soon: " << chrono::duration_cast< chrono::milliseconds >(m_thread1_state.m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
std::cout << "notify_all_test: first thread woke up too soon: "
|
||||
<< std::chrono::duration_cast< std::chrono::milliseconds >(m_thread1_state.m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((m_thread2_state.m_wakeup_time - start_time) < chrono::milliseconds(200))
|
||||
if ((m_thread2_state.m_wakeup_time - start_time) < std::chrono::milliseconds(200))
|
||||
{
|
||||
std::cout << "notify_all_test: second thread woke up too soon: " << chrono::duration_cast< chrono::milliseconds >(m_thread2_state.m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
std::cout << "notify_all_test: second thread woke up too soon: "
|
||||
<< std::chrono::duration_cast< std::chrono::milliseconds >(m_thread2_state.m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -289,7 +294,7 @@ inline void test_notify_all(T value1, T value2)
|
||||
|
||||
//! Invokes all wait/notify tests
|
||||
template< template< typename > class Wrapper, typename T >
|
||||
void test_wait_notify_api_impl(T value1, T value2, T value3, boost::true_type)
|
||||
void test_wait_notify_api_impl(T value1, T value2, T value3, std::true_type)
|
||||
{
|
||||
test_wait_value_mismatch< Wrapper >(value1, value2);
|
||||
test_notify_one< Wrapper >(value1, value2, value3);
|
||||
@@ -297,7 +302,7 @@ void test_wait_notify_api_impl(T value1, T value2, T value3, boost::true_type)
|
||||
}
|
||||
|
||||
template< template< typename > class Wrapper, typename T >
|
||||
inline void test_wait_notify_api_impl(T, T, T, boost::false_type)
|
||||
inline void test_wait_notify_api_impl(T, T, T, std::false_type)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -305,7 +310,7 @@ inline void test_wait_notify_api_impl(T, T, T, boost::false_type)
|
||||
template< template< typename > class Wrapper, typename T >
|
||||
inline void test_wait_notify_api(T value1, T value2, T value3)
|
||||
{
|
||||
test_wait_notify_api_impl< Wrapper >(value1, value2, value3, boost::integral_constant< bool, Wrapper< T >::atomic_type::is_always_lock_free >());
|
||||
test_wait_notify_api_impl< Wrapper >(value1, value2, value3, std::integral_constant< bool, Wrapper< T >::atomic_type::is_always_lock_free >());
|
||||
}
|
||||
|
||||
//! Invokes all wait/notify tests, if the atomic type is lock-free
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Copyright (c) 2011 Helge Bahmann
|
||||
// Copyright (c) 2012 Tim Blechmann
|
||||
// Copyright (c) 2023 Andrey Semashev
|
||||
// Copyright (c) 2023-2025 Andrey Semashev
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -39,7 +39,6 @@
|
||||
#include <condition_variable>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include "test_clock.hpp"
|
||||
#include "test_barrier.hpp"
|
||||
|
||||
// Two threads perform the following operations:
|
||||
@@ -58,7 +57,7 @@ class total_store_order_test
|
||||
public:
|
||||
total_store_order_test(void);
|
||||
|
||||
void run(steady_clock::duration& timeout);
|
||||
void run(std::chrono::steady_clock::duration& timeout);
|
||||
bool detected_conflict(void) const { return detected_conflict_; }
|
||||
|
||||
private:
|
||||
@@ -97,10 +96,10 @@ total_store_order_test<store_order, load_order>::total_store_order_test(void) :
|
||||
}
|
||||
|
||||
template<boost::memory_order store_order, boost::memory_order load_order>
|
||||
void total_store_order_test<store_order, load_order>::run(steady_clock::duration& timeout)
|
||||
void total_store_order_test<store_order, load_order>::run(std::chrono::steady_clock::duration& timeout)
|
||||
{
|
||||
steady_clock::time_point start = steady_clock::now();
|
||||
steady_clock::time_point end = start + timeout;
|
||||
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
|
||||
std::chrono::steady_clock::time_point end = start + timeout;
|
||||
|
||||
std::thread t1([this]() { this->thread1fn(); });
|
||||
std::thread t2([this]() { this->thread2fn(); });
|
||||
@@ -119,7 +118,7 @@ void total_store_order_test<store_order, load_order>::run(steady_clock::duration
|
||||
t2.join();
|
||||
t1.join();
|
||||
|
||||
steady_clock::duration duration = steady_clock::now() - start;
|
||||
std::chrono::steady_clock::duration duration = std::chrono::steady_clock::now() - start;
|
||||
if (duration < timeout)
|
||||
timeout = duration;
|
||||
}
|
||||
@@ -235,7 +234,7 @@ void test_seq_cst(void)
|
||||
/* take 10 samples */
|
||||
for (std::size_t n = 0; n < 10; n++)
|
||||
{
|
||||
steady_clock::duration timeout = std::chrono::seconds(10);
|
||||
std::chrono::steady_clock::duration timeout = std::chrono::seconds(10);
|
||||
|
||||
total_store_order_test<boost::memory_order_relaxed, boost::memory_order_relaxed> test;
|
||||
test.run(timeout);
|
||||
@@ -260,7 +259,7 @@ void test_seq_cst(void)
|
||||
|
||||
/* 5.298 = 0.995 quantile of exponential distribution */
|
||||
std::chrono::microseconds timeout_us(static_cast< std::chrono::microseconds::rep >(5.298 * avg_race_time_995));
|
||||
steady_clock::duration timeout = timeout_us;
|
||||
std::chrono::steady_clock::duration timeout = timeout_us;
|
||||
|
||||
std::cout << "run seq_cst for " << timeout_us.count() << " us\n";
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2020-2023 Andrey Semashev
|
||||
// Copyright (c) 2020-2025 Andrey Semashev
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -41,7 +41,6 @@
|
||||
#include <condition_variable>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/core/lightweight_test.hpp>
|
||||
#include "test_clock.hpp"
|
||||
#include "test_barrier.hpp"
|
||||
|
||||
// Two threads perform the following operations:
|
||||
@@ -60,7 +59,7 @@ class total_store_order_test
|
||||
public:
|
||||
total_store_order_test(void);
|
||||
|
||||
void run(steady_clock::duration& timeout);
|
||||
void run(std::chrono::steady_clock::duration& timeout);
|
||||
bool detected_conflict(void) const { return detected_conflict_; }
|
||||
|
||||
private:
|
||||
@@ -101,10 +100,10 @@ total_store_order_test<store_order, load_order>::total_store_order_test(void) :
|
||||
}
|
||||
|
||||
template<boost::memory_order store_order, boost::memory_order load_order>
|
||||
void total_store_order_test<store_order, load_order>::run(steady_clock::duration& timeout)
|
||||
void total_store_order_test<store_order, load_order>::run(std::chrono::steady_clock::duration& timeout)
|
||||
{
|
||||
steady_clock::time_point start = steady_clock::now();
|
||||
steady_clock::time_point end = start + timeout;
|
||||
std::chrono::steady_clock::time_point start = std::chrono::steady_clock::now();
|
||||
std::chrono::steady_clock::time_point end = start + timeout;
|
||||
|
||||
std::thread t1([this]() { this->thread1fn(); });
|
||||
std::thread t2([this]() { this->thread2fn(); });
|
||||
@@ -123,7 +122,7 @@ void total_store_order_test<store_order, load_order>::run(steady_clock::duration
|
||||
t2.join();
|
||||
t1.join();
|
||||
|
||||
steady_clock::duration duration = steady_clock::now() - start;
|
||||
std::chrono::steady_clock::duration duration = std::chrono::steady_clock::now() - start;
|
||||
if (duration < timeout)
|
||||
timeout = duration;
|
||||
}
|
||||
@@ -239,7 +238,7 @@ void test_seq_cst(void)
|
||||
/* take 10 samples */
|
||||
for (std::size_t n = 0; n < 10; n++)
|
||||
{
|
||||
steady_clock::duration timeout = std::chrono::seconds(10);
|
||||
std::chrono::steady_clock::duration timeout = std::chrono::seconds(10);
|
||||
|
||||
total_store_order_test<boost::memory_order_relaxed, boost::memory_order_relaxed> test;
|
||||
test.run(timeout);
|
||||
@@ -264,7 +263,7 @@ void test_seq_cst(void)
|
||||
|
||||
/* 5.298 = 0.995 quantile of exponential distribution */
|
||||
std::chrono::microseconds timeout_us(static_cast< std::chrono::microseconds::rep >(5.298 * avg_race_time_995));
|
||||
steady_clock::duration timeout = timeout_us;
|
||||
std::chrono::steady_clock::duration timeout = timeout_us;
|
||||
|
||||
std::cout << "run seq_cst for " << timeout_us.count() << " us\n";
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2020 Andrey Semashev
|
||||
// Copyright (c) 2020-2025 Andrey Semashev
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -16,14 +16,6 @@
|
||||
#endif
|
||||
#include <chrono>
|
||||
|
||||
namespace chrono = std::chrono;
|
||||
|
||||
#if defined(BOOST_LIBSTDCXX_VERSION) && BOOST_LIBSTDCXX_VERSION < 40700
|
||||
using steady_clock = chrono::monotonic_clock;
|
||||
#else
|
||||
using steady_clock = chrono::steady_clock;
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_WINDOWS)
|
||||
|
||||
// On Windows high precision clocks tend to cause spurious test failures because threads wake up earlier than expected.
|
||||
@@ -32,8 +24,8 @@ struct test_clock
|
||||
{
|
||||
using rep = long long;
|
||||
using period = std::milli;
|
||||
using duration = chrono::duration< rep, period >;
|
||||
using time_point = chrono::time_point< test_clock, duration >;
|
||||
using duration = std::chrono::duration< rep, period >;
|
||||
using time_point = std::chrono::time_point< test_clock, duration >;
|
||||
|
||||
static constexpr bool is_steady = true;
|
||||
|
||||
@@ -45,7 +37,7 @@ struct test_clock
|
||||
};
|
||||
|
||||
#else
|
||||
using test_clock = steady_clock;
|
||||
using test_clock = std::chrono::steady_clock;
|
||||
#endif
|
||||
|
||||
#endif // BOOST_ATOMIC_TEST_TEST_CLOCK_HPP_INCLUDED_
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2023 Andrey Semashev
|
||||
// Copyright (c) 2023-2025 Andrey Semashev
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -11,7 +11,6 @@
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include "test_clock.hpp"
|
||||
|
||||
//! Test thread class with the ability to join the thread with a timeout
|
||||
class test_thread
|
||||
@@ -53,7 +52,7 @@ public:
|
||||
template< typename Rep, typename Period >
|
||||
bool try_join_for(std::chrono::duration< Rep, Period > dur)
|
||||
{
|
||||
return try_join_until(steady_clock::now() + dur);
|
||||
return try_join_until(std::chrono::steady_clock::now() + dur);
|
||||
}
|
||||
|
||||
template< typename Clock, typename Duration >
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2020 Andrey Semashev
|
||||
// Copyright (c) 2020-2025 Andrey Semashev
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -18,12 +18,11 @@
|
||||
#include <memory>
|
||||
#include <iostream>
|
||||
#include <boost/config.hpp>
|
||||
#include "test_clock.hpp"
|
||||
#include "test_barrier.hpp"
|
||||
|
||||
boost::atomic< unsigned int > g_atomic(0u);
|
||||
|
||||
BOOST_CONSTEXPR_OR_CONST unsigned int loop_count = 4096u;
|
||||
constexpr unsigned int loop_count = 4096u;
|
||||
|
||||
void thread_func(test_barrier* barrier)
|
||||
{
|
||||
@@ -52,7 +51,7 @@ int main()
|
||||
barrier.arrive_and_wait();
|
||||
|
||||
// Let the threads block on the atomic counter
|
||||
std::this_thread::sleep_for(chrono::milliseconds(100));
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(100));
|
||||
|
||||
while (true)
|
||||
{
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// Copyright (c) 2020-2023 Andrey Semashev
|
||||
// Copyright (c) 2020-2025 Andrey Semashev
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// See accompanying file LICENSE_1_0.txt or copy at
|
||||
@@ -25,7 +25,7 @@
|
||||
#include "test_barrier.hpp"
|
||||
|
||||
//! Since some of the tests below are allowed to fail, we retry up to this many times to pass the test
|
||||
BOOST_CONSTEXPR_OR_CONST unsigned int test_retry_count = 5u;
|
||||
constexpr unsigned int test_retry_count = 5u;
|
||||
|
||||
//! The test verifies that the wait operation returns immediately if the passed value does not match the atomic value
|
||||
template< template< typename > class Wrapper, typename T >
|
||||
@@ -89,22 +89,22 @@ public:
|
||||
|
||||
test_clock::time_point start_time = test_clock::now();
|
||||
|
||||
std::this_thread::sleep_until(start_time + chrono::milliseconds(200));
|
||||
std::this_thread::sleep_until(start_time + std::chrono::milliseconds(200));
|
||||
|
||||
m_wrapper.a.store(m_value2, boost::memory_order_release);
|
||||
m_wrapper.a.notify_one();
|
||||
|
||||
std::this_thread::sleep_until(start_time + chrono::milliseconds(400));
|
||||
std::this_thread::sleep_until(start_time + std::chrono::milliseconds(400));
|
||||
|
||||
m_wrapper.a.store(m_value3, boost::memory_order_release);
|
||||
m_wrapper.a.notify_one();
|
||||
|
||||
if (!thread1.try_join_for(chrono::seconds(3)))
|
||||
if (!thread1.try_join_for(std::chrono::seconds(3)))
|
||||
{
|
||||
BOOST_ERROR("Thread 1 failed to join");
|
||||
std::abort();
|
||||
}
|
||||
if (!thread2.try_join_for(chrono::seconds(3)))
|
||||
if (!thread2.try_join_for(std::chrono::seconds(3)))
|
||||
{
|
||||
BOOST_ERROR("Thread 2 failed to join");
|
||||
std::abort();
|
||||
@@ -115,21 +115,24 @@ public:
|
||||
if (second_state->m_wakeup_time < first_state->m_wakeup_time)
|
||||
std::swap(first_state, second_state);
|
||||
|
||||
if ((first_state->m_wakeup_time - start_time) < chrono::milliseconds(200))
|
||||
if ((first_state->m_wakeup_time - start_time) < std::chrono::milliseconds(200))
|
||||
{
|
||||
std::cout << "notify_one_test: first thread woke up too soon: " << chrono::duration_cast< chrono::milliseconds >(first_state->m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
std::cout << "notify_one_test: first thread woke up too soon: "
|
||||
<< std::chrono::duration_cast< std::chrono::milliseconds >(first_state->m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((first_state->m_wakeup_time - start_time) >= chrono::milliseconds(400))
|
||||
if ((first_state->m_wakeup_time - start_time) >= std::chrono::milliseconds(400))
|
||||
{
|
||||
std::cout << "notify_one_test: first thread woke up too late: " << chrono::duration_cast< chrono::milliseconds >(first_state->m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
std::cout << "notify_one_test: first thread woke up too late: "
|
||||
<< std::chrono::duration_cast< std::chrono::milliseconds >(first_state->m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((second_state->m_wakeup_time - start_time) < chrono::milliseconds(400))
|
||||
if ((second_state->m_wakeup_time - start_time) < std::chrono::milliseconds(400))
|
||||
{
|
||||
std::cout << "notify_one_test: second thread woke up too soon: " << chrono::duration_cast< chrono::milliseconds >(second_state->m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
std::cout << "notify_one_test: second thread woke up too soon: "
|
||||
<< std::chrono::duration_cast< std::chrono::milliseconds >(second_state->m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -213,31 +216,33 @@ public:
|
||||
|
||||
test_clock::time_point start_time = test_clock::now();
|
||||
|
||||
std::this_thread::sleep_until(start_time + chrono::milliseconds(200));
|
||||
std::this_thread::sleep_until(start_time + std::chrono::milliseconds(200));
|
||||
|
||||
m_wrapper.a.store(m_value2, boost::memory_order_release);
|
||||
m_wrapper.a.notify_all();
|
||||
|
||||
if (!thread1.try_join_for(chrono::seconds(3)))
|
||||
if (!thread1.try_join_for(std::chrono::seconds(3)))
|
||||
{
|
||||
BOOST_ERROR("Thread 1 failed to join");
|
||||
std::abort();
|
||||
}
|
||||
if (!thread2.try_join_for(chrono::seconds(3)))
|
||||
if (!thread2.try_join_for(std::chrono::seconds(3)))
|
||||
{
|
||||
BOOST_ERROR("Thread 2 failed to join");
|
||||
std::abort();
|
||||
}
|
||||
|
||||
if ((m_thread1_state.m_wakeup_time - start_time) < chrono::milliseconds(200))
|
||||
if ((m_thread1_state.m_wakeup_time - start_time) < std::chrono::milliseconds(200))
|
||||
{
|
||||
std::cout << "notify_all_test: first thread woke up too soon: " << chrono::duration_cast< chrono::milliseconds >(m_thread1_state.m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
std::cout << "notify_all_test: first thread woke up too soon: "
|
||||
<< std::chrono::duration_cast< std::chrono::milliseconds >(m_thread1_state.m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((m_thread2_state.m_wakeup_time - start_time) < chrono::milliseconds(200))
|
||||
if ((m_thread2_state.m_wakeup_time - start_time) < std::chrono::milliseconds(200))
|
||||
{
|
||||
std::cout << "notify_all_test: second thread woke up too soon: " << chrono::duration_cast< chrono::milliseconds >(m_thread2_state.m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
std::cout << "notify_all_test: second thread woke up too soon: "
|
||||
<< std::chrono::duration_cast< std::chrono::milliseconds >(m_thread2_state.m_wakeup_time - start_time).count() << " ms" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user