mirror of
https://github.com/boostorg/atomic.git
synced 2026-02-02 08:22:08 +00:00
Added implementation of inter-process atomics.
The inter-process atomics have ipc_ prefixes: ipc_atomic, ipc_atomic_ref and ipc_atomic_flag. These types are similar to their unprefixed counterparts with the following distinctions: - The operations are provided with an added precondition that is_lock_free() returns true. - All operations, including waiting/notifying operations, are address-free, so the types are suitable for inter-process communication. - The new has_native_wait_notify() operation and always_has_native_wait_notify static constant allow to test if the target platform has native support for address-free waiting/notifying operations. If it does not, a generic implementation is used based on a busy wait. - The new set of capability macros added. The macros are named BOOST_ATOMIC_HAS_NATIVE_<T>_IPC_WAIT_NOTIFY and indicate whether address-free waiting/notifying operations are supported natively for a given type. Additionally, to unify interface and implementation of different components, the has_native_wait_notify() operation and always_has_native_wait_notify static constant were added to non-IPC atomic types as well. Added BOOST_ATOMIC_HAS_NATIVE_<T>_WAIT_NOTIFY capability macros to indicate native support for inter-thread waiting/notifying operations. Also, added is_lock_free() and is_always_lock_free to atomic_flag. This commit adds implementation, docs and tests.
This commit is contained in:
@@ -15,6 +15,9 @@
|
||||
#include <boost/atomic/atomic.hpp>
|
||||
#include <boost/atomic/atomic_ref.hpp>
|
||||
#include <boost/atomic/atomic_flag.hpp>
|
||||
#include <boost/atomic/ipc_atomic.hpp>
|
||||
#include <boost/atomic/ipc_atomic_ref.hpp>
|
||||
#include <boost/atomic/ipc_atomic_flag.hpp>
|
||||
#include <boost/atomic/fences.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
|
||||
@@ -42,10 +42,10 @@ namespace atomics {
|
||||
//! Atomic object
|
||||
template< typename T >
|
||||
class atomic :
|
||||
public atomics::detail::base_atomic< T, typename atomics::detail::classify< T >::type >
|
||||
public atomics::detail::base_atomic< T, typename atomics::detail::classify< T >::type, false >
|
||||
{
|
||||
private:
|
||||
typedef atomics::detail::base_atomic< T, typename atomics::detail::classify< T >::type > base_type;
|
||||
typedef atomics::detail::base_atomic< T, typename atomics::detail::classify< T >::type, false > base_type;
|
||||
typedef typename base_type::value_arg_type value_arg_type;
|
||||
|
||||
public:
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
*
|
||||
* Copyright (c) 2011 Helge Bahmann
|
||||
* Copyright (c) 2013 Tim Blechmann
|
||||
* Copyright (c) 2014 Andrey Semashev
|
||||
* Copyright (c) 2014, 2020 Andrey Semashev
|
||||
*/
|
||||
/*!
|
||||
* \file atomic/atomic_flag.hpp
|
||||
@@ -16,87 +16,19 @@
|
||||
#ifndef BOOST_ATOMIC_ATOMIC_FLAG_HPP_INCLUDED_
|
||||
#define BOOST_ATOMIC_ATOMIC_FLAG_HPP_INCLUDED_
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/capabilities.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/operations.hpp>
|
||||
#include <boost/atomic/detail/wait_operations.hpp>
|
||||
#include <boost/atomic/detail/aligned_variable.hpp>
|
||||
#include <boost/atomic/detail/atomic_flag_impl.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
/*
|
||||
* IMPLEMENTATION NOTE: All interface functions MUST be declared with BOOST_FORCEINLINE,
|
||||
* see comment for convert_memory_order_to_gcc in ops_gcc_atomic.hpp.
|
||||
*/
|
||||
|
||||
namespace boost {
|
||||
namespace atomics {
|
||||
|
||||
#if defined(BOOST_ATOMIC_DETAIL_NO_CXX11_CONSTEXPR_UNION_INIT) || defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
|
||||
#define BOOST_ATOMIC_NO_ATOMIC_FLAG_INIT
|
||||
#else
|
||||
#define BOOST_ATOMIC_FLAG_INIT {}
|
||||
#endif
|
||||
|
||||
//! Atomic flag
|
||||
struct atomic_flag
|
||||
{
|
||||
// Prefer 4-byte storage as most platforms support waiting/notifying operations without a lock pool for 32-bit integers
|
||||
typedef atomics::detail::operations< 4u, false > operations;
|
||||
typedef atomics::detail::wait_operations< operations > wait_operations;
|
||||
typedef operations::storage_type storage_type;
|
||||
|
||||
BOOST_ATOMIC_DETAIL_ALIGNED_VAR(operations::storage_alignment, storage_type, m_storage);
|
||||
|
||||
BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT atomic_flag() BOOST_NOEXCEPT : m_storage(0u)
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE bool test(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(order != memory_order_release);
|
||||
BOOST_ASSERT(order != memory_order_acq_rel);
|
||||
return !!operations::load(m_storage, order);
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE bool test_and_set(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return operations::test_and_set(m_storage, order);
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE void clear(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(order != memory_order_consume);
|
||||
BOOST_ASSERT(order != memory_order_acquire);
|
||||
BOOST_ASSERT(order != memory_order_acq_rel);
|
||||
operations::clear(m_storage, order);
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE bool wait(bool old_val, memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(order != memory_order_release);
|
||||
BOOST_ASSERT(order != memory_order_acq_rel);
|
||||
|
||||
return !!wait_operations::wait(m_storage, static_cast< storage_type >(old_val), order);
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE void notify_one() volatile BOOST_NOEXCEPT
|
||||
{
|
||||
wait_operations::notify_one(m_storage);
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE void notify_all() volatile BOOST_NOEXCEPT
|
||||
{
|
||||
wait_operations::notify_all(m_storage);
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(atomic_flag(atomic_flag const&))
|
||||
BOOST_DELETED_FUNCTION(atomic_flag& operator= (atomic_flag const&))
|
||||
};
|
||||
typedef atomics::detail::atomic_flag_impl< false > atomic_flag;
|
||||
|
||||
} // namespace atomics
|
||||
|
||||
|
||||
@@ -40,10 +40,10 @@ namespace atomics {
|
||||
//! Atomic reference to external object
|
||||
template< typename T >
|
||||
class atomic_ref :
|
||||
public atomics::detail::base_atomic_ref< T, typename atomics::detail::classify< T >::type >
|
||||
public atomics::detail::base_atomic_ref< T, typename atomics::detail::classify< T >::type, false >
|
||||
{
|
||||
private:
|
||||
typedef atomics::detail::base_atomic_ref< T, typename atomics::detail::classify< T >::type > base_type;
|
||||
typedef atomics::detail::base_atomic_ref< T, typename atomics::detail::classify< T >::type, false > base_type;
|
||||
typedef typename base_type::value_arg_type value_arg_type;
|
||||
|
||||
public:
|
||||
|
||||
@@ -16,5 +16,6 @@
|
||||
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/capabilities.hpp>
|
||||
#include <boost/atomic/detail/wait_capabilities.hpp>
|
||||
|
||||
#endif // BOOST_ATOMIC_CAPABILITIES_HPP_INCLUDED_
|
||||
|
||||
126
include/boost/atomic/detail/atomic_flag_impl.hpp
Normal file
126
include/boost/atomic/detail/atomic_flag_impl.hpp
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* 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)
|
||||
*
|
||||
* Copyright (c) 2011 Helge Bahmann
|
||||
* Copyright (c) 2013 Tim Blechmann
|
||||
* Copyright (c) 2014, 2020 Andrey Semashev
|
||||
*/
|
||||
/*!
|
||||
* \file atomic/detail/atomic_flag_impl.hpp
|
||||
*
|
||||
* This header contains implementation of \c atomic_flag.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_IMPL_HPP_INCLUDED_
|
||||
#define BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_IMPL_HPP_INCLUDED_
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/operations.hpp>
|
||||
#include <boost/atomic/detail/wait_operations.hpp>
|
||||
#include <boost/atomic/detail/aligned_variable.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
/*
|
||||
* IMPLEMENTATION NOTE: All interface functions MUST be declared with BOOST_FORCEINLINE,
|
||||
* see comment for convert_memory_order_to_gcc in ops_gcc_atomic.hpp.
|
||||
*/
|
||||
|
||||
namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
#if defined(BOOST_ATOMIC_DETAIL_NO_CXX11_CONSTEXPR_UNION_INIT) || defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
|
||||
#define BOOST_ATOMIC_NO_ATOMIC_FLAG_INIT
|
||||
#else
|
||||
#define BOOST_ATOMIC_FLAG_INIT {}
|
||||
#endif
|
||||
|
||||
//! Atomic flag implementation
|
||||
template< bool IsInterprocess >
|
||||
struct atomic_flag_impl
|
||||
{
|
||||
// Prefer 4-byte storage as most platforms support waiting/notifying operations without a lock pool for 32-bit integers
|
||||
typedef atomics::detail::operations< 4u, false, IsInterprocess > operations;
|
||||
typedef atomics::detail::wait_operations< operations > wait_operations;
|
||||
typedef typename operations::storage_type storage_type;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = operations::is_always_lock_free;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = wait_operations::always_has_native_wait_notify;
|
||||
|
||||
BOOST_ATOMIC_DETAIL_ALIGNED_VAR_TPL(operations::storage_alignment, storage_type, m_storage);
|
||||
|
||||
BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT atomic_flag_impl() BOOST_NOEXCEPT : m_storage(0u)
|
||||
{
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE bool is_lock_free() const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return is_always_lock_free;
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE bool has_native_wait_notify() const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return wait_operations::has_native_wait_notify(m_storage);
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE bool test(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(order != memory_order_release);
|
||||
BOOST_ASSERT(order != memory_order_acq_rel);
|
||||
return !!operations::load(m_storage, order);
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE bool test_and_set(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return operations::test_and_set(m_storage, order);
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE void clear(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(order != memory_order_consume);
|
||||
BOOST_ASSERT(order != memory_order_acquire);
|
||||
BOOST_ASSERT(order != memory_order_acq_rel);
|
||||
operations::clear(m_storage, order);
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE bool wait(bool old_val, memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_ASSERT(order != memory_order_release);
|
||||
BOOST_ASSERT(order != memory_order_acq_rel);
|
||||
|
||||
return !!wait_operations::wait(m_storage, static_cast< storage_type >(old_val), order);
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE void notify_one() volatile BOOST_NOEXCEPT
|
||||
{
|
||||
wait_operations::notify_one(m_storage);
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE void notify_all() volatile BOOST_NOEXCEPT
|
||||
{
|
||||
wait_operations::notify_all(m_storage);
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(atomic_flag_impl(atomic_flag_impl const&))
|
||||
BOOST_DELETED_FUNCTION(atomic_flag_impl& operator= (atomic_flag_impl const&))
|
||||
};
|
||||
|
||||
#if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
|
||||
template< bool IsInterprocess >
|
||||
BOOST_CONSTEXPR_OR_CONST bool atomic_flag_impl< IsInterprocess >::is_always_lock_free;
|
||||
template< bool IsInterprocess >
|
||||
BOOST_CONSTEXPR_OR_CONST bool atomic_flag_impl< IsInterprocess >::always_has_native_wait_notify;
|
||||
#endif
|
||||
|
||||
} // namespace detail
|
||||
} // namespace atomics
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_IMPL_HPP_INCLUDED_
|
||||
@@ -59,14 +59,14 @@ namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
template< typename T, bool IsSigned >
|
||||
template< typename T, bool Signed, bool Interprocess >
|
||||
class base_atomic_common
|
||||
{
|
||||
public:
|
||||
typedef T value_type;
|
||||
|
||||
protected:
|
||||
typedef atomics::detail::operations< storage_size_of< value_type >::value, IsSigned > operations;
|
||||
typedef atomics::detail::operations< storage_size_of< value_type >::value, Signed, Interprocess > operations;
|
||||
typedef atomics::detail::wait_operations< operations > wait_operations;
|
||||
typedef typename atomics::detail::conditional< sizeof(value_type) <= sizeof(void*), value_type, value_type const& >::type value_arg_type;
|
||||
typedef typename operations::storage_type storage_type;
|
||||
@@ -76,6 +76,7 @@ protected:
|
||||
|
||||
public:
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = operations::is_always_lock_free;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = wait_operations::always_has_native_wait_notify;
|
||||
|
||||
protected:
|
||||
BOOST_ATOMIC_DETAIL_ALIGNED_VAR_TPL(storage_alignment, storage_type, m_storage);
|
||||
@@ -105,6 +106,11 @@ public:
|
||||
return is_always_lock_free;
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE bool has_native_wait_notify() const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return wait_operations::has_native_wait_notify(this->storage());
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE void notify_one() volatile BOOST_NOEXCEPT
|
||||
{
|
||||
wait_operations::notify_one(this->storage());
|
||||
@@ -117,20 +123,22 @@ public:
|
||||
};
|
||||
|
||||
#if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
|
||||
template< typename T, bool IsSigned >
|
||||
BOOST_CONSTEXPR_OR_CONST bool base_atomic_common< T, IsSigned >::is_always_lock_free;
|
||||
template< typename T, bool Signed, bool Interprocess >
|
||||
BOOST_CONSTEXPR_OR_CONST bool base_atomic_common< T, Signed, Interprocess >::is_always_lock_free;
|
||||
template< typename T, bool Signed, bool Interprocess >
|
||||
BOOST_CONSTEXPR_OR_CONST bool base_atomic_common< T, Signed, Interprocess >::always_has_native_wait_notify;
|
||||
#endif
|
||||
|
||||
|
||||
template< typename T, bool IsTriviallyDefaultConstructible = atomics::detail::is_trivially_default_constructible< T >::value >
|
||||
template< typename T, bool Interprocess, bool IsTriviallyDefaultConstructible = atomics::detail::is_trivially_default_constructible< T >::value >
|
||||
class base_atomic_generic;
|
||||
|
||||
template< typename T >
|
||||
class base_atomic_generic< T, true > :
|
||||
public base_atomic_common< T, false >
|
||||
template< typename T, bool Interprocess >
|
||||
class base_atomic_generic< T, Interprocess, true > :
|
||||
public base_atomic_common< T, false, Interprocess >
|
||||
{
|
||||
private:
|
||||
typedef base_atomic_common< T, false > base_type;
|
||||
typedef base_atomic_common< T, false, Interprocess > base_type;
|
||||
|
||||
protected:
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
@@ -143,12 +151,12 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
template< typename T >
|
||||
class base_atomic_generic< T, false > :
|
||||
public base_atomic_common< T, false >
|
||||
template< typename T, bool Interprocess >
|
||||
class base_atomic_generic< T, Interprocess, false > :
|
||||
public base_atomic_common< T, false, Interprocess >
|
||||
{
|
||||
private:
|
||||
typedef base_atomic_common< T, false > base_type;
|
||||
typedef base_atomic_common< T, false, Interprocess > base_type;
|
||||
|
||||
public:
|
||||
typedef typename base_type::value_type value_type;
|
||||
@@ -164,16 +172,16 @@ public:
|
||||
};
|
||||
|
||||
|
||||
template< typename T, typename Kind >
|
||||
template< typename T, typename Kind, bool Interprocess >
|
||||
class base_atomic;
|
||||
|
||||
//! General template. Implementation for user-defined types, such as structs and enums, and pointers to non-object types
|
||||
template< typename T >
|
||||
class base_atomic< T, void > :
|
||||
public base_atomic_generic< T >
|
||||
template< typename T, bool Interprocess >
|
||||
class base_atomic< T, void, Interprocess > :
|
||||
public base_atomic_generic< T, Interprocess >
|
||||
{
|
||||
private:
|
||||
typedef base_atomic_generic< T > base_type;
|
||||
typedef base_atomic_generic< T, Interprocess > base_type;
|
||||
|
||||
public:
|
||||
typedef typename base_type::value_type value_type;
|
||||
@@ -292,12 +300,12 @@ private:
|
||||
|
||||
|
||||
//! Implementation for integers
|
||||
template< typename T >
|
||||
class base_atomic< T, int > :
|
||||
public base_atomic_common< T, atomics::detail::is_signed< T >::value >
|
||||
template< typename T, bool Interprocess >
|
||||
class base_atomic< T, int, Interprocess > :
|
||||
public base_atomic_common< T, atomics::detail::is_signed< T >::value, Interprocess >
|
||||
{
|
||||
private:
|
||||
typedef base_atomic_common< T, atomics::detail::is_signed< T >::value > base_type;
|
||||
typedef base_atomic_common< T, atomics::detail::is_signed< T >::value, Interprocess > base_type;
|
||||
|
||||
public:
|
||||
typedef typename base_type::value_type value_type;
|
||||
@@ -621,20 +629,20 @@ private:
|
||||
};
|
||||
|
||||
//! Implementation for bool
|
||||
template< >
|
||||
class base_atomic< bool, int > :
|
||||
public base_atomic_common< bool, false >
|
||||
template< bool Interprocess >
|
||||
class base_atomic< bool, int, Interprocess > :
|
||||
public base_atomic_common< bool, false, Interprocess >
|
||||
{
|
||||
private:
|
||||
typedef base_atomic_common< bool, false > base_type;
|
||||
typedef base_atomic_common< bool, false, Interprocess > base_type;
|
||||
|
||||
public:
|
||||
typedef base_type::value_type value_type;
|
||||
typedef typename base_type::value_type value_type;
|
||||
|
||||
protected:
|
||||
typedef base_type::operations operations;
|
||||
typedef base_type::wait_operations wait_operations;
|
||||
typedef base_type::storage_type storage_type;
|
||||
typedef typename base_type::operations operations;
|
||||
typedef typename base_type::wait_operations wait_operations;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
typedef value_type value_arg_type;
|
||||
|
||||
private:
|
||||
@@ -746,12 +754,12 @@ private:
|
||||
#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
|
||||
|
||||
//! Implementation for floating point types
|
||||
template< typename T >
|
||||
class base_atomic< T, float > :
|
||||
public base_atomic_common< T, false >
|
||||
template< typename T, bool Interprocess >
|
||||
class base_atomic< T, float, Interprocess > :
|
||||
public base_atomic_common< T, false, Interprocess >
|
||||
{
|
||||
private:
|
||||
typedef base_atomic_common< T, false > base_type;
|
||||
typedef base_atomic_common< T, false, Interprocess > base_type;
|
||||
|
||||
public:
|
||||
typedef typename base_type::value_type value_type;
|
||||
@@ -933,12 +941,12 @@ private:
|
||||
|
||||
|
||||
//! Implementation for pointers to object types
|
||||
template< typename T >
|
||||
class base_atomic< T*, void* > :
|
||||
public base_atomic_common< T*, false >
|
||||
template< typename T, bool Interprocess >
|
||||
class base_atomic< T*, void*, Interprocess > :
|
||||
public base_atomic_common< T*, false, Interprocess >
|
||||
{
|
||||
private:
|
||||
typedef base_atomic_common< T*, false > base_type;
|
||||
typedef base_atomic_common< T*, false, Interprocess > base_type;
|
||||
|
||||
public:
|
||||
typedef typename base_type::value_type value_type;
|
||||
|
||||
@@ -54,17 +54,17 @@ namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
template< typename T, bool IsSigned >
|
||||
template< typename T, bool Signed, bool Interprocess >
|
||||
struct is_atomic_ref_lock_free
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef atomics::detail::operations< sizeof(value_type), IsSigned > operations;
|
||||
typedef atomics::detail::operations< sizeof(value_type), Signed, Interprocess > operations;
|
||||
typedef typename operations::storage_type storage_type;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST bool value = sizeof(value_type) == sizeof(storage_type) && operations::is_always_lock_free;
|
||||
};
|
||||
|
||||
template< typename T, bool IsSigned >
|
||||
template< typename T, bool Signed, bool Interprocess >
|
||||
class base_atomic_ref_common
|
||||
{
|
||||
public:
|
||||
@@ -72,9 +72,9 @@ public:
|
||||
|
||||
protected:
|
||||
typedef typename atomics::detail::conditional<
|
||||
atomics::detail::is_atomic_ref_lock_free< T, IsSigned >::value,
|
||||
atomics::detail::operations< sizeof(value_type), IsSigned >,
|
||||
atomics::detail::emulated_operations< sizeof(value_type), atomics::detail::alignment_of< value_type >::value, IsSigned >
|
||||
atomics::detail::is_atomic_ref_lock_free< T, Signed, Interprocess >::value,
|
||||
atomics::detail::operations< sizeof(value_type), Signed, Interprocess >,
|
||||
atomics::detail::emulated_operations< sizeof(value_type), atomics::detail::alignment_of< value_type >::value, Signed, Interprocess >
|
||||
>::type operations;
|
||||
typedef atomics::detail::wait_operations< operations > wait_operations;
|
||||
typedef typename atomics::detail::conditional< sizeof(value_type) <= sizeof(void*), value_type, value_type const& >::type value_arg_type;
|
||||
@@ -84,6 +84,7 @@ protected:
|
||||
public:
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t required_alignment = atomics::detail::alignment_of< value_type >::value <= operations::storage_alignment ? operations::storage_alignment : atomics::detail::alignment_of< value_type >::value;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = operations::is_always_lock_free;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = wait_operations::always_has_native_wait_notify;
|
||||
|
||||
protected:
|
||||
value_type* m_value;
|
||||
@@ -110,6 +111,11 @@ public:
|
||||
return is_always_lock_free;
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE bool has_native_wait_notify() const BOOST_NOEXCEPT
|
||||
{
|
||||
return wait_operations::has_native_wait_notify(this->storage());
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE void notify_one() const BOOST_NOEXCEPT
|
||||
{
|
||||
wait_operations::notify_one(this->storage());
|
||||
@@ -122,23 +128,25 @@ public:
|
||||
};
|
||||
|
||||
#if defined(BOOST_NO_CXX17_INLINE_VARIABLES)
|
||||
template< typename T, bool IsSigned >
|
||||
BOOST_CONSTEXPR_OR_CONST std::size_t base_atomic_ref_common< T, IsSigned >::required_alignment;
|
||||
template< typename T, bool IsSigned >
|
||||
BOOST_CONSTEXPR_OR_CONST bool base_atomic_ref_common< T, IsSigned >::is_always_lock_free;
|
||||
template< typename T, bool Signed, bool Interprocess >
|
||||
BOOST_CONSTEXPR_OR_CONST std::size_t base_atomic_ref_common< T, Signed, Interprocess >::required_alignment;
|
||||
template< typename T, bool Signed, bool Interprocess >
|
||||
BOOST_CONSTEXPR_OR_CONST bool base_atomic_ref_common< T, Signed, Interprocess >::is_always_lock_free;
|
||||
template< typename T, bool Signed, bool Interprocess >
|
||||
BOOST_CONSTEXPR_OR_CONST bool base_atomic_ref_common< T, Signed, Interprocess >::always_has_native_wait_notify;
|
||||
#endif
|
||||
|
||||
|
||||
template< typename T, typename Kind >
|
||||
template< typename T, typename Kind, bool Interprocess >
|
||||
class base_atomic_ref;
|
||||
|
||||
//! General template. Implementation for user-defined types, such as structs and enums, and pointers to non-object types
|
||||
template< typename T >
|
||||
class base_atomic_ref< T, void > :
|
||||
public base_atomic_ref_common< T, false >
|
||||
template< typename T, bool Interprocess >
|
||||
class base_atomic_ref< T, void, Interprocess > :
|
||||
public base_atomic_ref_common< T, false, Interprocess >
|
||||
{
|
||||
private:
|
||||
typedef base_atomic_ref_common< T, false > base_type;
|
||||
typedef base_atomic_ref_common< T, false, Interprocess > base_type;
|
||||
|
||||
public:
|
||||
typedef typename base_type::value_type value_type;
|
||||
@@ -256,12 +264,12 @@ private:
|
||||
|
||||
|
||||
//! Implementation for integers
|
||||
template< typename T >
|
||||
class base_atomic_ref< T, int > :
|
||||
public base_atomic_ref_common< T, atomics::detail::is_signed< T >::value >
|
||||
template< typename T, bool Interprocess >
|
||||
class base_atomic_ref< T, int, Interprocess > :
|
||||
public base_atomic_ref_common< T, atomics::detail::is_signed< T >::value, Interprocess >
|
||||
{
|
||||
private:
|
||||
typedef base_atomic_ref_common< T, atomics::detail::is_signed< T >::value > base_type;
|
||||
typedef base_atomic_ref_common< T, atomics::detail::is_signed< T >::value, Interprocess > base_type;
|
||||
|
||||
public:
|
||||
typedef typename base_type::value_type value_type;
|
||||
@@ -586,21 +594,20 @@ private:
|
||||
};
|
||||
|
||||
//! Implementation for bool
|
||||
template< >
|
||||
class base_atomic_ref< bool, int > :
|
||||
public base_atomic_ref_common< bool, false >
|
||||
template< bool Interprocess >
|
||||
class base_atomic_ref< bool, int, Interprocess > :
|
||||
public base_atomic_ref_common< bool, false, Interprocess >
|
||||
{
|
||||
private:
|
||||
typedef base_atomic_ref_common< bool, false > base_type;
|
||||
typedef base_atomic_ref_common< bool, false, Interprocess > base_type;
|
||||
|
||||
public:
|
||||
typedef bool value_type;
|
||||
|
||||
protected:
|
||||
typedef base_type::operations operations;
|
||||
typedef base_type::wait_operations wait_operations;
|
||||
typedef atomics::detail::extra_operations< operations > extra_operations;
|
||||
typedef base_type::storage_type storage_type;
|
||||
typedef typename base_type::operations operations;
|
||||
typedef typename base_type::wait_operations wait_operations;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
typedef value_type value_arg_type;
|
||||
|
||||
private:
|
||||
@@ -713,12 +720,12 @@ private:
|
||||
#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
|
||||
|
||||
//! Implementation for floating point types
|
||||
template< typename T >
|
||||
class base_atomic_ref< T, float > :
|
||||
public base_atomic_ref_common< T, false >
|
||||
template< typename T, bool Interprocess >
|
||||
class base_atomic_ref< T, float, Interprocess > :
|
||||
public base_atomic_ref_common< T, false, Interprocess >
|
||||
{
|
||||
private:
|
||||
typedef base_atomic_ref_common< T, false > base_type;
|
||||
typedef base_atomic_ref_common< T, false, Interprocess > base_type;
|
||||
|
||||
public:
|
||||
typedef typename base_type::value_type value_type;
|
||||
@@ -918,12 +925,12 @@ private:
|
||||
|
||||
|
||||
//! Implementation for pointers to object types
|
||||
template< typename T >
|
||||
class base_atomic_ref< T*, void* > :
|
||||
public base_atomic_ref_common< T*, false >
|
||||
template< typename T, bool Interprocess >
|
||||
class base_atomic_ref< T*, void*, Interprocess > :
|
||||
public base_atomic_ref_common< T*, false, Interprocess >
|
||||
{
|
||||
private:
|
||||
typedef base_atomic_ref_common< T*, false > base_type;
|
||||
typedef base_atomic_ref_common< T*, false, Interprocess > base_type;
|
||||
|
||||
public:
|
||||
typedef typename base_type::value_type value_type;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define BOOST_ATOMIC_DETAIL_EXTRA_FP_OPS_EMULATED_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/bitwise_fp_cast.hpp>
|
||||
@@ -28,7 +29,7 @@ namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
//! Generic implementation of extra floating point operations
|
||||
//! Emulated implementation of extra floating point operations
|
||||
template< typename Base, typename Value, std::size_t Size >
|
||||
struct emulated_extra_fp_operations :
|
||||
public Base
|
||||
@@ -40,6 +41,7 @@ struct emulated_extra_fp_operations :
|
||||
|
||||
static BOOST_FORCEINLINE value_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s);
|
||||
@@ -50,6 +52,7 @@ struct emulated_extra_fp_operations :
|
||||
|
||||
static BOOST_FORCEINLINE value_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s);
|
||||
@@ -60,6 +63,7 @@ struct emulated_extra_fp_operations :
|
||||
|
||||
static BOOST_FORCEINLINE value_type add(storage_type volatile& storage, value_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s);
|
||||
@@ -70,6 +74,7 @@ struct emulated_extra_fp_operations :
|
||||
|
||||
static BOOST_FORCEINLINE value_type sub(storage_type volatile& storage, value_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s);
|
||||
@@ -80,16 +85,19 @@ struct emulated_extra_fp_operations :
|
||||
|
||||
static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
fetch_negate(storage, order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
base_type::fetch_add(storage, v, order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, value_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
base_type::fetch_sub(storage, v, order);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define BOOST_ATOMIC_DETAIL_EXTRA_OPS_EMULATED_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/storage_traits.hpp>
|
||||
@@ -34,7 +35,7 @@ namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
//! Generic implementation of extra operations
|
||||
//! Emulated implementation of extra operations
|
||||
template< typename Base, std::size_t Size, bool Signed >
|
||||
struct emulated_extra_operations :
|
||||
public Base
|
||||
@@ -45,6 +46,7 @@ struct emulated_extra_operations :
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
storage_type old_val = s;
|
||||
@@ -54,6 +56,7 @@ struct emulated_extra_operations :
|
||||
|
||||
static BOOST_FORCEINLINE storage_type negate(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
storage_type new_val = static_cast< storage_type >(-s);
|
||||
@@ -63,6 +66,7 @@ struct emulated_extra_operations :
|
||||
|
||||
static BOOST_FORCEINLINE storage_type add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
storage_type new_val = s;
|
||||
@@ -73,6 +77,7 @@ struct emulated_extra_operations :
|
||||
|
||||
static BOOST_FORCEINLINE storage_type sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
storage_type new_val = s;
|
||||
@@ -83,6 +88,7 @@ struct emulated_extra_operations :
|
||||
|
||||
static BOOST_FORCEINLINE storage_type bitwise_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
storage_type new_val = s;
|
||||
@@ -93,6 +99,7 @@ struct emulated_extra_operations :
|
||||
|
||||
static BOOST_FORCEINLINE storage_type bitwise_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
storage_type new_val = s;
|
||||
@@ -103,6 +110,7 @@ struct emulated_extra_operations :
|
||||
|
||||
static BOOST_FORCEINLINE storage_type bitwise_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
storage_type new_val = s;
|
||||
@@ -113,6 +121,7 @@ struct emulated_extra_operations :
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
storage_type old_val = s;
|
||||
@@ -122,6 +131,7 @@ struct emulated_extra_operations :
|
||||
|
||||
static BOOST_FORCEINLINE storage_type bitwise_complement(storage_type volatile& storage, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
storage_type new_val = static_cast< storage_type >(~s);
|
||||
@@ -131,92 +141,109 @@ struct emulated_extra_operations :
|
||||
|
||||
static BOOST_FORCEINLINE void opaque_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
Base::fetch_add(storage, v, order);
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
base_type::fetch_add(storage, v, order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE void opaque_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
Base::fetch_sub(storage, v, order);
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
base_type::fetch_sub(storage, v, order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE void opaque_negate(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
fetch_negate(storage, order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE void opaque_and(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
Base::fetch_and(storage, v, order);
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
base_type::fetch_and(storage, v, order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE void opaque_or(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
Base::fetch_or(storage, v, order);
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
base_type::fetch_or(storage, v, order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE void opaque_xor(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
Base::fetch_xor(storage, v, order);
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
base_type::fetch_xor(storage, v, order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE void opaque_complement(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
fetch_complement(storage, order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE bool add_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
return !!add(storage, v, order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE bool sub_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
return !!sub(storage, v, order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE bool negate_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
return !!negate(storage, order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE bool and_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
return !!bitwise_and(storage, v, order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE bool or_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
return !!bitwise_or(storage, v, order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE bool xor_and_test(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
return !!bitwise_xor(storage, v, order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE bool complement_and_test(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
return !!bitwise_complement(storage, order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE bool bit_test_and_set(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type mask = static_cast< storage_type >(static_cast< storage_type >(1u) << bit_number);
|
||||
storage_type old_val = Base::fetch_or(storage, mask, order);
|
||||
storage_type old_val = base_type::fetch_or(storage, mask, order);
|
||||
return !!(old_val & mask);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE bool bit_test_and_reset(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type mask = static_cast< storage_type >(static_cast< storage_type >(1u) << bit_number);
|
||||
storage_type old_val = Base::fetch_and(storage, ~mask, order);
|
||||
storage_type old_val = base_type::fetch_and(storage, ~mask, order);
|
||||
return !!(old_val & mask);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE bool bit_test_and_complement(storage_type volatile& storage, unsigned int bit_number, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type mask = static_cast< storage_type >(static_cast< storage_type >(1u) << bit_number);
|
||||
storage_type old_val = Base::fetch_xor(storage, mask, order);
|
||||
storage_type old_val = base_type::fetch_xor(storage, mask, order);
|
||||
return !!(old_val & mask);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define BOOST_ATOMIC_DETAIL_FP_OPS_EMULATED_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/bitwise_fp_cast.hpp>
|
||||
@@ -28,7 +29,7 @@ namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
//! Generic implementation of floating point operations
|
||||
//! Emulated implementation of floating point operations
|
||||
template< typename Base, typename Value, std::size_t Size >
|
||||
struct emulated_fp_operations :
|
||||
public Base
|
||||
@@ -40,6 +41,7 @@ struct emulated_fp_operations :
|
||||
|
||||
static BOOST_FORCEINLINE value_type fetch_add(storage_type volatile& storage, value_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s);
|
||||
@@ -50,6 +52,7 @@ struct emulated_fp_operations :
|
||||
|
||||
static BOOST_FORCEINLINE value_type fetch_sub(storage_type volatile& storage, value_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
value_type old_val = atomics::detail::bitwise_fp_cast< value_type >(s);
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
typedef atomics::detail::operations< 1u, false > once_flag_operations;
|
||||
typedef atomics::detail::operations< 1u, false, false > once_flag_operations;
|
||||
|
||||
struct once_flag
|
||||
{
|
||||
|
||||
@@ -25,10 +25,10 @@ namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
template< std::size_t Size, std::size_t Alignment, bool Signed >
|
||||
template< std::size_t Size, std::size_t Alignment, bool Signed, bool Interprocess >
|
||||
struct emulated_operations;
|
||||
|
||||
template< std::size_t Size, bool Signed >
|
||||
template< std::size_t Size, bool Signed, bool Interprocess >
|
||||
struct operations;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#define BOOST_ATOMIC_DETAIL_OPS_EMULATED_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/storage_traits.hpp>
|
||||
@@ -41,7 +42,8 @@ struct base_emulated_operations< Size, Alignment, false >
|
||||
typedef buffer_storage< Size, Alignment > storage_type;
|
||||
};
|
||||
|
||||
template< std::size_t Size, std::size_t Alignment, bool Signed >
|
||||
//! Emulated implementation of atomic operations
|
||||
template< std::size_t Size, std::size_t Alignment, bool Signed, bool Interprocess >
|
||||
struct emulated_operations :
|
||||
public base_emulated_operations< Size, Alignment >
|
||||
{
|
||||
@@ -57,6 +59,7 @@ struct emulated_operations :
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = Alignment >= storage_traits< Size >::alignment ? storage_traits< Size >::alignment : Alignment;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = false;
|
||||
@@ -65,18 +68,21 @@ struct emulated_operations :
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
scoped_lock lock(&storage);
|
||||
const_cast< storage_type& >(storage) = v;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
scoped_lock lock(&storage);
|
||||
return const_cast< storage_type const& >(storage);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
storage_type old_val = s;
|
||||
@@ -86,6 +92,7 @@ struct emulated_operations :
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
storage_type old_val = s;
|
||||
@@ -95,6 +102,7 @@ struct emulated_operations :
|
||||
|
||||
static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
storage_type old_val = s;
|
||||
@@ -105,6 +113,7 @@ struct emulated_operations :
|
||||
static BOOST_FORCEINLINE bool compare_exchange_strong(
|
||||
storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
storage_type old_val = s;
|
||||
@@ -121,6 +130,7 @@ struct emulated_operations :
|
||||
{
|
||||
// Note: This function is the exact copy of compare_exchange_strong. The reason we're not just forwarding the call
|
||||
// is that MSVC-12 ICEs in this case.
|
||||
BOOST_STATIC_ASSERT_MSG(!is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
storage_type old_val = s;
|
||||
@@ -134,6 +144,7 @@ struct emulated_operations :
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
storage_type old_val = s;
|
||||
@@ -143,6 +154,7 @@ struct emulated_operations :
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
storage_type old_val = s;
|
||||
@@ -152,6 +164,7 @@ struct emulated_operations :
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type& s = const_cast< storage_type& >(storage);
|
||||
scoped_lock lock(&storage);
|
||||
storage_type old_val = s;
|
||||
@@ -161,18 +174,20 @@ struct emulated_operations :
|
||||
|
||||
static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
return !!exchange(storage, (storage_type)1, order);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
store(storage, (storage_type)0, order);
|
||||
}
|
||||
};
|
||||
|
||||
template< std::size_t Size, bool Signed >
|
||||
template< std::size_t Size, bool Signed, bool Interprocess >
|
||||
struct operations :
|
||||
public emulated_operations< Size, storage_traits< Size >::alignment, Signed >
|
||||
public emulated_operations< Size, storage_traits< Size >::alignment, Signed, Interprocess >
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
@@ -87,8 +87,8 @@ struct gcc_alpha_operations_base
|
||||
};
|
||||
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 4u, Signed > :
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 4u, Signed, Interprocess > :
|
||||
public gcc_alpha_operations_base
|
||||
{
|
||||
typedef typename storage_traits< 4u >::type storage_type;
|
||||
@@ -96,6 +96,7 @@ struct operations< 4u, Signed > :
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 4u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -347,12 +348,12 @@ struct operations< 4u, Signed > :
|
||||
};
|
||||
|
||||
|
||||
template< >
|
||||
struct operations< 1u, false > :
|
||||
public operations< 4u, false >
|
||||
template< bool Interprocess >
|
||||
struct operations< 1u, false, Interprocess > :
|
||||
public operations< 4u, false, Interprocess >
|
||||
{
|
||||
typedef operations< 4u, false > base_type;
|
||||
typedef base_type::storage_type storage_type;
|
||||
typedef operations< 4u, false, Interprocess > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -409,12 +410,12 @@ struct operations< 1u, false > :
|
||||
}
|
||||
};
|
||||
|
||||
template< >
|
||||
struct operations< 1u, true > :
|
||||
public operations< 4u, true >
|
||||
template< bool Interprocess >
|
||||
struct operations< 1u, true, Interprocess > :
|
||||
public operations< 4u, true, Interprocess >
|
||||
{
|
||||
typedef operations< 4u, true > base_type;
|
||||
typedef base_type::storage_type storage_type;
|
||||
typedef operations< 4u, true, Interprocess > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -472,12 +473,12 @@ struct operations< 1u, true > :
|
||||
};
|
||||
|
||||
|
||||
template< >
|
||||
struct operations< 2u, false > :
|
||||
public operations< 4u, false >
|
||||
template< bool Interprocess >
|
||||
struct operations< 2u, false, Interprocess > :
|
||||
public operations< 4u, false, Interprocess >
|
||||
{
|
||||
typedef operations< 4u, false > base_type;
|
||||
typedef base_type::storage_type storage_type;
|
||||
typedef operations< 4u, false, Interprocess > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -534,12 +535,12 @@ struct operations< 2u, false > :
|
||||
}
|
||||
};
|
||||
|
||||
template< >
|
||||
struct operations< 2u, true > :
|
||||
public operations< 4u, true >
|
||||
template< bool Interprocess >
|
||||
struct operations< 2u, true, Interprocess > :
|
||||
public operations< 4u, true, Interprocess >
|
||||
{
|
||||
typedef operations< 4u, true > base_type;
|
||||
typedef base_type::storage_type storage_type;
|
||||
typedef operations< 4u, true, Interprocess > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -597,8 +598,8 @@ struct operations< 2u, true > :
|
||||
};
|
||||
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 8u, Signed > :
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 8u, Signed, Interprocess > :
|
||||
public gcc_alpha_operations_base
|
||||
{
|
||||
typedef typename storage_traits< 8u >::type storage_type;
|
||||
@@ -606,6 +607,7 @@ struct operations< 8u, Signed > :
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 8u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
|
||||
@@ -56,8 +56,8 @@ namespace detail {
|
||||
// FIXME these are not yet used; should be mostly a matter of copy-and-paste.
|
||||
// I think you can supply an immediate offset to the address.
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 4u, Signed > :
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 4u, Signed, Interprocess > :
|
||||
public gcc_arm_operations_base
|
||||
{
|
||||
typedef typename storage_traits< 4u >::type storage_type;
|
||||
@@ -65,6 +65,7 @@ struct operations< 4u, Signed > :
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 4u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -314,8 +315,8 @@ struct operations< 4u, Signed > :
|
||||
|
||||
#if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 1u, Signed > :
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 1u, Signed, Interprocess > :
|
||||
public gcc_arm_operations_base
|
||||
{
|
||||
typedef typename storage_traits< 1u >::type storage_type;
|
||||
@@ -324,6 +325,7 @@ struct operations< 1u, Signed > :
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 1u;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 1u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -573,12 +575,12 @@ struct operations< 1u, Signed > :
|
||||
|
||||
#else // defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXB_STREXB)
|
||||
|
||||
template< >
|
||||
struct operations< 1u, false > :
|
||||
public operations< 4u, false >
|
||||
template< bool Interprocess >
|
||||
struct operations< 1u, false, Interprocess > :
|
||||
public operations< 4u, false, Interprocess >
|
||||
{
|
||||
typedef operations< 4u, false > base_type;
|
||||
typedef base_type::storage_type storage_type;
|
||||
typedef operations< 4u, false, Interprocess > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -635,12 +637,12 @@ struct operations< 1u, false > :
|
||||
}
|
||||
};
|
||||
|
||||
template< >
|
||||
struct operations< 1u, true > :
|
||||
public operations< 4u, true >
|
||||
template< bool Interprocess >
|
||||
struct operations< 1u, true, Interprocess > :
|
||||
public operations< 4u, true, Interprocess >
|
||||
{
|
||||
typedef operations< 4u, true > base_type;
|
||||
typedef base_type::storage_type storage_type;
|
||||
typedef operations< 4u, true, Interprocess > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -701,8 +703,8 @@ struct operations< 1u, true > :
|
||||
|
||||
#if defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 2u, Signed > :
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 2u, Signed, Interprocess > :
|
||||
public gcc_arm_operations_base
|
||||
{
|
||||
typedef typename storage_traits< 2u >::type storage_type;
|
||||
@@ -711,6 +713,7 @@ struct operations< 2u, Signed > :
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 2u;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 2u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -960,12 +963,12 @@ struct operations< 2u, Signed > :
|
||||
|
||||
#else // defined(BOOST_ATOMIC_DETAIL_ARM_HAS_LDREXH_STREXH)
|
||||
|
||||
template< >
|
||||
struct operations< 2u, false > :
|
||||
public operations< 4u, false >
|
||||
template< bool Interprocess >
|
||||
struct operations< 2u, false, Interprocess > :
|
||||
public operations< 4u, false, Interprocess >
|
||||
{
|
||||
typedef operations< 4u, false > base_type;
|
||||
typedef base_type::storage_type storage_type;
|
||||
typedef operations< 4u, false, Interprocess > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -1022,12 +1025,12 @@ struct operations< 2u, false > :
|
||||
}
|
||||
};
|
||||
|
||||
template< >
|
||||
struct operations< 2u, true > :
|
||||
public operations< 4u, true >
|
||||
template< bool Interprocess >
|
||||
struct operations< 2u, true, Interprocess > :
|
||||
public operations< 4u, true, Interprocess >
|
||||
{
|
||||
typedef operations< 4u, true > base_type;
|
||||
typedef base_type::storage_type storage_type;
|
||||
typedef operations< 4u, true, Interprocess > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -1099,8 +1102,8 @@ struct operations< 2u, true > :
|
||||
// and the upper half (Rt2) - via the same placeholder with an 'H' after the '%' sign (e.g. %H0).
|
||||
// See: http://hardwarebug.org/2010/07/06/arm-inline-asm-secrets/
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 8u, Signed > :
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 8u, Signed, Interprocess > :
|
||||
public gcc_arm_operations_base
|
||||
{
|
||||
typedef typename storage_traits< 8u >::type storage_type;
|
||||
@@ -1108,6 +1111,7 @@ struct operations< 8u, Signed > :
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 8u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
|
||||
@@ -81,7 +81,7 @@ BOOST_FORCEINLINE BOOST_CONSTEXPR int convert_memory_order_to_gcc(memory_order o
|
||||
(order == memory_order_acq_rel ? __ATOMIC_ACQ_REL : __ATOMIC_SEQ_CST)))));
|
||||
}
|
||||
|
||||
template< std::size_t Size, bool Signed >
|
||||
template< std::size_t Size, bool Signed, bool Interprocess >
|
||||
struct gcc_atomic_operations
|
||||
{
|
||||
typedef typename storage_traits< Size >::type storage_type;
|
||||
@@ -89,6 +89,7 @@ struct gcc_atomic_operations
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = Size;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = storage_traits< Size >::alignment;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = false;
|
||||
|
||||
// Note: In the current implementation, gcc_atomic_operations are used only when the particularly sized __atomic
|
||||
@@ -176,17 +177,17 @@ struct gcc_atomic_operations
|
||||
// Clang 3.4 does not implement 128-bit __atomic* intrinsics even though it defines __GCC_HAVE_SYNC_COMPARE_AND_SWAP_16
|
||||
// A similar problem exists with gcc 7 as well, as it requires to link with libatomic to use 16-byte intrinsics:
|
||||
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80878
|
||||
template< bool Signed >
|
||||
struct operations< 16u, Signed > :
|
||||
public cas_based_operations< gcc_dcas_x86_64< Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 16u, Signed, Interprocess > :
|
||||
public cas_based_operations< gcc_dcas_x86_64< Signed, Interprocess > >
|
||||
{
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 16u, Signed > :
|
||||
public gcc_atomic_operations< 16u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 16u, Signed, Interprocess > :
|
||||
public gcc_atomic_operations< 16u, Signed, Interprocess >
|
||||
{
|
||||
};
|
||||
|
||||
@@ -198,9 +199,9 @@ struct operations< 16u, Signed > :
|
||||
#if defined(__clang__) && defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B)
|
||||
|
||||
// Workaround for clang bug http://llvm.org/bugs/show_bug.cgi?id=19355
|
||||
template< bool Signed >
|
||||
struct operations< 8u, Signed > :
|
||||
public cas_based_operations< gcc_dcas_x86< Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 8u, Signed, Interprocess > :
|
||||
public cas_based_operations< gcc_dcas_x86< Signed, Interprocess > >
|
||||
{
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
@@ -214,17 +215,17 @@ struct operations< 8u, Signed > :
|
||||
|
||||
#define BOOST_ATOMIC_DETAIL_INT64_EXTENDED
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 8u, Signed > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 16u, Signed >, 8u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 8u, Signed, Interprocess > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 16u, Signed, Interprocess >, 8u, Signed >
|
||||
{
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 8u, Signed > :
|
||||
public gcc_atomic_operations< 8u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 8u, Signed, Interprocess > :
|
||||
public gcc_atomic_operations< 8u, Signed, Interprocess >
|
||||
{
|
||||
};
|
||||
|
||||
@@ -242,17 +243,17 @@ struct operations< 8u, Signed > :
|
||||
|
||||
#if !defined(BOOST_ATOMIC_DETAIL_INT64_EXTENDED)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 4u, Signed > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 8u, Signed >, 4u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 4u, Signed, Interprocess > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 8u, Signed, Interprocess >, 4u, Signed >
|
||||
{
|
||||
};
|
||||
|
||||
#else // !defined(BOOST_ATOMIC_DETAIL_INT64_EXTENDED)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 4u, Signed > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 16u, Signed >, 4u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 4u, Signed, Interprocess > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 16u, Signed, Interprocess >, 4u, Signed >
|
||||
{
|
||||
};
|
||||
|
||||
@@ -260,9 +261,9 @@ struct operations< 4u, Signed > :
|
||||
|
||||
#else
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 4u, Signed > :
|
||||
public gcc_atomic_operations< 4u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 4u, Signed, Interprocess > :
|
||||
public gcc_atomic_operations< 4u, Signed, Interprocess >
|
||||
{
|
||||
};
|
||||
|
||||
@@ -280,25 +281,25 @@ struct operations< 4u, Signed > :
|
||||
|
||||
#if !defined(BOOST_ATOMIC_DETAIL_INT32_EXTENDED)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 2u, Signed > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 4u, Signed >, 2u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 2u, Signed, Interprocess > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 4u, Signed, Interprocess >, 2u, Signed >
|
||||
{
|
||||
};
|
||||
|
||||
#elif !defined(BOOST_ATOMIC_DETAIL_INT64_EXTENDED)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 2u, Signed > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 8u, Signed >, 2u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 2u, Signed, Interprocess > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 8u, Signed, Interprocess >, 2u, Signed >
|
||||
{
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 2u, Signed > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 16u, Signed >, 2u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 2u, Signed, Interprocess > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 16u, Signed, Interprocess >, 2u, Signed >
|
||||
{
|
||||
};
|
||||
|
||||
@@ -306,9 +307,9 @@ struct operations< 2u, Signed > :
|
||||
|
||||
#else
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 2u, Signed > :
|
||||
public gcc_atomic_operations< 2u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 2u, Signed, Interprocess > :
|
||||
public gcc_atomic_operations< 2u, Signed, Interprocess >
|
||||
{
|
||||
};
|
||||
|
||||
@@ -326,33 +327,33 @@ struct operations< 2u, Signed > :
|
||||
|
||||
#if !defined(BOOST_ATOMIC_DETAIL_INT16_EXTENDED)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 1u, Signed > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 2u, Signed >, 1u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 1u, Signed, Interprocess > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 2u, Signed, Interprocess >, 1u, Signed >
|
||||
{
|
||||
};
|
||||
|
||||
#elif !defined(BOOST_ATOMIC_DETAIL_INT32_EXTENDED)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 1u, Signed > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 4u, Signed >, 1u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 1u, Signed, Interprocess > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 4u, Signed, Interprocess >, 1u, Signed >
|
||||
{
|
||||
};
|
||||
|
||||
#elif !defined(BOOST_ATOMIC_DETAIL_INT64_EXTENDED)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 1u, Signed > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 8u, Signed >, 1u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 1u, Signed, Interprocess > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 8u, Signed, Interprocess >, 1u, Signed >
|
||||
{
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 1u, Signed > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 16u, Signed >, 1u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 1u, Signed, Interprocess > :
|
||||
public extending_cas_based_operations< gcc_atomic_operations< 16u, Signed, Interprocess >, 1u, Signed >
|
||||
{
|
||||
};
|
||||
|
||||
@@ -360,9 +361,9 @@ struct operations< 1u, Signed > :
|
||||
|
||||
#else
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 1u, Signed > :
|
||||
public gcc_atomic_operations< 1u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 1u, Signed, Interprocess > :
|
||||
public gcc_atomic_operations< 1u, Signed, Interprocess >
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
@@ -79,8 +79,8 @@ namespace detail {
|
||||
to pose a problem.
|
||||
*/
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 4u, Signed > :
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 4u, Signed, Interprocess > :
|
||||
public gcc_ppc_operations_base
|
||||
{
|
||||
typedef typename storage_traits< 4u >::type storage_type;
|
||||
@@ -88,6 +88,7 @@ struct operations< 4u, Signed > :
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 4u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -309,8 +310,8 @@ struct operations< 4u, Signed > :
|
||||
|
||||
#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 1u, Signed > :
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 1u, Signed, Interprocess > :
|
||||
public gcc_ppc_operations_base
|
||||
{
|
||||
typedef typename storage_traits< 1u >::type storage_type;
|
||||
@@ -318,6 +319,7 @@ struct operations< 1u, Signed > :
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 1u;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 1u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -539,12 +541,12 @@ struct operations< 1u, Signed > :
|
||||
|
||||
#else // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LBARX_STBCX)
|
||||
|
||||
template< >
|
||||
struct operations< 1u, false > :
|
||||
public operations< 4u, false >
|
||||
template< bool Interprocess >
|
||||
struct operations< 1u, false, Interprocess > :
|
||||
public operations< 4u, false, Interprocess >
|
||||
{
|
||||
typedef operations< 4u, false > base_type;
|
||||
typedef base_type::storage_type storage_type;
|
||||
typedef operations< 4u, false, Interprocess > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -587,12 +589,12 @@ struct operations< 1u, false > :
|
||||
}
|
||||
};
|
||||
|
||||
template< >
|
||||
struct operations< 1u, true > :
|
||||
public operations< 4u, true >
|
||||
template< bool Interprocess >
|
||||
struct operations< 1u, true, Interprocess > :
|
||||
public operations< 4u, true, Interprocess >
|
||||
{
|
||||
typedef operations< 4u, true > base_type;
|
||||
typedef base_type::storage_type storage_type;
|
||||
typedef operations< 4u, true, Interprocess > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -639,8 +641,8 @@ struct operations< 1u, true > :
|
||||
|
||||
#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 2u, Signed > :
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 2u, Signed, Interprocess > :
|
||||
public gcc_ppc_operations_base
|
||||
{
|
||||
typedef typename storage_traits< 2u >::type storage_type;
|
||||
@@ -648,6 +650,7 @@ struct operations< 2u, Signed > :
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 2u;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 2u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -869,12 +872,12 @@ struct operations< 2u, Signed > :
|
||||
|
||||
#else // defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LHARX_STHCX)
|
||||
|
||||
template< >
|
||||
struct operations< 2u, false > :
|
||||
public operations< 4u, false >
|
||||
template< bool Interprocess >
|
||||
struct operations< 2u, false, Interprocess > :
|
||||
public operations< 4u, false, Interprocess >
|
||||
{
|
||||
typedef operations< 4u, false > base_type;
|
||||
typedef base_type::storage_type storage_type;
|
||||
typedef operations< 4u, false, Interprocess > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -917,12 +920,12 @@ struct operations< 2u, false > :
|
||||
}
|
||||
};
|
||||
|
||||
template< >
|
||||
struct operations< 2u, true > :
|
||||
public operations< 4u, true >
|
||||
template< bool Interprocess >
|
||||
struct operations< 2u, true, Interprocess > :
|
||||
public operations< 4u, true, Interprocess >
|
||||
{
|
||||
typedef operations< 4u, true > base_type;
|
||||
typedef base_type::storage_type storage_type;
|
||||
typedef operations< 4u, true, Interprocess > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -969,8 +972,8 @@ struct operations< 2u, true > :
|
||||
|
||||
#if defined(BOOST_ATOMIC_DETAIL_PPC_HAS_LDARX_STDCX)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 8u, Signed > :
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 8u, Signed, Interprocess > :
|
||||
public gcc_ppc_operations_base
|
||||
{
|
||||
typedef typename storage_traits< 8u >::type storage_type;
|
||||
@@ -978,6 +981,7 @@ struct operations< 8u, Signed > :
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 8u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
|
||||
@@ -61,7 +61,7 @@ struct gcc_sparc_cas_base
|
||||
}
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct gcc_sparc_cas32 :
|
||||
public gcc_sparc_cas_base
|
||||
{
|
||||
@@ -70,6 +70,7 @@ struct gcc_sparc_cas32 :
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 4u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -127,25 +128,25 @@ struct gcc_sparc_cas32 :
|
||||
}
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 4u, Signed > :
|
||||
public cas_based_operations< gcc_sparc_cas32< Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 4u, Signed, Interprocess > :
|
||||
public cas_based_operations< gcc_sparc_cas32< Signed, Interprocess > >
|
||||
{
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 1u, Signed > :
|
||||
public extending_cas_based_operations< operations< 4u, Signed >, 1u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 1u, Signed, Interprocess > :
|
||||
public extending_cas_based_operations< operations< 4u, Signed, Interprocess >, 1u, Signed >
|
||||
{
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 2u, Signed > :
|
||||
public extending_cas_based_operations< operations< 4u, Signed >, 2u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 2u, Signed, Interprocess > :
|
||||
public extending_cas_based_operations< operations< 4u, Signed, Interprocess >, 2u, Signed >
|
||||
{
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct gcc_sparc_cas64 :
|
||||
public gcc_sparc_cas_base
|
||||
{
|
||||
@@ -154,6 +155,7 @@ struct gcc_sparc_cas64 :
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 8u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -197,9 +199,9 @@ struct gcc_sparc_cas64 :
|
||||
}
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 8u, Signed > :
|
||||
public cas_based_operations< cas_based_exchange< gcc_sparc_cas64< Signed > > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 8u, Signed, Interprocess > :
|
||||
public cas_based_operations< cas_based_exchange< gcc_sparc_cas64< Signed, Interprocess > > >
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ struct gcc_sync_operations_base
|
||||
}
|
||||
};
|
||||
|
||||
template< std::size_t Size, bool Signed >
|
||||
template< std::size_t Size, bool Signed, bool Interprocess >
|
||||
struct gcc_sync_operations :
|
||||
public gcc_sync_operations_base
|
||||
{
|
||||
@@ -65,6 +65,7 @@ struct gcc_sync_operations :
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = Size;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = storage_traits< Size >::alignment;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -154,69 +155,69 @@ struct gcc_sync_operations :
|
||||
};
|
||||
|
||||
#if BOOST_ATOMIC_INT8_LOCK_FREE > 0
|
||||
template< bool Signed >
|
||||
struct operations< 1u, Signed > :
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 1u, Signed, Interprocess > :
|
||||
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1)
|
||||
public gcc_sync_operations< 1u, Signed >
|
||||
public gcc_sync_operations< 1u, Signed, Interprocess >
|
||||
#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)
|
||||
public extending_cas_based_operations< gcc_sync_operations< 2u, Signed >, 1u, Signed >
|
||||
public extending_cas_based_operations< gcc_sync_operations< 2u, Signed, Interprocess >, 1u, Signed >
|
||||
#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
|
||||
public extending_cas_based_operations< gcc_sync_operations< 4u, Signed >, 1u, Signed >
|
||||
public extending_cas_based_operations< gcc_sync_operations< 4u, Signed, Interprocess >, 1u, Signed >
|
||||
#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
|
||||
public extending_cas_based_operations< gcc_sync_operations< 8u, Signed >, 1u, Signed >
|
||||
public extending_cas_based_operations< gcc_sync_operations< 8u, Signed, Interprocess >, 1u, Signed >
|
||||
#else
|
||||
public extending_cas_based_operations< gcc_sync_operations< 16u, Signed >, 1u, Signed >
|
||||
public extending_cas_based_operations< gcc_sync_operations< 16u, Signed, Interprocess >, 1u, Signed >
|
||||
#endif
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
#if BOOST_ATOMIC_INT16_LOCK_FREE > 0
|
||||
template< bool Signed >
|
||||
struct operations< 2u, Signed > :
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 2u, Signed, Interprocess > :
|
||||
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)
|
||||
public gcc_sync_operations< 2u, Signed >
|
||||
public gcc_sync_operations< 2u, Signed, Interprocess >
|
||||
#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
|
||||
public extending_cas_based_operations< gcc_sync_operations< 4u, Signed >, 2u, Signed >
|
||||
public extending_cas_based_operations< gcc_sync_operations< 4u, Signed, Interprocess >, 2u, Signed >
|
||||
#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
|
||||
public extending_cas_based_operations< gcc_sync_operations< 8u, Signed >, 2u, Signed >
|
||||
public extending_cas_based_operations< gcc_sync_operations< 8u, Signed, Interprocess >, 2u, Signed >
|
||||
#else
|
||||
public extending_cas_based_operations< gcc_sync_operations< 16u, Signed >, 2u, Signed >
|
||||
public extending_cas_based_operations< gcc_sync_operations< 16u, Signed, Interprocess >, 2u, Signed >
|
||||
#endif
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
#if BOOST_ATOMIC_INT32_LOCK_FREE > 0
|
||||
template< bool Signed >
|
||||
struct operations< 4u, Signed > :
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 4u, Signed, Interprocess > :
|
||||
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
|
||||
public gcc_sync_operations< 4u, Signed >
|
||||
public gcc_sync_operations< 4u, Signed, Interprocess >
|
||||
#elif defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
|
||||
public extending_cas_based_operations< gcc_sync_operations< 8u, Signed >, 4u, Signed >
|
||||
public extending_cas_based_operations< gcc_sync_operations< 8u, Signed, Interprocess >, 4u, Signed >
|
||||
#else
|
||||
public extending_cas_based_operations< gcc_sync_operations< 16u, Signed >, 4u, Signed >
|
||||
public extending_cas_based_operations< gcc_sync_operations< 16u, Signed, Interprocess >, 4u, Signed >
|
||||
#endif
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
#if BOOST_ATOMIC_INT64_LOCK_FREE > 0
|
||||
template< bool Signed >
|
||||
struct operations< 8u, Signed > :
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 8u, Signed, Interprocess > :
|
||||
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
|
||||
public gcc_sync_operations< 8u, Signed >
|
||||
public gcc_sync_operations< 8u, Signed, Interprocess >
|
||||
#else
|
||||
public extending_cas_based_operations< gcc_sync_operations< 16u, Signed >, 8u, Signed >
|
||||
public extending_cas_based_operations< gcc_sync_operations< 16u, Signed, Interprocess >, 8u, Signed >
|
||||
#endif
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
#if BOOST_ATOMIC_INT128_LOCK_FREE > 0
|
||||
template< bool Signed >
|
||||
struct operations< 16u, Signed > :
|
||||
public gcc_sync_operations< 16u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 16u, Signed, Interprocess > :
|
||||
public gcc_sync_operations< 16u, Signed, Interprocess >
|
||||
{
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -53,12 +53,17 @@ struct gcc_x86_operations_base
|
||||
}
|
||||
};
|
||||
|
||||
template< std::size_t Size, bool Signed, typename Derived >
|
||||
template< std::size_t Size, bool Signed, bool Interprocess, typename Derived >
|
||||
struct gcc_x86_operations :
|
||||
public gcc_x86_operations_base
|
||||
{
|
||||
typedef typename storage_traits< Size >::type storage_type;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = Size;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = Size;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
if (order != memory_order_seq_cst)
|
||||
@@ -102,18 +107,14 @@ struct gcc_x86_operations :
|
||||
}
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 1u, Signed > :
|
||||
public gcc_x86_operations< 1u, Signed, operations< 1u, Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 1u, Signed, Interprocess > :
|
||||
public gcc_x86_operations< 1u, Signed, Interprocess, operations< 1u, Signed, Interprocess > >
|
||||
{
|
||||
typedef gcc_x86_operations< 1u, Signed, operations< 1u, Signed > > base_type;
|
||||
typedef gcc_x86_operations< 1u, Signed, Interprocess, operations< 1u, Signed, Interprocess > > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
typedef typename storage_traits< 4u >::type temp_storage_type;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 1u;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 1u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
__asm__ __volatile__
|
||||
@@ -203,18 +204,14 @@ struct operations< 1u, Signed > :
|
||||
#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 2u, Signed > :
|
||||
public gcc_x86_operations< 2u, Signed, operations< 2u, Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 2u, Signed, Interprocess > :
|
||||
public gcc_x86_operations< 2u, Signed, Interprocess, operations< 2u, Signed, Interprocess > >
|
||||
{
|
||||
typedef gcc_x86_operations< 2u, Signed, operations< 2u, Signed > > base_type;
|
||||
typedef gcc_x86_operations< 2u, Signed, Interprocess, operations< 2u, Signed, Interprocess > > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
typedef typename storage_traits< 4u >::type temp_storage_type;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 2u;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 2u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
__asm__ __volatile__
|
||||
@@ -304,17 +301,13 @@ struct operations< 2u, Signed > :
|
||||
#undef BOOST_ATOMIC_DETAIL_CAS_LOOP
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 4u, Signed > :
|
||||
public gcc_x86_operations< 4u, Signed, operations< 4u, Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 4u, Signed, Interprocess > :
|
||||
public gcc_x86_operations< 4u, Signed, Interprocess, operations< 4u, Signed, Interprocess > >
|
||||
{
|
||||
typedef gcc_x86_operations< 4u, Signed, operations< 4u, Signed > > base_type;
|
||||
typedef gcc_x86_operations< 4u, Signed, Interprocess, operations< 4u, Signed, Interprocess > > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 4u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
__asm__ __volatile__
|
||||
@@ -406,25 +399,21 @@ struct operations< 4u, Signed > :
|
||||
|
||||
#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 8u, Signed > :
|
||||
public cas_based_operations< gcc_dcas_x86< Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 8u, Signed, Interprocess > :
|
||||
public cas_based_operations< gcc_dcas_x86< Signed, Interprocess > >
|
||||
{
|
||||
};
|
||||
|
||||
#elif defined(__x86_64__)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 8u, Signed > :
|
||||
public gcc_x86_operations< 8u, Signed, operations< 8u, Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 8u, Signed, Interprocess > :
|
||||
public gcc_x86_operations< 8u, Signed, Interprocess, operations< 8u, Signed, Interprocess > >
|
||||
{
|
||||
typedef gcc_x86_operations< 8u, Signed, operations< 8u, Signed > > base_type;
|
||||
typedef gcc_x86_operations< 8u, Signed, Interprocess, operations< 8u, Signed, Interprocess > > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 8u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
__asm__ __volatile__
|
||||
@@ -518,9 +507,9 @@ struct operations< 8u, Signed > :
|
||||
|
||||
#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 16u, Signed > :
|
||||
public cas_based_operations< gcc_dcas_x86_64< Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 16u, Signed, Interprocess > :
|
||||
public cas_based_operations< gcc_dcas_x86_64< Signed, Interprocess > >
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace detail {
|
||||
|
||||
#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B)
|
||||
|
||||
template< bool Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct gcc_dcas_x86
|
||||
{
|
||||
typedef typename storage_traits< 8u >::type storage_type;
|
||||
@@ -50,6 +50,7 @@ struct gcc_dcas_x86
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 8u;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 8u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = true;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
|
||||
|
||||
@@ -381,7 +382,7 @@ struct gcc_dcas_x86
|
||||
|
||||
#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B)
|
||||
|
||||
template< bool Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct gcc_dcas_x86_64
|
||||
{
|
||||
typedef typename storage_traits< 16u >::type storage_type;
|
||||
@@ -390,6 +391,7 @@ struct gcc_dcas_x86_64
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 16u;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 16u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = true;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ struct linux_arm_cas_base
|
||||
}
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct linux_arm_cas :
|
||||
public linux_arm_cas_base
|
||||
{
|
||||
@@ -95,6 +95,7 @@ struct linux_arm_cas :
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = 4u;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = 4u;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -143,21 +144,21 @@ struct linux_arm_cas :
|
||||
}
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 1u, Signed > :
|
||||
public extending_cas_based_operations< cas_based_operations< cas_based_exchange< linux_arm_cas< Signed > > >, 1u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 1u, Signed, Interprocess > :
|
||||
public extending_cas_based_operations< cas_based_operations< cas_based_exchange< linux_arm_cas< Signed, Interprocess > > >, 1u, Signed >
|
||||
{
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 2u, Signed > :
|
||||
public extending_cas_based_operations< cas_based_operations< cas_based_exchange< linux_arm_cas< Signed > > >, 2u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 2u, Signed, Interprocess > :
|
||||
public extending_cas_based_operations< cas_based_operations< cas_based_exchange< linux_arm_cas< Signed, Interprocess > > >, 2u, Signed >
|
||||
{
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 4u, Signed > :
|
||||
public cas_based_operations< cas_based_exchange< linux_arm_cas< Signed > > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 4u, Signed, Interprocess > :
|
||||
public cas_based_operations< cas_based_exchange< linux_arm_cas< Signed, Interprocess > > >
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ struct msvc_arm_operations_base
|
||||
}
|
||||
};
|
||||
|
||||
template< std::size_t Size, bool Signed, typename Derived >
|
||||
template< std::size_t Size, bool Signed, bool Interprocess, typename Derived >
|
||||
struct msvc_arm_operations :
|
||||
public msvc_arm_operations_base
|
||||
{
|
||||
@@ -109,6 +109,7 @@ struct msvc_arm_operations :
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = Size;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = storage_traits< Size >::alignment;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -133,11 +134,11 @@ struct msvc_arm_operations :
|
||||
}
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 1u, Signed > :
|
||||
public msvc_arm_operations< 1u, Signed, operations< 1u, Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 1u, Signed, Interprocess > :
|
||||
public msvc_arm_operations< 1u, Signed, Interprocess, operations< 1u, Signed, Interprocess > >
|
||||
{
|
||||
typedef msvc_arm_operations< 1u, Signed, operations< 1u, Signed > > base_type;
|
||||
typedef msvc_arm_operations< 1u, Signed, Interprocess, operations< 1u, Signed, Interprocess > > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
@@ -298,11 +299,11 @@ struct operations< 1u, Signed > :
|
||||
}
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 2u, Signed > :
|
||||
public msvc_arm_operations< 2u, Signed, operations< 2u, Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 2u, Signed, Interprocess > :
|
||||
public msvc_arm_operations< 2u, Signed, Interprocess, operations< 2u, Signed, Interprocess > >
|
||||
{
|
||||
typedef msvc_arm_operations< 2u, Signed, operations< 2u, Signed > > base_type;
|
||||
typedef msvc_arm_operations< 2u, Signed, Interprocess, operations< 2u, Signed, Interprocess > > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
@@ -463,11 +464,11 @@ struct operations< 2u, Signed > :
|
||||
}
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 4u, Signed > :
|
||||
public msvc_arm_operations< 4u, Signed, operations< 4u, Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 4u, Signed, Interprocess > :
|
||||
public msvc_arm_operations< 4u, Signed, Interprocess, operations< 4u, Signed, Interprocess > >
|
||||
{
|
||||
typedef msvc_arm_operations< 4u, Signed, operations< 4u, Signed > > base_type;
|
||||
typedef msvc_arm_operations< 4u, Signed, Interprocess, operations< 4u, Signed, Interprocess > > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
@@ -628,11 +629,11 @@ struct operations< 4u, Signed > :
|
||||
}
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 8u, Signed > :
|
||||
public msvc_arm_operations< 8u, Signed, operations< 8u, Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 8u, Signed, Interprocess > :
|
||||
public msvc_arm_operations< 8u, Signed, Interprocess, operations< 8u, Signed, Interprocess > >
|
||||
{
|
||||
typedef msvc_arm_operations< 8u, Signed, operations< 8u, Signed > > base_type;
|
||||
typedef msvc_arm_operations< 8u, Signed, Interprocess, operations< 8u, Signed, Interprocess > > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
|
||||
@@ -109,7 +109,7 @@ struct msvc_x86_operations_base
|
||||
}
|
||||
};
|
||||
|
||||
template< std::size_t Size, bool Signed, typename Derived >
|
||||
template< std::size_t Size, bool Signed, bool Interprocess, typename Derived >
|
||||
struct msvc_x86_operations :
|
||||
public msvc_x86_operations_base
|
||||
{
|
||||
@@ -118,6 +118,7 @@ struct msvc_x86_operations :
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = Size;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = storage_traits< Size >::alignment;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -163,11 +164,11 @@ struct msvc_x86_operations :
|
||||
}
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 4u, Signed > :
|
||||
public msvc_x86_operations< 4u, Signed, operations< 4u, Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 4u, Signed, Interprocess > :
|
||||
public msvc_x86_operations< 4u, Signed, Interprocess, operations< 4u, Signed, Interprocess > >
|
||||
{
|
||||
typedef msvc_x86_operations< 4u, Signed, operations< 4u, Signed > > base_type;
|
||||
typedef msvc_x86_operations< 4u, Signed, Interprocess, operations< 4u, Signed, Interprocess > > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
@@ -234,11 +235,11 @@ struct operations< 4u, Signed > :
|
||||
|
||||
#if defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE8)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 1u, Signed > :
|
||||
public msvc_x86_operations< 1u, Signed, operations< 1u, Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 1u, Signed, Interprocess > :
|
||||
public msvc_x86_operations< 1u, Signed, Interprocess, operations< 1u, Signed, Interprocess > >
|
||||
{
|
||||
typedef msvc_x86_operations< 1u, Signed, operations< 1u, Signed > > base_type;
|
||||
typedef msvc_x86_operations< 1u, Signed, Interprocess, operations< 1u, Signed, Interprocess > > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
@@ -278,11 +279,11 @@ struct operations< 1u, Signed > :
|
||||
|
||||
#elif defined(_M_IX86)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 1u, Signed > :
|
||||
public msvc_x86_operations< 1u, Signed, operations< 1u, Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 1u, Signed, Interprocess > :
|
||||
public msvc_x86_operations< 1u, Signed, Interprocess, operations< 1u, Signed, Interprocess > >
|
||||
{
|
||||
typedef msvc_x86_operations< 1u, Signed, operations< 1u, Signed > > base_type;
|
||||
typedef msvc_x86_operations< 1u, Signed, Interprocess, operations< 1u, Signed, Interprocess > > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
@@ -399,9 +400,9 @@ struct operations< 1u, Signed > :
|
||||
|
||||
#else
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 1u, Signed > :
|
||||
public extending_cas_based_operations< operations< 4u, Signed >, 1u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 1u, Signed, Interprocess > :
|
||||
public extending_cas_based_operations< operations< 4u, Signed, Interprocess >, 1u, Signed >
|
||||
{
|
||||
};
|
||||
|
||||
@@ -409,11 +410,11 @@ struct operations< 1u, Signed > :
|
||||
|
||||
#if defined(BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE16)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 2u, Signed > :
|
||||
public msvc_x86_operations< 2u, Signed, operations< 2u, Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 2u, Signed, Interprocess > :
|
||||
public msvc_x86_operations< 2u, Signed, Interprocess, operations< 2u, Signed, Interprocess > >
|
||||
{
|
||||
typedef msvc_x86_operations< 2u, Signed, operations< 2u, Signed > > base_type;
|
||||
typedef msvc_x86_operations< 2u, Signed, Interprocess, operations< 2u, Signed, Interprocess > > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
@@ -453,11 +454,11 @@ struct operations< 2u, Signed > :
|
||||
|
||||
#elif defined(_M_IX86)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 2u, Signed > :
|
||||
public msvc_x86_operations< 2u, Signed, operations< 2u, Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 2u, Signed, Interprocess > :
|
||||
public msvc_x86_operations< 2u, Signed, Interprocess, operations< 2u, Signed, Interprocess > >
|
||||
{
|
||||
typedef msvc_x86_operations< 2u, Signed, operations< 2u, Signed > > base_type;
|
||||
typedef msvc_x86_operations< 2u, Signed, Interprocess, operations< 2u, Signed, Interprocess > > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
@@ -574,9 +575,9 @@ struct operations< 2u, Signed > :
|
||||
|
||||
#else
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 2u, Signed > :
|
||||
public extending_cas_based_operations< operations< 4u, Signed >, 2u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 2u, Signed, Interprocess > :
|
||||
public extending_cas_based_operations< operations< 4u, Signed, Interprocess >, 2u, Signed >
|
||||
{
|
||||
};
|
||||
|
||||
@@ -585,11 +586,12 @@ struct operations< 2u, Signed > :
|
||||
|
||||
#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG8B)
|
||||
|
||||
template< bool Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct msvc_dcas_x86
|
||||
{
|
||||
typedef typename storage_traits< 8u >::type storage_type;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = true;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
|
||||
|
||||
@@ -784,19 +786,19 @@ struct msvc_dcas_x86
|
||||
}
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 8u, Signed > :
|
||||
public cas_based_operations< msvc_dcas_x86< Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 8u, Signed, Interprocess > :
|
||||
public cas_based_operations< msvc_dcas_x86< Signed, Interprocess > >
|
||||
{
|
||||
};
|
||||
|
||||
#elif defined(_M_AMD64)
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 8u, Signed > :
|
||||
public msvc_x86_operations< 8u, Signed, operations< 8u, Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 8u, Signed, Interprocess > :
|
||||
public msvc_x86_operations< 8u, Signed, Interprocess, operations< 8u, Signed, Interprocess > >
|
||||
{
|
||||
typedef msvc_x86_operations< 8u, Signed, operations< 8u, Signed > > base_type;
|
||||
typedef msvc_x86_operations< 8u, Signed, Interprocess, operations< 8u, Signed, Interprocess > > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order) BOOST_NOEXCEPT
|
||||
@@ -838,11 +840,12 @@ struct operations< 8u, Signed > :
|
||||
|
||||
#if defined(BOOST_ATOMIC_DETAIL_X86_HAS_CMPXCHG16B)
|
||||
|
||||
template< bool Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct msvc_dcas_x86_64
|
||||
{
|
||||
typedef typename storage_traits< 16u >::type storage_type;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool full_cas_based = true;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_always_lock_free = true;
|
||||
|
||||
@@ -876,9 +879,9 @@ struct msvc_dcas_x86_64
|
||||
}
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 16u, Signed > :
|
||||
public cas_based_operations< cas_based_exchange< msvc_dcas_x86_64< Signed > > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 16u, Signed, Interprocess > :
|
||||
public cas_based_operations< cas_based_exchange< msvc_dcas_x86_64< Signed, Interprocess > > >
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ struct windows_operations_base
|
||||
}
|
||||
};
|
||||
|
||||
template< std::size_t Size, bool Signed, typename Derived >
|
||||
template< std::size_t Size, bool Signed, bool Interprocess, typename Derived >
|
||||
struct windows_operations :
|
||||
public windows_operations_base
|
||||
{
|
||||
@@ -73,6 +73,7 @@ struct windows_operations :
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_size = Size;
|
||||
static BOOST_CONSTEXPR_OR_CONST std::size_t storage_alignment = storage_traits< Size >::alignment;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_signed = Signed;
|
||||
static BOOST_CONSTEXPR_OR_CONST bool is_interprocess = Interprocess;
|
||||
|
||||
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
@@ -107,11 +108,11 @@ struct windows_operations :
|
||||
}
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 4u, Signed > :
|
||||
public windows_operations< 4u, Signed, operations< 4u, Signed > >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 4u, Signed, bool Interprocess > :
|
||||
public windows_operations< 4u, Signed, Interprocess, operations< 4u, Signed, Interprocess > >
|
||||
{
|
||||
typedef windows_operations< 4u, Signed, operations< 4u, Signed > > base_type;
|
||||
typedef windows_operations< 4u, Signed, Interprocess, operations< 4u, Signed, Interprocess > > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order) BOOST_NOEXCEPT
|
||||
@@ -185,15 +186,15 @@ struct operations< 4u, Signed > :
|
||||
}
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 1u, Signed > :
|
||||
public extending_cas_based_operations< operations< 4u, Signed >, 1u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 1u, Signed, Interprocess > :
|
||||
public extending_cas_based_operations< operations< 4u, Signed, Interprocess >, 1u, Signed >
|
||||
{
|
||||
};
|
||||
|
||||
template< bool Signed >
|
||||
struct operations< 2u, Signed > :
|
||||
public extending_cas_based_operations< operations< 4u, Signed >, 2u, Signed >
|
||||
template< bool Signed, bool Interprocess >
|
||||
struct operations< 2u, Signed, Interprocess > :
|
||||
public extending_cas_based_operations< operations< 4u, Signed, Interprocess >, 2u, Signed >
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
363
include/boost/atomic/detail/wait_capabilities.hpp
Normal file
363
include/boost/atomic/detail/wait_capabilities.hpp
Normal file
@@ -0,0 +1,363 @@
|
||||
/*
|
||||
* 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)
|
||||
*
|
||||
* Copyright (c) 2020 Andrey Semashev
|
||||
*/
|
||||
/*!
|
||||
* \file atomic/detail/wait_capabilities.hpp
|
||||
*
|
||||
* This header defines waiting/notifying operations capabilities macros.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ATOMIC_DETAIL_WAIT_CAPABILITIES_HPP_INCLUDED_
|
||||
#define BOOST_ATOMIC_DETAIL_WAIT_CAPABILITIES_HPP_INCLUDED_
|
||||
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/platform.hpp>
|
||||
#include <boost/atomic/detail/int_sizes.hpp>
|
||||
#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
|
||||
#include <boost/atomic/detail/float_sizes.hpp>
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_ATOMIC_EMULATED) && !defined(BOOST_ATOMIC_DETAIL_WAIT_BACKEND_GENERIC)
|
||||
#include BOOST_ATOMIC_DETAIL_WAIT_BACKEND_HEADER(boost/atomic/detail/wait_caps_)
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_INT8_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT8_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_INT8_IPC_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT8_IPC_WAIT_NOTIFY 0
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_INT16_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT16_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_INT16_IPC_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT16_IPC_WAIT_NOTIFY 0
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_INT32_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT32_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_INT32_IPC_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT32_IPC_WAIT_NOTIFY 0
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_INT64_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT64_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_INT64_IPC_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT64_IPC_WAIT_NOTIFY 0
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_INT128_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT128_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_INT128_IPC_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT128_IPC_WAIT_NOTIFY 0
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_CHAR_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_CHAR_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT8_WAIT_NOTIFY
|
||||
#endif
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_CHAR_IPC_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_CHAR_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT8_IPC_WAIT_NOTIFY
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_CHAR8_T_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_CHAR8_T_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT8_WAIT_NOTIFY
|
||||
#endif
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_CHAR8_T_IPC_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_CHAR8_T_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT8_IPC_WAIT_NOTIFY
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_CHAR16_T_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_CHAR16_T_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT16_WAIT_NOTIFY
|
||||
#endif
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_CHAR16_T_IPC_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_CHAR16_T_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT16_IPC_WAIT_NOTIFY
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_CHAR32_T_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_CHAR32_T_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_WAIT_NOTIFY
|
||||
#endif
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_CHAR32_T_IPC_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_CHAR32_T_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_IPC_WAIT_NOTIFY
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_WCHAR_T_WAIT_NOTIFY
|
||||
#if BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 1
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_WCHAR_T_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT8_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 2
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_WCHAR_T_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT16_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 4
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_WCHAR_T_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 8
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_WCHAR_T_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT64_WAIT_NOTIFY
|
||||
#else
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_WCHAR_T_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_WCHAR_T_IPC_WAIT_NOTIFY
|
||||
#if BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 1
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_WCHAR_T_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT8_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 2
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_WCHAR_T_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT16_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 4
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_WCHAR_T_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T == 8
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_WCHAR_T_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT64_IPC_WAIT_NOTIFY
|
||||
#else
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_WCHAR_T_IPC_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_SHORT_WAIT_NOTIFY
|
||||
#if BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 1
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_SHORT_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT8_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 2
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_SHORT_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT16_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 4
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_SHORT_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 8
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_SHORT_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT64_WAIT_NOTIFY
|
||||
#else
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_SHORT_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_SHORT_IPC_WAIT_NOTIFY
|
||||
#if BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 1
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_SHORT_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT8_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 2
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_SHORT_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT16_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 4
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_SHORT_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_SHORT == 8
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_SHORT_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT64_IPC_WAIT_NOTIFY
|
||||
#else
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_SHORT_IPC_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_INT_WAIT_NOTIFY
|
||||
#if BOOST_ATOMIC_DETAIL_SIZEOF_INT == 1
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT8_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 2
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT16_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 4
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 8
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT64_WAIT_NOTIFY
|
||||
#else
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_INT_IPC_WAIT_NOTIFY
|
||||
#if BOOST_ATOMIC_DETAIL_SIZEOF_INT == 1
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT8_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 2
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT16_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 4
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_INT == 8
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT64_IPC_WAIT_NOTIFY
|
||||
#else
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT_IPC_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_LONG_WAIT_NOTIFY
|
||||
#if BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 1
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT8_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 2
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT16_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 4
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 8
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT64_WAIT_NOTIFY
|
||||
#else
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_LONG_IPC_WAIT_NOTIFY
|
||||
#if BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 1
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT8_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 2
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT16_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 4
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 8
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT64_IPC_WAIT_NOTIFY
|
||||
#else
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_IPC_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_LLONG_WAIT_NOTIFY
|
||||
#if BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 1
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LLONG_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT8_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 2
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LLONG_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT16_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 4
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LLONG_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 8
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LLONG_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT64_WAIT_NOTIFY
|
||||
#else
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LLONG_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_LLONG_IPC_WAIT_NOTIFY
|
||||
#if BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 1
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LLONG_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT8_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 2
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LLONG_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT16_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 4
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LLONG_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LLONG == 8
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LLONG_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT64_IPC_WAIT_NOTIFY
|
||||
#else
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LLONG_IPC_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_POINTER_WAIT_NOTIFY
|
||||
#if (BOOST_ATOMIC_DETAIL_SIZEOF_POINTER + 0) == 8
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_POINTER_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT64_WAIT_NOTIFY
|
||||
#elif (BOOST_ATOMIC_DETAIL_SIZEOF_POINTER + 0) == 4
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_POINTER_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_WAIT_NOTIFY
|
||||
#else
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_POINTER_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_ADDRESS_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_POINTER_WAIT_NOTIFY
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_POINTER_IPC_WAIT_NOTIFY
|
||||
#if (BOOST_ATOMIC_DETAIL_SIZEOF_POINTER + 0) == 8
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_POINTER_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT64_IPC_WAIT_NOTIFY
|
||||
#elif (BOOST_ATOMIC_DETAIL_SIZEOF_POINTER + 0) == 4
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_POINTER_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_IPC_WAIT_NOTIFY
|
||||
#else
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_POINTER_IPC_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_ADDRESS_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_POINTER_IPC_WAIT_NOTIFY
|
||||
|
||||
// We store bools in 1-byte storage in all backends
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_BOOL_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_BOOL_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT8_WAIT_NOTIFY
|
||||
#endif
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_BOOL_IPC_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_BOOL_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT8_IPC_WAIT_NOTIFY
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_FLAG_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_FLAG_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_WAIT_NOTIFY
|
||||
#endif
|
||||
#ifndef BOOST_ATOMIC_HAS_NATIVE_FLAG_IPC_WAIT_NOTIFY
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_FLAG_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_IPC_WAIT_NOTIFY
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
|
||||
|
||||
#if !defined(BOOST_ATOMIC_HAS_NATIVE_FLOAT_WAIT_NOTIFY) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT)
|
||||
#if BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 2
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_FLOAT_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT16_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 4
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_FLOAT_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 8
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_FLOAT_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT64_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 16
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_FLOAT_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT128_WAIT_NOTIFY
|
||||
#else
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_FLOAT_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_ATOMIC_HAS_NATIVE_FLOAT_IPC_WAIT_NOTIFY) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT)
|
||||
#if BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 2
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_FLOAT_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT16_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 4
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_FLOAT_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 8
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_FLOAT_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT64_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_FLOAT == 16
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_FLOAT_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT128_IPC_WAIT_NOTIFY
|
||||
#else
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_FLOAT_IPC_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_ATOMIC_HAS_NATIVE_DOUBLE_WAIT_NOTIFY) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE)
|
||||
#if BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 2
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_DOUBLE_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT16_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 4
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_DOUBLE_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 8
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_DOUBLE_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT64_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 16
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_DOUBLE_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT128_WAIT_NOTIFY
|
||||
#else
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_DOUBLE_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_ATOMIC_HAS_NATIVE_DOUBLE_IPC_WAIT_NOTIFY) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE)
|
||||
#if BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 2
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_DOUBLE_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT16_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 4
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_DOUBLE_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 8
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_DOUBLE_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT64_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_DOUBLE == 16
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_DOUBLE_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT128_IPC_WAIT_NOTIFY
|
||||
#else
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_DOUBLE_IPC_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_ATOMIC_HAS_NATIVE_LONG_DOUBLE_WAIT_NOTIFY) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE)
|
||||
#if BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 2
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_DOUBLE_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT16_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 4
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_DOUBLE_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 8
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_DOUBLE_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT64_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 16
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_DOUBLE_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT128_WAIT_NOTIFY
|
||||
#else
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_DOUBLE_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(BOOST_ATOMIC_HAS_NATIVE_LONG_DOUBLE_IPC_WAIT_NOTIFY) && defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE)
|
||||
#if BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 2
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_DOUBLE_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT16_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 4
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_DOUBLE_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT32_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 8
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_DOUBLE_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT64_IPC_WAIT_NOTIFY
|
||||
#elif BOOST_ATOMIC_DETAIL_SIZEOF_LONG_DOUBLE == 16
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_DOUBLE_IPC_WAIT_NOTIFY BOOST_ATOMIC_HAS_NATIVE_INT128_IPC_WAIT_NOTIFY
|
||||
#else
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_LONG_DOUBLE_IPC_WAIT_NOTIFY 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif // !defined(BOOST_ATOMIC_NO_FLOATING_POINT)
|
||||
|
||||
#endif // BOOST_ATOMIC_DETAIL_WAIT_CAPABILITIES_HPP_INCLUDED_
|
||||
30
include/boost/atomic/detail/wait_caps_dragonfly_umtx.hpp
Normal file
30
include/boost/atomic/detail/wait_caps_dragonfly_umtx.hpp
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* 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)
|
||||
*
|
||||
* Copyright (c) 2020 Andrey Semashev
|
||||
*/
|
||||
/*!
|
||||
* \file atomic/detail/wait_caps_dragonfly_umtx.hpp
|
||||
*
|
||||
* This header defines waiting/notifying operations capabilities macros.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ATOMIC_DETAIL_WAIT_CAPS_DRAGONFLY_UMTX_HPP_INCLUDED_
|
||||
#define BOOST_ATOMIC_DETAIL_WAIT_CAPS_DRAGONFLY_UMTX_HPP_INCLUDED_
|
||||
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/capabilities.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// DragonFly BSD umtx_sleep/umtx_wakeup use physical address to the atomic object as a key, which means it should support address-free operations.
|
||||
// https://man.dragonflybsd.org/?command=umtx§ion=2
|
||||
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT32_WAIT_NOTIFY BOOST_ATOMIC_INT32_LOCK_FREE
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT32_IPC_WAIT_NOTIFY BOOST_ATOMIC_INT32_LOCK_FREE
|
||||
|
||||
#endif // BOOST_ATOMIC_DETAIL_WAIT_CAPS_DRAGONFLY_UMTX_HPP_INCLUDED_
|
||||
40
include/boost/atomic/detail/wait_caps_freebsd_umtx.hpp
Normal file
40
include/boost/atomic/detail/wait_caps_freebsd_umtx.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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)
|
||||
*
|
||||
* Copyright (c) 2020 Andrey Semashev
|
||||
*/
|
||||
/*!
|
||||
* \file atomic/detail/wait_caps_freebsd_umtx.hpp
|
||||
*
|
||||
* This header defines waiting/notifying operations capabilities macros.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ATOMIC_DETAIL_WAIT_CAPS_FREEBSD_UMTX_HPP_INCLUDED_
|
||||
#define BOOST_ATOMIC_DETAIL_WAIT_CAPS_FREEBSD_UMTX_HPP_INCLUDED_
|
||||
|
||||
#include <sys/umtx.h>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/int_sizes.hpp>
|
||||
#include <boost/atomic/detail/capabilities.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// FreeBSD _umtx_op uses physical address to the atomic object as a key, which means it should support address-free operations.
|
||||
// https://www.freebsd.org/cgi/man.cgi?query=_umtx_op&apropos=0&sektion=2&manpath=FreeBSD+11-current&format=html
|
||||
|
||||
#if (defined(UMTX_OP_WAIT_UINT) && BOOST_ATOMIC_DETAIL_SIZEOF_INT == 4) ||\
|
||||
(defined(UMTX_OP_WAIT) && BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 4)
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT32_WAIT_NOTIFY BOOST_ATOMIC_INT32_LOCK_FREE
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT32_IPC_WAIT_NOTIFY BOOST_ATOMIC_INT32_LOCK_FREE
|
||||
#endif
|
||||
|
||||
#if defined(UMTX_OP_WAIT) && BOOST_ATOMIC_DETAIL_SIZEOF_LONG == 8
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT64_WAIT_NOTIFY BOOST_ATOMIC_INT64_LOCK_FREE
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT64_IPC_WAIT_NOTIFY BOOST_ATOMIC_INT64_LOCK_FREE
|
||||
#endif
|
||||
|
||||
#endif // BOOST_ATOMIC_DETAIL_WAIT_CAPS_FREEBSD_UMTX_HPP_INCLUDED_
|
||||
31
include/boost/atomic/detail/wait_caps_futex.hpp
Normal file
31
include/boost/atomic/detail/wait_caps_futex.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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)
|
||||
*
|
||||
* Copyright (c) 2020 Andrey Semashev
|
||||
*/
|
||||
/*!
|
||||
* \file atomic/detail/wait_caps_futex.hpp
|
||||
*
|
||||
* This header defines waiting/notifying operations capabilities macros.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ATOMIC_DETAIL_WAIT_CAPS_FUTEX_HPP_INCLUDED_
|
||||
#define BOOST_ATOMIC_DETAIL_WAIT_CAPS_FUTEX_HPP_INCLUDED_
|
||||
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/capabilities.hpp>
|
||||
#include <boost/atomic/detail/futex.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_ATOMIC_DETAIL_HAS_FUTEX)
|
||||
// futexes are always 32-bit and they always supported address-free operations
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT32_WAIT_NOTIFY BOOST_ATOMIC_INT32_LOCK_FREE
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT32_IPC_WAIT_NOTIFY BOOST_ATOMIC_INT32_LOCK_FREE
|
||||
#endif // defined(BOOST_ATOMIC_DETAIL_HAS_FUTEX)
|
||||
|
||||
#endif // BOOST_ATOMIC_DETAIL_WAIT_CAPS_FUTEX_HPP_INCLUDED_
|
||||
55
include/boost/atomic/detail/wait_caps_windows.hpp
Normal file
55
include/boost/atomic/detail/wait_caps_windows.hpp
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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)
|
||||
*
|
||||
* Copyright (c) 2020 Andrey Semashev
|
||||
*/
|
||||
/*!
|
||||
* \file atomic/detail/wait_caps_windows.hpp
|
||||
*
|
||||
* This header defines waiting/notifying operations capabilities macros.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ATOMIC_DETAIL_WAIT_CAPS_WINDOWS_HPP_INCLUDED_
|
||||
#define BOOST_ATOMIC_DETAIL_WAIT_CAPS_WINDOWS_HPP_INCLUDED_
|
||||
|
||||
#include <boost/winapi/config.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/capabilities.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// MSDN says WaitOnAddress, WakeByAddressSingle and WakeByAddressAll only support notifications between threads of the same process, so no address-free operations.
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitonaddress
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-wakebyaddresssingle
|
||||
// https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-wakebyaddressall
|
||||
|
||||
#if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN8 && (BOOST_WINAPI_PARTITION_APP || BOOST_WINAPI_PARTITION_SYSTEM)
|
||||
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT8_WAIT_NOTIFY BOOST_ATOMIC_INT8_LOCK_FREE
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT16_WAIT_NOTIFY BOOST_ATOMIC_INT16_LOCK_FREE
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT32_WAIT_NOTIFY BOOST_ATOMIC_INT32_LOCK_FREE
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT64_WAIT_NOTIFY BOOST_ATOMIC_INT64_LOCK_FREE
|
||||
|
||||
#else // BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN8 && (BOOST_WINAPI_PARTITION_APP || BOOST_WINAPI_PARTITION_SYSTEM)
|
||||
|
||||
// Since will detect availability of WaitOnAddress etc. at run time, we have to define capability macros to 1 instead of 2
|
||||
#if BOOST_ATOMIC_INT8_LOCK_FREE > 0
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT8_WAIT_NOTIFY 1
|
||||
#endif
|
||||
#if BOOST_ATOMIC_INT16_LOCK_FREE > 0
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT16_WAIT_NOTIFY 1
|
||||
#endif
|
||||
#if BOOST_ATOMIC_INT32_LOCK_FREE > 0
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT32_WAIT_NOTIFY 1
|
||||
#endif
|
||||
#if BOOST_ATOMIC_INT64_LOCK_FREE > 0
|
||||
#define BOOST_ATOMIC_HAS_NATIVE_INT64_WAIT_NOTIFY 1
|
||||
#endif
|
||||
|
||||
#endif // BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN8 && (BOOST_WINAPI_PARTITION_APP || BOOST_WINAPI_PARTITION_SYSTEM)
|
||||
|
||||
#endif // BOOST_ATOMIC_DETAIL_WAIT_CAPS_WINDOWS_HPP_INCLUDED_
|
||||
@@ -25,7 +25,12 @@ namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
template< typename Base, std::size_t Size = sizeof(typename Base::storage_type), bool = Base::is_always_lock_free >
|
||||
template<
|
||||
typename Base,
|
||||
std::size_t Size = sizeof(typename Base::storage_type),
|
||||
bool AlwaysLockFree = Base::is_always_lock_free,
|
||||
bool Interprocess = Base::is_interprocess
|
||||
>
|
||||
struct wait_operations;
|
||||
|
||||
} // namespace detail
|
||||
|
||||
@@ -28,13 +28,20 @@ namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
template< typename Base >
|
||||
struct wait_operations< Base, sizeof(int), true > :
|
||||
template< typename Base, bool Interprocess >
|
||||
struct wait_operations< Base, sizeof(int), true, Interprocess > :
|
||||
public Base
|
||||
{
|
||||
typedef Base base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = true;
|
||||
|
||||
static BOOST_FORCEINLINE bool has_native_wait_notify(storage_type const volatile&) BOOST_NOEXCEPT
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type wait(storage_type const volatile& storage, storage_type old_val, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
storage_type new_val = base_type::load(storage, order);
|
||||
|
||||
@@ -8,13 +8,14 @@
|
||||
/*!
|
||||
* \file atomic/detail/wait_ops_emulated.hpp
|
||||
*
|
||||
* This header contains emulated (lock-based) implementation of the wait/notify atomic operations.
|
||||
* This header contains emulated (lock-based) implementation of the waiting and notifying atomic operations.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ATOMIC_DETAIL_WAIT_OPS_EMULATED_HPP_INCLUDED_
|
||||
#define BOOST_ATOMIC_DETAIL_WAIT_OPS_EMULATED_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/lock_pool.hpp>
|
||||
@@ -28,7 +29,7 @@ namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
//! Emulated implementation of wait/notify operations
|
||||
//! Emulated implementation of waiting and notifying operations
|
||||
template< typename Base >
|
||||
struct emulated_wait_operations :
|
||||
public Base
|
||||
@@ -38,8 +39,16 @@ struct emulated_wait_operations :
|
||||
typedef lock_pool::scoped_lock< base_type::storage_alignment, true > scoped_lock;
|
||||
typedef lock_pool::scoped_wait_state< base_type::storage_alignment > scoped_wait_state;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = false;
|
||||
|
||||
static BOOST_FORCEINLINE bool has_native_wait_notify(storage_type const volatile&) BOOST_NOEXCEPT
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type wait(storage_type const volatile& storage, storage_type old_val, memory_order) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
storage_type const& s = const_cast< storage_type const& >(storage);
|
||||
scoped_wait_state wait_state(&storage);
|
||||
storage_type new_val = s;
|
||||
@@ -54,19 +63,21 @@ struct emulated_wait_operations :
|
||||
|
||||
static BOOST_FORCEINLINE void notify_one(storage_type volatile& storage) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
scoped_lock lock(&storage);
|
||||
lock_pool::notify_one(lock.get_lock_state(), &storage);
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE void notify_all(storage_type volatile& storage) BOOST_NOEXCEPT
|
||||
{
|
||||
BOOST_STATIC_ASSERT_MSG(!base_type::is_interprocess, "Boost.Atomic: operation invoked on a non-lock-free inter-process atomic object");
|
||||
scoped_lock lock(&storage);
|
||||
lock_pool::notify_all(lock.get_lock_state(), &storage);
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Base, std::size_t Size >
|
||||
struct wait_operations< Base, Size, false > :
|
||||
template< typename Base, std::size_t Size, bool Interprocess >
|
||||
struct wait_operations< Base, Size, false, Interprocess > :
|
||||
public emulated_wait_operations< Base >
|
||||
{
|
||||
};
|
||||
|
||||
@@ -40,6 +40,13 @@ struct freebsd_umtx_wait_operations_common :
|
||||
typedef Base base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = true;
|
||||
|
||||
static BOOST_FORCEINLINE bool has_native_wait_notify(storage_type const volatile&) BOOST_NOEXCEPT
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE void notify_one(storage_type volatile& storage) BOOST_NOEXCEPT
|
||||
{
|
||||
::_umtx_op(const_cast< storage_type* >(&storage), UMTX_OP_WAKE, 1u, NULL, NULL);
|
||||
@@ -56,8 +63,8 @@ struct freebsd_umtx_wait_operations_common :
|
||||
// UMTX_OP_WAIT_UINT only appeared in FreeBSD 8.0
|
||||
#if defined(UMTX_OP_WAIT_UINT) && BOOST_ATOMIC_DETAIL_SIZEOF_INT < BOOST_ATOMIC_DETAIL_SIZEOF_LONG
|
||||
|
||||
template< typename Base >
|
||||
struct wait_operations< Base, sizeof(unsigned int), true > :
|
||||
template< typename Base, bool Interprocess >
|
||||
struct wait_operations< Base, sizeof(unsigned int), true, Interprocess > :
|
||||
public freebsd_umtx_wait_operations_common< Base >
|
||||
{
|
||||
typedef freebsd_umtx_wait_operations_common< Base > base_type;
|
||||
@@ -80,8 +87,8 @@ struct wait_operations< Base, sizeof(unsigned int), true > :
|
||||
|
||||
#if defined(UMTX_OP_WAIT)
|
||||
|
||||
template< typename Base >
|
||||
struct wait_operations< Base, sizeof(unsigned long), true > :
|
||||
template< typename Base, bool Interprocess >
|
||||
struct wait_operations< Base, sizeof(unsigned long), true, Interprocess > :
|
||||
public freebsd_umtx_wait_operations_common< Base >
|
||||
{
|
||||
typedef freebsd_umtx_wait_operations_common< Base > base_type;
|
||||
|
||||
@@ -28,12 +28,19 @@ namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
template< typename Base >
|
||||
struct wait_operations< Base, 4u, true > :
|
||||
struct wait_operations< Base, 4u, true, false > :
|
||||
public Base
|
||||
{
|
||||
typedef Base base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = true;
|
||||
|
||||
static BOOST_FORCEINLINE bool has_native_wait_notify(storage_type const volatile&) BOOST_NOEXCEPT
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type wait(storage_type const volatile& storage, storage_type old_val, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
storage_type new_val = base_type::load(storage, order);
|
||||
@@ -57,6 +64,43 @@ struct wait_operations< Base, 4u, true > :
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Base >
|
||||
struct wait_operations< Base, 4u, true, true > :
|
||||
public Base
|
||||
{
|
||||
typedef Base base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = true;
|
||||
|
||||
static BOOST_FORCEINLINE bool has_native_wait_notify(storage_type const volatile&) BOOST_NOEXCEPT
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type wait(storage_type const volatile& storage, storage_type old_val, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
storage_type new_val = base_type::load(storage, order);
|
||||
while (new_val == old_val)
|
||||
{
|
||||
atomics::detail::futex_wait(const_cast< storage_type* >(&storage), old_val);
|
||||
new_val = base_type::load(storage, order);
|
||||
}
|
||||
|
||||
return new_val;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE void notify_one(storage_type volatile& storage) BOOST_NOEXCEPT
|
||||
{
|
||||
atomics::detail::futex_signal(const_cast< storage_type* >(&storage));
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE void notify_all(storage_type volatile& storage) BOOST_NOEXCEPT
|
||||
{
|
||||
atomics::detail::futex_broadcast(const_cast< storage_type* >(&storage));
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace atomics
|
||||
} // namespace boost
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include <cstddef>
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/pause.hpp>
|
||||
#include <boost/atomic/detail/lock_pool.hpp>
|
||||
#include <boost/atomic/detail/wait_operations_fwd.hpp>
|
||||
|
||||
@@ -29,8 +30,11 @@ namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
//! Generic implementation of wait/notify operations
|
||||
template< typename Base, bool Interprocess >
|
||||
struct generic_wait_operations;
|
||||
|
||||
template< typename Base >
|
||||
struct generic_wait_operations :
|
||||
struct generic_wait_operations< Base, false > :
|
||||
public Base
|
||||
{
|
||||
typedef Base base_type;
|
||||
@@ -38,6 +42,13 @@ struct generic_wait_operations :
|
||||
typedef lock_pool::scoped_lock< base_type::storage_alignment, true > scoped_lock;
|
||||
typedef lock_pool::scoped_wait_state< base_type::storage_alignment > scoped_wait_state;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = false;
|
||||
|
||||
static BOOST_FORCEINLINE bool has_native_wait_notify(storage_type const volatile&) BOOST_NOEXCEPT
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type wait(storage_type const volatile& storage, storage_type old_val, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
storage_type new_val = base_type::load(storage, order);
|
||||
@@ -68,9 +79,57 @@ struct generic_wait_operations :
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Base, std::size_t Size >
|
||||
struct wait_operations< Base, Size, true > :
|
||||
public generic_wait_operations< Base >
|
||||
template< typename Base >
|
||||
struct generic_wait_operations< Base, true > :
|
||||
public Base
|
||||
{
|
||||
typedef Base base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = false;
|
||||
|
||||
static BOOST_FORCEINLINE bool has_native_wait_notify(storage_type const volatile&) BOOST_NOEXCEPT
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type wait(storage_type const volatile& storage, storage_type old_val, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
storage_type new_val = base_type::load(storage, order);
|
||||
if (new_val == old_val)
|
||||
{
|
||||
for (unsigned int i = 0u; i < 16u; ++i)
|
||||
{
|
||||
atomics::detail::pause();
|
||||
new_val = base_type::load(storage, order);
|
||||
if (new_val != old_val)
|
||||
goto finish;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
atomics::detail::wait_some();
|
||||
new_val = base_type::load(storage, order);
|
||||
}
|
||||
while (new_val == old_val);
|
||||
}
|
||||
|
||||
finish:
|
||||
return new_val;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE void notify_one(storage_type volatile& storage) BOOST_NOEXCEPT
|
||||
{
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE void notify_all(storage_type volatile& storage) BOOST_NOEXCEPT
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template< typename Base, std::size_t Size, bool Interprocess >
|
||||
struct wait_operations< Base, Size, true, Interprocess > :
|
||||
public generic_wait_operations< Base, Interprocess >
|
||||
{
|
||||
};
|
||||
|
||||
|
||||
@@ -61,11 +61,19 @@ BOOST_FORCEINLINE void ensure_wait_functions_initialized() BOOST_NOEXCEPT
|
||||
|
||||
template< typename Base, std::size_t Size >
|
||||
struct windows_wait_operations :
|
||||
public atomics::detail::generic_wait_operations< Base >
|
||||
public atomics::detail::generic_wait_operations< Base, false >
|
||||
{
|
||||
typedef atomics::detail::generic_wait_operations< Base > base_type;
|
||||
typedef atomics::detail::generic_wait_operations< Base, false > base_type;
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
static BOOST_CONSTEXPR_OR_CONST bool always_has_native_wait_notify = false;
|
||||
|
||||
static BOOST_FORCEINLINE bool has_native_wait_notify(storage_type const volatile&) BOOST_NOEXCEPT
|
||||
{
|
||||
ensure_wait_functions_initialized();
|
||||
return atomics::detail::wait_on_address != NULL;
|
||||
}
|
||||
|
||||
static BOOST_FORCEINLINE storage_type wait(storage_type const volatile& storage, storage_type old_val, memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
ensure_wait_functions_initialized();
|
||||
@@ -109,25 +117,25 @@ struct windows_wait_operations :
|
||||
};
|
||||
|
||||
template< typename Base >
|
||||
struct wait_operations< Base, 1u, true > :
|
||||
struct wait_operations< Base, 1u, true, false > :
|
||||
public windows_wait_operations< Base, 1u >
|
||||
{
|
||||
};
|
||||
|
||||
template< typename Base >
|
||||
struct wait_operations< Base, 2u, true > :
|
||||
struct wait_operations< Base, 2u, true, false > :
|
||||
public windows_wait_operations< Base, 2u >
|
||||
{
|
||||
};
|
||||
|
||||
template< typename Base >
|
||||
struct wait_operations< Base, 4u, true > :
|
||||
struct wait_operations< Base, 4u, true, false > :
|
||||
public windows_wait_operations< Base, 4u >
|
||||
{
|
||||
};
|
||||
|
||||
template< typename Base >
|
||||
struct wait_operations< Base, 8u, true > :
|
||||
struct wait_operations< Base, 8u, true, false > :
|
||||
public windows_wait_operations< Base, 8u >
|
||||
{
|
||||
};
|
||||
|
||||
92
include/boost/atomic/ipc_atomic.hpp
Normal file
92
include/boost/atomic/ipc_atomic.hpp
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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)
|
||||
*
|
||||
* Copyright (c) 2020 Andrey Semashev
|
||||
*/
|
||||
/*!
|
||||
* \file atomic/ipc_atomic.hpp
|
||||
*
|
||||
* This header contains definition of \c ipc_atomic template.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ATOMIC_IPC_ATOMIC_HPP_INCLUDED_
|
||||
#define BOOST_ATOMIC_IPC_ATOMIC_HPP_INCLUDED_
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/capabilities.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/classify.hpp>
|
||||
#include <boost/atomic/detail/atomic_impl.hpp>
|
||||
#include <boost/atomic/detail/type_traits/is_trivially_copyable.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
// 'boost::atomics::ipc_atomic<T>' : multiple assignment operators specified
|
||||
#pragma warning(disable: 4522)
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace atomics {
|
||||
|
||||
//! Atomic object for inter-process communication
|
||||
template< typename T >
|
||||
class ipc_atomic :
|
||||
public atomics::detail::base_atomic< T, typename atomics::detail::classify< T >::type, true >
|
||||
{
|
||||
private:
|
||||
typedef atomics::detail::base_atomic< T, typename atomics::detail::classify< T >::type, true > base_type;
|
||||
typedef typename base_type::value_arg_type value_arg_type;
|
||||
|
||||
public:
|
||||
typedef typename base_type::value_type value_type;
|
||||
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(value_type) > 0u, "boost::ipc_atomic<T> requires T to be a complete type");
|
||||
#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_IS_TRIVIALLY_COPYABLE)
|
||||
BOOST_STATIC_ASSERT_MSG(atomics::detail::is_trivially_copyable< value_type >::value, "boost::ipc_atomic<T> requires T to be a trivially copyable type");
|
||||
#endif
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(ipc_atomic() BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL {})
|
||||
BOOST_FORCEINLINE BOOST_ATOMIC_DETAIL_CONSTEXPR_UNION_INIT ipc_atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(v) {}
|
||||
|
||||
BOOST_FORCEINLINE value_type operator= (value_arg_type v) BOOST_NOEXCEPT
|
||||
{
|
||||
this->store(v);
|
||||
return v;
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE value_type operator= (value_arg_type v) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
this->store(v);
|
||||
return v;
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE operator value_type() const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return this->load();
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(ipc_atomic(ipc_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(ipc_atomic& operator= (ipc_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(ipc_atomic& operator= (ipc_atomic const&) volatile)
|
||||
};
|
||||
|
||||
} // namespace atomics
|
||||
|
||||
using atomics::ipc_atomic;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_ATOMIC_IPC_ATOMIC_HPP_INCLUDED_
|
||||
37
include/boost/atomic/ipc_atomic_flag.hpp
Normal file
37
include/boost/atomic/ipc_atomic_flag.hpp
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* 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)
|
||||
*
|
||||
* Copyright (c) 2020 Andrey Semashev
|
||||
*/
|
||||
/*!
|
||||
* \file atomic/ipc_atomic_flag.hpp
|
||||
*
|
||||
* This header contains definition of \c ipc_atomic_flag.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ATOMIC_IPC_ATOMIC_FLAG_HPP_INCLUDED_
|
||||
#define BOOST_ATOMIC_IPC_ATOMIC_FLAG_HPP_INCLUDED_
|
||||
|
||||
#include <boost/atomic/capabilities.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/atomic_flag_impl.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace atomics {
|
||||
|
||||
//! Atomic flag for inter-process communication
|
||||
typedef atomics::detail::atomic_flag_impl< true > ipc_atomic_flag;
|
||||
|
||||
} // namespace atomics
|
||||
|
||||
using atomics::ipc_atomic_flag;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_ATOMIC_IPC_ATOMIC_FLAG_HPP_INCLUDED_
|
||||
92
include/boost/atomic/ipc_atomic_ref.hpp
Normal file
92
include/boost/atomic/ipc_atomic_ref.hpp
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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)
|
||||
*
|
||||
* Copyright (c) 2020 Andrey Semashev
|
||||
*/
|
||||
/*!
|
||||
* \file atomic/ipc_atomic_ref.hpp
|
||||
*
|
||||
* This header contains definition of \c ipc_atomic_ref template.
|
||||
*/
|
||||
|
||||
#ifndef BOOST_ATOMIC_IPC_ATOMIC_REF_HPP_INCLUDED_
|
||||
#define BOOST_ATOMIC_IPC_ATOMIC_REF_HPP_INCLUDED_
|
||||
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/capabilities.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/intptr.hpp>
|
||||
#include <boost/atomic/detail/classify.hpp>
|
||||
#include <boost/atomic/detail/atomic_ref_impl.hpp>
|
||||
#include <boost/atomic/detail/type_traits/is_trivially_copyable.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
// 'boost::atomics::ipc_atomic_ref<T>' : multiple assignment operators specified
|
||||
#pragma warning(disable: 4522)
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace atomics {
|
||||
|
||||
//! Atomic reference to external object for inter-process communication
|
||||
template< typename T >
|
||||
class ipc_atomic_ref :
|
||||
public atomics::detail::base_atomic_ref< T, typename atomics::detail::classify< T >::type, true >
|
||||
{
|
||||
private:
|
||||
typedef atomics::detail::base_atomic_ref< T, typename atomics::detail::classify< T >::type, true > base_type;
|
||||
typedef typename base_type::value_arg_type value_arg_type;
|
||||
|
||||
public:
|
||||
typedef typename base_type::value_type value_type;
|
||||
|
||||
BOOST_STATIC_ASSERT_MSG(sizeof(value_type) > 0u, "boost::ipc_atomic_ref<T> requires T to be a complete type");
|
||||
#if !defined(BOOST_ATOMIC_DETAIL_NO_CXX11_IS_TRIVIALLY_COPYABLE)
|
||||
BOOST_STATIC_ASSERT_MSG(atomics::detail::is_trivially_copyable< value_type >::value, "boost::ipc_atomic_ref<T> requires T to be a trivially copyable type");
|
||||
#endif
|
||||
|
||||
private:
|
||||
typedef typename base_type::storage_type storage_type;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(ipc_atomic_ref(ipc_atomic_ref const& that) BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_DECL, BOOST_ATOMIC_DETAIL_DEF_NOEXCEPT_IMPL : base_type(static_cast< base_type const& >(that)) {})
|
||||
BOOST_FORCEINLINE explicit ipc_atomic_ref(value_type& v) BOOST_NOEXCEPT : base_type(v)
|
||||
{
|
||||
// Check that referenced object alignment satisfies required alignment
|
||||
BOOST_ASSERT((((atomics::detail::uintptr_t)this->m_value) & (base_type::required_alignment - 1u)) == 0u);
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE value_type operator= (value_arg_type v) const BOOST_NOEXCEPT
|
||||
{
|
||||
this->store(v);
|
||||
return v;
|
||||
}
|
||||
|
||||
BOOST_FORCEINLINE operator value_type() const BOOST_NOEXCEPT
|
||||
{
|
||||
return this->load();
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(ipc_atomic_ref& operator= (ipc_atomic_ref const&))
|
||||
};
|
||||
|
||||
} // namespace atomics
|
||||
|
||||
using atomics::ipc_atomic_ref;
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // BOOST_ATOMIC_IPC_ATOMIC_REF_HPP_INCLUDED_
|
||||
Reference in New Issue
Block a user