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 namespace drizzled {
00039 namespace internal {
00040
00041 template<typename I>
00042 struct atomic_base {
00043 volatile I my_value;
00044 atomic_base() : my_value(0) {}
00045 virtual ~atomic_base() {}
00046 };
00047
00048 template<typename I, typename D, typename T >
00049 class atomic_impl: private atomic_base<I>
00050 {
00051 T traits;
00052 public:
00053 typedef I value_type;
00054
00055 atomic_impl() : atomic_base<I>(), traits() {}
00056
00057 value_type add_and_fetch( D addend )
00058 {
00059 return traits.add_and_fetch(&this->my_value, addend);
00060 }
00061
00062 value_type fetch_and_add( D addend )
00063 {
00064 return traits.fetch_and_add(&this->my_value, addend);
00065 }
00066
00067 value_type fetch_and_increment()
00068 {
00069 return traits.fetch_and_increment(&this->my_value);
00070 }
00071
00072 value_type fetch_and_decrement()
00073 {
00074 return traits.fetch_and_decrement(&this->my_value);
00075 }
00076
00077 value_type fetch_and_store( value_type value )
00078 {
00079 return traits.fetch_and_store(&this->my_value, value);
00080 }
00081
00082 bool compare_and_swap( value_type value, value_type comparand )
00083 {
00084 return traits.compare_and_swap(&this->my_value, value, comparand);
00085 }
00086
00087 operator value_type() const volatile
00088 {
00089 return traits.fetch(&this->my_value);
00090 }
00091
00092 value_type& _internal_reference() const
00093 {
00094 return this->my_value;
00095 }
00096
00097 protected:
00098 value_type store_with_release( value_type rhs )
00099 {
00100 return traits.store_with_release(&this->my_value, rhs);
00101 }
00102
00103 public:
00104 atomic_impl<I,D,T>& operator+=( D addend )
00105 {
00106 increment(addend);
00107 return *this;
00108 }
00109
00110 atomic_impl<I,D,T>& operator-=( D addend )
00111 {
00112
00113
00114 return operator+=(D(0)-addend);
00115 }
00116
00117 value_type increment()
00118 {
00119 return add_and_fetch(1);
00120 }
00121
00122 value_type decrement()
00123 {
00124 return add_and_fetch(D(-1));
00125 }
00126 };
00127
00128 }
00129
00131
00133 template<typename T>
00134 struct atomic {
00135 };
00136
00137
00138 #define __DRIZZLE_DECL_ATOMIC(T) \
00139 template<> struct atomic<T> \
00140 : internal::atomic_impl<T,T,ATOMIC_TRAITS<T,T> > { \
00141 atomic<T>() : internal::atomic_impl<T,T,ATOMIC_TRAITS<T,T> >() {} \
00142 atomic<T>& operator=( T rhs ) { store_with_release(rhs); return *this; } \
00143 };
00144
00145
00146
00147 __DRIZZLE_DECL_ATOMIC(long)
00148 __DRIZZLE_DECL_ATOMIC(unsigned long)
00149 __DRIZZLE_DECL_ATOMIC(unsigned int)
00150 __DRIZZLE_DECL_ATOMIC(int)
00151 __DRIZZLE_DECL_ATOMIC(unsigned short)
00152 __DRIZZLE_DECL_ATOMIC(short)
00153 __DRIZZLE_DECL_ATOMIC(char)
00154 __DRIZZLE_DECL_ATOMIC(signed char)
00155 __DRIZZLE_DECL_ATOMIC(unsigned char)
00156 __DRIZZLE_DECL_ATOMIC(bool)
00157
00158
00159
00160
00161
00162 # if !defined(__ppc__) && (defined(_INT64_TYPE) || defined(_LP64))
00163 __DRIZZLE_DECL_ATOMIC(long long)
00164 __DRIZZLE_DECL_ATOMIC(unsigned long long)
00165 # else
00166 # define __DRIZZLE_DECL_ATOMIC64(T) \
00167 template<> struct atomic<T> \
00168 : internal::atomic_impl<T,T,internal::pthread_traits<T,T> > { \
00169 atomic<T>() \
00170 : internal::atomic_impl<T,T,internal::pthread_traits<T,T> >() {} \
00171 T operator=( T rhs ) { return store_with_release(rhs); } \
00172 };
00173 __DRIZZLE_DECL_ATOMIC64(long long)
00174 __DRIZZLE_DECL_ATOMIC64(unsigned long long)
00175 # endif
00176
00177
00178 }
00179