Drizzled Public API Documentation

pthread_traits.h
00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2009 Sun Microsystems, Inc.
00005  *  Copyright 2005-2008 Intel Corporation.  All Rights Reserved.
00006  *
00007  *  This program is free software; you can redistribute it and/or modify
00008  *  it under the terms of the GNU General Public License as published by
00009  *  the Free Software Foundation; version 2 of the License.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
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 }; /* pthread_traits */
00146 
00147 
00148 } /* namespace internal */
00149 } /* namespace drizzled */
00150 
00151