- add sources.
[platform/framework/web/crosswalk.git] / src / base / atomicops_internals_mac.h
1 // Copyright (c) 2012 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 // This file is an internal atomic implementation, use base/atomicops.h instead.
6
7 #ifndef BASE_ATOMICOPS_INTERNALS_MAC_H_
8 #define BASE_ATOMICOPS_INTERNALS_MAC_H_
9
10 #include <libkern/OSAtomic.h>
11
12 namespace base {
13 namespace subtle {
14
15 inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr,
16                                          Atomic32 old_value,
17                                          Atomic32 new_value) {
18   Atomic32 prev_value;
19   do {
20     if (OSAtomicCompareAndSwap32(old_value, new_value,
21                                  const_cast<Atomic32*>(ptr))) {
22       return old_value;
23     }
24     prev_value = *ptr;
25   } while (prev_value == old_value);
26   return prev_value;
27 }
28
29 inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr,
30                                          Atomic32 new_value) {
31   Atomic32 old_value;
32   do {
33     old_value = *ptr;
34   } while (!OSAtomicCompareAndSwap32(old_value, new_value,
35                                      const_cast<Atomic32*>(ptr)));
36   return old_value;
37 }
38
39 inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr,
40                                           Atomic32 increment) {
41   return OSAtomicAdd32(increment, const_cast<Atomic32*>(ptr));
42 }
43
44 inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32 *ptr,
45                                           Atomic32 increment) {
46   return OSAtomicAdd32Barrier(increment, const_cast<Atomic32*>(ptr));
47 }
48
49 inline void MemoryBarrier() {
50   OSMemoryBarrier();
51 }
52
53 inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr,
54                                        Atomic32 old_value,
55                                        Atomic32 new_value) {
56   Atomic32 prev_value;
57   do {
58     if (OSAtomicCompareAndSwap32Barrier(old_value, new_value,
59                                         const_cast<Atomic32*>(ptr))) {
60       return old_value;
61     }
62     prev_value = *ptr;
63   } while (prev_value == old_value);
64   return prev_value;
65 }
66
67 inline Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr,
68                                        Atomic32 old_value,
69                                        Atomic32 new_value) {
70   return Acquire_CompareAndSwap(ptr, old_value, new_value);
71 }
72
73 inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
74   *ptr = value;
75 }
76
77 inline void Acquire_Store(volatile Atomic32 *ptr, Atomic32 value) {
78   *ptr = value;
79   MemoryBarrier();
80 }
81
82 inline void Release_Store(volatile Atomic32 *ptr, Atomic32 value) {
83   MemoryBarrier();
84   *ptr = value;
85 }
86
87 inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
88   return *ptr;
89 }
90
91 inline Atomic32 Acquire_Load(volatile const Atomic32 *ptr) {
92   Atomic32 value = *ptr;
93   MemoryBarrier();
94   return value;
95 }
96
97 inline Atomic32 Release_Load(volatile const Atomic32 *ptr) {
98   MemoryBarrier();
99   return *ptr;
100 }
101
102 #ifdef __LP64__
103
104 // 64-bit implementation on 64-bit platform
105
106 inline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64 *ptr,
107                                          Atomic64 old_value,
108                                          Atomic64 new_value) {
109   Atomic64 prev_value;
110   do {
111     if (OSAtomicCompareAndSwap64(old_value, new_value,
112                                  reinterpret_cast<volatile int64_t*>(ptr))) {
113       return old_value;
114     }
115     prev_value = *ptr;
116   } while (prev_value == old_value);
117   return prev_value;
118 }
119
120 inline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64 *ptr,
121                                          Atomic64 new_value) {
122   Atomic64 old_value;
123   do {
124     old_value = *ptr;
125   } while (!OSAtomicCompareAndSwap64(old_value, new_value,
126                                      reinterpret_cast<volatile int64_t*>(ptr)));
127   return old_value;
128 }
129
130 inline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64 *ptr,
131                                           Atomic64 increment) {
132   return OSAtomicAdd64(increment, reinterpret_cast<volatile int64_t*>(ptr));
133 }
134
135 inline Atomic64 Barrier_AtomicIncrement(volatile Atomic64 *ptr,
136                                         Atomic64 increment) {
137   return OSAtomicAdd64Barrier(increment,
138                               reinterpret_cast<volatile int64_t*>(ptr));
139 }
140
141 inline Atomic64 Acquire_CompareAndSwap(volatile Atomic64 *ptr,
142                                        Atomic64 old_value,
143                                        Atomic64 new_value) {
144   Atomic64 prev_value;
145   do {
146     if (OSAtomicCompareAndSwap64Barrier(
147         old_value, new_value, reinterpret_cast<volatile int64_t*>(ptr))) {
148       return old_value;
149     }
150     prev_value = *ptr;
151   } while (prev_value == old_value);
152   return prev_value;
153 }
154
155 inline Atomic64 Release_CompareAndSwap(volatile Atomic64 *ptr,
156                                        Atomic64 old_value,
157                                        Atomic64 new_value) {
158   // The lib kern interface does not distinguish between
159   // Acquire and Release memory barriers; they are equivalent.
160   return Acquire_CompareAndSwap(ptr, old_value, new_value);
161 }
162
163 inline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
164   *ptr = value;
165 }
166
167 inline void Acquire_Store(volatile Atomic64 *ptr, Atomic64 value) {
168   *ptr = value;
169   MemoryBarrier();
170 }
171
172 inline void Release_Store(volatile Atomic64 *ptr, Atomic64 value) {
173   MemoryBarrier();
174   *ptr = value;
175 }
176
177 inline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
178   return *ptr;
179 }
180
181 inline Atomic64 Acquire_Load(volatile const Atomic64 *ptr) {
182   Atomic64 value = *ptr;
183   MemoryBarrier();
184   return value;
185 }
186
187 inline Atomic64 Release_Load(volatile const Atomic64 *ptr) {
188   MemoryBarrier();
189   return *ptr;
190 }
191
192 #endif  // defined(__LP64__)
193
194 }   // namespace base::subtle
195 }   // namespace base
196
197 #endif  // BASE_ATOMICOPS_INTERNALS_MAC_H_