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
12namespace sdk_util {
13
14typedef int32_t Atomic32;
15
16#ifndef __llvm__
17static inline void MemoryBarrier() {
18  __sync_synchronize();
19}
20#endif
21
22inline 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
28inline Atomic32 AtomicAddFetch(volatile Atomic32* ptr, Atomic32 value) {
29  return __sync_add_and_fetch(ptr, value);
30}
31
32inline Atomic32 AtomicAndFetch(volatile Atomic32* ptr, Atomic32 value) {
33  return __sync_and_and_fetch(ptr, value);
34}
35
36inline Atomic32 AtomicOrFetch(volatile Atomic32* ptr, Atomic32 value) {
37  return __sync_or_and_fetch(ptr, value);
38}
39
40inline 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
56namespace sdk_util {
57
58typedef long Atomic32;
59
60/* Windows.h already defines a MemoryBarrier macro. */
61
62inline Atomic32 AtomicCompareExchange(volatile Atomic32* ptr,
63                                      Atomic32 newvalue,
64                                      Atomic32 oldvalue) {
65  return InterlockedCompareExchange(ptr, newvalue, oldvalue);
66}
67
68inline Atomic32 AtomicAddFetch(volatile Atomic32* ptr, Atomic32 value) {
69  return InterlockedExchangeAdd(ptr, value);
70}
71
72inline 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
83inline 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
94inline 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