00001 #ifndef BOOST_ATOMIC_DETAIL_ATOMIC_LINUX_ARM_HPP
00002 #define BOOST_ATOMIC_DETAIL_ATOMIC_LINUX_ARM_HPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "../memory_order2.hpp"
00013 #include "base.hpp"
00014 #include "builder.hpp"
00015
00016 namespace boost_atomic {
00017 namespace detail {
00018 namespace atomic {
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034 typedef void (kernel_dmb_t)(void);
00035 #define BOOST_ATOMIC_KERNEL_DMB (*(kernel_dmb_t *)0xffff0fa0)
00036
00037 static inline void fence_before(memory_order2 order)
00038 {
00039 switch(order) {
00040
00041
00042 case memory_order2_consume:
00043 case memory_order2_release:
00044 case memory_order2_acq_rel:
00045 case memory_order2_seq_cst:
00046 BOOST_ATOMIC_KERNEL_DMB();
00047 default:;
00048 }
00049 }
00050
00051 static inline void fence_after(memory_order2 order)
00052 {
00053 switch(order) {
00054
00055
00056 case memory_order2_acquire:
00057 case memory_order2_acq_rel:
00058 case memory_order2_seq_cst:
00059 BOOST_ATOMIC_KERNEL_DMB();
00060 default:;
00061 }
00062 }
00063
00064 #undef BOOST_ATOMIC_KERNEL_DMB
00065
00066
00067 template<typename T>
00068 class atomic_linux_arm_4 {
00069
00070 typedef int (kernel_cmpxchg_t)(T oldval, T newval, T *ptr);
00071 # define BOOST_ATOMIC_KERNEL_CMPXCHG (*(kernel_cmpxchg_t *)0xffff0fc0)
00072
00073
00074 public:
00075 explicit atomic_linux_arm_4(T v) : i(v) {}
00076 atomic_linux_arm_4() {}
00077 T load(memory_order2 order=memory_order2_seq_cst) const volatile
00078 {
00079 T v=const_cast<volatile const T &>(i);
00080 fence_after(order);
00081 return v;
00082 }
00083 void store(T v, memory_order2 order=memory_order2_seq_cst) volatile
00084 {
00085 fence_before(order);
00086 const_cast<volatile T &>(i)=v;
00087 }
00088 bool compare_exchange_strong(
00089 T &expected,
00090 T desired,
00091 memory_order2 success_order,
00092 memory_order2 failure_order) volatile
00093 {
00094
00095
00096
00097
00098 bool success = BOOST_ATOMIC_KERNEL_CMPXCHG(expected,desired,&i)==0;
00099 if (!success) e = load(memory_order2_relaxed);
00100 return success;
00101 }
00102 bool compare_exchange_weak(
00103 T &expected,
00104 T desired,
00105 memory_order2 success_order,
00106 memory_order2 failure_order) volatile
00107 {
00108 return compare_exchange_strong(expected, desired, success_order, failure_order);
00109 }
00110 T exchange(T replacement, memory_order2 order=memory_order2_seq_cst) volatile
00111 {
00112
00113 T o=load(memory_order2_relaxed);
00114 do {} while(!compare_exchange_weak(o, replacement, order));
00115 return o;
00116
00117
00118
00119
00120
00121
00122
00123 }
00124
00125 bool is_lock_free(void) const volatile {return true;}
00126 protected:
00127 typedef T integral_type;
00128 private:
00129 T i;
00130
00131 # undef BOOST_ATOMIC_KERNEL_CMPXCHG
00132
00133 };
00134
00135 template<typename T>
00136 class platform_atomic_integral<T, 4> : public build_atomic_from_exchange<atomic_linux_arm_4<T> > {
00137 public:
00138 typedef build_atomic_from_exchange<atomic_linux_arm_4<T> > super;
00139 explicit platform_atomic_integral(T v) : super(v) {}
00140 platform_atomic_integral(void) {}
00141 };
00142
00143
00144 template<typename T>
00145 class platform_atomic_integral<T, 1> : public build_atomic_from_larger_type<atomic_linux_arm_4<uint32_t>, T > {
00146 public:
00147 typedef build_atomic_from_larger_type<atomic_linux_arm_4<uint32_t>, T> super;
00148 explicit platform_atomic_integral(T v) : super(v) {}
00149 platform_atomic_integral(void) {}
00150 };
00151
00152
00153 template<typename T>
00154 class platform_atomic_integral<T, 2> : public build_atomic_from_larger_type<atomic_linux_arm_4<uint32_t>, T > {
00155 public:
00156 typedef build_atomic_from_larger_type<atomic_linux_arm_4<uint32_t>, T> super;
00157 explicit platform_atomic_integral(T v) : super(v) {}
00158 platform_atomic_integral(void) {}
00159 };
00160
00161
00162 typedef atomic_linux_arm_4<void *> platform_atomic_address;
00163
00164
00165 }
00166 }
00167 }
00168
00169 #endif