summaryrefslogtreecommitdiff
path: root/src/thread
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2014-06-19 02:59:44 -0400
committerRich Felker <dalias@aerifal.cx>2014-06-19 02:59:44 -0400
commit5ba238e1e48d2fe4107e09903b26b2b36aa9e9ff (patch)
tree2933bdc33c131122acea9b188186443da2e6a37b /src/thread
parent4e0b4a5de735ecb241fadb1e15381c947e16e71f (diff)
downloadmusl-5ba238e1e48d2fe4107e09903b26b2b36aa9e9ff.tar.gz
separate __tls_get_addr implementation from dynamic linker/init_tls
such separation serves multiple purposes: - by having the common path for __tls_get_addr alone in its own function with a tail call to the slow case, code generation is greatly improved. - by having __tls_get_addr in it own file, it can be replaced on a per-arch basis as needed, for optimization or ABI-specific purposes. - by removing __tls_get_addr from __init_tls.c, a few bytes of code are shaved off of static binaries (which are unlikely to use this function unless the linker messed up).
Diffstat (limited to 'src/thread')
-rw-r--r--src/thread/__tls_get_addr.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/src/thread/__tls_get_addr.c b/src/thread/__tls_get_addr.c
new file mode 100644
index 00000000..28ec7f02
--- /dev/null
+++ b/src/thread/__tls_get_addr.c
@@ -0,0 +1,17 @@
+#include <stddef.h>
+#include "pthread_impl.h"
+#include "libc.h"
+
+void *__tls_get_new(size_t *) ATTR_LIBC_VISIBILITY;
+
+void *__tls_get_addr(size_t *v)
+{
+ pthread_t self = __pthread_self();
+#ifdef SHARED
+ if (v[0]<=(size_t)self->dtv[0])
+ return (char *)self->dtv[v[0]]+v[1];
+ return __tls_get_new(v);
+#else
+ return (char *)self->dtv[1]+v[1];
+#endif
+}