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 | |
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>
-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 |