HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
SYS_AtomicInt.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: SYS_AtomicInt.h ( UT Library, C++)
7  *
8  * COMMENTS: Thread-safe operations on 32-bit integers
9  */
10 
11 #ifndef __SYS_AtomicInt__
12 #define __SYS_AtomicInt__
13 
14 #include "SYS_API.h"
15 #include "SYS_Types.h"
16 #include "SYS_MemoryOrder.h"
17 #include "SYS_AtomicImpl.h"
18 
19 template <typename T>
21 {
22 public:
23  explicit SYS_AtomicInt(T value = 0) : myValue(value) {}
24 
25  /// An empty constructor. This will initialize the value with garbage,
26  /// unless used as a static object (in which case it will be guaranteed
27  /// by the C++ standard to be initialized to zero). Only use if required
28  /// to be set prior to other, dependent statically initialized objects.
30 
31  /// Atomically assigns val to myValue, returning the prior value of
32  /// myValue.
33  inline T exchange(T val);
34 
35  /// Atomically adds val to myValue, returning the prior value of
36  /// myValue.
37  inline T exchangeAdd(T val);
38 
39  /// Atomically adds val to myValue, returning the new value of myValue.
40  inline T add(T val);
41 
42  /// Atomically set myValue to the maximum of val and myValue.
43  inline void maximum(T val);
44 
45  /// Atomically compares (myValue == expected), and if true, replaces
46  /// myValue with desired. Returns prior myValue.
47  inline T compare_swap(T expected, T desired);
48 
49  /// @pre The supplied order must be one of [RELAXED, STORE, SEQ_CST].
50  inline void store(T val,
52 
53  /// @pre The supplied order must be one of [RELAXED, LOAD, SEQ_CST].
55  const;
56  /// Atomically retrieve value. Same as calling load().
57  operator T() const;
58 
59  /// Forced RELAXED memory load
60  /// GCC has trouble inlining so we pull the definition up here.
62 #ifdef WIN32
63  { return load(SYS_MEMORY_ORDER_RELAXED); }
64 #else
65  { return *static_cast<const volatile T *>(&myValue); }
66 #endif
67 
70 
71 private:
72  T myValue;
73 
74 private:
75  // Prohibited operators
77  SYS_AtomicInt &operator=(const SYS_AtomicInt &);
78 };
79 
82 
83 #ifdef AMD64
85 #else
87 #endif
88 
89 template <typename T>
92 {
93  return SYS_AtomicImpl::test_and_set(&myValue, val);
94 }
95 
96 template <typename T>
99 {
100  return SYS_AtomicImpl::test_and_add(&myValue, val);
101 }
102 
103 template <typename T>
106 {
107  return SYS_AtomicImpl::test_and_add(&myValue, val) + val;
108 }
109 
110 template <typename T>
113 {
114  while (true)
115  {
116  T me = myValue;
117  if (val > me)
118  {
119  if (me == compare_swap(me, val))
120  return;
121  }
122  else
123  {
124  return;
125  }
126  }
127 }
128 
129 template <typename T>
131 SYS_AtomicInt<T>::compare_swap(T expected, T desired)
132 {
133  return SYS_AtomicImpl::compare_and_swap(&myValue, expected, desired);
134 }
135 
136 /// Next two methods intentionally not marked as volatile as this would cause
137 /// &myValue to evaluate to a pointer to a volatile myValue and that has
138 /// implications on MSVC2005+ beyond the C++ spec.
139 ///
140 /// This shouldn't be a problem unless somebody needs a volatile instance of
141 /// SYS_AtomicInt<T>.
142 template <typename T>
145 {
146  SYS_AtomicImpl::store(&myValue, val, order);
147 }
148 
149 template <typename T>
152 {
153  return SYS_AtomicImpl::load(&myValue, order);
154 }
155 
156 template <typename T>
159 {
160  return load();
161 }
162 
163 #endif
164 
T compare_and_swap(volatile T *addr, T oldval, T newval)
SYS_AtomicInt(T value=0)
Definition: SYS_AtomicInt.h:23
T test_and_set(T *addr, T val)
SYS_AtomicInt< int32 > SYS_AtomicInt32
Definition: SYS_AtomicInt.h:80
void store(T val, SYS_MemoryOrder order=SYS_MEMORY_ORDER_SEQ_CST)
T exchange(T val)
Definition: SYS_AtomicInt.h:91
SYS_AtomicInt(SYS_EmptyConstructor)
Definition: SYS_AtomicInt.h:29
T exchangeAdd(T val)
Definition: SYS_AtomicInt.h:98
SYS_MemoryOrder
void maximum(T val)
Atomically set myValue to the maximum of val and myValue.
SYS_EmptyConstructor
Definition: SYS_Types.h:413
T load(SYS_MemoryOrder order=SYS_MEMORY_ORDER_SEQ_CST) const
#define SYS_FORCE_INLINE
Definition: SYS_Inline.h:45
#define SYS_ATOMIC_INLINE
T compare_swap(T expected, T desired)
SYS_AtomicInt< int64 > SYS_AtomicInt64
Definition: SYS_AtomicInt.h:81
T test_and_add(T *addr, T val)
Any reordering the compiler or hardware chooses to do is okay.
GLsizei const GLfloat * value
Definition: glcorearb.h:823
SYS_AtomicInt< int32 > SYS_AtomicCounter
Definition: SYS_AtomicInt.h:86
GLuint GLfloat * val
Definition: glcorearb.h:1607
T add(T val)
Atomically adds val to myValue, returning the new value of myValue.
#define const
Definition: zconf.h:214
SYS_FORCE_INLINE void relaxedStore(T val)
Definition: SYS_AtomicInt.h:68
SYS_FORCE_INLINE T relaxedLoad() const
Definition: SYS_AtomicInt.h:61