1 /* 2 * Copyright (C) 2002 - David W. Durham 3 * 4 * This file is part of ReZound, an audio editing application. 5 * 6 * ReZound is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License as published 8 * by the Free Software Foundation; either version 2 of the License, 9 * or (at your option) any later version. 10 * 11 * ReZound is distributed in the hope that it will be useful, but 12 * WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 19 */ 20 #ifndef __CAtomicCounter_H__ 21 #define __CAtomicCounter_H__ 22 23 #include "../../config/common.h" 24 25 #if defined(__linux) && defined(__i386__) && ((__GNUC__ * 100) + __GNUC_MINOR__) < 401 26 27 // using linux's exposed atomic operations on Intel-32bit 28 #define LINUX_ATOMIX 29 #include <asm/atomic.h> 30 31 #elif defined(__clang__) || defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 405 && defined(__GXX_EXPERIMENTAL_CXX0X__)/*for now detect --std=c++0x.. will be removed later*/ 32 33 // gcc-4.5 uses the atomic header (c++v0) 34 #define STL_ATOMIX 35 #include <atomic> 36 37 #elif defined(__GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 404 && defined(__GXX_EXPERIMENTAL_CXX0X__)/*for now detect --std=c++0x.. will be removed later*/ 38 39 // gcc-4.4 introduced atomic operations into the STL (c++v0) 40 #define STL_ATOMIX 41 #include <cstdatomic> 42 #else 43 44 // could use this only and nix the above three implementations.. need look into the cost tho 45 #define BOOST_ATOMIX 46 #include <boost/detail/atomic_count.hpp> 47 48 #endif 49 50 class CAtomicCounter { 51 public: CAtomicCounter()52 CAtomicCounter() 53 #if defined(BOOST_ATOMIX) 54 : counter(0) 55 #endif 56 { 57 #if defined(LINUX_ATOMIX) 58 atomic_set(&counter, 0); 59 #elif defined(STL_ATOMIX) || defined(MUTEX_ATOMIX) 60 counter = 0; 61 #elif defined(BOOST_ATOMIX) 62 // handled in ctor init list 63 #else 64 #error unimplemented 65 #endif 66 } 67 inc()68 int inc() { 69 #if defined(LINUX_ATOMIX) 70 return atomic_inc_return(&counter); 71 #elif defined(STL_ATOMIX) || defined(BOOST_ATOMIX) 72 return ++counter; 73 #elif defined(MUTEX_ATOMIX) 74 CMutexLocker ml(mMutex); 75 return ++counter; 76 #else 77 #error unimplemented 78 #endif 79 } 80 dec()81 int dec() { 82 #if defined(LINUX_ATOMIX) 83 return atomic_dec_return(&counter); 84 #elif defined(STL_ATOMIX) || defined(BOOST_ATOMIX) 85 return --counter; 86 #elif defined(MUTEX_ATOMIX) 87 CMutexLocker ml(mMutex); 88 return --counter; 89 #else 90 #error unimplemented 91 #endif 92 } 93 value()94 int value() const { 95 #if defined(LINUX_ATOMIX) 96 return atomic_read(&counter); 97 #elif defined(STL_ATOMIX) || defined(BOOST_ATOMIX) || defined(MUTEX_ATOMIX) 98 return (int)counter; 99 #endif 100 } 101 102 private: 103 #if defined(LINUX_ATOMIX) 104 atomic_t counter; 105 #elif defined(STL_ATOMIX) 106 std::atomic<int> counter; 107 #elif defined(BOOST_ATOMIX) 108 boost::detail::atomic_count counter; 109 #elif defined(MUTEX_ATOMIX) 110 CMutex mMutex; 111 volatile int counter; 112 #else 113 #error unimplemented 114 #endif 115 116 }; 117 118 #endif 119