mirror of
https://github.com/boostorg/atomic.git
synced 2026-02-02 20:32:09 +00:00
Removed no longer used files.
This commit is contained in:
@@ -1,605 +0,0 @@
|
||||
#ifndef BOOST_ATOMIC_DETAIL_BASE_HPP
|
||||
#define BOOST_ATOMIC_DETAIL_BASE_HPP
|
||||
|
||||
// Copyright (c) 2009 Helge Bahmann
|
||||
// Copyright (c) 2013 Tim Blechmann
|
||||
//
|
||||
// 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)
|
||||
|
||||
// Base class definition and fallback implementation.
|
||||
// To be overridden (through partial specialization) by
|
||||
// platform implementations.
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/lockpool.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#define BOOST_ATOMIC_DECLARE_BASE_OPERATORS \
|
||||
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, calculate_failure_order(order)); \
|
||||
} \
|
||||
\
|
||||
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, calculate_failure_order(order)); \
|
||||
} \
|
||||
|
||||
#define BOOST_ATOMIC_DECLARE_ADDITIVE_OPERATORS \
|
||||
value_type \
|
||||
operator++(int) volatile BOOST_NOEXCEPT \
|
||||
{ \
|
||||
return fetch_add(1); \
|
||||
} \
|
||||
\
|
||||
value_type \
|
||||
operator++(void) volatile BOOST_NOEXCEPT \
|
||||
{ \
|
||||
return fetch_add(1) + 1; \
|
||||
} \
|
||||
\
|
||||
value_type \
|
||||
operator--(int) volatile BOOST_NOEXCEPT \
|
||||
{ \
|
||||
return fetch_sub(1); \
|
||||
} \
|
||||
\
|
||||
value_type \
|
||||
operator--(void) 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; \
|
||||
} \
|
||||
|
||||
#define BOOST_ATOMIC_DECLARE_VOID_POINTER_ADDITIVE_OPERATORS \
|
||||
value_type \
|
||||
operator++(int) volatile BOOST_NOEXCEPT \
|
||||
{ \
|
||||
return fetch_add(1); \
|
||||
} \
|
||||
\
|
||||
value_type \
|
||||
operator++(void) volatile BOOST_NOEXCEPT \
|
||||
{ \
|
||||
return (char*)fetch_add(1) + 1; \
|
||||
} \
|
||||
\
|
||||
value_type \
|
||||
operator--(int) volatile BOOST_NOEXCEPT \
|
||||
{ \
|
||||
return fetch_sub(1); \
|
||||
} \
|
||||
\
|
||||
value_type \
|
||||
operator--(void) 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; \
|
||||
} \
|
||||
|
||||
#define BOOST_ATOMIC_DECLARE_BIT_OPERATORS \
|
||||
value_type \
|
||||
operator&=(difference_type v) volatile BOOST_NOEXCEPT \
|
||||
{ \
|
||||
return fetch_and(v) & v; \
|
||||
} \
|
||||
\
|
||||
value_type \
|
||||
operator|=(difference_type v) volatile BOOST_NOEXCEPT \
|
||||
{ \
|
||||
return fetch_or(v) | v; \
|
||||
} \
|
||||
\
|
||||
value_type \
|
||||
operator^=(difference_type v) volatile BOOST_NOEXCEPT\
|
||||
{ \
|
||||
return fetch_xor(v) ^ v; \
|
||||
} \
|
||||
|
||||
#define BOOST_ATOMIC_DECLARE_POINTER_OPERATORS \
|
||||
BOOST_ATOMIC_DECLARE_BASE_OPERATORS \
|
||||
BOOST_ATOMIC_DECLARE_ADDITIVE_OPERATORS \
|
||||
|
||||
#define BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS \
|
||||
BOOST_ATOMIC_DECLARE_BASE_OPERATORS \
|
||||
BOOST_ATOMIC_DECLARE_VOID_POINTER_ADDITIVE_OPERATORS \
|
||||
|
||||
#define BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS \
|
||||
BOOST_ATOMIC_DECLARE_BASE_OPERATORS \
|
||||
BOOST_ATOMIC_DECLARE_ADDITIVE_OPERATORS \
|
||||
BOOST_ATOMIC_DECLARE_BIT_OPERATORS \
|
||||
|
||||
namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
inline memory_order
|
||||
calculate_failure_order(memory_order order)
|
||||
{
|
||||
switch(order)
|
||||
{
|
||||
case memory_order_acq_rel:
|
||||
return memory_order_acquire;
|
||||
case memory_order_release:
|
||||
return memory_order_relaxed;
|
||||
default:
|
||||
return order;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename C, unsigned int Size, bool Sign>
|
||||
class base_atomic
|
||||
{
|
||||
private:
|
||||
typedef base_atomic this_type;
|
||||
typedef T value_type;
|
||||
typedef lockpool::scoped_lock guard_type;
|
||||
|
||||
protected:
|
||||
typedef value_type const& value_arg_type;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(v)
|
||||
{}
|
||||
|
||||
void
|
||||
store(value_type const& v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
char * storage = storage_ptr();
|
||||
guard_type guard(storage);
|
||||
|
||||
memcpy(storage, &v, sizeof(value_type));
|
||||
}
|
||||
|
||||
value_type
|
||||
load(memory_order /*order*/ = memory_order_seq_cst) volatile const BOOST_NOEXCEPT
|
||||
{
|
||||
char * storage = storage_ptr();
|
||||
guard_type guard(storage);
|
||||
|
||||
value_type v;
|
||||
memcpy(&v, storage, sizeof(value_type));
|
||||
return v;
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_strong(
|
||||
value_type & expected,
|
||||
value_type const& desired,
|
||||
memory_order /*success_order*/,
|
||||
memory_order /*failure_order*/) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
char * storage = storage_ptr();
|
||||
guard_type guard(storage);
|
||||
|
||||
if (memcmp(storage, &expected, sizeof(value_type)) == 0) {
|
||||
memcpy(storage, &desired, sizeof(value_type));
|
||||
return true;
|
||||
} else {
|
||||
memcpy(&expected, storage, sizeof(value_type));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_weak(
|
||||
value_type & expected,
|
||||
value_type const& desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
||||
}
|
||||
|
||||
value_type
|
||||
exchange(value_type const& v, memory_order /*order*/=memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
char * storage = storage_ptr();
|
||||
guard_type guard(storage);
|
||||
|
||||
value_type tmp;
|
||||
memcpy(&tmp, storage, sizeof(value_type));
|
||||
|
||||
memcpy(storage, &v, sizeof(value_type));
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free(void) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOST_ATOMIC_DECLARE_BASE_OPERATORS
|
||||
|
||||
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
|
||||
|
||||
private:
|
||||
char * storage_ptr() volatile const BOOST_NOEXCEPT
|
||||
{
|
||||
return const_cast<char *>(&reinterpret_cast<char const volatile &>(v_));
|
||||
}
|
||||
|
||||
T v_;
|
||||
};
|
||||
|
||||
template<typename T, unsigned int Size, bool Sign>
|
||||
class base_atomic<T, int, Size, Sign>
|
||||
{
|
||||
private:
|
||||
typedef base_atomic this_type;
|
||||
typedef T value_type;
|
||||
typedef T difference_type;
|
||||
typedef lockpool::scoped_lock guard_type;
|
||||
|
||||
protected:
|
||||
typedef value_type value_arg_type;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
|
||||
|
||||
void
|
||||
store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
|
||||
v_ = v;
|
||||
}
|
||||
|
||||
value_type
|
||||
load(memory_order /*order*/ = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
|
||||
value_type v = const_cast<const volatile value_type &>(v_);
|
||||
return v;
|
||||
}
|
||||
|
||||
value_type
|
||||
exchange(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
|
||||
value_type old = v_;
|
||||
v_ = v;
|
||||
return old;
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_strong(value_type & expected, value_type desired,
|
||||
memory_order /*success_order*/,
|
||||
memory_order /*failure_order*/) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
|
||||
if (v_ == expected) {
|
||||
v_ = desired;
|
||||
return true;
|
||||
} else {
|
||||
expected = v_;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_weak(value_type & expected, value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_add(difference_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
|
||||
value_type old = v_;
|
||||
v_ += v;
|
||||
return old;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_sub(difference_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
|
||||
value_type old = v_;
|
||||
v_ -= v;
|
||||
return old;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_and(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
|
||||
value_type old = v_;
|
||||
v_ &= v;
|
||||
return old;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_or(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
|
||||
value_type old = v_;
|
||||
v_ |= v;
|
||||
return old;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_xor(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
|
||||
value_type old = v_;
|
||||
v_ ^= v;
|
||||
return old;
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free(void) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
|
||||
|
||||
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
|
||||
|
||||
private:
|
||||
value_type v_;
|
||||
};
|
||||
|
||||
template<typename T, unsigned int Size, bool Sign>
|
||||
class base_atomic<T *, void *, Size, Sign>
|
||||
{
|
||||
private:
|
||||
typedef base_atomic this_type;
|
||||
typedef T * value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef lockpool::scoped_lock guard_type;
|
||||
|
||||
protected:
|
||||
typedef value_type value_arg_type;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
|
||||
|
||||
void
|
||||
store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
v_ = v;
|
||||
}
|
||||
|
||||
value_type
|
||||
load(memory_order /*order*/ = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
|
||||
value_type v = const_cast<const volatile value_type &>(v_);
|
||||
return v;
|
||||
}
|
||||
|
||||
value_type
|
||||
exchange(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
|
||||
value_type old = v_;
|
||||
v_ = v;
|
||||
return old;
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_strong(value_type & expected, value_type desired,
|
||||
memory_order /*success_order*/,
|
||||
memory_order /*failure_order*/) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
|
||||
if (v_ == expected) {
|
||||
v_ = desired;
|
||||
return true;
|
||||
} else {
|
||||
expected = v_;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_weak(value_type & expected, value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
||||
}
|
||||
|
||||
value_type fetch_add(difference_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
|
||||
value_type old = v_;
|
||||
v_ += v;
|
||||
return old;
|
||||
}
|
||||
|
||||
value_type fetch_sub(difference_type v, memory_order /*order*/ = memory_order_seq_cst) volatile
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
|
||||
value_type old = v_;
|
||||
v_ -= v;
|
||||
return old;
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free(void) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
|
||||
|
||||
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
|
||||
|
||||
private:
|
||||
value_type v_;
|
||||
};
|
||||
|
||||
template<unsigned int Size, bool Sign>
|
||||
class base_atomic<void *, void *, Size, Sign>
|
||||
{
|
||||
private:
|
||||
typedef base_atomic this_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef void * value_type;
|
||||
typedef lockpool::scoped_lock guard_type;
|
||||
|
||||
protected:
|
||||
typedef value_type value_arg_type;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
|
||||
|
||||
void
|
||||
store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
v_ = v;
|
||||
}
|
||||
|
||||
value_type
|
||||
load(memory_order /*order*/ = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
|
||||
value_type v = const_cast<const volatile value_type &>(v_);
|
||||
return v;
|
||||
}
|
||||
|
||||
value_type
|
||||
exchange(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
|
||||
value_type old = v_;
|
||||
v_ = v;
|
||||
return old;
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_strong(value_type & expected, value_type desired,
|
||||
memory_order /*success_order*/,
|
||||
memory_order /*failure_order*/) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
|
||||
if (v_ == expected) {
|
||||
v_ = desired;
|
||||
return true;
|
||||
} else {
|
||||
expected = v_;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_weak(value_type & expected, value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free(void) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
value_type fetch_add(difference_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
|
||||
value_type old = v_;
|
||||
char * cv = reinterpret_cast<char*>(old);
|
||||
cv += v;
|
||||
v_ = cv;
|
||||
return old;
|
||||
}
|
||||
|
||||
value_type fetch_sub(difference_type v, memory_order /*order*/ = memory_order_seq_cst) volatile
|
||||
{
|
||||
guard_type guard(const_cast<value_type *>(&v_));
|
||||
|
||||
value_type old = v_;
|
||||
char * cv = reinterpret_cast<char*>(old);
|
||||
cv -= v;
|
||||
v_ = cv;
|
||||
return old;
|
||||
}
|
||||
|
||||
BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
|
||||
|
||||
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
|
||||
|
||||
private:
|
||||
value_type v_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,290 +0,0 @@
|
||||
#ifndef BOOST_ATOMIC_DETAIL_CAS128STRONG_HPP
|
||||
#define BOOST_ATOMIC_DETAIL_CAS128STRONG_HPP
|
||||
|
||||
// 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, Andrey Semashev
|
||||
|
||||
// Build 128-bit atomic operation on integers/UDTs from platform_cmpxchg128_strong
|
||||
// primitive. It is assumed that 128-bit loads/stores are not
|
||||
// atomic, so they are implemented through platform_load128/platform_store128.
|
||||
|
||||
#include <string.h>
|
||||
#include <cstddef>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/base.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
/* integral types */
|
||||
|
||||
template<typename T, bool Sign>
|
||||
class base_atomic<T, int, 16, Sign>
|
||||
{
|
||||
private:
|
||||
typedef base_atomic this_type;
|
||||
typedef T value_type;
|
||||
typedef T difference_type;
|
||||
|
||||
protected:
|
||||
typedef value_type value_arg_type;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
|
||||
|
||||
void
|
||||
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_before_store(order);
|
||||
platform_store128(v, &v_);
|
||||
platform_fence_after_store(order);
|
||||
}
|
||||
|
||||
value_type
|
||||
load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type v = platform_load128(&v_);
|
||||
platform_fence_after_load(order);
|
||||
return v;
|
||||
}
|
||||
|
||||
value_type
|
||||
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_weak(
|
||||
value_type & expected,
|
||||
value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_strong(
|
||||
value_type & expected,
|
||||
value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_before(success_order);
|
||||
|
||||
bool success = platform_cmpxchg128_strong(expected, desired, &v_);
|
||||
|
||||
if (success) {
|
||||
platform_fence_after(success_order);
|
||||
} else {
|
||||
platform_fence_after(failure_order);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free(void) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
|
||||
|
||||
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
|
||||
|
||||
private:
|
||||
value_type v_;
|
||||
};
|
||||
|
||||
/* generic types */
|
||||
|
||||
#if defined(BOOST_HAS_INT128)
|
||||
|
||||
typedef boost::uint128_type storage128_type;
|
||||
|
||||
#else // defined(BOOST_HAS_INT128)
|
||||
|
||||
struct BOOST_ALIGNMENT(16) storage128_type
|
||||
{
|
||||
uint64_t data[2];
|
||||
};
|
||||
|
||||
inline bool operator== (storage128_type const& left, storage128_type const& right)
|
||||
{
|
||||
return left.data[0] == right.data[0] && left.data[1] == right.data[1];
|
||||
}
|
||||
inline bool operator!= (storage128_type const& left, storage128_type const& right)
|
||||
{
|
||||
return !(left == right);
|
||||
}
|
||||
|
||||
#endif // defined(BOOST_HAS_INT128)
|
||||
|
||||
template<typename T, bool Sign>
|
||||
class base_atomic<T, void, 16, Sign>
|
||||
{
|
||||
private:
|
||||
typedef base_atomic this_type;
|
||||
typedef T value_type;
|
||||
typedef storage128_type storage_type;
|
||||
|
||||
protected:
|
||||
typedef value_type const& value_arg_type;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT
|
||||
{
|
||||
memset(&v_, 0, sizeof(v_));
|
||||
memcpy(&v_, &v, sizeof(value_type));
|
||||
}
|
||||
|
||||
void
|
||||
store(value_type const& value, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
storage_type value_s;
|
||||
memset(&value_s, 0, sizeof(value_s));
|
||||
memcpy(&value_s, &value, sizeof(value_type));
|
||||
platform_fence_before_store(order);
|
||||
platform_store128(value_s, &v_);
|
||||
platform_fence_after_store(order);
|
||||
}
|
||||
|
||||
value_type
|
||||
load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
storage_type value_s = platform_load128(&v_);
|
||||
platform_fence_after_load(order);
|
||||
value_type value;
|
||||
memcpy(&value, &value_s, sizeof(value_type));
|
||||
return value;
|
||||
}
|
||||
|
||||
value_type
|
||||
exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_weak(
|
||||
value_type & expected,
|
||||
value_type const& desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_strong(
|
||||
value_type & expected,
|
||||
value_type const& desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
storage_type expected_s, desired_s;
|
||||
memset(&expected_s, 0, sizeof(expected_s));
|
||||
memset(&desired_s, 0, sizeof(desired_s));
|
||||
memcpy(&expected_s, &expected, sizeof(value_type));
|
||||
memcpy(&desired_s, &desired, sizeof(value_type));
|
||||
|
||||
platform_fence_before(success_order);
|
||||
bool success = platform_cmpxchg128_strong(expected_s, desired_s, &v_);
|
||||
|
||||
if (success) {
|
||||
platform_fence_after(success_order);
|
||||
} else {
|
||||
platform_fence_after(failure_order);
|
||||
memcpy(&expected, &expected_s, sizeof(value_type));
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free(void) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOST_ATOMIC_DECLARE_BASE_OPERATORS
|
||||
|
||||
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
|
||||
|
||||
private:
|
||||
storage_type v_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,939 +0,0 @@
|
||||
#ifndef BOOST_ATOMIC_DETAIL_CAS32STRONG_HPP
|
||||
#define BOOST_ATOMIC_DETAIL_CAS32STRONG_HPP
|
||||
|
||||
// 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
|
||||
|
||||
|
||||
// Build 8-, 16- and 32-bit atomic operations from
|
||||
// a platform_cmpxchg32_strong primitive.
|
||||
|
||||
#include <string.h>
|
||||
#include <cstddef>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/base.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
/* integral types */
|
||||
|
||||
template<typename T, bool Sign>
|
||||
class base_atomic<T, int, 1, Sign>
|
||||
{
|
||||
private:
|
||||
typedef base_atomic this_type;
|
||||
typedef T value_type;
|
||||
typedef T difference_type;
|
||||
typedef uint32_t storage_type;
|
||||
|
||||
protected:
|
||||
typedef value_type value_arg_type;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
|
||||
|
||||
void
|
||||
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_before_store(order);
|
||||
const_cast<volatile storage_type &>(v_) = v;
|
||||
platform_fence_after_store(order);
|
||||
}
|
||||
|
||||
value_type
|
||||
load(memory_order order = memory_order_seq_cst) const volatile
|
||||
{
|
||||
value_type v = const_cast<const volatile storage_type &>(v_);
|
||||
platform_fence_after_load(order);
|
||||
return v;
|
||||
}
|
||||
|
||||
value_type
|
||||
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_weak(
|
||||
value_type & expected,
|
||||
value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_strong(
|
||||
value_type & expected,
|
||||
value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_before(success_order);
|
||||
|
||||
storage_type expected_s = (storage_type) expected;
|
||||
storage_type desired_s = (storage_type) desired;
|
||||
|
||||
bool success = platform_cmpxchg32_strong(expected_s, desired_s, &v_);
|
||||
|
||||
if (success) {
|
||||
platform_fence_after(success_order);
|
||||
} else {
|
||||
platform_fence_after(failure_order);
|
||||
expected = (value_type) expected_s;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free(void) const volatile
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
|
||||
|
||||
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
|
||||
|
||||
private:
|
||||
storage_type v_;
|
||||
};
|
||||
|
||||
template<typename T, bool Sign>
|
||||
class base_atomic<T, int, 2, Sign>
|
||||
{
|
||||
private:
|
||||
typedef base_atomic this_type;
|
||||
typedef T value_type;
|
||||
typedef T difference_type;
|
||||
typedef uint32_t storage_type;
|
||||
|
||||
protected:
|
||||
typedef value_type value_arg_type;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
|
||||
|
||||
void
|
||||
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_before_store(order);
|
||||
const_cast<volatile storage_type &>(v_) = v;
|
||||
platform_fence_after_store(order);
|
||||
}
|
||||
|
||||
value_type
|
||||
load(memory_order order = memory_order_seq_cst) const volatile
|
||||
{
|
||||
value_type v = const_cast<const volatile storage_type &>(v_);
|
||||
platform_fence_after_load(order);
|
||||
return v;
|
||||
}
|
||||
|
||||
value_type
|
||||
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_weak(
|
||||
value_type & expected,
|
||||
value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_strong(
|
||||
value_type & expected,
|
||||
value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_before(success_order);
|
||||
|
||||
storage_type expected_s = (storage_type) expected;
|
||||
storage_type desired_s = (storage_type) desired;
|
||||
|
||||
bool success = platform_cmpxchg32_strong(expected_s, desired_s, &v_);
|
||||
|
||||
if (success) {
|
||||
platform_fence_after(success_order);
|
||||
} else {
|
||||
platform_fence_after(failure_order);
|
||||
expected = (value_type) expected_s;
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free(void) const volatile
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
|
||||
|
||||
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
|
||||
|
||||
private:
|
||||
storage_type v_;
|
||||
};
|
||||
|
||||
template<typename T, bool Sign>
|
||||
class base_atomic<T, int, 4, Sign>
|
||||
{
|
||||
private:
|
||||
typedef base_atomic this_type;
|
||||
typedef T value_type;
|
||||
typedef T difference_type;
|
||||
|
||||
protected:
|
||||
typedef value_type value_arg_type;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
|
||||
|
||||
void
|
||||
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_before_store(order);
|
||||
const_cast<volatile value_type &>(v_) = v;
|
||||
platform_fence_after_store(order);
|
||||
}
|
||||
|
||||
value_type
|
||||
load(memory_order order = memory_order_seq_cst) const volatile
|
||||
{
|
||||
value_type v = const_cast<const volatile value_type &>(v_);
|
||||
platform_fence_after_load(order);
|
||||
return v;
|
||||
}
|
||||
|
||||
value_type
|
||||
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_weak(
|
||||
value_type & expected,
|
||||
value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_strong(
|
||||
value_type & expected,
|
||||
value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_before(success_order);
|
||||
|
||||
bool success = platform_cmpxchg32_strong(expected, desired, &v_);
|
||||
|
||||
if (success) {
|
||||
platform_fence_after(success_order);
|
||||
} else {
|
||||
platform_fence_after(failure_order);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free(void) const volatile
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
|
||||
|
||||
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
|
||||
|
||||
private:
|
||||
value_type v_;
|
||||
};
|
||||
|
||||
/* pointer types */
|
||||
|
||||
template<bool Sign>
|
||||
class base_atomic<void *, void *, 4, Sign>
|
||||
{
|
||||
private:
|
||||
typedef base_atomic this_type;
|
||||
typedef void * value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
protected:
|
||||
typedef value_type value_arg_type;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
|
||||
|
||||
void
|
||||
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_before_store(order);
|
||||
const_cast<volatile value_type &>(v_) = v;
|
||||
platform_fence_after_store(order);
|
||||
}
|
||||
|
||||
value_type
|
||||
load(memory_order order = memory_order_seq_cst) const volatile
|
||||
{
|
||||
value_type v = const_cast<const volatile value_type &>(v_);
|
||||
platform_fence_after_load(order);
|
||||
return v;
|
||||
}
|
||||
|
||||
value_type
|
||||
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_weak(
|
||||
value_type & expected,
|
||||
value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_strong(
|
||||
value_type & expected,
|
||||
value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_before(success_order);
|
||||
|
||||
bool success = platform_cmpxchg32_strong(expected, desired, &v_);
|
||||
|
||||
if (success) {
|
||||
platform_fence_after(success_order);
|
||||
} else {
|
||||
platform_fence_after(failure_order);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, (char*)original + v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, (char*)original - v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free(void) const volatile
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
|
||||
|
||||
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
|
||||
|
||||
private:
|
||||
value_type v_;
|
||||
};
|
||||
|
||||
template<typename T, bool Sign>
|
||||
class base_atomic<T *, void *, 4, Sign>
|
||||
{
|
||||
private:
|
||||
typedef base_atomic this_type;
|
||||
typedef T * value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
protected:
|
||||
typedef value_type value_arg_type;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
|
||||
|
||||
void
|
||||
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_before_store(order);
|
||||
const_cast<volatile value_type &>(v_) = v;
|
||||
platform_fence_after_store(order);
|
||||
}
|
||||
|
||||
value_type
|
||||
load(memory_order order = memory_order_seq_cst) const volatile
|
||||
{
|
||||
value_type v = const_cast<const volatile value_type &>(v_);
|
||||
platform_fence_after_load(order);
|
||||
return v;
|
||||
}
|
||||
|
||||
value_type
|
||||
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_weak(
|
||||
value_type & expected,
|
||||
value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_strong(
|
||||
value_type & expected,
|
||||
value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_before(success_order);
|
||||
|
||||
bool success = platform_cmpxchg32_strong(expected, desired, &v_);
|
||||
|
||||
if (success) {
|
||||
platform_fence_after(success_order);
|
||||
} else {
|
||||
platform_fence_after(failure_order);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free(void) const volatile
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
|
||||
|
||||
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
|
||||
|
||||
private:
|
||||
value_type v_;
|
||||
};
|
||||
|
||||
/* generic types */
|
||||
|
||||
template<typename T, bool Sign>
|
||||
class base_atomic<T, void, 1, Sign>
|
||||
{
|
||||
private:
|
||||
typedef base_atomic this_type;
|
||||
typedef T value_type;
|
||||
typedef uint32_t storage_type;
|
||||
|
||||
protected:
|
||||
typedef value_type const& value_arg_type;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
|
||||
{
|
||||
memcpy(&v_, &v, sizeof(value_type));
|
||||
}
|
||||
|
||||
void
|
||||
store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
storage_type tmp = 0;
|
||||
memcpy(&tmp, &v, sizeof(value_type));
|
||||
platform_fence_before_store(order);
|
||||
const_cast<volatile storage_type &>(v_) = tmp;
|
||||
platform_fence_after_store(order);
|
||||
}
|
||||
|
||||
value_type
|
||||
load(memory_order order = memory_order_seq_cst) const volatile
|
||||
{
|
||||
storage_type tmp = const_cast<const volatile storage_type &>(v_);
|
||||
platform_fence_after_load(order);
|
||||
|
||||
value_type v;
|
||||
memcpy(&v, &tmp, sizeof(value_type));
|
||||
return v;
|
||||
}
|
||||
|
||||
value_type
|
||||
exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_weak(
|
||||
value_type & expected,
|
||||
value_type const& desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_strong(
|
||||
value_type & expected,
|
||||
value_type const& desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
storage_type expected_s = 0, desired_s = 0;
|
||||
memcpy(&expected_s, &expected, sizeof(value_type));
|
||||
memcpy(&desired_s, &desired, sizeof(value_type));
|
||||
|
||||
platform_fence_before(success_order);
|
||||
bool success = platform_cmpxchg32_strong(expected_s, desired_s, &v_);
|
||||
|
||||
if (success) {
|
||||
platform_fence_after(success_order);
|
||||
} else {
|
||||
platform_fence_after(failure_order);
|
||||
memcpy(&expected, &expected_s, sizeof(value_type));
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free(void) const volatile
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOST_ATOMIC_DECLARE_BASE_OPERATORS
|
||||
|
||||
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
|
||||
|
||||
private:
|
||||
storage_type v_;
|
||||
};
|
||||
|
||||
template<typename T, bool Sign>
|
||||
class base_atomic<T, void, 2, Sign>
|
||||
{
|
||||
private:
|
||||
typedef base_atomic this_type;
|
||||
typedef T value_type;
|
||||
typedef uint32_t storage_type;
|
||||
|
||||
protected:
|
||||
typedef value_type const& value_arg_type;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
|
||||
{
|
||||
memcpy(&v_, &v, sizeof(value_type));
|
||||
}
|
||||
|
||||
void
|
||||
store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
storage_type tmp = 0;
|
||||
memcpy(&tmp, &v, sizeof(value_type));
|
||||
platform_fence_before_store(order);
|
||||
const_cast<volatile storage_type &>(v_) = tmp;
|
||||
platform_fence_after_store(order);
|
||||
}
|
||||
|
||||
value_type
|
||||
load(memory_order order = memory_order_seq_cst) const volatile
|
||||
{
|
||||
storage_type tmp = const_cast<const volatile storage_type &>(v_);
|
||||
platform_fence_after_load(order);
|
||||
|
||||
value_type v;
|
||||
memcpy(&v, &tmp, sizeof(value_type));
|
||||
return v;
|
||||
}
|
||||
|
||||
value_type
|
||||
exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_weak(
|
||||
value_type & expected,
|
||||
value_type const& desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_strong(
|
||||
value_type & expected,
|
||||
value_type const& desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
|
||||
storage_type expected_s = 0, desired_s = 0;
|
||||
memcpy(&expected_s, &expected, sizeof(value_type));
|
||||
memcpy(&desired_s, &desired, sizeof(value_type));
|
||||
|
||||
platform_fence_before(success_order);
|
||||
bool success = platform_cmpxchg32_strong(expected_s, desired_s, &v_);
|
||||
|
||||
if (success) {
|
||||
platform_fence_after(success_order);
|
||||
} else {
|
||||
platform_fence_after(failure_order);
|
||||
memcpy(&expected, &expected_s, sizeof(value_type));
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free(void) const volatile
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOST_ATOMIC_DECLARE_BASE_OPERATORS
|
||||
|
||||
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
|
||||
|
||||
private:
|
||||
storage_type v_;
|
||||
};
|
||||
|
||||
template<typename T, bool Sign>
|
||||
class base_atomic<T, void, 4, Sign>
|
||||
{
|
||||
private:
|
||||
typedef base_atomic this_type;
|
||||
typedef T value_type;
|
||||
typedef uint32_t storage_type;
|
||||
|
||||
protected:
|
||||
typedef value_type const& value_arg_type;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
|
||||
{
|
||||
memcpy(&v_, &v, sizeof(value_type));
|
||||
}
|
||||
|
||||
void
|
||||
store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
storage_type tmp = 0;
|
||||
memcpy(&tmp, &v, sizeof(value_type));
|
||||
platform_fence_before_store(order);
|
||||
const_cast<volatile storage_type &>(v_) = tmp;
|
||||
platform_fence_after_store(order);
|
||||
}
|
||||
|
||||
value_type
|
||||
load(memory_order order = memory_order_seq_cst) const volatile
|
||||
{
|
||||
storage_type tmp = const_cast<const volatile storage_type &>(v_);
|
||||
platform_fence_after_load(order);
|
||||
|
||||
value_type v;
|
||||
memcpy(&v, &tmp, sizeof(value_type));
|
||||
return v;
|
||||
}
|
||||
|
||||
value_type
|
||||
exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_weak(
|
||||
value_type & expected,
|
||||
value_type const& desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_strong(
|
||||
value_type & expected,
|
||||
value_type const& desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
|
||||
storage_type expected_s = 0, desired_s = 0;
|
||||
memcpy(&expected_s, &expected, sizeof(value_type));
|
||||
memcpy(&desired_s, &desired, sizeof(value_type));
|
||||
|
||||
platform_fence_before(success_order);
|
||||
bool success = platform_cmpxchg32_strong(expected_s, desired_s, &v_);
|
||||
|
||||
if (success) {
|
||||
platform_fence_after(success_order);
|
||||
} else {
|
||||
platform_fence_after(failure_order);
|
||||
memcpy(&expected, &expected_s, sizeof(value_type));
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free(void) const volatile
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOST_ATOMIC_DECLARE_BASE_OPERATORS
|
||||
|
||||
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
|
||||
|
||||
private:
|
||||
storage_type v_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,247 +0,0 @@
|
||||
#ifndef BOOST_ATOMIC_DETAIL_CAS64STRONG_PTR_HPP
|
||||
#define BOOST_ATOMIC_DETAIL_CAS64STRONG_PTR_HPP
|
||||
|
||||
// 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
|
||||
|
||||
// Build 64-bit atomic operation on pointers from platform_cmpxchg64_strong
|
||||
// primitive. It is assumed that 64-bit loads/stores are not
|
||||
// atomic, so they are implemented through platform_load64/platform_store64.
|
||||
//
|
||||
// The reason for extracting pointer specializations to a separate header is
|
||||
// that 64-bit CAS is available on some 32-bit platforms (notably, x86).
|
||||
// On these platforms there is no need for 64-bit pointer specializations,
|
||||
// since they will never be used.
|
||||
|
||||
#include <string.h>
|
||||
#include <cstddef>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/base.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
/* pointer types */
|
||||
|
||||
template<bool Sign>
|
||||
class base_atomic<void *, void *, 8, Sign>
|
||||
{
|
||||
private:
|
||||
typedef base_atomic this_type;
|
||||
typedef void * value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
protected:
|
||||
typedef value_type value_arg_type;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
|
||||
|
||||
void
|
||||
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_before_store(order);
|
||||
platform_store64(v, &v_);
|
||||
platform_fence_after_store(order);
|
||||
}
|
||||
|
||||
value_type
|
||||
load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type v = platform_load64(&v_);
|
||||
platform_fence_after_load(order);
|
||||
return v;
|
||||
}
|
||||
|
||||
value_type
|
||||
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_weak(
|
||||
value_type & expected,
|
||||
value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_strong(
|
||||
value_type & expected,
|
||||
value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_before(success_order);
|
||||
|
||||
bool success = platform_cmpxchg64_strong(expected, desired, &v_);
|
||||
|
||||
if (success) {
|
||||
platform_fence_after(success_order);
|
||||
} else {
|
||||
platform_fence_after(failure_order);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, (char*)original + v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, (char*)original - v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free(void) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
|
||||
|
||||
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
|
||||
|
||||
private:
|
||||
value_type v_;
|
||||
};
|
||||
|
||||
template<typename T, bool Sign>
|
||||
class base_atomic<T *, void *, 8, Sign>
|
||||
{
|
||||
private:
|
||||
typedef base_atomic this_type;
|
||||
typedef T * value_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
protected:
|
||||
typedef value_type value_arg_type;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
|
||||
|
||||
void
|
||||
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_before_store(order);
|
||||
platform_store64(v, &v_);
|
||||
platform_fence_after_store(order);
|
||||
}
|
||||
|
||||
value_type
|
||||
load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type v = platform_load64(&v_);
|
||||
platform_fence_after_load(order);
|
||||
return v;
|
||||
}
|
||||
|
||||
value_type
|
||||
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_weak(
|
||||
value_type & expected,
|
||||
value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_strong(
|
||||
value_type & expected,
|
||||
value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_before(success_order);
|
||||
|
||||
bool success = platform_cmpxchg64_strong(expected, desired, &v_);
|
||||
|
||||
if (success) {
|
||||
platform_fence_after(success_order);
|
||||
} else {
|
||||
platform_fence_after(failure_order);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free(void) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
|
||||
|
||||
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
|
||||
|
||||
private:
|
||||
value_type v_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,264 +0,0 @@
|
||||
#ifndef BOOST_ATOMIC_DETAIL_CAS64STRONG_HPP
|
||||
#define BOOST_ATOMIC_DETAIL_CAS64STRONG_HPP
|
||||
|
||||
// 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
|
||||
|
||||
// Build 64-bit atomic operation on integers/UDTs from platform_cmpxchg64_strong
|
||||
// primitive. It is assumed that 64-bit loads/stores are not
|
||||
// atomic, so they are implemented through platform_load64/platform_store64.
|
||||
|
||||
#include <string.h>
|
||||
#include <cstddef>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/base.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
/* integral types */
|
||||
|
||||
template<typename T, bool Sign>
|
||||
class base_atomic<T, int, 8, Sign>
|
||||
{
|
||||
private:
|
||||
typedef base_atomic this_type;
|
||||
typedef T value_type;
|
||||
typedef T difference_type;
|
||||
|
||||
protected:
|
||||
typedef value_type value_arg_type;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
|
||||
|
||||
void
|
||||
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_before_store(order);
|
||||
platform_store64(v, &v_);
|
||||
platform_fence_after_store(order);
|
||||
}
|
||||
|
||||
value_type
|
||||
load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type v = platform_load64(&v_);
|
||||
platform_fence_after_load(order);
|
||||
return v;
|
||||
}
|
||||
|
||||
value_type
|
||||
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_weak(
|
||||
value_type & expected,
|
||||
value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_strong(
|
||||
value_type & expected,
|
||||
value_type desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_before(success_order);
|
||||
|
||||
bool success = platform_cmpxchg64_strong(expected, desired, &v_);
|
||||
|
||||
if (success) {
|
||||
platform_fence_after(success_order);
|
||||
} else {
|
||||
platform_fence_after(failure_order);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
value_type
|
||||
fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free(void) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
|
||||
|
||||
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
|
||||
|
||||
private:
|
||||
value_type v_;
|
||||
};
|
||||
|
||||
/* generic types */
|
||||
|
||||
template<typename T, bool Sign>
|
||||
class base_atomic<T, void, 8, Sign>
|
||||
{
|
||||
private:
|
||||
typedef base_atomic this_type;
|
||||
typedef T value_type;
|
||||
typedef uint64_t storage_type;
|
||||
|
||||
protected:
|
||||
typedef value_type const& value_arg_type;
|
||||
|
||||
public:
|
||||
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
|
||||
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
|
||||
{
|
||||
memcpy(&v_, &v, sizeof(value_type));
|
||||
}
|
||||
|
||||
void
|
||||
store(value_type const& value, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
storage_type value_s = 0;
|
||||
memcpy(&value_s, &value, sizeof(value_type));
|
||||
platform_fence_before_store(order);
|
||||
platform_store64(value_s, &v_);
|
||||
platform_fence_after_store(order);
|
||||
}
|
||||
|
||||
value_type
|
||||
load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
storage_type value_s = platform_load64(&v_);
|
||||
platform_fence_after_load(order);
|
||||
value_type value;
|
||||
memcpy(&value, &value_s, sizeof(value_type));
|
||||
return value;
|
||||
}
|
||||
|
||||
value_type
|
||||
exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
value_type original = load(memory_order_relaxed);
|
||||
do {
|
||||
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
|
||||
return original;
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_weak(
|
||||
value_type & expected,
|
||||
value_type const& desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
||||
}
|
||||
|
||||
bool
|
||||
compare_exchange_strong(
|
||||
value_type & expected,
|
||||
value_type const& desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
storage_type expected_s = 0, desired_s = 0;
|
||||
memcpy(&expected_s, &expected, sizeof(value_type));
|
||||
memcpy(&desired_s, &desired, sizeof(value_type));
|
||||
|
||||
platform_fence_before(success_order);
|
||||
bool success = platform_cmpxchg64_strong(expected_s, desired_s, &v_);
|
||||
|
||||
if (success) {
|
||||
platform_fence_after(success_order);
|
||||
} else {
|
||||
platform_fence_after(failure_order);
|
||||
memcpy(&expected, &expected_s, sizeof(value_type));
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
bool
|
||||
is_lock_free(void) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
BOOST_ATOMIC_DECLARE_BASE_OPERATORS
|
||||
|
||||
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
|
||||
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
|
||||
|
||||
private:
|
||||
storage_type v_;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,368 +0,0 @@
|
||||
#ifndef BOOST_ATOMIC_DETAIL_GCC_ALPHA_HPP
|
||||
#define BOOST_ATOMIC_DETAIL_GCC_ALPHA_HPP
|
||||
|
||||
// Copyright (c) 2009 Helge Bahmann
|
||||
// Copyright (c) 2013 Tim Blechmann
|
||||
//
|
||||
// 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/atomic/detail/base.hpp>
|
||||
#include <boost/atomic/detail/builder.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
/*
|
||||
Refer to http://h71000.www7.hp.com/doc/82final/5601/5601pro_004.html
|
||||
(HP OpenVMS systems documentation) and the alpha reference manual.
|
||||
*/
|
||||
|
||||
/*
|
||||
NB: The most natural thing would be to write the increment/decrement
|
||||
operators along the following lines:
|
||||
|
||||
__asm__ __volatile__(
|
||||
"1: ldl_l %0,%1 \n"
|
||||
"addl %0,1,%0 \n"
|
||||
"stl_c %0,%1 \n"
|
||||
"beq %0,1b\n"
|
||||
: "=&b" (tmp)
|
||||
: "m" (value)
|
||||
: "cc"
|
||||
);
|
||||
|
||||
However according to the comments on the HP website and matching
|
||||
comments in the Linux kernel sources this defies branch prediction,
|
||||
as the cpu assumes that backward branches are always taken; so
|
||||
instead copy the trick from the Linux kernel, introduce a forward
|
||||
branch and back again.
|
||||
|
||||
I have, however, had a hard time measuring the difference between
|
||||
the two versions in microbenchmarks -- I am leaving it in nevertheless
|
||||
as it apparently does not hurt either.
|
||||
*/
|
||||
|
||||
namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
inline void fence_before(memory_order order)
|
||||
{
|
||||
switch(order) {
|
||||
case memory_order_consume:
|
||||
case memory_order_release:
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
__asm__ __volatile__ ("mb" ::: "memory");
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
inline void fence_after(memory_order order)
|
||||
{
|
||||
switch(order) {
|
||||
case memory_order_acquire:
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
__asm__ __volatile__ ("mb" ::: "memory");
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
template<>
|
||||
inline void platform_atomic_thread_fence(memory_order order)
|
||||
{
|
||||
switch(order) {
|
||||
case memory_order_acquire:
|
||||
case memory_order_consume:
|
||||
case memory_order_release:
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
__asm__ __volatile__ ("mb" ::: "memory");
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
class atomic_alpha_32
|
||||
{
|
||||
public:
|
||||
typedef T integral_type;
|
||||
BOOST_CONSTEXPR atomic_alpha_32(T v) BOOST_NOEXCEPT: i(v) {}
|
||||
atomic_alpha_32() {}
|
||||
T load(memory_order order=memory_order_seq_cst) const volatile BOOST_NOEXCEPT
|
||||
{
|
||||
T v=*reinterpret_cast<volatile const int *>(&i);
|
||||
fence_after(order);
|
||||
return v;
|
||||
}
|
||||
void store(T v, memory_order order=memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
fence_before(order);
|
||||
*reinterpret_cast<volatile int *>(&i)=(int)v;
|
||||
}
|
||||
bool compare_exchange_weak(
|
||||
T &expected,
|
||||
T desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
fence_before(success_order);
|
||||
int current, success;
|
||||
__asm__ __volatile__(
|
||||
"1: ldl_l %2, %4\n"
|
||||
"cmpeq %2, %0, %3\n"
|
||||
"mov %2, %0\n"
|
||||
"beq %3, 3f\n"
|
||||
"stl_c %1, %4\n"
|
||||
"2:\n"
|
||||
|
||||
".subsection 2\n"
|
||||
"3: mov %3, %1\n"
|
||||
"br 2b\n"
|
||||
".previous\n"
|
||||
|
||||
: "+&r" (expected), "+&r" (desired), "=&r"(current), "=&r"(success)
|
||||
: "m" (i)
|
||||
:
|
||||
);
|
||||
if (desired) fence_after(success_order);
|
||||
else fence_after(failure_order);
|
||||
return desired;
|
||||
}
|
||||
|
||||
bool is_lock_free(void) const volatile BOOST_NOEXCEPT {return true;}
|
||||
protected:
|
||||
inline T fetch_add_var(T c, memory_order order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
fence_before(order);
|
||||
T original, modified;
|
||||
__asm__ __volatile__(
|
||||
"1: ldl_l %0, %2\n"
|
||||
"addl %0, %3, %1\n"
|
||||
"stl_c %1, %2\n"
|
||||
"beq %1, 2f\n"
|
||||
|
||||
".subsection 2\n"
|
||||
"2: br 1b\n"
|
||||
".previous\n"
|
||||
|
||||
: "=&r" (original), "=&r" (modified)
|
||||
: "m" (i), "r" (c)
|
||||
:
|
||||
);
|
||||
fence_after(order);
|
||||
return original;
|
||||
}
|
||||
inline T fetch_inc(memory_order order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
fence_before(order);
|
||||
int original, modified;
|
||||
__asm__ __volatile__(
|
||||
"1: ldl_l %0, %2\n"
|
||||
"addl %0, 1, %1\n"
|
||||
"stl_c %1, %2\n"
|
||||
"beq %1, 2f\n"
|
||||
|
||||
".subsection 2\n"
|
||||
"2: br 1b\n"
|
||||
".previous\n"
|
||||
|
||||
: "=&r" (original), "=&r" (modified)
|
||||
: "m" (i)
|
||||
:
|
||||
);
|
||||
fence_after(order);
|
||||
return original;
|
||||
}
|
||||
inline T fetch_dec(memory_order order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
fence_before(order);
|
||||
int original, modified;
|
||||
__asm__ __volatile__(
|
||||
"1: ldl_l %0, %2\n"
|
||||
"subl %0, 1, %1\n"
|
||||
"stl_c %1, %2\n"
|
||||
"beq %1, 2f\n"
|
||||
|
||||
".subsection 2\n"
|
||||
"2: br 1b\n"
|
||||
".previous\n"
|
||||
|
||||
: "=&r" (original), "=&r" (modified)
|
||||
: "m" (i)
|
||||
:
|
||||
);
|
||||
fence_after(order);
|
||||
return original;
|
||||
}
|
||||
private:
|
||||
T i;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class atomic_alpha_64
|
||||
{
|
||||
public:
|
||||
typedef T integral_type;
|
||||
BOOST_CONSTEXPR atomic_alpha_64(T v) BOOST_NOEXCEPT: i(v) {}
|
||||
atomic_alpha_64() {}
|
||||
T load(memory_order order=memory_order_seq_cst) const volatile
|
||||
{
|
||||
T v=*reinterpret_cast<volatile const T *>(&i);
|
||||
fence_after(order);
|
||||
return v;
|
||||
}
|
||||
void store(T v, memory_order order=memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
fence_before(order);
|
||||
*reinterpret_cast<volatile T *>(&i)=v;
|
||||
}
|
||||
bool compare_exchange_weak(
|
||||
T &expected,
|
||||
T desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
fence_before(success_order);
|
||||
int current, success;
|
||||
__asm__ __volatile__(
|
||||
"1: ldq_l %2, %4\n"
|
||||
"cmpeq %2, %0, %3\n"
|
||||
"mov %2, %0\n"
|
||||
"beq %3, 3f\n"
|
||||
"stq_c %1, %4\n"
|
||||
"2:\n"
|
||||
|
||||
".subsection 2\n"
|
||||
"3: mov %3, %1\n"
|
||||
"br 2b\n"
|
||||
".previous\n"
|
||||
|
||||
: "+&r" (expected), "+&r" (desired), "=&r"(current), "=&r"(success)
|
||||
: "m" (i)
|
||||
:
|
||||
);
|
||||
if (desired) fence_after(success_order);
|
||||
else fence_after(failure_order);
|
||||
return desired;
|
||||
}
|
||||
|
||||
bool is_lock_free(void) const volatile BOOST_NOEXCEPT {return true;}
|
||||
protected:
|
||||
inline T fetch_add_var(T c, memory_order order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
fence_before(order);
|
||||
T original, modified;
|
||||
__asm__ __volatile__(
|
||||
"1: ldq_l %0, %2\n"
|
||||
"addq %0, %3, %1\n"
|
||||
"stq_c %1, %2\n"
|
||||
"beq %1, 2f\n"
|
||||
|
||||
".subsection 2\n"
|
||||
"2: br 1b\n"
|
||||
".previous\n"
|
||||
|
||||
: "=&r" (original), "=&r" (modified)
|
||||
: "m" (i), "r" (c)
|
||||
:
|
||||
);
|
||||
fence_after(order);
|
||||
return original;
|
||||
}
|
||||
inline T fetch_inc(memory_order order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
fence_before(order);
|
||||
T original, modified;
|
||||
__asm__ __volatile__(
|
||||
"1: ldq_l %0, %2\n"
|
||||
"addq %0, 1, %1\n"
|
||||
"stq_c %1, %2\n"
|
||||
"beq %1, 2f\n"
|
||||
|
||||
".subsection 2\n"
|
||||
"2: br 1b\n"
|
||||
".previous\n"
|
||||
|
||||
: "=&r" (original), "=&r" (modified)
|
||||
: "m" (i)
|
||||
:
|
||||
);
|
||||
fence_after(order);
|
||||
return original;
|
||||
}
|
||||
inline T fetch_dec(memory_order order) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
fence_before(order);
|
||||
T original, modified;
|
||||
__asm__ __volatile__(
|
||||
"1: ldq_l %0, %2\n"
|
||||
"subq %0, 1, %1\n"
|
||||
"stq_c %1, %2\n"
|
||||
"beq %1, 2f\n"
|
||||
|
||||
".subsection 2\n"
|
||||
"2: br 1b\n"
|
||||
".previous\n"
|
||||
|
||||
: "=&r" (original), "=&r" (modified)
|
||||
: "m" (i)
|
||||
:
|
||||
);
|
||||
fence_after(order);
|
||||
return original;
|
||||
}
|
||||
private:
|
||||
T i;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class platform_atomic_integral<T, 4> :
|
||||
public build_atomic_from_typical<build_exchange<atomic_alpha_32<T> > >
|
||||
{
|
||||
public:
|
||||
typedef build_atomic_from_typical<build_exchange<atomic_alpha_32<T> > > super;
|
||||
BOOST_CONSTEXPR platform_atomic_integral(T v) BOOST_NOEXCEPT: super(v) {}
|
||||
platform_atomic_integral(void) {}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class platform_atomic_integral<T, 8> :
|
||||
public build_atomic_from_typical<build_exchange<atomic_alpha_64<T> > >
|
||||
{
|
||||
public:
|
||||
typedef build_atomic_from_typical<build_exchange<atomic_alpha_64<T> > > super;
|
||||
BOOST_CONSTEXPR platform_atomic_integral(T v) BOOST_NOEXCEPT: super(v) {}
|
||||
platform_atomic_integral(void) {}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class platform_atomic_integral<T, 1> :
|
||||
public build_atomic_from_larger_type<atomic_alpha_32<uint32_t>, T>
|
||||
{
|
||||
public:
|
||||
typedef build_atomic_from_larger_type<atomic_alpha_32<uint32_t>, T> super;
|
||||
BOOST_CONSTEXPR platform_atomic_integral(T v) BOOST_NOEXCEPT: super(v) {}
|
||||
platform_atomic_integral(void) {}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class platform_atomic_integral<T, 2> :
|
||||
public build_atomic_from_larger_type<atomic_alpha_32<uint32_t>, T>
|
||||
{
|
||||
public:
|
||||
typedef build_atomic_from_larger_type<atomic_alpha_32<uint32_t>, T> super;
|
||||
BOOST_CONSTEXPR platform_atomic_integral(T v) BOOST_NOEXCEPT: super(v) {}
|
||||
platform_atomic_integral(void) {}
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,255 +0,0 @@
|
||||
#ifndef BOOST_ATOMIC_DETAIL_GCC_ARMV6PLUS_HPP
|
||||
#define BOOST_ATOMIC_DETAIL_GCC_ARMV6PLUS_HPP
|
||||
|
||||
// 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) 2009 Phil Endecott
|
||||
// Copyright (c) 2013 Tim Blechmann
|
||||
// ARM Code by Phil Endecott, based on other architectures.
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
// From the ARM Architecture Reference Manual for architecture v6:
|
||||
//
|
||||
// LDREX{<cond>} <Rd>, [<Rn>]
|
||||
// <Rd> Specifies the destination register for the memory word addressed by <Rd>
|
||||
// <Rn> Specifies the register containing the address.
|
||||
//
|
||||
// STREX{<cond>} <Rd>, <Rm>, [<Rn>]
|
||||
// <Rd> Specifies the destination register for the returned status value.
|
||||
// 0 if the operation updates memory
|
||||
// 1 if the operation fails to update memory
|
||||
// <Rm> Specifies the register containing the word to be stored to memory.
|
||||
// <Rn> Specifies the register containing the address.
|
||||
// Rd must not be the same register as Rm or Rn.
|
||||
//
|
||||
// ARM v7 is like ARM v6 plus:
|
||||
// There are half-word and byte versions of the LDREX and STREX instructions,
|
||||
// LDREXH, LDREXB, STREXH and STREXB.
|
||||
// There are also double-word versions, LDREXD and STREXD.
|
||||
// (Actually it looks like these are available from version 6k onwards.)
|
||||
// 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.
|
||||
//
|
||||
// A memory barrier is effected using a "co-processor 15" instruction,
|
||||
// though a separate assembler mnemonic is available for it in v7.
|
||||
|
||||
namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
// "Thumb 1" is a subset of the ARM instruction set that uses a 16-bit encoding. It
|
||||
// doesn't include all instructions and in particular it doesn't include the co-processor
|
||||
// instruction used for the memory barrier or the load-locked/store-conditional
|
||||
// instructions. So, if we're compiling in "Thumb 1" mode, we need to wrap all of our
|
||||
// asm blocks with code to temporarily change to ARM mode.
|
||||
//
|
||||
// You can only change between ARM and Thumb modes when branching using the bx instruction.
|
||||
// bx takes an address specified in a register. The least significant bit of the address
|
||||
// indicates the mode, so 1 is added to indicate that the destination code is Thumb.
|
||||
// A temporary register is needed for the address and is passed as an argument to these
|
||||
// macros. It must be one of the "low" registers accessible to Thumb code, specified
|
||||
// using the "l" attribute in the asm statement.
|
||||
//
|
||||
// Architecture v7 introduces "Thumb 2", which does include (almost?) all of the ARM
|
||||
// instruction set. So in v7 we don't need to change to ARM mode; we can write "universal
|
||||
// assembler" which will assemble to Thumb 2 or ARM code as appropriate. The only thing
|
||||
// we need to do to make this "universal" assembler mode work is to insert "IT" instructions
|
||||
// to annotate the conditional instructions. These are ignored in other modes (e.g. v6),
|
||||
// so they can always be present.
|
||||
|
||||
#if defined(__thumb__) && !defined(__thumb2__)
|
||||
#define BOOST_ATOMIC_ARM_ASM_START(TMPREG) "adr " #TMPREG ", 1f\n" "bx " #TMPREG "\n" ".arm\n" ".align 4\n" "1: "
|
||||
#define BOOST_ATOMIC_ARM_ASM_END(TMPREG) "adr " #TMPREG ", 1f + 1\n" "bx " #TMPREG "\n" ".thumb\n" ".align 2\n" "1: "
|
||||
#else
|
||||
// The tmpreg is wasted in this case, which is non-optimal.
|
||||
#define BOOST_ATOMIC_ARM_ASM_START(TMPREG)
|
||||
#define BOOST_ATOMIC_ARM_ASM_END(TMPREG)
|
||||
#endif
|
||||
|
||||
#if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)
|
||||
#define BOOST_ATOMIC_ARM_DMB "dmb\n"
|
||||
#else
|
||||
#define BOOST_ATOMIC_ARM_DMB "mcr\tp15, 0, r0, c7, c10, 5\n"
|
||||
#endif
|
||||
|
||||
inline void
|
||||
arm_barrier(void) BOOST_NOEXCEPT
|
||||
{
|
||||
int brtmp;
|
||||
__asm__ __volatile__
|
||||
(
|
||||
BOOST_ATOMIC_ARM_ASM_START(%0)
|
||||
BOOST_ATOMIC_ARM_DMB
|
||||
BOOST_ATOMIC_ARM_ASM_END(%0)
|
||||
: "=&l" (brtmp) :: "memory"
|
||||
);
|
||||
}
|
||||
|
||||
inline void
|
||||
platform_fence_before(memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch(order)
|
||||
{
|
||||
case memory_order_release:
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
arm_barrier();
|
||||
case memory_order_consume:
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
platform_fence_after(memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
switch(order)
|
||||
{
|
||||
case memory_order_acquire:
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
arm_barrier();
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
platform_fence_before_store(memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_before(order);
|
||||
}
|
||||
|
||||
inline void
|
||||
platform_fence_after_store(memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
if (order == memory_order_seq_cst)
|
||||
arm_barrier();
|
||||
}
|
||||
|
||||
inline void
|
||||
platform_fence_after_load(memory_order order) BOOST_NOEXCEPT
|
||||
{
|
||||
platform_fence_after(order);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool
|
||||
platform_cmpxchg32(T & expected, T desired, volatile T * ptr) BOOST_NOEXCEPT
|
||||
{
|
||||
int success;
|
||||
int tmp;
|
||||
__asm__ __volatile__
|
||||
(
|
||||
BOOST_ATOMIC_ARM_ASM_START(%2)
|
||||
"mov %1, #0\n" // success = 0
|
||||
"ldrex %0, %3\n" // expected' = *(&i)
|
||||
"teq %0, %4\n" // flags = expected'==expected
|
||||
"ittt eq\n"
|
||||
"strexeq %2, %5, %3\n" // if (flags.equal) *(&i) = desired, tmp = !OK
|
||||
"teqeq %2, #0\n" // if (flags.equal) flags = tmp==0
|
||||
"moveq %1, #1\n" // if (flags.equal) success = 1
|
||||
BOOST_ATOMIC_ARM_ASM_END(%2)
|
||||
: "=&r" (expected), // %0
|
||||
"=&r" (success), // %1
|
||||
"=&l" (tmp), // %2
|
||||
"+Q" (*ptr) // %3
|
||||
: "r" (expected), // %4
|
||||
"r" (desired) // %5
|
||||
: "cc"
|
||||
);
|
||||
return success;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#define BOOST_ATOMIC_THREAD_FENCE 2
|
||||
inline void
|
||||
atomic_thread_fence(memory_order order)
|
||||
{
|
||||
switch(order)
|
||||
{
|
||||
case memory_order_acquire:
|
||||
case memory_order_release:
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
atomics::detail::arm_barrier();
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
#define BOOST_ATOMIC_SIGNAL_FENCE 2
|
||||
inline void
|
||||
atomic_signal_fence(memory_order)
|
||||
{
|
||||
__asm__ __volatile__ ("" ::: "memory");
|
||||
}
|
||||
|
||||
class atomic_flag
|
||||
{
|
||||
private:
|
||||
uint32_t v_;
|
||||
|
||||
public:
|
||||
BOOST_CONSTEXPR atomic_flag(void) BOOST_NOEXCEPT : v_(0) {}
|
||||
|
||||
void
|
||||
clear(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
atomics::detail::platform_fence_before_store(order);
|
||||
const_cast<volatile uint32_t &>(v_) = 0;
|
||||
atomics::detail::platform_fence_after_store(order);
|
||||
}
|
||||
|
||||
bool
|
||||
test_and_set(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
atomics::detail::platform_fence_before(order);
|
||||
uint32_t expected = v_;
|
||||
do {
|
||||
if (expected == 1)
|
||||
break;
|
||||
} while (!atomics::detail::platform_cmpxchg32(expected, (uint32_t)1, &v_));
|
||||
atomics::detail::platform_fence_after(order);
|
||||
return expected;
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(atomic_flag(const atomic_flag &))
|
||||
BOOST_DELETED_FUNCTION(atomic_flag& operator=(const atomic_flag &))
|
||||
};
|
||||
|
||||
#define BOOST_ATOMIC_FLAG_LOCK_FREE 2
|
||||
|
||||
}
|
||||
|
||||
#undef BOOST_ATOMIC_ARM_ASM_START
|
||||
#undef BOOST_ATOMIC_ARM_ASM_END
|
||||
|
||||
#include <boost/atomic/detail/base.hpp>
|
||||
|
||||
#if !defined(BOOST_ATOMIC_FORCE_FALLBACK)
|
||||
|
||||
#define BOOST_ATOMIC_CHAR_LOCK_FREE 2
|
||||
#define BOOST_ATOMIC_CHAR16_T_LOCK_FREE 2
|
||||
#define BOOST_ATOMIC_CHAR32_T_LOCK_FREE 2
|
||||
#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 2
|
||||
#define BOOST_ATOMIC_SHORT_LOCK_FREE 2
|
||||
#define BOOST_ATOMIC_INT_LOCK_FREE 2
|
||||
#define BOOST_ATOMIC_LONG_LOCK_FREE 2
|
||||
#define BOOST_ATOMIC_LLONG_LOCK_FREE 0
|
||||
#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
|
||||
#define BOOST_ATOMIC_BOOL_LOCK_FREE 2
|
||||
|
||||
#include <boost/atomic/detail/cas32weak.hpp>
|
||||
|
||||
#endif /* !defined(BOOST_ATOMIC_FORCE_FALLBACK) */
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,163 +0,0 @@
|
||||
// Copyright (c) 2011 Helge Bahmann
|
||||
// Copyright (c) 2013 Tim Blechmann
|
||||
//
|
||||
// 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)
|
||||
|
||||
// Use the gnu builtin __sync_val_compare_and_swap to build
|
||||
// atomic operations for 32 bit and smaller.
|
||||
|
||||
#ifndef BOOST_ATOMIC_DETAIL_GENERIC_CAS_HPP
|
||||
#define BOOST_ATOMIC_DETAIL_GENERIC_CAS_HPP
|
||||
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
|
||||
#define BOOST_ATOMIC_THREAD_FENCE 2
|
||||
inline void
|
||||
atomic_thread_fence(memory_order order)
|
||||
{
|
||||
switch(order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
break;
|
||||
case memory_order_release:
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
__sync_synchronize();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
inline void
|
||||
platform_fence_before(memory_order)
|
||||
{
|
||||
/* empty, as compare_and_swap is synchronizing already */
|
||||
}
|
||||
|
||||
inline void
|
||||
platform_fence_after(memory_order)
|
||||
{
|
||||
/* empty, as compare_and_swap is synchronizing already */
|
||||
}
|
||||
|
||||
inline void
|
||||
platform_fence_before_store(memory_order order)
|
||||
{
|
||||
switch(order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
case memory_order_acquire:
|
||||
case memory_order_consume:
|
||||
break;
|
||||
case memory_order_release:
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
__sync_synchronize();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
platform_fence_after_store(memory_order order)
|
||||
{
|
||||
if (order == memory_order_seq_cst)
|
||||
__sync_synchronize();
|
||||
}
|
||||
|
||||
inline void
|
||||
platform_fence_after_load(memory_order order)
|
||||
{
|
||||
switch(order)
|
||||
{
|
||||
case memory_order_relaxed:
|
||||
case memory_order_release:
|
||||
break;
|
||||
case memory_order_consume:
|
||||
case memory_order_acquire:
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
__sync_synchronize();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool
|
||||
platform_cmpxchg32_strong(T & expected, T desired, volatile T * ptr)
|
||||
{
|
||||
T found = __sync_val_compare_and_swap(ptr, expected, desired);
|
||||
bool success = (found == expected);
|
||||
expected = found;
|
||||
return success;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
class atomic_flag
|
||||
{
|
||||
private:
|
||||
uint32_t v_;
|
||||
|
||||
public:
|
||||
BOOST_CONSTEXPR atomic_flag(void) BOOST_NOEXCEPT : v_(0) {}
|
||||
|
||||
void
|
||||
clear(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
atomics::detail::platform_fence_before_store(order);
|
||||
const_cast<volatile uint32_t &>(v_) = 0;
|
||||
atomics::detail::platform_fence_after_store(order);
|
||||
}
|
||||
|
||||
bool
|
||||
test_and_set(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
atomics::detail::platform_fence_before(order);
|
||||
uint32_t expected = v_;
|
||||
do {
|
||||
if (expected == 1)
|
||||
break;
|
||||
} while (!atomics::detail::platform_cmpxchg32_strong(expected, (uint32_t)1, &v_));
|
||||
atomics::detail::platform_fence_after(order);
|
||||
return expected;
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(atomic_flag(atomic_flag const&))
|
||||
BOOST_DELETED_FUNCTION(atomic_flag& operator= (atomic_flag const&))
|
||||
};
|
||||
|
||||
#define BOOST_ATOMIC_FLAG_LOCK_FREE 2
|
||||
|
||||
}
|
||||
|
||||
#include <boost/atomic/detail/base.hpp>
|
||||
|
||||
#if !defined(BOOST_ATOMIC_FORCE_FALLBACK)
|
||||
|
||||
#define BOOST_ATOMIC_CHAR_LOCK_FREE 2
|
||||
#define BOOST_ATOMIC_SHORT_LOCK_FREE 2
|
||||
#define BOOST_ATOMIC_INT_LOCK_FREE 2
|
||||
#define BOOST_ATOMIC_LONG_LOCK_FREE (__SIZEOF_LONG__ <= 4 ? 2 : 0)
|
||||
#define BOOST_ATOMIC_LLONG_LOCK_FREE (__SIZEOF_LONG_LONG__ <= 4 ? 2 : 0)
|
||||
#define BOOST_ATOMIC_POINTER_LOCK_FREE (__SIZEOF_POINTER__ <= 4 ? 2 : 0)
|
||||
#define BOOST_ATOMIC_BOOL_LOCK_FREE 2
|
||||
|
||||
#include <boost/atomic/detail/cas32strong.hpp>
|
||||
|
||||
#endif /* !defined(BOOST_ATOMIC_FORCE_FALLBACK) */
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,206 +0,0 @@
|
||||
#ifndef BOOST_ATOMIC_DETAIL_GENERIC_CAS_HPP
|
||||
#define BOOST_ATOMIC_DETAIL_GENERIC_CAS_HPP
|
||||
|
||||
// Copyright (c) 2009 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 <cstddef>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
#include <boost/atomic/detail/base.hpp>
|
||||
#include <boost/atomic/detail/builder.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
/* fallback implementation for various compilation targets;
|
||||
this is *not* efficient, particularly because all operations
|
||||
are fully fenced (full memory barriers before and after
|
||||
each operation) */
|
||||
|
||||
#if defined(__GNUC__)
|
||||
namespace boost { namespace atomics { namespace detail {
|
||||
inline int32_t
|
||||
fenced_compare_exchange_strong_32(volatile int32_t *ptr, int32_t expected, int32_t desired)
|
||||
{
|
||||
return __sync_val_compare_and_swap_4(ptr, expected, desired);
|
||||
}
|
||||
#define BOOST_ATOMIC_HAVE_CAS32 1
|
||||
|
||||
#if defined(__amd64__) || defined(__i686__)
|
||||
inline int64_t
|
||||
fenced_compare_exchange_strong_64(int64_t *ptr, int64_t expected, int64_t desired)
|
||||
{
|
||||
return __sync_val_compare_and_swap_8(ptr, expected, desired);
|
||||
}
|
||||
#define BOOST_ATOMIC_HAVE_CAS64 1
|
||||
#endif
|
||||
}}}
|
||||
|
||||
#elif defined(__ICL) || defined(_MSC_VER)
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#include <Windows.h>
|
||||
#include <intrin.h>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace atomics { namespace detail {
|
||||
inline int32_t
|
||||
fenced_compare_exchange_strong(int32_t *ptr, int32_t expected, int32_t desired)
|
||||
{
|
||||
return _InterlockedCompareExchange(reinterpret_cast<volatile long*>(ptr), desired, expected);
|
||||
}
|
||||
#define BOOST_ATOMIC_HAVE_CAS32 1
|
||||
#if defined(_WIN64)
|
||||
inline int64_t
|
||||
fenced_compare_exchange_strong(int64_t *ptr, int64_t expected, int64_t desired)
|
||||
{
|
||||
return _InterlockedCompareExchange64(ptr, desired, expected);
|
||||
}
|
||||
#define BOOST_ATOMIC_HAVE_CAS64 1
|
||||
#endif
|
||||
}}}
|
||||
|
||||
#elif (defined(__ICC) || defined(__ECC))
|
||||
namespace boost { namespace atomics { namespace detail {
|
||||
inline int32_t
|
||||
fenced_compare_exchange_strong_32(int32_t *ptr, int32_t expected, int32_t desired)
|
||||
{
|
||||
return _InterlockedCompareExchange((void*)ptr, desired, expected);
|
||||
}
|
||||
#define BOOST_ATOMIC_HAVE_CAS32 1
|
||||
#if defined(__x86_64)
|
||||
inline int64_t
|
||||
fenced_compare_exchange_strong(int64_t *ptr, int64_t expected, int64_t desired)
|
||||
{
|
||||
return cas64<int>(ptr, expected, desired);
|
||||
}
|
||||
#define BOOST_ATOMIC_HAVE_CAS64 1
|
||||
#elif defined(__ECC) //IA-64 version
|
||||
inline int64_t
|
||||
fenced_compare_exchange_strong(int64_t *ptr, int64_t expected, int64_t desired)
|
||||
{
|
||||
return _InterlockedCompareExchange64((void*)ptr, desired, expected);
|
||||
}
|
||||
#define BOOST_ATOMIC_HAVE_CAS64 1
|
||||
#endif
|
||||
}}}
|
||||
|
||||
#elif (defined(__SUNPRO_CC) && defined(__sparc))
|
||||
#include <sys/atomic.h>
|
||||
namespace boost { namespace atomics { namespace detail {
|
||||
inline int32_t
|
||||
fenced_compare_exchange_strong_32(int32_t *ptr, int32_t expected, int32_t desired)
|
||||
{
|
||||
return atomic_cas_32((volatile unsigned int*)ptr, expected, desired);
|
||||
}
|
||||
#define BOOST_ATOMIC_HAVE_CAS32 1
|
||||
|
||||
/* FIXME: check for 64 bit mode */
|
||||
inline int64_t
|
||||
fenced_compare_exchange_strong_64(int64_t *ptr, int64_t expected, int64_t desired)
|
||||
{
|
||||
return atomic_cas_64((volatile unsigned long long*)ptr, expected, desired);
|
||||
}
|
||||
#define BOOST_ATOMIC_HAVE_CAS64 1
|
||||
}}}
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
#ifdef BOOST_ATOMIC_HAVE_CAS32
|
||||
template<typename T>
|
||||
class atomic_generic_cas32
|
||||
{
|
||||
private:
|
||||
typedef atomic_generic_cas32 this_type;
|
||||
public:
|
||||
explicit atomic_generic_cas32(T v) : i((int32_t)v) {}
|
||||
atomic_generic_cas32() {}
|
||||
T load(memory_order order=memory_order_seq_cst) const volatile
|
||||
{
|
||||
T expected=(T)i;
|
||||
do { } while(!const_cast<this_type *>(this)->compare_exchange_weak(expected, expected, order, memory_order_relaxed));
|
||||
return expected;
|
||||
}
|
||||
void store(T v, memory_order order=memory_order_seq_cst) volatile
|
||||
{
|
||||
exchange(v);
|
||||
}
|
||||
bool compare_exchange_strong(
|
||||
T &expected,
|
||||
T desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile
|
||||
{
|
||||
T found;
|
||||
found=(T)fenced_compare_exchange_strong_32(&i, (int32_t)expected, (int32_t)desired);
|
||||
bool success=(found==expected);
|
||||
expected=found;
|
||||
return success;
|
||||
}
|
||||
bool compare_exchange_weak(
|
||||
T &expected,
|
||||
T desired,
|
||||
memory_order success_order,
|
||||
memory_order failure_order) volatile
|
||||
{
|
||||
return compare_exchange_strong(expected, desired, success_order, failure_order);
|
||||
}
|
||||
T exchange(T r, memory_order order=memory_order_seq_cst) volatile
|
||||
{
|
||||
T expected=(T)i;
|
||||
do { } while(!compare_exchange_weak(expected, r, order, memory_order_relaxed));
|
||||
return expected;
|
||||
}
|
||||
|
||||
bool is_lock_free(void) const volatile {return true;}
|
||||
typedef T integral_type;
|
||||
private:
|
||||
mutable int32_t i;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class platform_atomic_integral<T, 4> :
|
||||
public build_atomic_from_exchange<atomic_generic_cas32<T> >
|
||||
{
|
||||
public:
|
||||
typedef build_atomic_from_exchange<atomic_generic_cas32<T> > super;
|
||||
explicit platform_atomic_integral(T v) : super(v) {}
|
||||
platform_atomic_integral(void) {}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class platform_atomic_integral<T, 1> :
|
||||
public build_atomic_from_larger_type<atomic_generic_cas32<int32_t>, T>
|
||||
{
|
||||
public:
|
||||
typedef build_atomic_from_larger_type<atomic_generic_cas32<int32_t>, T> super;
|
||||
|
||||
explicit platform_atomic_integral(T v) : super(v) {}
|
||||
platform_atomic_integral(void) {}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
class platform_atomic_integral<T, 2> :
|
||||
public build_atomic_from_larger_type<atomic_generic_cas32<int32_t>, T>
|
||||
{
|
||||
public:
|
||||
typedef build_atomic_from_larger_type<atomic_generic_cas32<int32_t>, T> super;
|
||||
|
||||
explicit platform_atomic_integral(T v) : super(v) {}
|
||||
platform_atomic_integral(void) {}
|
||||
};
|
||||
#endif
|
||||
|
||||
} } }
|
||||
|
||||
#endif
|
||||
@@ -1,192 +0,0 @@
|
||||
#ifndef BOOST_ATOMIC_DETAIL_LINUX_ARM_HPP
|
||||
#define BOOST_ATOMIC_DETAIL_LINUX_ARM_HPP
|
||||
|
||||
// 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, 2011 Helge Bahmann
|
||||
// Copyright (c) 2009 Phil Endecott
|
||||
// Copyright (c) 2013 Tim Blechmann
|
||||
// Linux-specific code by Phil Endecott
|
||||
|
||||
// Different ARM processors have different atomic instructions. In particular,
|
||||
// architecture versions before v6 (which are still in widespread use, e.g. the
|
||||
// Intel/Marvell XScale chips like the one in the NSLU2) have only atomic swap.
|
||||
// On Linux the kernel provides some support that lets us abstract away from
|
||||
// these differences: it provides emulated CAS and barrier functions at special
|
||||
// addresses that are guaranteed not to be interrupted by the kernel. Using
|
||||
// this facility is slightly slower than inline assembler would be, but much
|
||||
// faster than a system call.
|
||||
//
|
||||
// While this emulated CAS is "strong" in the sense that it does not fail
|
||||
// "spuriously" (i.e.: it never fails to perform the exchange when the value
|
||||
// found equals the value expected), it does not return the found value on
|
||||
// failure. To satisfy the atomic API, compare_exchange_{weak|strong} must
|
||||
// return the found value on failure, and we have to manually load this value
|
||||
// after the emulated CAS reports failure. This in turn introduces a race
|
||||
// between the CAS failing (due to the "wrong" value being found) and subsequently
|
||||
// loading (which might turn up the "right" value). From an application's
|
||||
// point of view this looks like "spurious failure", and therefore the
|
||||
// emulated CAS is only good enough to provide compare_exchange_weak
|
||||
// semantics.
|
||||
|
||||
#include <cstddef>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/memory_order.hpp>
|
||||
#include <boost/atomic/detail/config.hpp>
|
||||
|
||||
#ifdef BOOST_HAS_PRAGMA_ONCE
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
namespace boost {
|
||||
namespace atomics {
|
||||
namespace detail {
|
||||
|
||||
inline void
|
||||
arm_barrier(void)
|
||||
{
|
||||
void (*kernel_dmb)(void) = (void (*)(void)) 0xffff0fa0;
|
||||
kernel_dmb();
|
||||
}
|
||||
|
||||
inline void
|
||||
platform_fence_before(memory_order order)
|
||||
{
|
||||
switch(order) {
|
||||
case memory_order_release:
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
arm_barrier();
|
||||
case memory_order_consume:
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
platform_fence_after(memory_order order)
|
||||
{
|
||||
switch(order) {
|
||||
case memory_order_acquire:
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
arm_barrier();
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
inline void
|
||||
platform_fence_before_store(memory_order order)
|
||||
{
|
||||
platform_fence_before(order);
|
||||
}
|
||||
|
||||
inline void
|
||||
platform_fence_after_store(memory_order order)
|
||||
{
|
||||
if (order == memory_order_seq_cst)
|
||||
arm_barrier();
|
||||
}
|
||||
|
||||
inline void
|
||||
platform_fence_after_load(memory_order order)
|
||||
{
|
||||
platform_fence_after(order);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline bool
|
||||
platform_cmpxchg32(T & expected, T desired, volatile T * ptr)
|
||||
{
|
||||
typedef T (*kernel_cmpxchg32_t)(T oldval, T newval, volatile T * ptr);
|
||||
|
||||
if (((kernel_cmpxchg32_t) 0xffff0fc0)(expected, desired, ptr) == 0) {
|
||||
return true;
|
||||
} else {
|
||||
expected = *ptr;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#define BOOST_ATOMIC_THREAD_FENCE 2
|
||||
inline void
|
||||
atomic_thread_fence(memory_order order)
|
||||
{
|
||||
switch(order) {
|
||||
case memory_order_acquire:
|
||||
case memory_order_release:
|
||||
case memory_order_acq_rel:
|
||||
case memory_order_seq_cst:
|
||||
atomics::detail::arm_barrier();
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
#define BOOST_ATOMIC_SIGNAL_FENCE 2
|
||||
inline void
|
||||
atomic_signal_fence(memory_order)
|
||||
{
|
||||
__asm__ __volatile__ ("" ::: "memory");
|
||||
}
|
||||
|
||||
class atomic_flag
|
||||
{
|
||||
private:
|
||||
uint32_t v_;
|
||||
|
||||
public:
|
||||
BOOST_CONSTEXPR atomic_flag(void) BOOST_NOEXCEPT : v_(0) {}
|
||||
|
||||
void
|
||||
clear(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
atomics::detail::platform_fence_before_store(order);
|
||||
const_cast<volatile uint32_t &>(v_) = 0;
|
||||
atomics::detail::platform_fence_after_store(order);
|
||||
}
|
||||
|
||||
bool
|
||||
test_and_set(memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
|
||||
{
|
||||
atomics::detail::platform_fence_before(order);
|
||||
uint32_t expected = v_;
|
||||
do {
|
||||
if (expected == 1)
|
||||
break;
|
||||
} while (!atomics::detail::platform_cmpxchg32(expected, (uint32_t)1, &v_));
|
||||
atomics::detail::platform_fence_after(order);
|
||||
return expected;
|
||||
}
|
||||
|
||||
BOOST_DELETED_FUNCTION(atomic_flag(atomic_flag const&))
|
||||
BOOST_DELETED_FUNCTION(atomic_flag& operator= (atomic_flag const&))
|
||||
};
|
||||
|
||||
#define BOOST_ATOMIC_FLAG_LOCK_FREE 2
|
||||
|
||||
}
|
||||
|
||||
#include <boost/atomic/detail/base.hpp>
|
||||
|
||||
#if !defined(BOOST_ATOMIC_FORCE_FALLBACK)
|
||||
|
||||
#define BOOST_ATOMIC_CHAR_LOCK_FREE 2
|
||||
#define BOOST_ATOMIC_CHAR16_T_LOCK_FREE 2
|
||||
#define BOOST_ATOMIC_CHAR32_T_LOCK_FREE 2
|
||||
#define BOOST_ATOMIC_WCHAR_T_LOCK_FREE 2
|
||||
#define BOOST_ATOMIC_SHORT_LOCK_FREE 2
|
||||
#define BOOST_ATOMIC_INT_LOCK_FREE 2
|
||||
#define BOOST_ATOMIC_LONG_LOCK_FREE 2
|
||||
#define BOOST_ATOMIC_LLONG_LOCK_FREE 0
|
||||
#define BOOST_ATOMIC_POINTER_LOCK_FREE 2
|
||||
#define BOOST_ATOMIC_BOOL_LOCK_FREE 2
|
||||
|
||||
#include <boost/atomic/detail/cas32weak.hpp>
|
||||
|
||||
#endif /* !defined(BOOST_ATOMIC_FORCE_FALLBACK) */
|
||||
|
||||
#endif
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user