summaryrefslogtreecommitdiffstats
path: root/base/atomicops_internals_gcc.h
diff options
context:
space:
mode:
authorbbudge@chromium.org <bbudge@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-22 18:22:03 +0000
committerbbudge@chromium.org <bbudge@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-08-22 18:22:03 +0000
commitb2e7f957f7fed546c540a0ee7123dcb976712022 (patch)
treec6f069e7a4fca83281d8b7d96b65e26576f709d5 /base/atomicops_internals_gcc.h
parent382255a53861cb2eec39b85bf06aed7a05e22530 (diff)
downloadchromium_src-b2e7f957f7fed546c540a0ee7123dcb976712022.zip
chromium_src-b2e7f957f7fed546c540a0ee7123dcb976712022.tar.gz
chromium_src-b2e7f957f7fed546c540a0ee7123dcb976712022.tar.bz2
Fix atomic ops on ARM to compile in NaCl untrusted targets.
This makes the arm version of atomicops_internals use gcc intrinsics for the NaCl build. Other linux targets won't change. BUG=116317 TEST=compiles on arm bots Review URL: https://chromiumcodereview.appspot.com/10831358 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@152791 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/atomicops_internals_gcc.h')
-rw-r--r--base/atomicops_internals_gcc.h104
1 files changed, 104 insertions, 0 deletions
diff --git a/base/atomicops_internals_gcc.h b/base/atomicops_internals_gcc.h
new file mode 100644
index 0000000..fe7a862
--- /dev/null
+++ b/base/atomicops_internals_gcc.h
@@ -0,0 +1,104 @@
+// Copyright (c) 2009 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// This file is an internal atomic implementation, include base/atomicops.h
+// instead. This file is for platforms that use GCC intrinsics rather than
+// platform-specific assembly code for atomic operations.
+
+#ifndef BASE_ATOMICOPS_INTERNALS_GCC_H_
+#define BASE_ATOMICOPS_INTERNALS_GCC_H_
+
+namespace base {
+namespace subtle {
+
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ Atomic32 prev_value;
+ do {
+ prev_value = __sync_val_compare_and_swap(ptr, old_value, new_value);
+ } while (prev_value != old_value);
+ return old_value;
+}
+
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
+ Atomic32 new_value) {
+ Atomic32 old_value;
+ do {
+ old_value = *ptr;
+ } while (!__sync_bool_compare_and_swap(ptr, old_value, new_value));
+ return old_value;
+}
+
+inline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ return Barrier_AtomicIncrement(ptr, increment);
+}
+
+inline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
+ Atomic32 increment) {
+ for (;;) {
+ // Atomic exchange the old value with an incremented one.
+ Atomic32 old_value = *ptr;
+ Atomic32 new_value = old_value + increment;
+ if (__sync_bool_compare_and_swap(ptr, old_value, new_value)) {
+ // The exchange took place as expected.
+ return new_value;
+ }
+ // Otherwise, *ptr changed mid-loop and we need to retry.
+ }
+}
+
+inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ // Since NoBarrier_CompareAndSwap uses __sync_bool_compare_and_swap, which
+ // is a full memory barrier, none is needed here or below in Release.
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
+ Atomic32 old_value,
+ Atomic32 new_value) {
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+}
+
+inline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+}
+
+inline void MemoryBarrier() {
+ __sync_synchronize();
+}
+
+inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
+ *ptr = value;
+ MemoryBarrier();
+}
+
+inline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
+ MemoryBarrier();
+ *ptr = value;
+}
+
+inline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
+ return *ptr;
+}
+
+inline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
+ Atomic32 value = *ptr;
+ MemoryBarrier();
+ return value;
+}
+
+inline Atomic32 Release_Load(volatile const Atomic32* ptr) {
+ MemoryBarrier();
+ return *ptr;
+}
+
+} // namespace base::subtle
+} // namespace base
+
+#endif // BASE_ATOMICOPS_INTERNALS_GCC_H_
+