summaryrefslogtreecommitdiff
path: root/libpthread/linuxthreads.old/sysdeps
diff options
context:
space:
mode:
authorBernd Schmidt <bernds_cb1@t-online.de>2007-11-23 17:28:17 +0000
committerBernd Schmidt <bernds_cb1@t-online.de>2007-11-23 17:28:17 +0000
commit38c0a1e4cd50926863dd7e380aa7fe83d71508f9 (patch)
tree22477dee8fd1b5c45501cb8870a3a4507bb25747 /libpthread/linuxthreads.old/sysdeps
parent8f4f670a307a9174cfd78db8b689d545e0ed314a (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.h48
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 */