Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2881)

Unified Diff: base/atomicops_internals_arm_gcc.h

Issue 18984012: Refine atomic operations for Linux/ARM. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: remove empty line Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: base/atomicops_internals_arm_gcc.h
diff --git a/base/atomicops_internals_arm_gcc.h b/base/atomicops_internals_arm_gcc.h
index 9a6606ef5137bc885d1bf8cc5192caca4c471935..9f4fe2e586e2425270ae2f57da0730bc6bcda8b8 100644
--- a/base/atomicops_internals_arm_gcc.h
+++ b/base/atomicops_internals_arm_gcc.h
@@ -70,7 +70,7 @@ inline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
// reloop = STREX(ptr, new_value)
__asm__ __volatile__(" ldrex %0, [%3]\n"
" mov %1, #0\n"
- " teq %0, %4\n"
+ " cmp %0, %4\n"
#ifdef __thumb2__
" it eq\n"
#endif
@@ -135,7 +135,7 @@ inline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
int reloop;
do {
// old_value = LDREX(ptr)
- // fail = STREX(ptr, new_value)
+ // reloop = STREX(ptr, new_value)
__asm__ __volatile__(" ldrex %0, [%3]\n"
" strex %1, %4, [%3]\n"
: "=&r"(old_value), "=&r"(reloop), "+m"(*ptr)
@@ -232,10 +232,17 @@ inline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
inline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
Atomic32 old_value,
Atomic32 new_value) {
- // Use NoBarrier_CompareAndSwap(), because its implementation
- // ensures that all stores happen through the kernel helper
- // which always implement a full barrier.
- return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
+ // This could be implemented as:
+ // MemoryBarrier();
+ // return NoBarrier_CompareAndSwap();
+ //
+ // But would use 3 barriers per succesful CAS. To save performance,
+ // use Acquire_CompareAndSwap(). Its implementation guarantees that:
+ // - A succesful swap uses only 2 barriers (in the kernel helper).
+ // - An early return due to (prev_value != old_value) performs
+ // a memory barrier with no store, which is equivalent to the
+ // generic implementation above.
+ return Acquire_CompareAndSwap(ptr, old_value, new_value);
Dmitry Vyukov 2013/07/15 14:42:32 A failing Release_CompareAndSwap() does not need a
}
#else
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698