2
0
mirror of https://github.com/boostorg/atomic.git synced 2026-02-02 20:32:09 +00:00

Working on the new library design.

Added implementation of atomic ops with gcc __atomic intrinsics.
Implemented the unified atomic interface. Extracted atomic_flag to a
separate header. atomic_flag now follows standard requirements for
static initialization, if possible.
This commit is contained in:
Andrey Semashev
2014-04-19 22:25:02 +04:00
parent 928bdea4f6
commit f3d59ec1c1
10 changed files with 1004 additions and 47 deletions

View File

@@ -127,6 +127,11 @@
#endif
#ifndef BOOST_ATOMIC_POINTER_LOCK_FREE
#if (BOOST_ATOMIC_DETAIL_SIZEOF_POINTER + 0) == 8
#define BOOST_ATOMIC_POINTER_LOCK_FREE BOOST_ATOMIC_INT64_LOCK_FREE
#elif (BOOST_ATOMIC_DETAIL_SIZEOF_POINTER + 0) == 4
#define BOOST_ATOMIC_POINTER_LOCK_FREE BOOST_ATOMIC_INT32_LOCK_FREE
#else
#define BOOST_ATOMIC_POINTER_LOCK_FREE 0
#endif

View File

@@ -0,0 +1,79 @@
/*
* 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) 2014 Andrey Semashev
*/
/*!
* \file atomic/detail/atomic_flag.hpp
*
* This header contains interface definition of \c atomic_flag.
*/
#ifndef BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_HPP_INCLUDED_
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/operations_fwd.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace atomics {
#if defined(BOOST_NO_CXX11_CONSTEXPR)
#define BOOST_ATOMIC_NO_STATIC_INIT_ATOMIC_FLAG
#endif
#if !defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX) && !defined(BOOST_ATOMIC_DEFAULT_INITIALIZE_ATOMIC_FLAG)
#define BOOST_ATOMIC_FLAG_INIT { 0 }
#else
namespace detail {
struct default_initializer {};
BOOST_CONSTEXPR_OR_CONST default_initializer default_init = {};
} // namespace detail
#define BOOST_ATOMIC_FLAG_INIT ::boost::atomics::detail::default_init
#endif
struct atomic_flag
{
typedef atomics::detail::operations< 1u > operations;
typedef operations::storage_type storage_type;
storage_type m_storage;
#if !defined(BOOST_ATOMIC_DEFAULT_INITIALIZE_ATOMIC_FLAG)
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS)
BOOST_CONSTEXPR atomic_flag() BOOST_NOEXCEPT = default;
#else
BOOST_CONSTEXPR atomic_flag() BOOST_NOEXCEPT {}
#endif
#if defined(BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX)
BOOST_CONSTEXPR atomic_flag(atomics::detail::default_initializer) BOOST_NOEXCEPT : m_storage(0) {}
#endif
#else
BOOST_CONSTEXPR atomic_flag() BOOST_NOEXCEPT : m_storage(0) {}
BOOST_CONSTEXPR atomic_flag(atomics::detail::default_initializer) BOOST_NOEXCEPT : m_storage(0) {}
#endif
bool test_and_set(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return operations::test_and_set(m_storage, order);
}
void clear(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
operations::clear(m_storage, order);
}
BOOST_DELETED_FUNCTION(atomic_flag(atomic_flag const&))
BOOST_DELETED_FUNCTION(atomic_flag& operator= (atomic_flag const&))
};
} // namespace atomics
} // namespace boost
#endif // BOOST_ATOMIC_DETAIL_ATOMIC_FLAG_HPP_INCLUDED_

View File

@@ -0,0 +1,561 @@
/*
* 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) 2014 Andrey Semashev
*/
/*!
* \file atomic/detail/atomic_template.hpp
*
* This header contains interface definition of \c atomic template.
*/
#ifndef BOOST_ATOMIC_DETAIL_ATOMIC_TEMPLATE_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_ATOMIC_TEMPLATE_HPP_INCLUDED_
#include <cstddef>
#include <boost/type_traits/is_integral.hpp>
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/union_cast.hpp>
#include <boost/atomic/detail/operations_fwd.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace atomics {
namespace detail {
BOOST_FORCEINLINE BOOST_CONSTEXPR memory_order deduce_failure_order(memory_order order) BOOST_NOEXCEPT
{
return order == memory_order_acq_rel ? memory_order_acquire : (order == memory_order_release ? memory_order_relaxed : order);
}
template< typename T, bool IsInt = boost::is_integral< T >::value >
struct classify
{
typedef void type;
};
template< typename T >
struct classify< T, true > { typedef int type; };
template< typename T >
struct classify< T*, false > { typedef void* type; };
template< typename T, typename Kind >
class base_atomic;
//! Implementation for integers
template< typename T >
class base_atomic< T, int >
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef T difference_type;
typedef operations< storage_size_of< value_type >::value > operations;
protected:
typedef value_type value_arg_type;
public:
typedef typename operations::storage_type storage_type;
protected:
storage_type m_storage;
public:
BOOST_DEFAULTED_FUNCTION(base_atomic(), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : m_storage(v) {}
void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
operations::store(m_storage, static_cast< storage_type >(v), order);
}
value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
{
return static_cast< value_type >(operations::load(m_storage, order));
}
value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return static_cast< value_type >(operations::fetch_add(m_storage, static_cast< storage_type >(v), order));
}
value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return static_cast< value_type >(operations::fetch_sub(m_storage, static_cast< storage_type >(v), order));
}
value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return static_cast< value_type >(operations::exchange(m_storage, static_cast< storage_type >(v), order));
}
bool compare_exchange_strong(
value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
{
storage_type old_value = static_cast< storage_type >(expected);
const bool res = operations::compare_exchange_strong(m_storage, old_value, static_cast< storage_type >(desired), success_order, failure_order);
expected = static_cast< value_type >(old_value);
return res;
}
bool compare_exchange_strong(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
}
bool compare_exchange_weak(
value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
{
storage_type old_value = static_cast< storage_type >(expected);
const bool res = operations::compare_exchange_weak(m_storage, old_value, static_cast< storage_type >(desired), success_order, failure_order);
expected = static_cast< value_type >(old_value);
return res;
}
bool compare_exchange_weak(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
}
value_type fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return static_cast< value_type >(operations::fetch_and(m_storage, static_cast< storage_type >(v), order));
}
value_type fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return static_cast< value_type >(operations::fetch_or(m_storage, static_cast< storage_type >(v), order));
}
value_type fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return static_cast< value_type >(operations::fetch_xor(m_storage, static_cast< storage_type >(v), order));
}
bool is_lock_free() const volatile BOOST_NOEXCEPT
{
return operations::is_lock_free(m_storage);
}
value_type operator++(int) volatile BOOST_NOEXCEPT
{
return fetch_add(1);
}
value_type operator++() volatile BOOST_NOEXCEPT
{
return fetch_add(1) + 1;
}
value_type operator--(int) volatile BOOST_NOEXCEPT
{
return fetch_sub(1);
}
value_type operator--() volatile BOOST_NOEXCEPT
{
return fetch_sub(1) - 1;
}
value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT
{
return fetch_add(v) + v;
}
value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT
{
return fetch_sub(v) - v;
}
value_type operator&=(value_type v) volatile BOOST_NOEXCEPT
{
return fetch_and(v) & v;
}
value_type operator|=(value_type v) volatile BOOST_NOEXCEPT
{
return fetch_or(v) | v;
}
value_type operator^=(value_type v) volatile BOOST_NOEXCEPT
{
return fetch_xor(v) ^ v;
}
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
};
//! Implementation for user-defined types, such as structs and enums
template< typename T >
class base_atomic< T, void >
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef operations< storage_size_of< value_type >::value > operations;
protected:
typedef value_type const& value_arg_type;
public:
typedef typename operations::storage_type storage_type;
protected:
storage_type m_storage;
public:
BOOST_DEFAULTED_FUNCTION(base_atomic(), {})
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : m_storage(atomics::detail::union_cast< storage_type >(v))
{
}
void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
operations::store(m_storage, atomics::detail::union_cast< storage_type >(v), order);
}
value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
{
return atomics::detail::union_cast< value_type >(operations::load(m_storage, order));
}
value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return atomics::detail::union_cast< value_type >(operations::exchange(m_storage, atomics::detail::union_cast< storage_type >(v), order));
}
bool compare_exchange_strong(
value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
{
storage_type old_value = atomics::detail::union_cast< storage_type >(expected);
const bool res = operations::compare_exchange_strong(m_storage, old_value, atomics::detail::union_cast< storage_type >(desired), success_order, failure_order);
expected = atomics::detail::union_cast< value_type >(old_value);
return res;
}
bool compare_exchange_strong(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
}
bool compare_exchange_weak(
value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
{
storage_type old_value = atomics::detail::union_cast< storage_type >(expected);
const bool res = operations::compare_exchange_weak(m_storage, old_value, atomics::detail::union_cast< storage_type >(desired), success_order, failure_order);
expected = atomics::detail::union_cast< value_type >(old_value);
return res;
}
bool compare_exchange_weak(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
}
bool is_lock_free() const volatile BOOST_NOEXCEPT
{
return operations::is_lock_free(m_storage);
}
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
};
//! Implementation for pointers
template<typename T >
class base_atomic< T*, void* >
{
private:
typedef base_atomic this_type;
typedef T* value_type;
typedef std::ptrdiff_t difference_type;
typedef operations< storage_size_of< value_type >::value > operations;
protected:
typedef value_type value_arg_type;
public:
typedef typename operations::storage_type storage_type;
protected:
storage_type m_storage;
public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : m_storage(atomics::detail::union_cast< storage_type >(v))
{
}
void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
operations::store(m_storage, atomics::detail::union_cast< storage_type >(v), order);
}
value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
{
return atomics::detail::union_cast< value_type >(operations::load(m_storage, order));
}
value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return atomics::detail::union_cast< value_type >(operations::fetch_add(m_storage, static_cast< storage_type >(v * sizeof(T)), order));
}
value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return atomics::detail::union_cast< value_type >(operations::fetch_sub(m_storage, static_cast< storage_type >(v * sizeof(T)), order));
}
value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return atomics::detail::union_cast< value_type >(operations::exchange(m_storage, atomics::detail::union_cast< storage_type >(v), order));
}
bool compare_exchange_strong(
value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
{
storage_type old_value = atomics::detail::union_cast< storage_type >(expected);
const bool res = operations::compare_exchange_strong(m_storage, old_value, atomics::detail::union_cast< storage_type >(desired), success_order, failure_order);
expected = atomics::detail::union_cast< value_type >(old_value);
return res;
}
bool compare_exchange_strong(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
}
bool compare_exchange_weak(
value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
{
storage_type old_value = atomics::detail::union_cast< storage_type >(expected);
const bool res = operations::compare_exchange_weak(m_storage, old_value, atomics::detail::union_cast< storage_type >(desired), success_order, failure_order);
expected = atomics::detail::union_cast< value_type >(old_value);
return res;
}
bool compare_exchange_weak(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
}
bool is_lock_free() const volatile BOOST_NOEXCEPT
{
return operations::is_lock_free(m_storage);
}
value_type operator++(int) volatile BOOST_NOEXCEPT
{
return fetch_add(1);
}
value_type operator++() volatile BOOST_NOEXCEPT
{
return fetch_add(1) + 1;
}
value_type operator--(int) volatile BOOST_NOEXCEPT
{
return fetch_sub(1);
}
value_type operator--() volatile BOOST_NOEXCEPT
{
return fetch_sub(1) - 1;
}
value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT
{
return fetch_add(v) + v;
}
value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT
{
return fetch_sub(v) - v;
}
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
};
//! Implementation for void pointers
template< >
class base_atomic< void*, void* >
{
private:
typedef base_atomic this_type;
typedef void* value_type;
typedef std::ptrdiff_t difference_type;
typedef operations< storage_size_of< value_type >::value > operations;
protected:
typedef value_type value_arg_type;
public:
typedef typename operations::storage_type storage_type;
protected:
storage_type m_storage;
public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : m_storage(atomics::detail::union_cast< storage_type >(v))
{
}
void store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
operations::store(m_storage, atomics::detail::union_cast< storage_type >(v), order);
}
value_type load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
{
return atomics::detail::union_cast< value_type >(operations::load(m_storage, order));
}
value_type fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return atomics::detail::union_cast< value_type >(operations::fetch_add(m_storage, static_cast< storage_type >(v * sizeof(T)), order));
}
value_type fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return atomics::detail::union_cast< value_type >(operations::fetch_sub(m_storage, static_cast< storage_type >(v * sizeof(T)), order));
}
value_type exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return atomics::detail::union_cast< value_type >(operations::exchange(m_storage, atomics::detail::union_cast< storage_type >(v), order));
}
bool compare_exchange_strong(
value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
{
storage_type old_value = atomics::detail::union_cast< storage_type >(expected);
const bool res = operations::compare_exchange_strong(m_storage, old_value, atomics::detail::union_cast< storage_type >(desired), success_order, failure_order);
expected = atomics::detail::union_cast< value_type >(old_value);
return res;
}
bool compare_exchange_strong(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return compare_exchange_strong(expected, desired, order, atomics::detail::deduce_failure_order(order));
}
bool compare_exchange_weak(
value_type& expected, value_type desired, memory_order success_order, memory_order failure_order) volatile BOOST_NOEXCEPT
{
storage_type old_value = atomics::detail::union_cast< storage_type >(expected);
const bool res = operations::compare_exchange_weak(m_storage, old_value, atomics::detail::union_cast< storage_type >(desired), success_order, failure_order);
expected = atomics::detail::union_cast< value_type >(old_value);
return res;
}
bool compare_exchange_weak(value_type& expected, value_type desired, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
return compare_exchange_weak(expected, desired, order, atomics::detail::deduce_failure_order(order));
}
bool is_lock_free() const volatile BOOST_NOEXCEPT
{
return operations::is_lock_free(m_storage);
}
value_type operator++(int) volatile BOOST_NOEXCEPT
{
return fetch_add(1);
}
value_type operator++() volatile BOOST_NOEXCEPT
{
return (char*)fetch_add(1) + 1;
}
value_type operator--(int) volatile BOOST_NOEXCEPT
{
return fetch_sub(1);
}
value_type operator--() volatile BOOST_NOEXCEPT
{
return (char*)fetch_sub(1) - 1;
}
value_type operator+=(difference_type v) volatile BOOST_NOEXCEPT
{
return (char*)fetch_add(v) + v;
}
value_type operator-=(difference_type v) volatile BOOST_NOEXCEPT
{
return (char*)fetch_sub(v) - v;
}
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
};
} // namespace detail
template< typename T >
class atomic :
public atomics::detail::base_atomic<
T,
typename atomics::detail::classify< T >::type
>
{
private:
typedef T value_type;
typedef atomics::detail::base_atomic<
T,
typename atomics::detail::classify< T >::type
> base_type;
typedef typename base_type::value_arg_type value_arg_type;
public:
typedef typename base_type::storage_type storage_type;
public:
BOOST_DEFAULTED_FUNCTION(atomic(), BOOST_NOEXCEPT {})
// NOTE: The constructor is made explicit because gcc 4.7 complains that
// operator=(value_arg_type) is considered ambiguous with operator=(atomic const&)
// in assignment expressions, even though conversion to atomic<> is less preferred
// than conversion to value_arg_type.
explicit BOOST_CONSTEXPR atomic(value_arg_type v) BOOST_NOEXCEPT : base_type(v) {}
BOOST_FORCEINLINE value_type operator= (value_arg_type v) volatile BOOST_NOEXCEPT
{
this->store(v);
return v;
}
BOOST_FORCEINLINE operator value_type() volatile const BOOST_NOEXCEPT
{
return this->load();
}
BOOST_FORCEINLINE storage_type& storage() BOOST_NOEXCEPT { return this->m_storage; }
BOOST_FORCEINLINE storage_type volatile& storage() volatile BOOST_NOEXCEPT { return this->m_storage; }
BOOST_FORCEINLINE storage_type const& storage() const BOOST_NOEXCEPT { return this->m_storage; }
BOOST_FORCEINLINE storage_type const volatile& storage() const volatile BOOST_NOEXCEPT { return this->m_storage; }
BOOST_DELETED_FUNCTION(atomic(atomic const&))
BOOST_DELETED_FUNCTION(atomic& operator= (atomic const&) volatile)
};
} // namespace atomics
} // namespace boost
#endif // BOOST_ATOMIC_DETAIL_ATOMIC_TEMPLATE_HPP_INCLUDED_

View File

@@ -22,16 +22,31 @@
#pragma once
#endif
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
#define BOOST_ATOMIC_INT8_LOCK_FREE 2
#endif
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
#define BOOST_ATOMIC_INT16_LOCK_FREE 2
#endif
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
#define BOOST_ATOMIC_INT32_LOCK_FREE 2
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)
#endif
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_8)\
|| defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
#define BOOST_ATOMIC_INT64_LOCK_FREE 2
#endif
#if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_16)
#define BOOST_ATOMIC_INT128_LOCK_FREE 2
#endif
#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
#define BOOST_ATOMIC_THREAD_FENCE 2
#define BOOST_ATOMIC_SIGNAL_FENCE 2

View File

@@ -36,6 +36,15 @@
#if defined(__SIZEOF_WCHAR_T__)
#define BOOST_ATOMIC_DETAIL_SIZEOF_WCHAR_T __SIZEOF_WCHAR_T__
#endif
#if defined(__SIZEOF_POINTER__)
#define BOOST_ATOMIC_DETAIL_SIZEOF_POINTER __SIZEOF_POINTER__
#elif defined(_MSC_VER)
#if defined(_M_AMD64) || defined(_M_IA64)
#define BOOST_ATOMIC_DETAIL_SIZEOF_POINTER 8
#else
#define BOOST_ATOMIC_DETAIL_SIZEOF_POINTER 4
#endif
#endif
#if !defined(BOOST_ATOMIC_DETAIL_SIZEOF_SHORT) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_INT) ||\
!defined(BOOST_ATOMIC_DETAIL_SIZEOF_LONG) || !defined(BOOST_ATOMIC_DETAIL_SIZEOF_LLONG)

View File

@@ -0,0 +1,28 @@
/*
* 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) 2014 Andrey Semashev
*/
/*!
* \file atomic/detail/operations_lockfree.hpp
*
* This header defines lockfree atomic operations.
*/
#ifndef BOOST_ATOMIC_DETAIL_OPERATIONS_LOCKFREE_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_OPERATIONS_LOCKFREE_HPP_INCLUDED_
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/platform.hpp>
#if !defined(BOOST_ATOMIC_EMULATED)
#include BOOST_ATOMIC_DETAIL_HEADER(boost/atomic/detail/ops_)
#endif
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#endif // BOOST_ATOMIC_DETAIL_OPERATIONS_LOCKFREE_HPP_INCLUDED_

View File

@@ -0,0 +1,175 @@
/*
* 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) 2014 Andrey Semashev
*/
/*!
* \file atomic/detail/ops_gcc_atomic.hpp
*
* This header contains implementation of the \c operations template.
*/
#ifndef BOOST_ATOMIC_DETAIL_OPS_GCC_ATOMIC_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_OPS_GCC_ATOMIC_HPP_INCLUDED_
#include <boost/memory_order.hpp>
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/storage_types.hpp>
#include <boost/atomic/detail/operations_fwd.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace atomics {
namespace detail {
BOOST_FORCEINLINE BOOST_CONSTEXPR int convert_memory_order_to_gcc(memory_order order) BOOST_NOEXCEPT
{
return (order == memory_order_relaxed ? __ATOMIC_RELAXED : (order == memory_order_consume ? __ATOMIC_CONSUME :
(order == memory_order_acquire ? __ATOMIC_ACQUIRE : (order == memory_order_release ? __ATOMIC_RELEASE :
(order == memory_order_acq_rel ? __ATOMIC_ACQ_REL : __ATOMIC_SEQ_CST)))));
}
template< typename T >
struct gcc_atomic_operations
{
typedef T storage_type;
static BOOST_FORCEINLINE void store(storage_type volatile& storage, storage_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
{
__atomic_store_n(&storage, v, atomics::detail::convert_memory_order_to_gcc(order));
}
static BOOST_FORCEINLINE storage_type load(storage_type const volatile& storage, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
{
return __atomic_load_n(&storage, atomics::detail::convert_memory_order_to_gcc(order));
}
static BOOST_FORCEINLINE storage_type fetch_add(storage_type volatile& storage, storage_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
{
return __atomic_fetch_add(&storage, v, atomics::detail::convert_memory_order_to_gcc(order));
}
static BOOST_FORCEINLINE storage_type fetch_sub(storage_type volatile& storage, storage_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
{
return __atomic_fetch_sub(&storage, v, atomics::detail::convert_memory_order_to_gcc(order));
}
static BOOST_FORCEINLINE storage_type exchange(storage_type volatile& storage, storage_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
{
return __atomic_exchange_n(&storage, v, atomics::detail::convert_memory_order_to_gcc(order));
}
static BOOST_FORCEINLINE bool compare_exchange_strong(
storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
{
return __atomic_compare_exchange_n
(
&storage, &expected, desired, false,
atomics::detail::convert_memory_order_to_gcc(success_order),
atomics::detail::convert_memory_order_to_gcc(failure_order)
);
}
static BOOST_FORCEINLINE bool compare_exchange_weak(
storage_type volatile& storage, storage_type& expected, storage_type desired, memory_order success_order, memory_order failure_order) BOOST_NOEXCEPT
{
return __atomic_compare_exchange_n
(
&storage, &expected, desired, true,
atomics::detail::convert_memory_order_to_gcc(success_order),
atomics::detail::convert_memory_order_to_gcc(failure_order)
);
}
static BOOST_FORCEINLINE storage_type fetch_and(storage_type volatile& storage, storage_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
{
return __atomic_fetch_and(&storage, v, atomics::detail::convert_memory_order_to_gcc(order));
}
static BOOST_FORCEINLINE storage_type fetch_or(storage_type volatile& storage, storage_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
{
return __atomic_fetch_or(&storage, v, atomics::detail::convert_memory_order_to_gcc(order));
}
static BOOST_FORCEINLINE storage_type fetch_xor(storage_type volatile& storage, storage_type v, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
{
return __atomic_fetch_xor(&storage, v, atomics::detail::convert_memory_order_to_gcc(order));
}
static BOOST_FORCEINLINE bool test_and_set(storage_type volatile& storage, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
{
return __atomic_test_and_set(&storage, atomics::detail::convert_memory_order_to_gcc(order));
}
static BOOST_FORCEINLINE void clear(storage_type volatile& storage, memory_order order = memory_order_seq_cst) BOOST_NOEXCEPT
{
__atomic_clear(const_cast< storage_type* >(&storage), atomics::detail::convert_memory_order_to_gcc(order));
}
static BOOST_FORCEINLINE bool is_lock_free(storage_type const volatile& storage) BOOST_NOEXCEPT
{
return __atomic_is_lock_free(sizeof(storage_type), &storage);
}
};
#if BOOST_ATOMIC_INT8_LOCK_FREE > 0
template< >
struct operations< 1u > :
public gcc_atomic_operations< storage8_t >
{
};
#endif
#if BOOST_ATOMIC_INT16_LOCK_FREE > 0
template< >
struct operations< 2u > :
public gcc_atomic_operations< storage16_t >
{
};
#endif
#if BOOST_ATOMIC_INT32_LOCK_FREE > 0
template< >
struct operations< 4u > :
public gcc_atomic_operations< storage32_t >
{
};
#endif
#if BOOST_ATOMIC_INT64_LOCK_FREE > 0
template< >
struct operations< 8u > :
public gcc_atomic_operations< storage64_t >
{
};
#endif
#if BOOST_ATOMIC_INT128_LOCK_FREE > 0
template< >
struct operations< 16u > :
public gcc_atomic_operations< storage128_t >
{
};
#endif
} // namespace detail
BOOST_FORCEINLINE void atomic_thread_fence(memory_order order)
{
__atomic_thread_fence(atomics::detail::convert_memory_order_to_gcc(order));
}
BOOST_FORCEINLINE void atomic_signal_fence(memory_order order)
{
__atomic_signal_fence(atomics::detail::convert_memory_order_to_gcc(order));
}
} // namespace atomics
} // namespace boost
#endif // BOOST_ATOMIC_DETAIL_OPS_GCC_ATOMIC_HPP_INCLUDED_

View File

@@ -0,0 +1,84 @@
/*
* 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) 2009 Helge Bahmann
* Copyright (c) 2012 Tim Blechmann
* Copyright (c) 2013 - 2014 Andrey Semashev
*/
/*!
* \file atomic/detail/storage_types.hpp
*
* This header defines underlying types used as storage
*/
#ifndef BOOST_ATOMIC_DETAIL_STORAGE_TYPES_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_STORAGE_TYPES_HPP_INCLUDED_
#include <boost/cstdint.hpp>
#include <boost/atomic/detail/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace atomics {
namespace detail {
typedef boost::uint8_t storage8_t;
typedef boost::uint16_t storage16_t;
typedef boost::uint32_t storage32_t;
#if !defined(BOOST_NO_INT64_T)
typedef boost::uint64_t storage64_t;
#else
struct BOOST_ALIGNMENT(8) storage64_t
{
boost::uint32_t data[2];
};
BOOST_FORCEINLINE bool operator== (storage64_t const& left, storage64_t const& right) BOOST_NOEXCEPT
{
return left.data[0] == right.data[0] && left.data[1] == right.data[1];
}
BOOST_FORCEINLINE bool operator!= (storage64_t const& left, storage64_t const& right) BOOST_NOEXCEPT
{
return !(left == right);
}
#endif
#if !defined(BOOST_HAS_INT128)
typedef boost::uint128_type storage128_t;
#else
struct BOOST_ALIGNMENT(16) storage128_t
{
storage64_t data[2];
};
BOOST_FORCEINLINE bool operator== (storage128_t const& left, storage128_t const& right) BOOST_NOEXCEPT
{
return left.data[0] == right.data[0] && left.data[1] == right.data[1];
}
BOOST_FORCEINLINE bool operator!= (storage128_t const& left, storage128_t const& right) BOOST_NOEXCEPT
{
return !(left == right);
}
#endif
template< typename T >
struct storage_size_of
{
enum _
{
size = sizeof(T),
value = (size == 3 ? 4 : (size >= 5 && size <= 7 ? 8 : (size >= 9 && size <= 15 ? 16 : size)))
};
};
} // namespace detail
} // namespace atomics
} // namespace boost
#endif // BOOST_ATOMIC_DETAIL_STORAGE_TYPES_HPP_INCLUDED_

View File

@@ -1,45 +0,0 @@
#ifndef BOOST_ATOMIC_DETAIL_TYPE_CLASSIFICATION_HPP
#define BOOST_ATOMIC_DETAIL_TYPE_CLASSIFICATION_HPP
// Copyright (c) 2011 Helge Bahmann
//
// 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)
#include <boost/atomic/detail/config.hpp>
#include <boost/type_traits/is_integral.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace atomics {
namespace detail {
template<typename T, bool IsInt = boost::is_integral<T>::value>
struct classify
{
typedef void type;
};
template<typename T>
struct classify<T, true> {typedef int type;};
template<typename T>
struct classify<T*, false> {typedef void* type;};
template<typename T>
struct storage_size_of
{
enum _
{
size = sizeof(T),
value = (size == 3 ? 4 : (size >= 5 && size <= 7 ? 8 : (size >= 9 && size <= 15 ? 16 : size)))
};
};
}}}
#endif

View File

@@ -0,0 +1,46 @@
/*
* 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) 2009 Helge Bahmann
* Copyright (c) 2012 Tim Blechmann
* Copyright (c) 2013 - 2014 Andrey Semashev
*/
/*!
* \file atomic/detail/union_cast.hpp
*
* This header defines \c union_cast used to convert between storage and value types
*/
#ifndef BOOST_ATOMIC_DETAIL_UNION_CAST_HPP_INCLUDED_
#define BOOST_ATOMIC_DETAIL_UNION_CAST_HPP_INCLUDED_
#include <boost/atomic/detail/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace atomics {
namespace detail {
template< typename To, typename From >
BOOST_FORCEINLINE To union_cast(From const& from) BOOST_NOEXCEPT
{
union
{
To as_to;
From as_from;
}
caster = {};
caster.as_from = from;
return caster.as_to;
}
} // namespace detail
} // namespace atomics
} // namespace boost
#endif // BOOST_ATOMIC_DETAIL_UNION_CAST_HPP_INCLUDED_