Index: base/atomicops_internals_nacl.h |
=================================================================== |
--- base/atomicops_internals_nacl.h (revision 0) |
+++ base/atomicops_internals_nacl.h (revision 0) |
@@ -0,0 +1,108 @@ |
+// Copyright (c) 2012 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, use base/atomicops.h instead. |
+ |
+#ifndef BASE_ATOMICOPS_INTERNALS_NACL_H_ |
+#define BASE_ATOMICOPS_INTERNALS_NACL_H_ |
+ |
+// For Native Client, use GCC atomic op intrinsics. |
bbudge
2012/08/16 20:44:17
This file is a copy of base/atomicops_internals_ar
jar (doing other things)
2012/08/16 22:47:21
You should at a minimum put this comment in the co
Mark Seaborn
2012/08/17 00:08:24
Is there any reason you can't modify the existing
bbudge
2012/08/21 02:02:07
Done. I added conditional expressions to switch be
bbudge
2012/08/21 02:02:07
Since I have no idea what the strange Linux code t
|
+ |
+namespace base { |
+namespace subtle { |
+ |
+inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr, |
+ Atomic32 old_value, |
+ Atomic32 new_value) { |
+ Atomic32 prev_value = *ptr; |
+ do { |
+ if (!__sync_val_compare_and_swap(const_cast<Atomic32*>(ptr), |
+ old_value, new_value)) { |
+ return old_value; |
+ } |
+ prev_value = *ptr; |
+ } while (prev_value == old_value); |
+ return prev_value; |
+} |
+ |
+inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr, |
+ Atomic32 new_value) { |
+ Atomic32 old_value; |
+ do { |
+ old_value = *ptr; |
+ } while (__sync_val_compare_and_swap(const_cast<Atomic32*>(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_val_compare_and_swap(const_cast<Atomic32*>(ptr), |
+ old_value, new_value) == 0) { |
+ // 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) { |
+ return NoBarrier_CompareAndSwap(ptr, old_value, new_value); |
jar (doing other things)
2012/08/16 22:47:21
This was confusing, since Acquire semantics requir
bbudge
2012/08/21 21:49:02
This code is indeed confusing. I succeeded in merg
|
+} |
+ |
+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_NACL_H_ |