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 namespace drizzled {
00024
00025 namespace internal {
00026
00027 class mutex_wrapper
00028 {
00029 private:
00030 pthread_mutex_t the_mutex;
00031 bool locked;
00032 public:
00033 mutex_wrapper(void)
00034 : the_mutex(),
00035 locked(false)
00036 {
00037 (void) pthread_mutex_init(&the_mutex, NULL);
00038 }
00039 ~mutex_wrapper(void)
00040 {
00041 if (locked)
00042 unlock();
00043 pthread_mutex_destroy(&the_mutex);
00044 }
00045 void lock(void)
00046 {
00047 pthread_mutex_lock(&the_mutex);
00048 locked=true;
00049 }
00050 void unlock(void)
00051 {
00052 pthread_mutex_unlock(&the_mutex);
00053 locked=false;
00054 }
00055 };
00056
00057 template<typename T, typename D>
00058 class pthread_traits
00059 {
00060 private:
00061 mutex_wrapper my_lock;
00062
00063 public:
00064
00065 typedef T value_type;
00066
00067 pthread_traits() {}
00068
00069 inline value_type add_and_fetch(volatile value_type *value, D addend )
00070 {
00071 my_lock.lock();
00072 *value += addend;
00073 value_type ret= *value;
00074 my_lock.unlock();
00075 return ret;
00076 }
00077
00078 inline value_type fetch_and_add(volatile value_type *value, D addend )
00079 {
00080 my_lock.lock();
00081 value_type ret= *value;
00082 *value += addend;
00083 my_lock.unlock();
00084 return ret;
00085 }
00086
00087 inline value_type fetch_and_increment(volatile value_type *value)
00088 {
00089 my_lock.lock();
00090 value_type ret= *value;
00091 (*value)++;
00092 my_lock.unlock();
00093 return ret;
00094 }
00095
00096 inline value_type fetch_and_decrement(volatile value_type *value)
00097 {
00098 my_lock.lock();
00099 value_type ret= *value;
00100 (*value)--;
00101 my_lock.unlock();
00102 return ret;
00103 }
00104
00105 inline value_type fetch_and_store(volatile value_type *value,
00106 value_type new_value )
00107 {
00108 my_lock.lock();
00109 value_type ret= *value;
00110 *value= new_value;
00111 my_lock.unlock();
00112 return ret;
00113 }
00114
00115 inline bool compare_and_swap(volatile value_type *value,
00116 value_type new_value,
00117 value_type comparand )
00118 {
00119 my_lock.lock();
00120 bool ret= (*value == comparand);
00121 if (ret)
00122 *value= new_value;
00123 my_lock.unlock();
00124 return ret;
00125 }
00126
00127 inline value_type fetch(const volatile value_type *value) const volatile
00128 {
00129 const_cast<pthread_traits *>(this)->my_lock.lock();
00130 value_type ret= *value;
00131 const_cast<pthread_traits *>(this)->my_lock.unlock();
00132 return ret;
00133 }
00134
00135 inline value_type store_with_release(volatile value_type *value,
00136 value_type new_value)
00137 {
00138 my_lock.lock();
00139 *value= new_value;
00140 value_type ret= *value;
00141 my_lock.unlock();
00142 return ret;
00143 }
00144
00145 };
00146
00147
00148 }
00149 }
00150
00151