Files
filesystem/src/atomic_tools.hpp
Andrey Semashev 2dda038306 Reworked function pointers use and definitions.
Instead of using atomic<> to access global function pointers, use raw
pointers and atomic_ref to access them safely in multi-threaded builds.
This allows to ensure constant initialization of the function pointers,
even in C++03. This also solves the problem of undefined dynamic
initialization order that we previously tried to solve with the
init_priority attribute. The attribute turns out to not work if the
pointers were raw pointers (in single-threaded builds). It is also
not supported by Intel Compiler and possibly other, which required
us to avoid using the function pointer for fill_random.

The resulting code should be simpler and more portable. In order to
check for C++20 std::atomic_ref availability, the older check for <atomic>
header was replaced with a check for std::atomic_ref. If not available,
we're using Boost.Atomic, as before.
2021-06-14 22:09:15 +03:00

70 lines
1.6 KiB
C++

// atomic_tools.hpp ------------------------------------------------------------------//
// Copyright 2021 Andrey Semashev
// Distributed under the Boost Software License, Version 1.0.
// See http://www.boost.org/LICENSE_1_0.txt
// See library home page at http://www.boost.org/libs/filesystem
//--------------------------------------------------------------------------------------//
#ifndef BOOST_FILESYSTEM_SRC_ATOMIC_TOOLS_HPP_
#define BOOST_FILESYSTEM_SRC_ATOMIC_TOOLS_HPP_
#include <boost/filesystem/config.hpp>
#if !defined(BOOST_FILESYSTEM_SINGLE_THREADED)
#include "atomic_ref.hpp"
namespace boost {
namespace filesystem {
namespace detail {
//! Atomically loads the value
template< typename T >
BOOST_FORCEINLINE T atomic_load_relaxed(T& a)
{
return atomic_ns::atomic_ref< T >(a).load(atomic_ns::memory_order_relaxed);
}
//! Atomically stores the value
template< typename T >
BOOST_FORCEINLINE void atomic_store_relaxed(T& a, T val)
{
atomic_ns::atomic_ref< T >(a).store(val, atomic_ns::memory_order_relaxed);
}
} // namespace detail
} // namespace filesystem
} // namespace boost
#else // !defined(BOOST_FILESYSTEM_SINGLE_THREADED)
namespace boost {
namespace filesystem {
namespace detail {
//! Atomically loads the value
template< typename T >
BOOST_FORCEINLINE T atomic_load_relaxed(T const& a)
{
return a;
}
//! Atomically stores the value
template< typename T >
BOOST_FORCEINLINE void atomic_store_relaxed(T& a, T val)
{
a = val;
}
} // namespace detail
} // namespace filesystem
} // namespace boost
#endif // !defined(BOOST_FILESYSTEM_SINGLE_THREADED)
#endif // BOOST_FILESYSTEM_SRC_ATOMIC_TOOLS_HPP_