Chromium Code Reviews| Index: base/atomicops_internals_gcc.h | 
| =================================================================== | 
| --- base/atomicops_internals_gcc.h (revision 152192) | 
| +++ base/atomicops_internals_gcc.h (working copy) | 
| @@ -2,39 +2,22 @@ | 
| // 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, use base/atomicops.h instead. | 
| -// | 
| -// LinuxKernelCmpxchg and Barrier_AtomicIncrement are from Google Gears. | 
| +// 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_ARM_GCC_H_ | 
| -#define BASE_ATOMICOPS_INTERNALS_ARM_GCC_H_ | 
| +#ifndef BASE_ATOMICOPS_INTERNALS_GCC_H_ | 
| +#define BASE_ATOMICOPS_INTERNALS_GCC_H_ | 
| namespace base { | 
| namespace subtle { | 
| -// 0xffff0fc0 is the hard coded address of a function provided by | 
| -// the kernel which implements an atomic compare-exchange. On older | 
| -// ARM architecture revisions (pre-v6) this may be implemented using | 
| -// a syscall. This address is stable, and in active use (hard coded) | 
| -// by at least glibc-2.7 and the Android C library. | 
| -typedef Atomic32 (*LinuxKernelCmpxchgFunc)(Atomic32 old_value, | 
| - Atomic32 new_value, | 
| - volatile Atomic32* ptr); | 
| -LinuxKernelCmpxchgFunc pLinuxKernelCmpxchg __attribute__((weak)) = | 
| - (LinuxKernelCmpxchgFunc) 0xffff0fc0; | 
| - | 
| -typedef void (*LinuxKernelMemoryBarrierFunc)(void); | 
| -LinuxKernelMemoryBarrierFunc pLinuxKernelMemoryBarrier __attribute__((weak)) = | 
| - (LinuxKernelMemoryBarrierFunc) 0xffff0fa0; | 
| - | 
| - | 
| inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, | 
| Atomic32 old_value, | 
| Atomic32 new_value) { | 
| Atomic32 prev_value = *ptr; | 
| do { | 
| - if (!pLinuxKernelCmpxchg(old_value, new_value, | 
| - const_cast<Atomic32*>(ptr))) { | 
| + if (__sync_bool_compare_and_swap(ptr, old_value, new_value)) { | 
| 
 
Roland McGrath
2012/08/21 22:14:15
Why not just use __sync_val_compare_and_swap here?
 
bbudge
2012/08/21 23:23:40
Done.
 
 | 
| return old_value; | 
| } | 
| prev_value = *ptr; | 
| @@ -47,8 +30,7 @@ | 
| Atomic32 old_value; | 
| do { | 
| old_value = *ptr; | 
| - } while (pLinuxKernelCmpxchg(old_value, new_value, | 
| - const_cast<Atomic32*>(ptr))); | 
| + } while (!__sync_bool_compare_and_swap(ptr, old_value, new_value)); | 
| return old_value; | 
| } | 
| @@ -63,19 +45,19 @@ | 
| // Atomic exchange the old value with an incremented one. | 
| Atomic32 old_value = *ptr; | 
| Atomic32 new_value = old_value + increment; | 
| - if (pLinuxKernelCmpxchg(old_value, new_value, | 
| - const_cast<Atomic32*>(ptr)) == 0) { | 
| + if (!__sync_bool_compare_and_swap(ptr, old_value, new_value) == 0) { | 
| 
 
Roland McGrath
2012/08/21 22:14:15
(!... == 0) should be just (...).
 
bbudge
2012/08/21 23:23:40
Done.
 
 | 
| // 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); | 
| } | 
| @@ -90,7 +72,7 @@ | 
| } | 
| inline void MemoryBarrier() { | 
| - pLinuxKernelMemoryBarrier(); | 
| + __sync_synchronize(); | 
| } | 
| inline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) { | 
| @@ -118,7 +100,8 @@ | 
| return *ptr; | 
| } | 
| -} // namespace base::subtle | 
| -} // namespace base | 
| +} // namespace base::subtle | 
| +} // namespace base | 
| -#endif // BASE_ATOMICOPS_INTERNALS_ARM_GCC_H_ | 
| +#endif // BASE_ATOMICOPS_INTERNALS_GCC_H_ | 
| + |