summaryrefslogtreecommitdiff
path: root/libpthread
diff options
context:
space:
mode:
authorWaldemar Brodkorb <wbx@openadk.org>2015-02-12 14:06:43 -0600
committerWaldemar Brodkorb <wbx@openadk.org>2015-02-12 14:08:52 -0600
commit322fdd37d307a12c913be78cebcc348a77731dd3 (patch)
treeca9d101d32462a60b3a635f1a5d4b5012b1a151e /libpthread
parentc725f1deaef5bbfb22c83fbfc221a86255a3072b (diff)
unbreak support for ARM no MMU case
As suggested on the uCLibc mailing list: http://lists.uclibc.org/pipermail/uclibc/2014-November/048702.html http://lists.uclibc.org/pipermail/uclibc/2014-November/048703.html http://lists.uclibc.org/pipermail/uclibc/2014-November/048704.html
Diffstat (limited to 'libpthread')
-rw-r--r--libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h56
1 files changed, 49 insertions, 7 deletions
diff --git a/libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h b/libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h
index 438c12ab9..2b877f980 100644
--- a/libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h
+++ b/libpthread/linuxthreads.old/sysdeps/arm/pt-machine.h
@@ -21,12 +21,50 @@
#ifndef _PT_MACHINE_H
#define _PT_MACHINE_H 1
-#include <features.h>
+#include <sys/syscall.h>
+#include <unistd.h>
#ifndef PT_EI
# define PT_EI __extern_always_inline
#endif
+#if defined(__thumb__)
+#if defined(__USE_LDREXSTREX__)
+PT_EI long int ldrex(int *spinlock)
+{
+ long int ret;
+ __asm__ __volatile__(
+ "ldrex %0, [%1]\n"
+ : "=r"(ret)
+ : "r"(spinlock) : "memory");
+ return ret;
+}
+
+PT_EI long int strex(int val, int *spinlock)
+{
+ long int ret;
+ __asm__ __volatile__(
+ "strex %0, %1, [%2]\n"
+ : "=r"(ret)
+ : "r" (val), "r"(spinlock) : "memory");
+ return ret;
+}
+
+/* Spinlock implementation; required. */
+PT_EI long int
+testandset (int *spinlock)
+{
+ register unsigned int ret;
+
+ do {
+ ret = ldrex(spinlock);
+ } while (strex(1, spinlock));
+
+ return ret;
+}
+
+#else /* __USE_LDREXSTREX__ */
+
/* This will not work on ARM1 or ARM2 because SWP is lacking on those
machines. Unfortunately we have no way to detect this at compile
time; let's hope nobody tries to use one. */
@@ -36,8 +74,6 @@ PT_EI long int testandset (int *spinlock);
PT_EI long int testandset (int *spinlock)
{
register unsigned int ret;
-
-#if defined(__thumb__)
void *pc;
__asm__ __volatile__(
".align 0\n"
@@ -50,15 +86,21 @@ PT_EI long int testandset (int *spinlock)
"\t.force_thumb"
: "=r"(ret), "=r"(pc)
: "0"(1), "r"(spinlock));
-#else
+ return ret;
+}
+#endif
+#else /* __thumb__ */
+
+PT_EI long int testandset (int *spinlock);
+PT_EI long int testandset (int *spinlock)
+{
+ register unsigned int ret;
__asm__ __volatile__("swp %0, %1, [%2]"
: "=r"(ret)
: "0"(1), "r"(spinlock));
-#endif
-
return ret;
}
-
+#endif
/* Get some notion of the current stack. Need not be exactly the top
of the stack, just something somewhere in the current frame. */