peerplays-fc/include/boost/atomic/detail/base.hpp
2012-09-07 22:50:37 -04:00

186 lines
5.9 KiB
C++

#ifndef BOOST_DETAIL_ATOMIC_BASE_HPP
#define BOOST_DETAIL_ATOMIC_BASE_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 <boost/atomic/detail/fallback.hpp>
#include <boost/atomic/detail/builder.hpp>
#include <boost/atomic/detail/valid_integral_types.hpp>
namespace boost {
namespace detail {
namespace atomic {
static 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, unsigned short Size=sizeof(T)>
class platform_atomic : public fallback_atomic<T> {
public:
typedef fallback_atomic<T> super;
explicit platform_atomic(T v) : super(v) {}
platform_atomic() {}
protected:
typedef typename super::integral_type integral_type;
};
template<typename T, unsigned short Size=sizeof(T)>
class platform_atomic_integral : public build_atomic_from_exchange<fallback_atomic<T> > {
public:
typedef build_atomic_from_exchange<fallback_atomic<T> > super;
explicit platform_atomic_integral(T v) : super(v) {}
platform_atomic_integral() {}
protected:
typedef typename super::integral_type integral_type;
};
template<typename T>
static inline void platform_atomic_thread_fence(T order)
{
/* FIXME: this does not provide
sequential consistency, need one global
variable for that... */
platform_atomic<int> a;
a.exchange(0, order);
}
template<typename T, unsigned short Size=sizeof(T), typename Int=typename is_integral_type<T>::test>
class internal_atomic;
template<typename T, unsigned short Size>
class internal_atomic<T, Size, void> : private detail::atomic::platform_atomic<T> {
public:
typedef detail::atomic::platform_atomic<T> super;
internal_atomic() {}
explicit internal_atomic(T v) : super(v) {}
operator T(void) const volatile {return load();}
T operator=(T v) volatile {store(v); return v;}
using super::is_lock_free;
using super::load;
using super::store;
using super::exchange;
bool compare_exchange_strong(
T &expected,
T desired,
memory_order order=memory_order_seq_cst) volatile
{
return super::compare_exchange_strong(expected, desired, order, calculate_failure_order(order));
}
bool compare_exchange_weak(
T &expected,
T desired,
memory_order order=memory_order_seq_cst) volatile
{
return super::compare_exchange_strong(expected, desired, order, calculate_failure_order(order));
}
bool compare_exchange_strong(
T &expected,
T desired,
memory_order success_order,
memory_order failure_order) volatile
{
return super::compare_exchange_strong(expected, desired, success_order, failure_order);
}
bool compare_exchange_weak(
T &expected,
T desired,
memory_order success_order,
memory_order failure_order) volatile
{
return super::compare_exchange_strong(expected, desired, success_order, failure_order);
}
private:
internal_atomic(const internal_atomic &);
void operator=(const internal_atomic &);
};
template<typename T, unsigned short Size>
class internal_atomic<T, Size, int> : private detail::atomic::platform_atomic_integral<T> {
public:
typedef detail::atomic::platform_atomic_integral<T> super;
typedef typename super::integral_type integral_type;
internal_atomic() {}
explicit internal_atomic(T v) : super(v) {}
using super::is_lock_free;
using super::load;
using super::store;
using super::exchange;
using super::fetch_add;
using super::fetch_sub;
using super::fetch_and;
using super::fetch_or;
using super::fetch_xor;
operator integral_type(void) const volatile {return load();}
integral_type operator=(integral_type v) volatile {store(v); return v;}
integral_type operator&=(integral_type c) volatile {return fetch_and(c)&c;}
integral_type operator|=(integral_type c) volatile {return fetch_or(c)|c;}
integral_type operator^=(integral_type c) volatile {return fetch_xor(c)^c;}
integral_type operator+=(integral_type c) volatile {return fetch_add(c)+c;}
integral_type operator-=(integral_type c) volatile {return fetch_sub(c)-c;}
integral_type operator++(void) volatile {return fetch_add(1)+1;}
integral_type operator++(int) volatile {return fetch_add(1);}
integral_type operator--(void) volatile {return fetch_sub(1)-1;}
integral_type operator--(int) volatile {return fetch_sub(1);}
bool compare_exchange_strong(
integral_type &expected,
integral_type desired,
memory_order order=memory_order_seq_cst) volatile
{
return super::compare_exchange_strong(expected, desired, order, calculate_failure_order(order));
}
bool compare_exchange_weak(
integral_type &expected,
integral_type desired,
memory_order order=memory_order_seq_cst) volatile
{
return super::compare_exchange_strong(expected, desired, order, calculate_failure_order(order));
}
bool compare_exchange_strong(
integral_type &expected,
integral_type desired,
memory_order success_order,
memory_order failure_order) volatile
{
return super::compare_exchange_strong(expected, desired, success_order, failure_order);
}
bool compare_exchange_weak(
integral_type &expected,
integral_type desired,
memory_order success_order,
memory_order failure_order) volatile
{
return super::compare_exchange_strong(expected, desired, success_order, failure_order);
}
private:
internal_atomic(const internal_atomic &);
void operator=(const internal_atomic &);
};
}
}
}
#endif