Add a thread-properties API
(Based on proposal at https://sourceware.org/glibc/wiki/ThreadPropertiesAPI)
This includes API to:
- locate static and dynamic TLS
- register thread-exit and dynamic TLS creation/destruction callbacks
Change-Id: Icd9d29a5b2f47495395645e19d3b2c96826f19c8
diff --git a/libc/private/bionic_elf_tls.h b/libc/private/bionic_elf_tls.h
index fa1af76..e0ec7b5 100644
--- a/libc/private/bionic_elf_tls.h
+++ b/libc/private/bionic_elf_tls.h
@@ -111,6 +111,18 @@
void* soinfo_ptr = nullptr;
};
+// Signature of the callbacks that will be called after DTLS creation and
+// before DTLS destruction.
+typedef void (*dtls_listener_t)(void* dynamic_tls_begin, void* dynamic_tls_end);
+
+// Signature of the thread-exit callbacks.
+typedef void (*thread_exit_cb_t)(void);
+
+struct CallbackHolder {
+ thread_exit_cb_t cb;
+ CallbackHolder* prev;
+};
+
// Table of the ELF TLS modules. Either the dynamic linker or the static
// initialization code prepares this table, and it's then used during thread
// creation and for dynamic TLS lookups.
@@ -128,7 +140,20 @@
// Pointer to a block of TlsModule objects. The first module has ID 1 and
// is stored at index 0 in this table.
size_t module_count = 0;
+ size_t static_module_count = 0;
TlsModule* module_table = nullptr;
+
+ // Callback to be invoked after a dynamic TLS allocation.
+ dtls_listener_t on_creation_cb = nullptr;
+
+ // Callback to be invoked before a dynamic TLS deallocation.
+ dtls_listener_t on_destruction_cb = nullptr;
+
+ // The first thread-exit callback; inlined to avoid allocation.
+ thread_exit_cb_t first_thread_exit_callback = nullptr;
+
+ // The additional callbacks, if any.
+ CallbackHolder* thread_exit_callback_tail_node = nullptr;
};
void __init_static_tls(void* static_tls);
@@ -175,3 +200,4 @@
struct bionic_tcb;
void __free_dynamic_tls(bionic_tcb* tcb);
+void __notify_thread_exit_callbacks();