00001 // Copyright (c) 2011 Helge Bahmann 00002 // 00003 // Distributed under the Boost Software License, Version 1.0. 00004 // See accompanying file LICENSE_1_0.txt or copy at 00005 // http://www.boost.org/LICENSE_1_0.txt) 00006 00007 // Use the gnu builtin __sync_val_compare_and_swap to build 00008 // atomic operations for 32 bit and smaller. 00009 00010 #ifndef BOOST_DETAIL_ATOMIC_GENERIC_CAS_HPP 00011 #define BOOST_DETAIL_ATOMIC_GENERIC_CAS_HPP 00012 00013 #define BOOST_ATOMIC_CHAR_LOCK_FREE 2 00014 #define BOOST_ATOMIC_SHORT_LOCK_FREE 2 00015 #define BOOST_ATOMIC_INT_LOCK_FREE 2 00016 #define BOOST_ATOMIC_LONG_LOCK_FREE (sizeof(long) <= 4 ? 2 : 0) 00017 #define BOOST_ATOMIC_LLONG_LOCK_FREE (sizeof(long long) <= 4 ? 2 : 0) 00018 #define BOOST_ATOMIC_ADDRESS_LOCK_FREE (sizeof(void *) <= 4 ? 2 : 0) 00019 #define BOOST_ATOMIC_BOOL_LOCK_FREE 2 00020 00021 namespace boost { 00022 00023 #define BOOST_ATOMIC_THREAD_FENCE 2 00024 inline void 00025 atomic_thread_fence(memory_order order) 00026 { 00027 switch(order) { 00028 case memory_order_relaxed: 00029 break; 00030 case memory_order_release: 00031 case memory_order_consume: 00032 case memory_order_acquire: 00033 case memory_order_acq_rel: 00034 case memory_order_seq_cst: 00035 __sync_synchronize(); 00036 break; 00037 } 00038 } 00039 00040 namespace detail { 00041 namespace atomic { 00042 00043 static inline void 00044 platform_fence_before(memory_order) 00045 { 00046 /* empty, as compare_and_swap is synchronizing already */ 00047 } 00048 00049 static inline void 00050 platform_fence_after(memory_order) 00051 { 00052 /* empty, as compare_and_swap is synchronizing already */ 00053 } 00054 00055 static inline void 00056 platform_fence_before_store(memory_order order) 00057 { 00058 switch(order) { 00059 case memory_order_relaxed: 00060 case memory_order_acquire: 00061 case memory_order_consume: 00062 break; 00063 case memory_order_release: 00064 case memory_order_acq_rel: 00065 case memory_order_seq_cst: 00066 __sync_synchronize(); 00067 break; 00068 } 00069 } 00070 00071 static inline void 00072 platform_fence_after_store(memory_order order) 00073 { 00074 if (order == memory_order_seq_cst) 00075 __sync_synchronize(); 00076 } 00077 00078 static inline void 00079 platform_fence_after_load(memory_order order) 00080 { 00081 switch(order) { 00082 case memory_order_relaxed: 00083 case memory_order_release: 00084 break; 00085 case memory_order_consume: 00086 case memory_order_acquire: 00087 case memory_order_acq_rel: 00088 case memory_order_seq_cst: 00089 __sync_synchronize(); 00090 break; 00091 } 00092 } 00093 00094 template<typename T> 00095 bool 00096 platform_cmpxchg32_strong(T & expected, T desired, volatile T * ptr) 00097 { 00098 T found = __sync_val_compare_and_swap(ptr, expected, desired); 00099 bool success = (found == expected); 00100 expected = found; 00101 return success; 00102 } 00103 00104 } 00105 } 00106 } 00107 00108 #include <boost/atomic/detail/cas32strong.hpp> 00109 00110 #endif