diff options
| author | Chris Zankel <chris@zankel.net> | 2012-10-17 16:02:01 -0700 | 
|---|---|---|
| committer | Chris Zankel <chris@zankel.net> | 2012-11-03 12:57:45 -0700 | 
| commit | 5c0a3b60fbc3442a14169a37657b27ff3173f9db (patch) | |
| tree | df5678bbdaa4d45b7a4e2a9b352fe536dc14e0a1 /libpthread | |
| parent | 888b232d1e6bf6819aec7f13be298226ce91bf5b (diff) | |
xtensa: use atomic instructions instead of a syscall
Replace system calls with atomic instructions for 'compare and swap'
in linuxthreads.old.
Signed-off-by: Chris Zankel <chris@zankel.net>
Diffstat (limited to 'libpthread')
| -rw-r--r-- | libpthread/linuxthreads.old/sysdeps/xtensa/pt-machine.h | 42 | 
1 files changed, 37 insertions, 5 deletions
diff --git a/libpthread/linuxthreads.old/sysdeps/xtensa/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/xtensa/pt-machine.h index acd4d109f..2ae227581 100644 --- a/libpthread/linuxthreads.old/sysdeps/xtensa/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/xtensa/pt-machine.h @@ -26,19 +26,51 @@  #include <asm/unistd.h>  #ifndef PT_EI -# define PT_EI __extern_always_inline +# define PT_EI extern inline __attribute__ ((gnu_inline))  #endif -/* Memory barrier.  */  #define MEMORY_BARRIER() __asm__ ("memw" : : : "memory") +#define HAS_COMPARE_AND_SWAP + +extern long int testandset (int *spinlock); +extern int __compare_and_swap (long int *p, long int oldval, long int newval);  /* Spinlock implementation; required.  */  PT_EI long int  testandset (int *spinlock)  { -  int unused = 0; -  return INTERNAL_SYSCALL (xtensa, , 4, SYS_XTENSA_ATOMIC_SET, -			   spinlock, 1, unused); +	unsigned long tmp; +	__asm__ volatile ( +"	movi	%0, 0			\n" +"	wsr	%0, SCOMPARE1		\n" +"	movi	%0, 1			\n" +"	s32c1i	%0, %1, 0		\n" +	: "=&a" (tmp) +	: "a" (spinlock) +	: "memory" +	); +	return tmp; +} + +PT_EI int +__compare_and_swap (long int *p, long int oldval, long int newval) +{ +        unsigned long tmp; +        unsigned long value; +        __asm__ volatile ( +"1:     l32i    %0, %2, 0            \n" +"       bne     %0, %4, 2f           \n" +"       wsr     %0, SCOMPARE1        \n" +"       mov     %1, %0               \n" +"       mov     %0, %3               \n" +"       s32c1i  %0, %2, 0            \n" +"       bne     %1, %0, 1b           \n" +"2:                                  \n" +          : "=&a" (tmp), "=&a" (value) +          : "a" (p), "a" (newval), "a" (oldval) +          : "memory" ); + +        return tmp == oldval;  }  /* Get some notion of the current stack.  Need not be exactly the top  | 
