Handling Thread Local Storage in the C Library: NOTE: - When building against this library some care is needed. - Ensure libc.a is the last library searched in the linker directory path. - See C Library Note. GOALS: - Clean binary (meaning a binary with minimal sections and symbols to function). - Native Performance (direct calls). - Main thread must be agnostic to threading. Native TLS initialization: Pros: - Clean binary. - Native performance. - Main thread agnostic to threading (only link if main uses thread local storage). - Works if main uses thread local storage or creates threads. Cons: - Adds another TLS initialization version of each entry point (and a version that also includes a thread local version of errno). Lazy TLS initialization: Pros: - Clean binary. - Almost native performance (one extra level of indirection). - Main thread agnostic to threading. - Entry points remain unchanged. Cons: - Increased code complexity. - Hard to get right. - Patching code at runtime. - dlopen() must handle correctly. - Runtime performance cost when initializing new threads. (Small but acceptable performance cost). Emulated TLS: **Must be implemented as a fallback.** - Used as a fallback if compiled with C99 compiler or without TLS support. - Clean binary. - Slower performance because of indirection. - Main thread agnostic to threading. - Entry points remain unchanged. Entry point initialization using a check for .tdata and .tbss size. Pros: - Extremely simple implementation. - Native performance. - Main thread agnostic to threading. - No performance cost. Cons: - All binaries will include initialization code (fails clean binary goal). - All entry points must have initialization check. Implementation: Native TLS initialization: - For each entry point include a duplicate version that initializes TLS. - The entry point must call and also contain TLS initialization code. - The TLS init code will define and reference the following exposed symbols: __tdata_start -> .tdata start address. __tbss_start -> .tbss start address. ... - TLS init code uses these variables for TLS initialization. - Use a linker script to expose those variables. - If the main executable uses thread local storage the TLS init version of entry code will be linked. - In thread creation code each thread need a copy of every variable that is considered thread local (i.e. errno). Test for lack of C11 compliance or TLS disabled. - Provide emulated TLS fallback.