diff options
author | bbudge@chromium.org <bbudge@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-22 18:22:03 +0000 |
---|---|---|
committer | bbudge@chromium.org <bbudge@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-08-22 18:22:03 +0000 |
commit | b2e7f957f7fed546c540a0ee7123dcb976712022 (patch) | |
tree | c6f069e7a4fca83281d8b7d96b65e26576f709d5 /base/atomicops_internals_gcc.h | |
parent | 382255a53861cb2eec39b85bf06aed7a05e22530 (diff) | |
download | chromium_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.h | 104 |
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_ + |