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 # define SGATOMIC_USE_MUTEX
39 # include <simgear/threads/SGThread.hxx>
44 SGAtomic(unsigned value = 0) : mValue(value)
47 #if defined(SGATOMIC_USE_LIBRARY_FUNCTIONS)
48 unsigned operator++();
52 # if defined(SGATOMIC_USE_GCC4_BUILTINS)
53 return __sync_add_and_fetch(&mValue, 1);
54 # elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
55 return __add_and_fetch(&mValue, 1);
62 #if defined(SGATOMIC_USE_LIBRARY_FUNCTIONS)
63 unsigned operator--();
67 # if defined(SGATOMIC_USE_GCC4_BUILTINS)
68 return __sync_sub_and_fetch(&mValue, 1);
69 # elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
70 return __sub_and_fetch(&mValue, 1);
77 #if defined(SGATOMIC_USE_LIBRARY_FUNCTIONS)
78 operator unsigned() const;
80 operator unsigned() const
82 # if defined(SGATOMIC_USE_GCC4_BUILTINS)
85 # elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
94 #if defined(SGATOMIC_USE_LIBRARY_FUNCTIONS)
95 bool compareAndExchange(unsigned oldValue, unsigned newValue);
97 bool compareAndExchange(unsigned oldValue, unsigned newValue)
99 # if defined(SGATOMIC_USE_GCC4_BUILTINS)
100 return __sync_bool_compare_and_swap(&mValue, oldValue, newValue);
101 # elif defined(SGATOMIC_USE_MIPOSPRO_BUILTINS)
102 return __compare_and_swap(&mValue, oldValue, newValue);
110 SGAtomic(const SGAtomic&);
111 SGAtomic& operator=(const SGAtomic&);
113 #if defined(SGATOMIC_USE_MUTEX)
114 mutable SGMutex mMutex;
121 // Typesafe wrapper around SGSwappable
122 template <typename T>
123 class Swappable : private SGAtomic
126 Swappable(const T& value) : SGAtomic(static_cast<unsigned>(value))
129 T operator() () const
131 return static_cast<T>(SGAtomic::operator unsigned ());
133 Swappable& operator=(const Swappable& rhs)
135 for (unsigned oldval = unsigned(*this);
136 !compareAndExchange(oldval, unsigned(rhs));
137 oldval = unsigned(*this))
141 bool compareAndSwap(const T& oldVal, const T& newVal)
143 return SGAtomic::compareAndExchange(static_cast<unsigned>(oldVal),
144 static_cast<unsigned>(newVal));