[PATCH] ppc64: speedup cmpxchg

Herbert Poetzl herbert at 13thfloor.at
Thu Sep 15 15:35:08 EST 2005


On Tue, Sep 06, 2005 at 01:05:58PM +1000, Anton Blanchard wrote:
> 
> cmpxchg has the following code:
> 
> __typeof__(*(ptr)) _o_ = (o);
> __typeof__(*(ptr)) _n_ = (n);
> 
> Unfortunately it makes gcc 4.0 store and load the variables to the stack.
> Eg in atomic_dec_and_test we get:
> 
>   stw     r10,112(r1)
>   stw     r9,116(r1)
>   lwz     r9,112(r1)
>   lwz     r0,116(r1)
> 
> x86 is just casting the values so do that instead. Also change __xchg*
> and __cmpxchg* to take unsigned values, removing a few sign extensions.

hmm, isn't that removing an implicit typecheck?

maybe adding register and/or improving gcc would
be a better solution here?

best,
Herbert

> Signed-off-by: Anton Blanchard <anton at samba.org>
> 
> Index: build/include/asm-ppc64/system.h
> ===================================================================
> --- build.orig/include/asm-ppc64/system.h	2005-09-06 11:29:32.000000000 +1000
> +++ build/include/asm-ppc64/system.h	2005-09-06 11:29:37.000000000 +1000
> @@ -158,7 +158,7 @@
>   * is more like most of the other architectures.
>   */
>  static __inline__ unsigned long
> -__xchg_u32(volatile int *m, unsigned long val)
> +__xchg_u32(volatile unsigned int *m, unsigned long val)
>  {
>  	unsigned long dummy;
>  
> @@ -200,7 +200,7 @@
>  extern void __xchg_called_with_bad_pointer(void);
>  
>  static __inline__ unsigned long
> -__xchg(volatile void *ptr, unsigned long x, int size)
> +__xchg(volatile void *ptr, unsigned long x, unsigned int size)
>  {
>  	switch (size) {
>  	case 4:
> @@ -223,7 +223,7 @@
>  #define __HAVE_ARCH_CMPXCHG	1
>  
>  static __inline__ unsigned long
> -__cmpxchg_u32(volatile int *p, int old, int new)
> +__cmpxchg_u32(volatile unsigned int *p, unsigned long old, unsigned long new)
>  {
>  	unsigned int prev;
>  
> @@ -271,7 +271,8 @@
>  extern void __cmpxchg_called_with_bad_pointer(void);
>  
>  static __inline__ unsigned long
> -__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size)
> +__cmpxchg(volatile void *ptr, unsigned long old, unsigned long new,
> +	  unsigned int size)
>  {
>  	switch (size) {
>  	case 4:
> @@ -283,13 +284,9 @@
>  	return old;
>  }
>  
> -#define cmpxchg(ptr,o,n)						 \
> -  ({									 \
> -     __typeof__(*(ptr)) _o_ = (o);					 \
> -     __typeof__(*(ptr)) _n_ = (n);					 \
> -     (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_,		 \
> -				    (unsigned long)_n_, sizeof(*(ptr))); \
> -  })
> +#define cmpxchg(ptr,o,n)\
> +	((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\
> +	(unsigned long)(n),sizeof(*(ptr))))
>  
>  /*
>   * We handle most unaligned accesses in hardware. On the other hand 
> _______________________________________________
> Linuxppc64-dev mailing list
> Linuxppc64-dev at ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc64-dev



More information about the Linuxppc64-dev mailing list