diff options
author | Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> | 2007-05-08 03:34:44 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-05-08 14:15:20 -0400 |
commit | a075227948636e10aa2cc2d8725fbbab27681d4a (patch) | |
tree | 6b459363916c4db4cc62a293f122f4c9172b1d6a /include/asm-i386/system.h | |
parent | f43f7b46eb101f50950cfcead0cb0b7a9c4f6823 (diff) |
local_t: i386 extension
Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Cc: Andi Kleen <ak@muc.de>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/asm-i386/system.h')
-rw-r--r-- | include/asm-i386/system.h | 59 |
1 files changed, 58 insertions, 1 deletions
diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h index c3a58c08c495..e0454afb950f 100644 --- a/include/asm-i386/system.h +++ b/include/asm-i386/system.h | |||
@@ -305,6 +305,9 @@ static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int siz | |||
305 | #define sync_cmpxchg(ptr,o,n)\ | 305 | #define sync_cmpxchg(ptr,o,n)\ |
306 | ((__typeof__(*(ptr)))__sync_cmpxchg((ptr),(unsigned long)(o),\ | 306 | ((__typeof__(*(ptr)))__sync_cmpxchg((ptr),(unsigned long)(o),\ |
307 | (unsigned long)(n),sizeof(*(ptr)))) | 307 | (unsigned long)(n),sizeof(*(ptr)))) |
308 | #define cmpxchg_local(ptr,o,n)\ | ||
309 | ((__typeof__(*(ptr)))__cmpxchg_local((ptr),(unsigned long)(o),\ | ||
310 | (unsigned long)(n),sizeof(*(ptr)))) | ||
308 | #endif | 311 | #endif |
309 | 312 | ||
310 | static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, | 313 | static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, |
@@ -367,6 +370,33 @@ static inline unsigned long __sync_cmpxchg(volatile void *ptr, | |||
367 | return old; | 370 | return old; |
368 | } | 371 | } |
369 | 372 | ||
373 | static inline unsigned long __cmpxchg_local(volatile void *ptr, | ||
374 | unsigned long old, unsigned long new, int size) | ||
375 | { | ||
376 | unsigned long prev; | ||
377 | switch (size) { | ||
378 | case 1: | ||
379 | __asm__ __volatile__("cmpxchgb %b1,%2" | ||
380 | : "=a"(prev) | ||
381 | : "q"(new), "m"(*__xg(ptr)), "0"(old) | ||
382 | : "memory"); | ||
383 | return prev; | ||
384 | case 2: | ||
385 | __asm__ __volatile__("cmpxchgw %w1,%2" | ||
386 | : "=a"(prev) | ||
387 | : "r"(new), "m"(*__xg(ptr)), "0"(old) | ||
388 | : "memory"); | ||
389 | return prev; | ||
390 | case 4: | ||
391 | __asm__ __volatile__("cmpxchgl %1,%2" | ||
392 | : "=a"(prev) | ||
393 | : "r"(new), "m"(*__xg(ptr)), "0"(old) | ||
394 | : "memory"); | ||
395 | return prev; | ||
396 | } | ||
397 | return old; | ||
398 | } | ||
399 | |||
370 | #ifndef CONFIG_X86_CMPXCHG | 400 | #ifndef CONFIG_X86_CMPXCHG |
371 | /* | 401 | /* |
372 | * Building a kernel capable running on 80386. It may be necessary to | 402 | * Building a kernel capable running on 80386. It may be necessary to |
@@ -403,6 +433,17 @@ static inline unsigned long cmpxchg_386(volatile void *ptr, unsigned long old, | |||
403 | (unsigned long)(n), sizeof(*(ptr))); \ | 433 | (unsigned long)(n), sizeof(*(ptr))); \ |
404 | __ret; \ | 434 | __ret; \ |
405 | }) | 435 | }) |
436 | #define cmpxchg_local(ptr,o,n) \ | ||
437 | ({ \ | ||
438 | __typeof__(*(ptr)) __ret; \ | ||
439 | if (likely(boot_cpu_data.x86 > 3)) \ | ||
440 | __ret = __cmpxchg_local((ptr), (unsigned long)(o), \ | ||
441 | (unsigned long)(n), sizeof(*(ptr))); \ | ||
442 | else \ | ||
443 | __ret = cmpxchg_386((ptr), (unsigned long)(o), \ | ||
444 | (unsigned long)(n), sizeof(*(ptr))); \ | ||
445 | __ret; \ | ||
446 | }) | ||
406 | #endif | 447 | #endif |
407 | 448 | ||
408 | #ifdef CONFIG_X86_CMPXCHG64 | 449 | #ifdef CONFIG_X86_CMPXCHG64 |
@@ -421,10 +462,26 @@ static inline unsigned long long __cmpxchg64(volatile void *ptr, unsigned long l | |||
421 | return prev; | 462 | return prev; |
422 | } | 463 | } |
423 | 464 | ||
465 | static inline unsigned long long __cmpxchg64_local(volatile void *ptr, | ||
466 | unsigned long long old, unsigned long long new) | ||
467 | { | ||
468 | unsigned long long prev; | ||
469 | __asm__ __volatile__("cmpxchg8b %3" | ||
470 | : "=A"(prev) | ||
471 | : "b"((unsigned long)new), | ||
472 | "c"((unsigned long)(new >> 32)), | ||
473 | "m"(*__xg(ptr)), | ||
474 | "0"(old) | ||
475 | : "memory"); | ||
476 | return prev; | ||
477 | } | ||
478 | |||
424 | #define cmpxchg64(ptr,o,n)\ | 479 | #define cmpxchg64(ptr,o,n)\ |
425 | ((__typeof__(*(ptr)))__cmpxchg64((ptr),(unsigned long long)(o),\ | 480 | ((__typeof__(*(ptr)))__cmpxchg64((ptr),(unsigned long long)(o),\ |
426 | (unsigned long long)(n))) | 481 | (unsigned long long)(n))) |
427 | 482 | #define cmpxchg64_local(ptr,o,n)\ | |
483 | ((__typeof__(*(ptr)))__cmpxchg64_local((ptr),(unsigned long long)(o),\ | ||
484 | (unsigned long long)(n))) | ||
428 | #endif | 485 | #endif |
429 | 486 | ||
430 | /* | 487 | /* |