about summary refs log tree commit diff
path: root/arch/arm/pthread_arch.h
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2014-11-19 00:40:32 -0500
committerRich Felker <dalias@aerifal.cx>2014-11-19 01:02:01 -0500
commit4a241f14a6bea81b9b50edda09f8184e35a75860 (patch)
treecafc783295719edfa98d5e654e337acfe19ee83e /arch/arm/pthread_arch.h
parentd8bdc97d148088bdaa672f56d4b8e0a15b03e70e (diff)
downloadmusl-4a241f14a6bea81b9b50edda09f8184e35a75860.tar.gz
musl-4a241f14a6bea81b9b50edda09f8184e35a75860.tar.xz
musl-4a241f14a6bea81b9b50edda09f8184e35a75860.zip
overhaul ARM atomics/tls for performance and compatibility
previously, builds for pre-armv6 targets hard-coded use of the "kuser
helper" system for atomics and thread-pointer access, resulting in
binaries that fail to run (crash) on systems where this functionality
has been disabled (as a security/hardening measure) in the kernel.
additionally, builds for armv6 hard-coded an outdated/deprecated
memory barrier instruction which may require emulation (extremely
slow) on future models.

this overhaul replaces the behavior for all pre-armv7 builds (both of
the above cases) to perform runtime detection of the appropriate
mechanisms for barrier, atomic compare-and-swap, and thread pointer
access. detection is based on information provided by the kernel in
auxv: presence of the HWCAP_TLS bit for AT_HWCAP and the architecture
version encoded in AT_PLATFORM. direct use of the instructions is
preferred when possible, since probing for the existence of the kuser
helper page would be difficult and would incur runtime cost.

for builds targeting armv7 or later, the runtime detection code is not
compiled at all, and much more efficient versions of the non-cas
atomic operations are provided by using ldrex/strex directly rather
than wrapping cas.
Diffstat (limited to 'arch/arm/pthread_arch.h')
-rw-r--r--arch/arm/pthread_arch.h14
1 files changed, 11 insertions, 3 deletions
diff --git a/arch/arm/pthread_arch.h b/arch/arm/pthread_arch.h
index 6d9dc3a6..7ab90580 100644
--- a/arch/arm/pthread_arch.h
+++ b/arch/arm/pthread_arch.h
@@ -10,9 +10,17 @@ static inline __attribute__((const)) pthread_t __pthread_self()
 
 #else
 
-typedef char *(*__ptr_func_t)(void) __attribute__((const));
-#define __pthread_self() \
-	((pthread_t)(((__ptr_func_t)0xffff0fe0)()+8-sizeof(struct pthread)))
+static inline __attribute__((const)) pthread_t __pthread_self()
+{
+#ifdef __clang__
+	char *p;
+	__asm__( "bl __a_gettp\n\tmov %0,r0" : "=r"(p) : : "cc", "r0", "lr" );
+#else
+	register char *p __asm__("r0");
+	__asm__( "bl __a_gettp" : "=r"(p) : : "cc", "lr" );
+#endif
+	return (void *)(p+8-sizeof(struct pthread));
+}
 
 #endif