mirror of
https://github.com/boostorg/filesystem.git
synced 2026-01-28 07:12:10 +00:00
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.
70 lines
1.6 KiB
C++
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_
|