GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / arch / arm / include / asm / mutex.h
blob66a5ddc175990fdc4e379229777fb2c4dc19a61c
1 /* Modified by Broadcom Corp. Portions Copyright (c) Broadcom Corp, 2012. */
2 /*
3 * arch/arm/include/asm/mutex.h
5 * ARM optimized mutex locking primitives
7 * Please look into asm-generic/mutex-xchg.h for a formal definition.
8 */
9 #ifndef _ASM_MUTEX_H
10 #define _ASM_MUTEX_H
12 #if __LINUX_ARM_ARCH__ < 6
13 /* On pre-ARMv6 hardware the swp based implementation is the most efficient. */
14 # include <asm-generic/mutex-xchg.h>
15 #else
18 * Attempting to lock a mutex on ARMv6+ can be done with a bastardized
19 * atomic decrement (it is not a reliable atomic decrement but it satisfies
20 * the defined semantics for our purpose, while being smaller and faster
21 * than a real atomic decrement or atomic swap. The idea is to attempt
22 * decrementing the lock value only once. If once decremented it isn't zero,
23 * or if its store-back fails due to a dispute on the exclusive store, we
24 * simply bail out immediately through the slow path where the lock will be
25 * reattempted until it succeeds.
27 static inline void
28 __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
30 int __ex_flag, __res;
32 __asm__ (
34 "ldrex %0, [%2] \n\t"
35 "sub %0, %0, #1 \n\t"
36 "strex %1, %0, [%2] "
38 : "=&r" (__res), "=&r" (__ex_flag)
39 : "r" (&(count)->counter)
40 : "cc","memory" );
42 __res |= __ex_flag;
43 if (unlikely(__res != 0))
44 fail_fn(count);
47 static inline int
48 __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
50 int __ex_flag, __res;
52 __asm__ (
54 "ldrex %0, [%2] \n\t"
55 "sub %0, %0, #1 \n\t"
56 "strex %1, %0, [%2] "
58 : "=&r" (__res), "=&r" (__ex_flag)
59 : "r" (&(count)->counter)
60 : "cc","memory" );
62 __res |= __ex_flag;
63 if (unlikely(__res != 0))
64 __res = fail_fn(count);
65 return __res;
69 * Same trick is used for the unlock fast path. However the original value,
70 * rather than the result, is used to test for success in order to have
71 * better generated assembly.
73 static inline void
74 __mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
76 int __ex_flag, __res, __orig;
78 __asm__ (
80 "ldrex %0, [%3] \n\t"
81 "add %1, %0, #1 \n\t"
82 "strex %2, %1, [%3] "
84 : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag)
85 : "r" (&(count)->counter)
86 : "cc","memory" );
88 __orig |= __ex_flag;
89 if (unlikely(__orig != 0))
90 fail_fn(count);
94 * If the unlock was done on a contended lock, or if the unlock simply fails
95 * then the mutex remains locked.
97 #define __mutex_slowpath_needs_to_unlock() 1
100 * For __mutex_fastpath_trylock we use another construct which could be
101 * described as a "single value cmpxchg".
103 * This provides the needed trylock semantics like cmpxchg would, but it is
104 * lighter and less generic than a true cmpxchg implementation.
106 static inline int
107 __mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
109 int __ex_flag, __res, __orig;
111 __asm__ (
113 "1: ldrex %0, [%3] \n\t"
114 "subs %1, %0, #1 \n\t"
115 "strexeq %2, %1, [%3] \n\t"
116 "movlt %0, #0 \n\t"
117 "cmpeq %2, #0 \n\t"
118 "bgt 1b "
120 : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag)
121 : "r" (&count->counter)
122 : "cc", "memory" );
124 return __orig;
127 #endif
128 #endif