diff options
| author | Arun Sharma <asharma@fb.com> | 2011-07-26 19:09:07 -0400 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-07-26 19:49:47 -0400 |
| commit | f24219b4e90cf70ec4a211b17fbabc725a0ddf3c (patch) | |
| tree | c1c753bd425d61a5094995d9835b23b46383d9b2 | |
| parent | 60063497a95e716c9a689af3be2687d261f115b4 (diff) | |
atomic: move atomic_add_unless to generic code
This is in preparation for more generic atomic primitives based on
__atomic_add_unless.
Signed-off-by: Arun Sharma <asharma@fb.com>
Signed-off-by: Hans-Christian Egtvedt <hans-christian.egtvedt@atmel.com>
Reviewed-by: Eric Dumazet <eric.dumazet@gmail.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: David Miller <davem@davemloft.net>
Acked-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
26 files changed, 109 insertions, 102 deletions
diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h index 88b7491490bc..3d6704910268 100644 --- a/arch/alpha/include/asm/atomic.h +++ b/arch/alpha/include/asm/atomic.h | |||
| @@ -176,15 +176,15 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v) | |||
| 176 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | 176 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) |
| 177 | 177 | ||
| 178 | /** | 178 | /** |
| 179 | * atomic_add_unless - add unless the number is a given value | 179 | * __atomic_add_unless - add unless the number is a given value |
| 180 | * @v: pointer of type atomic_t | 180 | * @v: pointer of type atomic_t |
| 181 | * @a: the amount to add to v... | 181 | * @a: the amount to add to v... |
| 182 | * @u: ...unless v is equal to u. | 182 | * @u: ...unless v is equal to u. |
| 183 | * | 183 | * |
| 184 | * Atomically adds @a to @v, so long as it was not @u. | 184 | * Atomically adds @a to @v, so long as it was not @u. |
| 185 | * Returns non-zero if @v was not @u, and zero otherwise. | 185 | * Returns the old value of @v. |
| 186 | */ | 186 | */ |
| 187 | static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) | 187 | static __inline__ int __atomic_add_unless(atomic_t *v, int a, int u) |
| 188 | { | 188 | { |
| 189 | int c, old; | 189 | int c, old; |
| 190 | c = atomic_read(v); | 190 | c = atomic_read(v); |
| @@ -196,7 +196,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) | |||
| 196 | break; | 196 | break; |
| 197 | c = old; | 197 | c = old; |
| 198 | } | 198 | } |
| 199 | return c != (u); | 199 | return c; |
| 200 | } | 200 | } |
| 201 | 201 | ||
| 202 | 202 | ||
| @@ -207,7 +207,7 @@ static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) | |||
| 207 | * @u: ...unless v is equal to u. | 207 | * @u: ...unless v is equal to u. |
| 208 | * | 208 | * |
| 209 | * Atomically adds @a to @v, so long as it was not @u. | 209 | * Atomically adds @a to @v, so long as it was not @u. |
| 210 | * Returns non-zero if @v was not @u, and zero otherwise. | 210 | * Returns the old value of @v. |
| 211 | */ | 211 | */ |
| 212 | static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) | 212 | static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u) |
| 213 | { | 213 | { |
diff --git a/arch/arm/include/asm/atomic.h b/arch/arm/include/asm/atomic.h index 4d501f1bdc9d..3757e91c5281 100644 --- a/arch/arm/include/asm/atomic.h +++ b/arch/arm/include/asm/atomic.h | |||
| @@ -208,14 +208,14 @@ static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr) | |||
| 208 | 208 | ||
| 209 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | 209 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) |
| 210 | 210 | ||
| 211 | static inline int atomic_add_unless(atomic_t *v, int a, int u) | 211 | static inline int __atomic_add_unless(atomic_t *v, int a, int u) |
| 212 | { | 212 | { |
| 213 | int c, old; | 213 | int c, old; |
| 214 | 214 | ||
| 215 | c = atomic_read(v); | 215 | c = atomic_read(v); |
| 216 | while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c) | 216 | while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c) |
| 217 | c = old; | 217 | c = old; |
| 218 | return c != u; | 218 | return c; |
| 219 | } | 219 | } |
| 220 | 220 | ||
| 221 | #define atomic_inc(v) atomic_add(1, v) | 221 | #define atomic_inc(v) atomic_add(1, v) |
diff --git a/arch/avr32/include/asm/atomic.h b/arch/avr32/include/asm/atomic.h index f229c3849f03..dc6c3a41a2d7 100644 --- a/arch/avr32/include/asm/atomic.h +++ b/arch/avr32/include/asm/atomic.h | |||
| @@ -78,70 +78,63 @@ static inline int atomic_add_return(int i, atomic_t *v) | |||
| 78 | /* | 78 | /* |
| 79 | * atomic_sub_unless - sub unless the number is a given value | 79 | * atomic_sub_unless - sub unless the number is a given value |
| 80 | * @v: pointer of type atomic_t | 80 | * @v: pointer of type atomic_t |
| 81 | * @a: the amount to add to v... | 81 | * @a: the amount to subtract from v... |
| 82 | * @u: ...unless v is equal to u. | 82 | * @u: ...unless v is equal to u. |
| 83 | * | 83 | * |
| 84 | * If the atomic value v is not equal to u, this function subtracts a | 84 | * Atomically subtract @a from @v, so long as it was not @u. |
| 85 | * from v, and returns non zero. If v is equal to u then it returns | 85 | * Returns the old value of @v. |
| 86 | * zero. This is done as an atomic operation. | ||
| 87 | */ | 86 | */ |
| 88 | static inline int atomic_sub_unless(atomic_t *v, int a, int u) | 87 | static inline void atomic_sub_unless(atomic_t *v, int a, int u) |
| 89 | { | 88 | { |
| 90 | int tmp, result = 0; | 89 | int tmp; |
| 91 | 90 | ||
| 92 | asm volatile( | 91 | asm volatile( |
| 93 | "/* atomic_sub_unless */\n" | 92 | "/* atomic_sub_unless */\n" |
| 94 | "1: ssrf 5\n" | 93 | "1: ssrf 5\n" |
| 95 | " ld.w %0, %3\n" | 94 | " ld.w %0, %2\n" |
| 96 | " cp.w %0, %5\n" | 95 | " cp.w %0, %4\n" |
| 97 | " breq 1f\n" | 96 | " breq 1f\n" |
| 98 | " sub %0, %4\n" | 97 | " sub %0, %3\n" |
| 99 | " stcond %2, %0\n" | 98 | " stcond %1, %0\n" |
| 100 | " brne 1b\n" | 99 | " brne 1b\n" |
| 101 | " mov %1, 1\n" | ||
| 102 | "1:" | 100 | "1:" |
| 103 | : "=&r"(tmp), "=&r"(result), "=o"(v->counter) | 101 | : "=&r"(tmp), "=o"(v->counter) |
| 104 | : "m"(v->counter), "rKs21"(a), "rKs21"(u), "1"(result) | 102 | : "m"(v->counter), "rKs21"(a), "rKs21"(u) |
| 105 | : "cc", "memory"); | 103 | : "cc", "memory"); |
| 106 | |||
| 107 | return result; | ||
| 108 | } | 104 | } |
| 109 | 105 | ||
| 110 | /* | 106 | /* |
| 111 | * atomic_add_unless - add unless the number is a given value | 107 | * __atomic_add_unless - add unless the number is a given value |
| 112 | * @v: pointer of type atomic_t | 108 | * @v: pointer of type atomic_t |
| 113 | * @a: the amount to add to v... | 109 | * @a: the amount to add to v... |
| 114 | * @u: ...unless v is equal to u. | 110 | * @u: ...unless v is equal to u. |
| 115 | * | 111 | * |
| 116 | * If the atomic value v is not equal to u, this function adds a to v, | 112 | * Atomically adds @a to @v, so long as it was not @u. |
| 117 | * and returns non zero. If v is equal to u then it returns zero. This | 113 | * Returns the old value of @v. |
| 118 | * is done as an atomic operation. | ||
| 119 | */ | 114 | */ |
| 120 | static inline int atomic_add_unless(atomic_t *v, int a, int u) | 115 | static inline int __atomic_add_unless(atomic_t *v, int a, int u) |
| 121 | { | 116 | { |
| 122 | int tmp, result; | 117 | int tmp, old = atomic_read(v); |
| 123 | 118 | ||
| 124 | if (__builtin_constant_p(a) && (a >= -1048575) && (a <= 1048576)) | 119 | if (__builtin_constant_p(a) && (a >= -1048575) && (a <= 1048576)) |
| 125 | result = atomic_sub_unless(v, -a, u); | 120 | atomic_sub_unless(v, -a, u); |
