diff options
author | Hugh Dickins <hugh@veritas.com> | 2005-11-23 16:37:40 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-23 19:08:39 -0500 |
commit | 7c72aaf29621d29ed19fd68c44edb45321645049 (patch) | |
tree | e1d9db94356ccb5276c500659f8abd85942d948c /include/asm-x86_64/atomic.h | |
parent | 7ce774b4808c019c2f143ff5dea1a1b094ff01e1 (diff) |
[PATCH] mm: fill arch atomic64 gaps
alpha, sparc64, x86_64 are each missing some primitives from their atomic64
support: fill in the gaps I've noticed by extrapolating asm, follow the
groupings in each file. But powerpc and parisc still lack atomic64.
Signed-off-by: Hugh Dickins <hugh@veritas.com>
Cc: Richard Henderson <rth@twiddle.net>
Cc: Ivan Kokshaysky <ink@jurassic.park.msu.ru>
Cc: "David S. Miller" <davem@davemloft.net>
Cc: Andi Kleen <ak@muc.de>
Cc: Nick Piggin <nickpiggin@yahoo.com.au>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'include/asm-x86_64/atomic.h')
-rw-r--r-- | include/asm-x86_64/atomic.h | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/include/asm-x86_64/atomic.h b/include/asm-x86_64/atomic.h index 0866ef67f198..50db9f39274f 100644 --- a/include/asm-x86_64/atomic.h +++ b/include/asm-x86_64/atomic.h | |||
@@ -160,8 +160,8 @@ static __inline__ int atomic_inc_and_test(atomic_t *v) | |||
160 | 160 | ||
161 | /** | 161 | /** |
162 | * atomic_add_negative - add and test if negative | 162 | * atomic_add_negative - add and test if negative |
163 | * @v: pointer of type atomic_t | ||
164 | * @i: integer value to add | 163 | * @i: integer value to add |
164 | * @v: pointer of type atomic_t | ||
165 | * | 165 | * |
166 | * Atomically adds @i to @v and returns true | 166 | * Atomically adds @i to @v and returns true |
167 | * if the result is negative, or false when | 167 | * if the result is negative, or false when |
@@ -178,6 +178,31 @@ static __inline__ int atomic_add_negative(int i, atomic_t *v) | |||
178 | return c; | 178 | return c; |
179 | } | 179 | } |
180 | 180 | ||
181 | /** | ||
182 | * atomic_add_return - add and return | ||
183 | * @i: integer value to add | ||
184 | * @v: pointer of type atomic_t | ||
185 | * | ||
186 | * Atomically adds @i to @v and returns @i + @v | ||
187 | */ | ||
188 | static __inline__ int atomic_add_return(int i, atomic_t *v) | ||
189 | { | ||
190 | int __i = i; | ||
191 | __asm__ __volatile__( | ||
192 | LOCK "xaddl %0, %1;" | ||
193 | :"=r"(i) | ||
194 | :"m"(v->counter), "0"(i)); | ||
195 | return i + __i; | ||
196 | } | ||
197 | |||
198 | static __inline__ int atomic_sub_return(int i, atomic_t *v) | ||
199 | { | ||
200 | return atomic_add_return(-i,v); | ||
201 | } | ||
202 | |||
203 | #define atomic_inc_return(v) (atomic_add_return(1,v)) | ||
204 | #define atomic_dec_return(v) (atomic_sub_return(1,v)) | ||
205 | |||
181 | /* An 64bit atomic type */ | 206 | /* An 64bit atomic type */ |
182 | 207 | ||
183 | typedef struct { volatile long counter; } atomic64_t; | 208 | typedef struct { volatile long counter; } atomic64_t; |
@@ -320,14 +345,14 @@ static __inline__ int atomic64_inc_and_test(atomic64_t *v) | |||
320 | 345 | ||
321 | /** | 346 | /** |
322 | * atomic64_add_negative - add and test if negative | 347 | * atomic64_add_negative - add and test if negative |
323 | * @v: pointer to atomic64_t | ||
324 | * @i: integer value to add | 348 | * @i: integer value to add |
349 | * @v: pointer to type atomic64_t | ||
325 | * | 350 | * |
326 | * Atomically adds @i to @v and returns true | 351 | * Atomically adds @i to @v and returns true |
327 | * if the result is negative, or false when | 352 | * if the result is negative, or false when |
328 | * result is greater than or equal to zero. | 353 | * result is greater than or equal to zero. |
329 | */ | 354 | */ |
330 | static __inline__ long atomic64_add_negative(long i, atomic64_t *v) | 355 | static __inline__ int atomic64_add_negative(long i, atomic64_t *v) |
331 | { | 356 | { |
332 | unsigned char c; | 357 | unsigned char c; |
333 | 358 | ||
@@ -339,27 +364,30 @@ static __inline__ long atomic64_add_negative(long i, atomic64_t *v) | |||
339 | } | 364 | } |
340 | 365 | ||
341 | /** | 366 | /** |
342 | * atomic_add_return - add and return | 367 | * atomic64_add_return - add and return |
343 | * @v: pointer of type atomic_t | ||
344 | * @i: integer value to add | 368 | * @i: integer value to add |
369 | * @v: pointer to type atomic64_t | ||
345 | * | 370 | * |
346 | * Atomically adds @i to @v and returns @i + @v | 371 | * Atomically adds @i to @v and returns @i + @v |
347 | */ | 372 | */ |
348 | static __inline__ int atomic_add_return(int i, atomic_t *v) | 373 | static __inline__ long atomic64_add_return(long i, atomic64_t *v) |
349 | { | 374 | { |
350 | int __i = i; | 375 | long __i = i; |
351 | __asm__ __volatile__( | 376 | __asm__ __volatile__( |
352 | LOCK "xaddl %0, %1;" | 377 | LOCK "xaddq %0, %1;" |
353 | :"=r"(i) | 378 | :"=r"(i) |
354 | :"m"(v->counter), "0"(i)); | 379 | :"m"(v->counter), "0"(i)); |
355 | return i + __i; | 380 | return i + __i; |
356 | } | 381 | } |
357 | 382 | ||
358 | static __inline__ int atomic_sub_return(int i, atomic_t *v) | 383 | static __inline__ long atomic64_sub_return(long i, atomic64_t *v) |
359 | { | 384 | { |
360 | return atomic_add_return(-i,v); | 385 | return atomic64_add_return(-i,v); |
361 | } | 386 | } |
362 | 387 | ||
388 | #define atomic64_inc_return(v) (atomic64_add_return(1,v)) | ||
389 | #define atomic64_dec_return(v) (atomic64_sub_return(1,v)) | ||
390 | |||
363 | #define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new)) | 391 | #define atomic_cmpxchg(v, old, new) ((int)cmpxchg(&((v)->counter), old, new)) |
364 | 392 | ||
365 | /** | 393 | /** |
@@ -381,9 +409,6 @@ static __inline__ int atomic_sub_return(int i, atomic_t *v) | |||
381 | }) | 409 | }) |
382 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) | 410 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) |
383 | 411 | ||
384 | #define atomic_inc_return(v) (atomic_add_return(1,v)) | ||
385 | #define atomic_dec_return(v) (atomic_sub_return(1,v)) | ||
386 | |||
387 | /* These are x86-specific, used by some header files */ | 412 | /* These are x86-specific, used by some header files */ |
388 | #define atomic_clear_mask(mask, addr) \ | 413 | #define atomic_clear_mask(mask, addr) \ |
389 | __asm__ __volatile__(LOCK "andl %0,%1" \ | 414 | __asm__ __volatile__(LOCK "andl %0,%1" \ |