Ice 3.7 C++11 API Reference
Atomic.h
Go to the documentation of this file.
1 //
2 // Copyright (c) ZeroC, Inc. All rights reserved.
3 //
4 
5 #ifndef ICE_UTIL_ATOMIC_H
6 #define ICE_UTIL_ATOMIC_H
7 
8 #if ((defined(ICE_CPP11_COMPILER) && defined(_MSC_VER) && (_MSC_VER > 1600)) || \
9  (defined(ICE_CPP11_COMPILER) && !defined(_MSC_VER)))
10 # define ICE_CPP11_COMPILER_HAS_ATOMIC
11 #endif
12 
13 #if defined(ICE_CPP11_COMPILER_HAS_ATOMIC)
14 # include <atomic>
15 #elif defined(ICE_USE_MUTEX_SHARED)
16 
17 # include <IceUtil/Mutex.h>
18 
19 // Using the gcc builtins requires gcc 4.1 or better. For Linux, i386
20 // doesn't work. Apple is supported for all architectures. Sun only
21 // supports sparc (32 and 64 bit).
22 
23 #elif ((defined(__GNUC__) && (((__GNUC__* 100) + __GNUC_MINOR__) >= 401)) || __clang__) && \
24  ((defined(__sun) && (defined(__sparc) || defined(__sparcv9))) || \
25  defined(__APPLE__) || \
26  (defined(__linux__) && \
27  (defined(__i486) || defined(__i586) || \
28  defined(__i686) || defined(__x86_64))))
29 
30 # define ICE_HAS_GCC_BUILTINS
31 
32 #elif defined(_WIN32)
33 // Nothing to include
34 #else
35 // Use a simple mutex
36 # include <IceUtil/Mutex.h>
37 #endif
38 
39 namespace IceUtilInternal
40 {
41 
42 #ifdef ICE_CPP11_COMPILER_HAS_ATOMIC
43 typedef std::atomic<int> Atomic;
44 #else
45 
46 #if defined(_WIN32)
47 //
48 // volatile here is required by InterlockedExchangeXXX
49 // family functions.
50 //
51 # if defined(__MINGW32__) || (defined(_MSC_VER) && (_MSC_VER <= 1500))
52 typedef volatile LONG ATOMIC_T;
53 # else
54 typedef unsigned int ATOMIC_T;
55 # endif
56 #else
57 typedef int ATOMIC_T;
58 #endif
59 
60 //
61 // This is temporary and very partial placeholder for std::atomic,
62 // which is not yet widely available.
63 //
64 class ICE_API Atomic : public IceUtil::noncopyable
65 {
66 public:
67 
68  Atomic() :
69  _ref(0)
70  {
71  }
72 
73  Atomic(int desired) :
74  _ref(desired)
75  {
76  }
77 
78  inline int fetch_add(int value)
79  {
80 #if defined(_WIN32)
81  return InterlockedExchangeAdd(&_ref, value);
82 #elif defined(ICE_HAS_GCC_BUILTINS)
83  return __sync_fetch_and_add(&_ref, value);
84 #else
85  IceUtil::Mutex::Lock sync(_mutex);
86  int tmp = _ref;
87  _ref += value;
88  return tmp;
89 #endif
90  }
91 
92  inline int fetch_sub(int value)
93  {
94 #if defined(_WIN32)
95 # if defined(__MINGW32__) || (defined(_MSC_VER) && (_MSC_VER <= 1500))
96  return InterlockedExchangeAdd(&_ref, -value);
97 # else
98  return InterlockedExchangeSubtract(&_ref, value);
99 #endif
100 #elif defined(ICE_HAS_GCC_BUILTINS)
101  return __sync_fetch_and_sub(&_ref, value);
102 #else
103  IceUtil::Mutex::Lock sync(_mutex);
104  ATOMIC_T tmp = _ref;
105  _ref -= value;
106  return tmp;
107 #endif
108  }
109 
110  inline int load() const
111  {
112 #if defined(_WIN32)
113  return InterlockedExchangeAdd(const_cast<ATOMIC_T*>(&_ref), 0);
114 #elif defined(ICE_HAS_GCC_BUILTINS)
115  return __sync_fetch_and_add(const_cast<ATOMIC_T*>(&_ref), 0);
116 #else
117  IceUtil::Mutex::Lock sync(_mutex);
118  return _ref;
119 #endif
120  }
121 
122  inline int exchange(int value)
123  {
124 #if defined(_WIN32)
125  return InterlockedExchange(&_ref, value);
126 #elif defined(ICE_HAS_GCC_BUILTINS)
127  __sync_synchronize();
128  return __sync_lock_test_and_set(&_ref, value);
129 #else
130  IceUtil::Mutex::Lock sync(_mutex);
131  int tmp = _ref;
132  _ref = value;
133  return tmp;
134 #endif
135  }
136 
137  inline int operator++()
138  {
139  return fetch_add(1) + 1;
140  }
141 
142  inline int operator--()
143  {
144  return fetch_sub(1) - 1;
145  }
146 
147  inline int operator++(int)
148  {
149  return fetch_add(1);
150  }
151 
152  inline int operator--(int)
153  {
154  return fetch_sub(1);
155  }
156 
157  inline operator int()
158  {
159  return load();
160  }
161 
162  inline operator int() const
163  {
164  return load();
165  }
166 
167 private:
168 
169  ATOMIC_T _ref;
170 #if !defined(_WIN32) && !defined(ICE_HAS_GCC_BUILTINS)
171  IceUtil::Mutex _mutex;
172 #endif
173 };
174 
175 #endif
176 
177 }
178 
179 #endif
IceUtil::LockT
Definition: Lock.h:37
ICE_API
#define ICE_API
Definition: Config.h:197
IceUtil::noncopyable
Definition: Config.h:313
IceUtil::Mutex
Definition: Mutex.h:33
Mutex.h