path: root/src/internal
diff options
authorRich Felker <>2012-10-05 11:51:50 -0400
committerRich Felker <>2012-10-05 11:51:50 -0400
commitdcd60371500a74d489372cac7240674c992c2484 (patch)
treeef219cc9f3e27e877aa0de62c6f74f1a4b89595a /src/internal
parent642b7593c3b3488d229488a436bab294dcc27ee9 (diff)
support for TLS in dynamic-loaded (dlopen) modules
unlike other implementations, this one reserves memory for new TLS in all pre-existing threads at dlopen-time, and dlopen will fail with no resources consumed and no new libraries loaded if memory is not available. memory is not immediately distributed to running threads; that would be too complex and too costly. instead, assurances are made that threads needing the new TLS can obtain it in an async-signal-safe way from a buffer belonging to the dynamic linker/new module (via atomic fetch-and-add based allocator). I've re-appropriated the lock that was previously used for __synccall (synchronizing set*id() syscalls between threads) as a general pthread_create lock. it's a "backwards" rwlock where the "read" operation is safe atomic modification of the live thread count, which multiple threads can perform at the same time, and the "write" operation is making sure the count does not increase during an operation that depends on it remaining bounded (__synccall or dlopen). in static-linked programs that don't use __synccall, this lock is a no-op and has no cost.
Diffstat (limited to 'src/internal')
2 files changed, 4 insertions, 3 deletions
diff --git a/src/internal/libc.h b/src/internal/libc.h
index ca06f319..f88d846d 100644
--- a/src/internal/libc.h
+++ b/src/internal/libc.h
@@ -16,7 +16,7 @@ struct __libc {
int canceldisable;
FILE *ofl_head;
int ofl_lock[2];
- volatile size_t tls_size, tls_cnt;
+ size_t tls_size;
extern size_t __hwcap;
diff --git a/src/internal/pthread_impl.h b/src/internal/pthread_impl.h
index f7facba3..0f10cc48 100644
--- a/src/internal/pthread_impl.h
+++ b/src/internal/pthread_impl.h
@@ -111,8 +111,9 @@ int __timedwait(volatile int *, int, clockid_t, const struct timespec *, void (*
void __wait(volatile int *, volatile int *, int, int);
void __wake(volatile int *, int, int);
-void __synccall_lock();
-void __synccall_unlock();
+void __acquire_ptc();
+void __release_ptc();
+void __inhibit_ptc();
#define DEFAULT_STACK_SIZE 81920