diff options
author | Bernd Schmidt <bernds_cb1@t-online.de> | 2007-11-23 17:28:17 +0000 |
---|---|---|
committer | Bernd Schmidt <bernds_cb1@t-online.de> | 2007-11-23 17:28:17 +0000 |
commit | 38c0a1e4cd50926863dd7e380aa7fe83d71508f9 (patch) | |
tree | 22477dee8fd1b5c45501cb8870a3a4507bb25747 /libpthread/linuxthreads.old/sysdeps | |
parent | 8f4f670a307a9174cfd78db8b689d545e0ed314a (diff) |
A better atomic ops implementation for the Blackfin, relying on a feature
present in our recent kernels.
Diffstat (limited to 'libpthread/linuxthreads.old/sysdeps')
-rw-r--r-- | libpthread/linuxthreads.old/sysdeps/bfin/pt-machine.h | 48 |
1 files changed, 38 insertions, 10 deletions
diff --git a/libpthread/linuxthreads.old/sysdeps/bfin/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/bfin/pt-machine.h index c384cab06..8d97d5ec5 100644 --- a/libpthread/linuxthreads.old/sysdeps/bfin/pt-machine.h +++ b/libpthread/linuxthreads.old/sysdeps/bfin/pt-machine.h @@ -22,12 +22,15 @@ #define _PT_MACHINE_H 1 #ifndef PT_EI -# define PT_EI extern inline +# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) +# define PT_EI static inline __attribute__((always_inline)) +# else +# define PT_EI extern inline __attribute__((always_inline)) +# endif #endif -extern long int testandset (int *spinlock); +#include <asm/fixed_code.h> -#include <asm/unistd.h> /* Spinlock implementation; required. */ /* The semantics of the TESTSET instruction cannot be guaranteed. We cannot easily move all locks used by linux kernel to non-cacheable memory. @@ -38,13 +41,38 @@ extern long int testandset (int *spinlock); PT_EI long int testandset (int *spinlock) { - long int res; - asm volatile ("R0 = %2; P0 = %4; EXCPT 0; %0 = R0;" - : "=d" (res), "=m" (*spinlock) - : "d" (spinlock), "m" (*spinlock), - "ida" (__NR_bfin_spinlock) - :"R0", "P0", "cc"); - return res; + long int res; + + __asm__ __volatile__ ( + "CALL (%4);" + : "=q0" (res), "=m" (*spinlock) + : "qA" (spinlock), "m" (*spinlock), "a" (ATOMIC_XCHG32), "q1" (1) + : "RETS", "cc", "memory"); + + return res; } +#define HAS_COMPARE_AND_SWAP +PT_EI int +__compare_and_swap (long int *p, long int oldval, long int newval) +{ + long int readval; + __asm__ __volatile__ ( + "CALL (%5);" + : "=q0" (readval), "=m" (*p) + : "qA" (p), + "q1" (oldval), + "q2" (newval), + "a" (ATOMIC_CAS32), + "m" (*p) + : "RETS", "memory", "cc"); + return readval == oldval; +} + +#ifdef SHARED +# define PTHREAD_STATIC_FN_REQUIRE(name) +#else +# define PTHREAD_STATIC_FN_REQUIRE(name) __asm (".globl " "_"#name); +#endif + #endif /* pt-machine.h */ |