3 * Copyright (C) 2005-2009,2011 Mathias Froehlich
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of the
8 * License, or (at your option) any later version.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 #if defined(__GNUC__) && ((4 < __GNUC__)||(4 == __GNUC__ && 1 <= __GNUC_MINOR__)) && \
26 // No need to include something. Is a Compiler API ...
27 # define SGATOMIC_USE_GCC4_BUILTINS
28 #elif defined(__GNUC__) && defined(__i386__)
29 # define SGATOMIC_USE_LIBRARY_FUNCTIONS
30 #elif defined(__sgi) && defined(_COMPILER_VERSION) && (_COMPILER_VERSION>=730)
31 // No need to include something. Is a Compiler API ...
32 # define SGATOMIC_USE_MIPSPRO_BUILTINS
34 # define SGATOMIC_USE_LIBRARY_FUNCTIONS
36 // The sledge hammer ...
37 # define SGATOMIC_USE_LIBRARY_FUNCTIONS
38 # include <simgear/threads/SGThread.hxx>
43 SGAtomic(unsigned value = 0) : mValue(value)
46 #if defined(SGATOMIC_USE_LIBRARY_FUNCTIONS)
47 unsigned operator++();
51 # if defined(SGATOMIC_USE_GCC4_BUILTINS)
52 return __sync_add_and_fetch(&mValue, 1);
53 # elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
54 return __add_and_fetch(&mValue, 1);
61 #if defined(SGATOMIC_USE_LIBRARY_FUNCTIONS)
62 unsigned operator--();
66 # if defined(SGATOMIC_USE_GCC4_BUILTINS)
67 return __sync_sub_and_fetch(&mValue, 1);
68 # elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
69 return __sub_and_fetch(&mValue, 1);
76 #if defined(SGATOMIC_USE_LIBRARY_FUNCTIONS)
77 operator unsigned() const;
79 operator unsigned() const
81 # if defined(SGATOMIC_USE_GCC4_BUILTINS)
84 # elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
93 #if defined(SGATOMIC_USE_LIBRARY_FUNCTIONS)
94 bool compareAndExchange(unsigned oldValue, unsigned newValue);
96 bool compareAndExchange(unsigned oldValue, unsigned newValue)
98 # if defined(SGATOMIC_USE_GCC4_BUILTINS)
99 return __sync_bool_compare_and_swap(&mValue, oldValue, newValue);
100 # elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
101 return __compare_and_swap(&mValue, oldValue, newValue);
109 SGAtomic(const SGAtomic&);
110 SGAtomic& operator=(const SGAtomic&);
112 #if !defined(SGATOMIC_USE_GCC4_BUILTINS) \
113 && !defined(SGATOMIC_USE_MIPOSPRO_BUILTINS) \
114 && !defined(SGATOMIC_USE_WIN32_INTERLOCKED)
115 mutable SGMutex mMutex;
122 // Typesafe wrapper around SGSwappable
123 template <typename T>
124 class Swappable : private SGAtomic
127 Swappable(const T& value) : SGAtomic(static_cast<unsigned>(value))
130 T operator() () const
132 return static_cast<T>(SGAtomic::operator unsigned ());
134 Swappable& operator=(const Swappable& rhs)
136 for (unsigned oldval = unsigned(*this);
137 !compareAndExchange(oldval, unsigned(rhs));
138 oldval = unsigned(*this))
142 bool compareAndSwap(const T& oldVal, const T& newVal)
144 return SGAtomic::compareAndExchange(static_cast<unsigned>(oldVal),
145 static_cast<unsigned>(newVal));