aboutsummaryrefslogtreecommitdiffstats
path: root/include/asm-i386/system.h
diff options
context:
space:
mode:
authorMathieu Desnoyers <mathieu.desnoyers@polymtl.ca>2007-05-08 03:34:44 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-08 14:15:20 -0400
commita075227948636e10aa2cc2d8725fbbab27681d4a (patch)
tree6b459363916c4db4cc62a293f122f4c9172b1d6a /include/asm-i386/system.h
parentf43f7b46eb101f50950cfcead0cb0b7a9c4f6823 (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.h59
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
310static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, 313static 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
373static 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
465static 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/*