00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #pragma once
00022
00023 # if defined(__SUNPRO_CC)
00024 # include <drizzled/atomic/sun_studio.h>
00025 # endif
00026 # if !defined(__ICC) && !defined(__clang__) && (defined(HAVE_GCC_ATOMIC_BUILTINS) || defined(__SUNPRO_CC))
00027 # include <drizzled/atomic/gcc_traits.h>
00028 # define ATOMIC_TRAITS internal::gcc_traits
00029 # else
00030 # define ATOMIC_TRAITS internal::pthread_traits
00031 # endif
00032
00033 # if (SIZEOF_SIZE_T >= SIZEOF_LONG_LONG) || (!defined(HAVE_GCC_ATOMIC_BUILTINS) || !defined(__SUNPRO_CC)) || defined(__ppc__)
00034 # include <pthread.h>
00035 # include <drizzled/atomic/pthread_traits.h>
00036 # endif
00037
00038
00039 namespace drizzled {
00040
00041 namespace internal {
00042
00043
00044 template<typename I>
00045 struct atomic_base {
00046 volatile I my_value;
00047 atomic_base() : my_value(0) {}
00048 virtual ~atomic_base() {}
00049 };
00050
00051 template<typename I, typename D, typename T >
00052 class atomic_impl: private atomic_base<I>
00053 {
00054 T traits;
00055 public:
00056 typedef I value_type;
00057
00058 atomic_impl() : atomic_base<I>(), traits() {}
00059
00060 value_type add_and_fetch( D addend )
00061 {
00062 return traits.add_and_fetch(&this->my_value, addend);
00063 }
00064
00065 value_type fetch_and_add( D addend )
00066 {
00067 return traits.fetch_and_add(&this->my_value, addend);
00068 }
00069
00070 value_type fetch_and_increment()
00071 {
00072 return traits.fetch_and_increment(&this->my_value);
00073 }
00074
00075 value_type fetch_and_decrement()
00076 {
00077 return traits.fetch_and_decrement(&this->my_value);
00078 }
00079
00080 value_type fetch_and_store( value_type value )
00081 {
00082 return traits.fetch_and_store(&this->my_value, value);
00083 }
00084
00085 bool compare_and_swap( value_type value, value_type comparand )
00086 {
00087 return traits.compare_and_swap(&this->my_value, value, comparand);
00088 }
00089
00090 operator value_type() const volatile
00091 {
00092 return traits.fetch(&this->my_value);
00093 }
00094
00095 value_type& _internal_reference() const
00096 {
00097 return this->my_value;
00098 }
00099
00100 protected:
00101 value_type store_with_release( value_type rhs )
00102 {
00103 return traits.store_with_release(&this->my_value, rhs);
00104 }
00105
00106 public:
00107 atomic_impl<I,D,T>& operator+=( D addend )
00108 {
00109 increment(addend);
00110 return *this;
00111 }
00112
00113 atomic_impl<I,D,T>& operator-=( D addend )
00114 {
00115
00116
00117 return operator+=(D(0)-addend);
00118 }
00119
00120 value_type increment()
00121 {
00122 return add_and_fetch(1);
00123 }
00124
00125 value_type decrement()
00126 {
00127 return add_and_fetch(D(-1));
00128 }
00129 };
00130
00131 }
00132
00134
00136 template<typename T>
00137 struct atomic {
00138 };
00139
00140
00141 #define __DRIZZLE_DECL_ATOMIC(T) \
00142 template<> struct atomic<T> \
00143 : internal::atomic_impl<T,T,ATOMIC_TRAITS<T,T> > { \
00144 atomic<T>() : internal::atomic_impl<T,T,ATOMIC_TRAITS<T,T> >() {} \
00145 atomic<T>& operator=( T rhs ) { store_with_release(rhs); return *this; } \
00146 };
00147
00148
00149
00150 __DRIZZLE_DECL_ATOMIC(long)
00151 __DRIZZLE_DECL_ATOMIC(unsigned long)
00152 __DRIZZLE_DECL_ATOMIC(unsigned int)
00153 __DRIZZLE_DECL_ATOMIC(int)
00154 __DRIZZLE_DECL_ATOMIC(unsigned short)
00155 __DRIZZLE_DECL_ATOMIC(short)
00156 __DRIZZLE_DECL_ATOMIC(char)
00157 __DRIZZLE_DECL_ATOMIC(signed char)
00158 __DRIZZLE_DECL_ATOMIC(unsigned char)
00159 __DRIZZLE_DECL_ATOMIC(bool)
00160
00161
00162
00163
00164
00165 # if !defined(__ppc__) && (defined(_INT64_TYPE) || defined(_LP64))
00166 __DRIZZLE_DECL_ATOMIC(long long)
00167 __DRIZZLE_DECL_ATOMIC(unsigned long long)
00168 # else
00169 # define __DRIZZLE_DECL_ATOMIC64(T) \
00170 template<> struct atomic<T> \
00171 : internal::atomic_impl<T,T,internal::pthread_traits<T,T> > { \
00172 atomic<T>() \
00173 : internal::atomic_impl<T,T,internal::pthread_traits<T,T> >() {} \
00174 T operator=( T rhs ) { return store_with_release(rhs); } \
00175 };
00176 __DRIZZLE_DECL_ATOMIC64(long long)
00177 __DRIZZLE_DECL_ATOMIC64(unsigned long long)
00178 # endif
00179
00180
00181 }
00182