24 #ifndef GRAPHLAB_ATOMIC_HPP
25 #define GRAPHLAB_ATOMIC_HPP
29 #include <boost/type_traits/is_integral.hpp>
31 #include <graphlab/serialization/serialization_includes.hpp>
32 #include <graphlab/parallel/atomic_ops.hpp>
35 namespace graphlab_impl {
36 template<
typename T,
bool IsIntegral>
44 class atomic_impl <T, true>:
public IS_POD_TYPE {
50 atomic_impl(
const T& value = T()) : value(value) { }
53 T inc() {
return __sync_add_and_fetch(&value, 1); }
56 T dec() {
return __sync_sub_and_fetch(&value, 1); }
59 operator T()
const {
return value; }
62 T operator++() {
return inc(); }
65 T operator--() {
return dec(); }
68 T inc(
const T val) {
return __sync_add_and_fetch(&value, val); }
71 T dec(
const T val) {
return __sync_sub_and_fetch(&value, val); }
74 T operator+=(
const T val) {
return inc(val); }
77 T operator-=(
const T val) {
return dec(val); }
80 T inc_ret_last() {
return __sync_fetch_and_add(&value, 1); }
83 T dec_ret_last() {
return __sync_fetch_and_sub(&value, 1); }
86 T operator++(
int) {
return inc_ret_last(); }
89 T operator--(
int) {
return dec_ret_last(); }
92 T inc_ret_last(
const T val) {
return __sync_fetch_and_add(&value, val); }
95 T dec_ret_last(
const T val) {
return __sync_fetch_and_sub(&value, val); }
98 T exchange(
const T val) {
return __sync_lock_test_and_set(&value, val); }
103 class atomic_impl <T, false>:
public IS_POD_TYPE {
109 atomic_impl(
const T& value = T()) : value(value) { }
112 T inc() {
return inc(1); }
115 T dec() {
return dec(1); }
118 operator T()
const {
return value; }
121 T operator++() {
return inc(); }
124 T operator--() {
return dec(); }
132 new_value = prev_value + val;
143 new_value = prev_value - val;
149 T operator+=(
const T val) {
return inc(val); }
152 T operator-=(
const T val) {
return dec(val); }
155 T inc_ret_last() {
return inc_ret_last(1); }
158 T dec_ret_last() {
return dec_ret_last(1); }
161 T operator++(
int) {
return inc_ret_last(); }
164 T operator--(
int) {
return dec_ret_last(); }
167 T inc_ret_last(
const T val) {
172 new_value = prev_value + val;
178 T dec_ret_last(
const T val) {
183 new_value = prev_value - val;
189 T exchange(
const T val) {
return __sync_lock_test_and_set(&value, val); }
193 template <
typename T>
194 class atomic:
public graphlab_impl::atomic_impl<T, boost::is_integral<T>::value> {
197 atomic(
const T& value = T()):
198 graphlab_impl::atomic_impl<T, boost::is_integral<T>::value>(value) { }