00001 #ifndef BOOST_ATOMIC_DETAIL_ATOMIC_INTERLOCKED_HPP
00002 #define BOOST_ATOMIC_DETAIL_ATOMIC_INTERLOCKED_HPP
00003
00004
00005
00006
00007
00008
00009
00010 #include <boost/detail/interlocked.hpp>
00011
00012 #include "base.hpp"
00013 #include "builder.hpp"
00014
00015 namespace boost_atomic {
00016 using namespace boost;
00017 namespace detail {
00018 namespace atomic {
00019
00020 static inline void full_fence(void)
00021 {
00022 long tmp;
00023 BOOST_INTERLOCKED_EXCHANGE(&tmp, 0);
00024 }
00025
00026 template<>
00027 inline void platform_atomic_thread_fence(memory_order2 order)
00028 {
00029 switch(order) {
00030 case memory_order2_seq_cst:
00031 full_fence();
00032 default:;
00033 }
00034 }
00035
00036 static inline void fence_after_load(memory_order2 order)
00037 {
00038 switch(order) {
00039 case memory_order2_seq_cst:
00040 full_fence();
00041 case memory_order2_acquire:
00042 case memory_order2_acq_rel:
00043 default:;
00044 }
00045 }
00046
00047
00048 template<typename T>
00049 class atomic_interlocked_32 {
00050 public:
00051 explicit atomic_interlocked_32(T v) : i(v) {}
00052 atomic_interlocked_32() {}
00053 T load(memory_order2 order=memory_order2_seq_cst) const volatile
00054 {
00055 T v=*reinterpret_cast<volatile const T *>(&i);
00056 fence_after_load(order);
00057 return v;
00058 }
00059 void store(T v, memory_order2 order=memory_order2_seq_cst) volatile
00060 {
00061 if (order!=memory_order2_seq_cst) {
00062 *reinterpret_cast<volatile T *>(&i)=v;
00063 } else {
00064 exchange(v);
00065 }
00066 }
00067 bool compare_exchange_strong(
00068 T &expected,
00069 T desired,
00070 memory_order2 success_order,
00071 memory_order2 failure_order) volatile
00072 {
00073 T prev=expected;
00074 expected=(T)BOOST_INTERLOCKED_COMPARE_EXCHANGE((long *)(&i), (long)desired, (long)expected);
00075 bool success=(prev==expected);
00076 return success;
00077 }
00078 bool compare_exchange_weak(
00079 T &expected,
00080 T desired,
00081 memory_order2 success_order,
00082 memory_order2 failure_order) volatile
00083 {
00084 return compare_exchange_strong(expected, desired, success_order, failure_order);
00085 }
00086 T exchange(T r, memory_order2 order=memory_order2_seq_cst) volatile
00087 {
00088 return (T)BOOST_INTERLOCKED_EXCHANGE((long *)&i, (long)r);
00089 }
00090 T fetch_add(T c, memory_order2 order=memory_order2_seq_cst) volatile
00091 {
00092 return (T)BOOST_INTERLOCKED_EXCHANGE_ADD((long *)&i, c);
00093 }
00094
00095 bool is_lock_free(void) const volatile {return true;}
00096
00097 typedef T integral_type;
00098 private:
00099 T i;
00100 };
00101
00102 template<typename T>
00103 class platform_atomic_integral<T, 4> : public build_atomic_from_add<atomic_interlocked_32<T> > {
00104 public:
00105 typedef build_atomic_from_add<atomic_interlocked_32<T> > super;
00106 explicit platform_atomic_integral(T v) : super(v) {}
00107 platform_atomic_integral(void) {}
00108 };
00109
00110 template<typename T>
00111 class platform_atomic_integral<T, 1>: public build_atomic_from_larger_type<atomic_interlocked_32<uint32_t>, T> {
00112 public:
00113 typedef build_atomic_from_larger_type<atomic_interlocked_32<uint32_t>, T> super;
00114
00115 explicit platform_atomic_integral(T v) : super(v) {}
00116 platform_atomic_integral(void) {}
00117 };
00118
00119 template<typename T>
00120 class platform_atomic_integral<T, 2>: public build_atomic_from_larger_type<atomic_interlocked_32<uint32_t>, T> {
00121 public:
00122 typedef build_atomic_from_larger_type<atomic_interlocked_32<uint32_t>, T> super;
00123
00124 explicit platform_atomic_integral(T v) : super(v) {}
00125 platform_atomic_integral(void) {}
00126 };
00127
00128 }
00129 }
00130 }
00131
00132 #endif