1 /* Copyright 2013 The Chromium Authors. All rights reserved.
2 * Use of this source code is governed by a BSD-style license that can be
3 * found in the LICENSE file. */
4
5 #ifndef LIBRARIES_SDK_UTIL_ATOMICOPS_H_
6 #define LIBRARIES_SDK_UTIL_ATOMICOPS_H_
7
8 #ifndef WIN32
9
10 #include <stdint.h>
11
12 namespace sdk_util {
13
14 typedef int32_t Atomic32;
15
16 #ifndef __llvm__
MemoryBarrier()17 static inline void MemoryBarrier() {
18 __sync_synchronize();
19 }
20 #endif
21
AtomicCompareExchange(volatile Atomic32 * ptr,Atomic32 new_value,Atomic32 old_value)22 inline Atomic32 AtomicCompareExchange(volatile Atomic32* ptr,
23 Atomic32 new_value,
24 Atomic32 old_value) {
25 return __sync_val_compare_and_swap(ptr, new_value, old_value);
26 }
27
AtomicAddFetch(volatile Atomic32 * ptr,Atomic32 value)28 inline Atomic32 AtomicAddFetch(volatile Atomic32* ptr, Atomic32 value) {
29 return __sync_add_and_fetch(ptr, value);
30 }
31
AtomicAndFetch(volatile Atomic32 * ptr,Atomic32 value)32 inline Atomic32 AtomicAndFetch(volatile Atomic32* ptr, Atomic32 value) {
33 return __sync_and_and_fetch(ptr, value);
34 }
35
AtomicOrFetch(volatile Atomic32 * ptr,Atomic32 value)36 inline Atomic32 AtomicOrFetch(volatile Atomic32* ptr, Atomic32 value) {
37 return __sync_or_and_fetch(ptr, value);
38 }
39
AtomicXorFetch(volatile Atomic32 * ptr,Atomic32 value)40 inline Atomic32 AtomicXorFetch(volatile Atomic32* ptr, Atomic32 value) {
41 return __sync_xor_and_fetch(ptr, value);
42 }
43
44 } // namespace sdk_util
45
46 #else // ifndef WIN32
47
48 #include <windows.h>
49
50 /* Undefine many Windows.h macros that we almost certainly do not want. */
51 #undef min
52 #undef max
53 #undef PostMessage
54 #undef interface
55
56 namespace sdk_util {
57
58 typedef long Atomic32;
59
60 /* Windows.h already defines a MemoryBarrier macro. */
61
AtomicCompareExchange(volatile Atomic32 * ptr,Atomic32 newvalue,Atomic32 oldvalue)62 inline Atomic32 AtomicCompareExchange(volatile Atomic32* ptr,
63 Atomic32 newvalue,
64 Atomic32 oldvalue) {
65 return InterlockedCompareExchange(ptr, newvalue, oldvalue);
66 }
67
AtomicAddFetch(volatile Atomic32 * ptr,Atomic32 value)68 inline Atomic32 AtomicAddFetch(volatile Atomic32* ptr, Atomic32 value) {
69 return InterlockedExchangeAdd(ptr, value);
70 }
71
AtomicAndFetch(volatile Atomic32 * ptr,Atomic32 value)72 inline Atomic32 AtomicAndFetch(volatile Atomic32* ptr, Atomic32 value) {
73 Atomic32 oldval;
74 Atomic32 newval;
75 do {
76 oldval = *ptr;
77 newval = oldval & value;
78 } while (InterlockedCompareExchange(ptr, newval, oldval) != oldval);
79
80 return newval;
81 }
82
AtomicOrFetch(volatile Atomic32 * ptr,Atomic32 value)83 inline Atomic32 AtomicOrFetch(volatile Atomic32* ptr, Atomic32 value) {
84 Atomic32 oldval;
85 Atomic32 newval;
86 do {
87 oldval = *ptr;
88 newval = oldval | value;
89 } while (InterlockedCompareExchange(ptr,newval, oldval) != oldval);
90
91 return newval;
92 }
93
AtomicXorFetch(volatile Atomic32 * ptr,Atomic32 value)94 inline Atomic32 AtomicXorFetch(volatile Atomic32* ptr, Atomic32 value) {
95 Atomic32 oldval;
96 Atomic32 newval;
97 do {
98 oldval = *ptr;
99 newval = oldval ^ value;
100 } while (InterlockedCompareExchange(ptr,newval, oldval) != oldval);
101
102 return newval;
103 }
104
105 } // namespace sdk_util
106
107 #endif // ifndef WIN32
108
109 #endif /* LIBRARIES_SDK_UTIL_ATOMICOPS_H_ */
110