2
0
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:
Andrey Semashev
2020-06-07 02:11:18 +03:00
parent e4f8770665
commit 80cfbfd0de
56 changed files with 2173 additions and 502 deletions

View File

@@ -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

View File

@@ -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:

View File

@@ -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

View File

@@ -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:

View File

@@ -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_

View 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_

View File

@@ -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;

View File

@@ -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;

View File

@@ -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);
}
};

View File

@@ -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);
}
};

View File

@@ -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);

View File

@@ -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
{

View File

@@ -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

View File

@@ -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 >
{
};

View File

@@ -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
{

View File

@@ -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
{

View File

@@ -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 >
{
};

View File

@@ -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
{

View File

@@ -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 > > >
{
};

View File

@@ -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

View File

@@ -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 > >
{
};

View File

@@ -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;

View File

@@ -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 > > >
{
};

View File

@@ -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

View File

@@ -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 > > >
{
};

View File

@@ -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 >
{
};

View 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_

View 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&section=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_

View 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_

View 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_

View 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_

View File

@@ -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

View File

@@ -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);

View File

@@ -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 >
{
};

View File

@@ -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;

View File

@@ -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

View File

@@ -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 >
{
};

View File

@@ -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 >
{
};

View 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_

View 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_

View 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_