1From 7d482f6ebc356e6ec455ccb5f51a23971bf6ce5b Mon Sep 17 00:00:00 2001 2From: jzmaddock <john@johnmaddock.co.uk> 3Date: Wed, 1 Sep 2021 20:31:53 +0100 4Subject: [PATCH] Make no atomics a soft failure in bernoulli_details.hpp. 5 Include an "escape macro" so thread safety can be disabled if certain 6 bernoulli features are to be used in a no-atomics environment. Fixes 7 https://github.com/boostorg/math/issues/673. 8 9[buildroot@heine.tech: 10 - backport from boostorg/math 7d482f6ebc356e6ec455ccb5f51a23971bf6ce5b 11 - alter path to match boost release 12] 13Signed-off-by: Michael Nosthoff <buildroot@heine.tech> 14--- 15 .../detail/bernoulli_details.hpp | 10 +++++++--- 16 libs/math/test/Jamfile.v2 | 3 +++ 17 test/compile_test/bernoulli_no_atomic_d.cpp | 14 ++++++++++++++ 18 test/compile_test/bernoulli_no_atomic_fail.cpp | 15 +++++++++++++++ 19 test/compile_test/bernoulli_no_atomic_mp.cpp | 16 ++++++++++++++++ 20 5 files changed, 55 insertions(+), 3 deletions(-) 21 create mode 100644 test/compile_test/bernoulli_no_atomic_d.cpp 22 create mode 100644 test/compile_test/bernoulli_no_atomic_fail.cpp 23 create mode 100644 test/compile_test/bernoulli_no_atomic_mp.cpp 24 25diff --git a/boost/math/special_functions/detail/bernoulli_details.hpp b/boost/math/special_functions/detail/bernoulli_details.hpp 26index cf35545264..8519b7c89c 100644 27--- a/boost/math/special_functions/detail/bernoulli_details.hpp 28+++ b/boost/math/special_functions/detail/bernoulli_details.hpp 29@@ -360,7 +360,7 @@ class bernoulli_numbers_cache 30 return out; 31 } 32 33- #ifndef BOOST_HAS_THREADS 34+ #if !defined(BOOST_HAS_THREADS) || defined(BOOST_MATH_BERNOULLI_UNTHREADED) 35 // 36 // Single threaded code, very simple: 37 // 38@@ -382,6 +382,8 @@ class bernoulli_numbers_cache 39 *out = (i >= m_overflow_limit) ? policies::raise_overflow_error<T>("boost::math::bernoulli_b2n<%1%>(std::size_t)", 0, T(i), pol) : bn[i]; 40 ++out; 41 } 42+ #elif defined(BOOST_MATH_NO_ATOMIC_INT) 43+ static_assert(sizeof(T) == 1, "Unsupported configuration: your platform appears to have no atomic integers. If you are happy with thread-unsafe code, then you may define BOOST_MATH_BERNOULLI_UNTHREADED to suppress this error."); 44 #else 45 // 46 // Double-checked locking pattern, lets us access cached already cached values 47@@ -464,7 +466,7 @@ class bernoulli_numbers_cache 48 return out; 49 } 50 51- #ifndef BOOST_HAS_THREADS 52+ #if !defined(BOOST_HAS_THREADS) || defined(BOOST_MATH_BERNOULLI_UNTHREADED) 53 // 54 // Single threaded code, very simple: 55 // 56@@ -494,6 +496,8 @@ class bernoulli_numbers_cache 57 } 58 ++out; 59 } 60+ #elif defined(BOOST_MATH_NO_ATOMIC_INT) 61+ static_assert(sizeof(T) == 1, "Unsupported configuration: your platform appears to have no atomic integers. If you are happy with thread-unsafe code, then you may define BOOST_MATH_BERNOULLI_UNTHREADED to suppress this error."); 62 #else 63 // 64 // Double-checked locking pattern, lets us access cached already cached values 65@@ -555,7 +559,7 @@ class bernoulli_numbers_cache 66 // The value at which we know overflow has already occurred for the Bn: 67 std::size_t m_overflow_limit; 68 69- #ifdef BOOST_HAS_THREADS 70+ #if defined(BOOST_HAS_THREADS) && !defined(BOOST_MATH_NO_ATOMIC_INT) 71 std::mutex m_mutex; 72 atomic_counter_type m_counter, m_current_precision; 73 #else 74diff --git a/libs/math/test/Jamfile.v2 b/libs/math/test/Jamfile.v2 75index 52fb87f5e5..3ac63f9279 100644 76--- a/libs/math/test/Jamfile.v2 77+++ b/libs/math/test/Jamfile.v2 78@@ -1137,6 +1137,9 @@ test-suite misc : 79 80 # [ run __temporary_test.cpp test_instances//test_instances : : : <test-info>always_show_run_output <pch>off ] 81 [ compile test_no_long_double_policy.cpp ] 82+ [ compile compile_test/bernoulli_no_atomic_d.cpp ] 83+ [ compile compile_test/bernoulli_no_atomic_mp.cpp ] 84+ [ compile-fail compile_test/bernoulli_no_atomic_fail.cpp ] 85 ; 86 87 test-suite interpolators : 88diff --git a/test/compile_test/bernoulli_no_atomic_d.cpp b/test/compile_test/bernoulli_no_atomic_d.cpp 89new file mode 100644 90index 0000000000..61926f7e1f 91--- /dev/null 92+++ b/test/compile_test/bernoulli_no_atomic_d.cpp 93@@ -0,0 +1,14 @@ 94+// (C) Copyright John Maddock 2021. 95+// Use, modification and distribution are subject to the 96+// Boost Software License, Version 1.0. (See accompanying file 97+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 98+ 99+#define BOOST_MATH_NO_ATOMIC_INT 100+ 101+#include <boost/math/special_functions/bernoulli.hpp> 102+#include "test_compile_result.hpp" 103+ 104+void compile_and_link_test() 105+{ 106+ check_result<double>(boost::math::bernoulli_b2n<double>(4)); 107+} 108diff --git a/test/compile_test/bernoulli_no_atomic_fail.cpp b/test/compile_test/bernoulli_no_atomic_fail.cpp 109new file mode 100644 110index 0000000000..bbd7152412 111--- /dev/null 112+++ b/test/compile_test/bernoulli_no_atomic_fail.cpp 113@@ -0,0 +1,15 @@ 114+// (C) Copyright John Maddock 2021. 115+// Use, modification and distribution are subject to the 116+// Boost Software License, Version 1.0. (See accompanying file 117+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 118+ 119+#define BOOST_MATH_NO_ATOMIC_INT 120+ 121+#include <boost/math/special_functions/bernoulli.hpp> 122+#include <boost/multiprecision/cpp_bin_float.hpp> 123+#include "test_compile_result.hpp" 124+ 125+void compile_and_link_test() 126+{ 127+ check_result<boost::multiprecision::cpp_bin_float_50>(boost::math::bernoulli_b2n<boost::multiprecision::cpp_bin_float_50>(4)); 128+} 129diff --git a/test/compile_test/bernoulli_no_atomic_mp.cpp b/test/compile_test/bernoulli_no_atomic_mp.cpp 130new file mode 100644 131index 0000000000..8d5a6e78e6 132--- /dev/null 133+++ b/test/compile_test/bernoulli_no_atomic_mp.cpp 134@@ -0,0 +1,16 @@ 135+// (C) Copyright John Maddock 2021. 136+// Use, modification and distribution are subject to the 137+// Boost Software License, Version 1.0. (See accompanying file 138+// LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 139+ 140+#define BOOST_MATH_NO_ATOMIC_INT 141+#define BOOST_MATH_BERNOULLI_UNTHREADED 142+ 143+#include <boost/math/special_functions/bernoulli.hpp> 144+#include <boost/multiprecision/cpp_bin_float.hpp> 145+#include "test_compile_result.hpp" 146+ 147+void compile_and_link_test() 148+{ 149+ check_result<boost::multiprecision::cpp_bin_float_50>(boost::math::bernoulli_b2n<boost::multiprecision::cpp_bin_float_50>(4)); 150+} 151