aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/include/asm
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2009-07-03 07:26:39 -0400
committerIngo Molnar <mingo@elte.hu>2009-07-03 07:26:39 -0400
commitb7882b7c65abb00194bdb3d4a22d27d70fcc59ba (patch)
treef22b1090c014f6d1da33c3791590d636104e8841 /arch/x86/include/asm
parentbbf2a330d92c5afccfd17592ba9ccd50f41cf748 (diff)
x86: atomic64: Move the 32-bit atomic64_t implementation to a .c file
Linus noted that the atomic64_t primitives are all inlines currently which is crazy because these functions have a large register footprint anyway. Move them to a separate file: arch/x86/lib/atomic64_32.c Also, while at it, rename all uses of 'unsigned long long' to the much shorter u64. This makes the appearance of the prototypes a lot nicer - and it also uncovered a few bugs where (yet unused) API variants had 'long' as their return type instead of u64. [ More intrusive changes are not yet done in this patch. ] Reported-by: Linus Torvalds <torvalds@linux-foundation.org> Cc: Eric Dumazet <eric.dumazet@gmail.com> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Arnaldo Carvalho de Melo <acme@redhat.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: David Howells <dhowells@redhat.com> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Arnd Bergmann <arnd@arndb.de> LKML-Reference: <alpine.LFD.2.01.0907021653030.3210@localhost.localdomain> Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'arch/x86/include/asm')
-rw-r--r--arch/x86/include/asm/atomic_32.h137
1 files changed, 20 insertions, 117 deletions
diff --git a/arch/x86/include/asm/atomic_32.h b/arch/x86/include/asm/atomic_32.h
index ae0fbb5b0578..311a43e47c0b 100644
--- a/arch/x86/include/asm/atomic_32.h
+++ b/arch/x86/include/asm/atomic_32.h
@@ -250,7 +250,7 @@ static inline int atomic_add_unless(atomic_t *v, int a, int u)
250/* An 64bit atomic type */ 250/* An 64bit atomic type */
251 251
252typedef struct { 252typedef struct {
253 unsigned long long __aligned(8) counter; 253 u64 __aligned(8) counter;
254} atomic64_t; 254} atomic64_t;
255 255
256#define ATOMIC64_INIT(val) { (val) } 256#define ATOMIC64_INIT(val) { (val) }
@@ -264,31 +264,7 @@ typedef struct {
264 */ 264 */
265#define __atomic64_read(ptr) ((ptr)->counter) 265#define __atomic64_read(ptr) ((ptr)->counter)
266 266
267static inline unsigned long long 267extern u64 atomic64_cmpxchg(atomic64_t *ptr, u64 old_val, u64 new_val);
268cmpxchg8b(unsigned long long *ptr, unsigned long long old, unsigned long long new)
269{
270 asm volatile(
271
272 LOCK_PREFIX "cmpxchg8b (%[ptr])\n"
273
274 : "=A" (old)
275
276 : [ptr] "D" (ptr),
277 "A" (old),
278 "b" (ll_low(new)),
279 "c" (ll_high(new))
280
281 : "memory");
282
283 return old;
284}
285
286static inline unsigned long long
287atomic64_cmpxchg(atomic64_t *ptr, unsigned long long old_val,
288 unsigned long long new_val)
289{
290 return cmpxchg8b(&ptr->counter, old_val, new_val);
291}
292 268
293/** 269/**
294 * atomic64_xchg - xchg atomic64 variable 270 * atomic64_xchg - xchg atomic64 variable
@@ -298,18 +274,7 @@ atomic64_cmpxchg(atomic64_t *ptr, unsigned long long old_val,
298 * Atomically xchgs the value of @ptr to @new_val and returns 274 * Atomically xchgs the value of @ptr to @new_val and returns
299 * the old value. 275 * the old value.
300 */ 276 */
301 277extern u64 atomic64_xchg(atomic64_t *ptr, u64 new_val);
302static inline unsigned long long
303atomic64_xchg(atomic64_t *ptr, unsigned long long new_val)
304{
305 unsigned long long old_val;
306
307 do {
308 old_val = atomic_read(ptr);
309 } while (atomic64_cmpxchg(ptr, old_val, new_val) != old_val);
310
311 return old_val;
312}
313 278
314/** 279/**
315 * atomic64_set - set atomic64 variable 280 * atomic64_set - set atomic64 variable
@@ -318,10 +283,7 @@ atomic64_xchg(atomic64_t *ptr, unsigned long long new_val)
318 * 283 *
319 * Atomically sets the value of @ptr to @new_val. 284 * Atomically sets the value of @ptr to @new_val.
320 */ 285 */
321static inline void atomic64_set(atomic64_t *ptr, unsigned long long new_val) 286extern void atomic64_set(atomic64_t *ptr, u64 new_val);
322{
323 atomic64_xchg(ptr, new_val);
324}
325 287
326/** 288/**
327 * atomic64_read - read atomic64 variable 289 * atomic64_read - read atomic64 variable
@@ -329,16 +291,7 @@ static inline void atomic64_set(atomic64_t *ptr, unsigned long long new_val)
329 * 291 *
330 * Atomically reads the value of @ptr and returns it. 292 * Atomically reads the value of @ptr and returns it.
331 */ 293 */
332static inline unsigned long long atomic64_read(atomic64_t *ptr) 294extern u64 atomic64_read(atomic64_t *ptr);
333{
334 unsigned long long curr_val;
335
336 do {
337 curr_val = __atomic64_read(ptr);
338 } while (atomic64_cmpxchg(ptr, curr_val, curr_val) != curr_val);
339
340 return curr_val;
341}
342 295
343/** 296/**
344 * atomic64_add_return - add and return 297 * atomic64_add_return - add and return
@@ -347,34 +300,14 @@ static inline unsigned long long atomic64_read(atomic64_t *ptr)
347 * 300 *
348 * Atomically adds @delta to @ptr and returns @delta + *@ptr 301 * Atomically adds @delta to @ptr and returns @delta + *@ptr
349 */ 302 */
350static inline unsigned long long 303extern u64 atomic64_add_return(u64 delta, atomic64_t *ptr);
351atomic64_add_return(unsigned long long delta, atomic64_t *ptr)
352{
353 unsigned long long old_val, new_val;
354
355 do {
356 old_val = atomic_read(ptr);
357 new_val = old_val + delta;
358
359 } while (atomic64_cmpxchg(ptr, old_val, new_val) != old_val);
360
361 return new_val;
362}
363
364static inline long atomic64_sub_return(unsigned long long delta, atomic64_t *ptr)
365{
366 return atomic64_add_return(-delta, ptr);
367}
368 304
369static inline long atomic64_inc_return(atomic64_t *ptr) 305/*
370{ 306 * Other variants with different arithmetic operators:
371 return atomic64_add_return(1, ptr); 307 */
372} 308extern u64 atomic64_sub_return(u64 delta, atomic64_t *ptr);
373 309extern u64 atomic64_inc_return(atomic64_t *ptr);
374static inline long atomic64_dec_return(atomic64_t *ptr) 310extern u64 atomic64_dec_return(atomic64_t *ptr);
375{
376 return atomic64_sub_return(1, ptr);
377}
378 311
379/** 312/**
380 * atomic64_add - add integer to atomic64 variable 313 * atomic64_add - add integer to atomic64 variable
@@ -383,10 +316,7 @@ static inline long atomic64_dec_return(atomic64_t *ptr)
383 * 316 *
384 * Atomically adds @delta to @ptr. 317 * Atomically adds @delta to @ptr.
385 */ 318 */
386static inline void atomic64_add(unsigned long long delta, atomic64_t *ptr) 319extern void atomic64_add(u64 delta, atomic64_t *ptr);
387{
388 atomic64_add_return(delta, ptr);
389}
390 320
391/** 321/**
392 * atomic64_sub - subtract the atomic64 variable 322 * atomic64_sub - subtract the atomic64 variable
@@ -395,10 +325,7 @@ static inline void atomic64_add(unsigned long long delta, atomic64_t *ptr)
395 * 325 *
396 * Atomically subtracts @delta from @ptr. 326 * Atomically subtracts @delta from @ptr.
397 */ 327 */
398static inline void atomic64_sub(unsigned long long delta, atomic64_t *ptr) 328extern void atomic64_sub(u64 delta, atomic64_t *ptr);
399{
400 atomic64_add(-delta, ptr);
401}
402 329
403/** 330/**
404 * atomic64_sub_and_test - subtract value from variable and test result 331 * atomic64_sub_and_test - subtract value from variable and test result
@@ -409,13 +336,7 @@ static inline void atomic64_sub(unsigned long long delta, atomic64_t *ptr)
409 * true if the result is zero, or false for all 336 * true if the result is zero, or false for all
410 * other cases. 337 * other cases.
411 */ 338 */
412static inline int 339extern int atomic64_sub_and_test(u64 delta, atomic64_t *ptr);
413atomic64_sub_and_test(unsigned long long delta, atomic64_t *ptr)
414{
415 unsigned long long old_val = atomic64_sub_return(delta, ptr);
416
417 return old_val == 0;
418}
419 340
420/** 341/**
421 * atomic64_inc - increment atomic64 variable 342 * atomic64_inc - increment atomic64 variable
@@ -423,10 +344,7 @@ atomic64_sub_and_test(unsigned long long delta, atomic64_t *ptr)
423 * 344 *
424 * Atomically increments @ptr by 1. 345 * Atomically increments @ptr by 1.
425 */ 346 */
426static inline void atomic64_inc(atomic64_t *ptr) 347extern void atomic64_inc(atomic64_t *ptr);
427{
428 atomic64_add(1, ptr);
429}
430 348
431/** 349/**
432 * atomic64_dec - decrement atomic64 variable 350 * atomic64_dec - decrement atomic64 variable
@@ -434,10 +352,7 @@ static inline void atomic64_inc(atomic64_t *ptr)
434 * 352 *
435 * Atomically decrements @ptr by 1. 353 * Atomically decrements @ptr by 1.
436 */ 354 */
437static inline void atomic64_dec(atomic64_t *ptr) 355extern void atomic64_dec(atomic64_t *ptr);
438{
439 atomic64_sub(1, ptr);
440}
441 356
442/** 357/**
443 * atomic64_dec_and_test - decrement and test 358 * atomic64_dec_and_test - decrement and test
@@ -447,10 +362,7 @@ static inline void atomic64_dec(atomic64_t *ptr)
447 * returns true if the result is 0, or false for all other 362 * returns true if the result is 0, or false for all other
448 * cases. 363 * cases.
449 */ 364 */
450static inline int atomic64_dec_and_test(atomic64_t *ptr) 365extern int atomic64_dec_and_test(atomic64_t *ptr);
451{
452 return atomic64_sub_and_test(1, ptr);
453}
454 366
455/** 367/**
456 * atomic64_inc_and_test - increment and test 368 * atomic64_inc_and_test - increment and test
@@ -460,10 +372,7 @@ static inline int atomic64_dec_and_test(atomic64_t *ptr)
460 * and returns true if the result is zero, or false for all 372 * and returns true if the result is zero, or false for all
461 * other cases. 373 * other cases.
462 */ 374 */
463static inline int atomic64_inc_and_test(atomic64_t *ptr) 375extern int atomic64_inc_and_test(atomic64_t *ptr);
464{
465 return atomic64_sub_and_test(-1, ptr);
466}
467 376
468/** 377/**
469 * atomic64_add_negative - add and test if negative 378 * atomic64_add_negative - add and test if negative
@@ -474,13 +383,7 @@ static inline int atomic64_inc_and_test(atomic64_t *ptr)
474 * if the result is negative, or false when 383 * if the result is negative, or false when
475 * result is greater than or equal to zero. 384 * result is greater than or equal to zero.
476 */ 385 */
477static inline int 386extern int atomic64_add_negative(u64 delta, atomic64_t *ptr);
478atomic64_add_negative(unsigned long long delta, atomic64_t *ptr)
479{
480 long long old_val = atomic64_add_return(delta, ptr);
481
482 return old_val < 0;
483}
484 387
485#include <asm-generic/atomic-long.h> 388#include <asm-generic/atomic-long.h>
486#endif /* _ASM_X86_ATOMIC_32_H */ 389#endif /* _ASM_X86_ATOMIC_32_H */