@@ -5,27 +5,63 @@ import cllvm
55/// Enumerates the supported models of reference of thread-local variables.
66///
77/// These models are listed from the most general, but least optimized, to the
8- /// fastest, but most restrictive.
8+ /// fastest, but most restrictive in general, as architectural differences
9+ /// play a role in determining the access patterns for thread-local storage.
910///
10- /// Documentation of these models quotes the [Oracle Linker and Libraries
11- /// Guide](https://docs.oracle.com/cd/E23824_01/html/819-0690/chapter8-20.html).
11+ /// In general, support for thread-local storage in statically-linked
12+ /// applications is limited: some platforms may not even define the behavior of
13+ /// TLS in such cases. This is usually not an issue as statically-linked code
14+ /// only ever has one TLS block, the offset of the variables within that block
15+ /// is known, and support for additional dynamic loading of code in
16+ /// statically-linked code is limited.
17+ ///
18+ /// Computing the thread-specific address of a TLS variable is usually a dynamic
19+ /// process that relies on an ABI-defined function call (usually
20+ /// `__tls_get_addr`) to do the heavy lifting.
21+ ///
22+ /// TLS access models fall into two classes: static and dynamic. Regardless of
23+ /// the actual model used, the dynamic linker must process all relocations
24+ /// for thread-local variables whenever the module is loaded. Some models,
25+ /// therefore, provide for a decrease in the overall number of relocations at
26+ /// a cost of restrictions on which modules can access variables.
1227public enum ThreadLocalModel {
1328 /// The variable is not thread local and hence has no associated model.
1429 case notThreadLocal
1530 /// Allows reference of all thread-local variables, from either a shared
1631 /// object or a dynamic executable. This model also supports the deferred
1732 /// allocation of a block of thread-local storage when the block is first
18- /// referenced from a specific thread.
33+ /// referenced from a specific thread. Note that the linker is free to
34+ /// optimize accesses using this model to one of the more specific models
35+ /// below which may ultimately defeat lazy allocation of the TLS storagee
36+ /// block.
37+ ///
38+ /// The code generated for this model does nto assume that any information
39+ /// about the module or variable offsets is known at link-time. Instead, the
40+ /// exact value of these variables is computed by the dynamic linker at
41+ /// runtime and passeed to `__tls_get_addr` in an architecture-specific way.
42+ ///
43+ /// If possible, this model should be avoided if one of the more specific
44+ /// models applies out of concern for code size and application startup
45+ /// performance.
1946 case generalDynamic
20- /// This model is an optimization of the General Dynamic model. The compiler
47+ /// This model is an optimization of the `generalDynamic` model. The compiler
2148 /// might determine that a variable is bound locally, or protected, within the
22- /// object being built. In this case, the compiler instructs the link-editor
23- /// to statically bind the dynamic `tlsoffset` and use this model.
49+ /// object being built. In this case, the compiler instructs the linker
50+ /// to statically bind the dynamic offset of the variable and use this model.
2451 ///
2552 /// This model provides a performance benefit over the General Dynamic model.
26- /// Only one call to `tls_get_addr()` is required per function, to determine
27- /// the address of `dtv0,m`. The dynamic thread-local storage offset, bound at
28- /// link-edit time, is added to the `dtv0,m` address for each reference.
53+ /// Only one call to `__tls_get_addr` is required per function, to determine
54+ /// the starting address of the variable within the TLS block for its
55+ /// parent module. Additional accesses can add an offset to this address
56+ /// value for repeated accesses.
57+ ///
58+ /// The optimization available over the `generalDynamic` model is defeated if
59+ /// a variable is only ever accessed once, as its access would incur the
60+ /// same `__tls_get_addr` call and the additional overhead of the offset
61+ /// calculation.
62+ ///
63+ /// The linker cannot, in general, optimize from the general dynamic model
64+ /// to the local dynamic model.
2965 case localDynamic
3066 /// This model can only reference thread-local variables which are available
3167 /// as part of the initial static thread-local template. This template is
@@ -43,8 +79,10 @@ public enum ThreadLocalModel {
4379 /// objects should reference thread-local variables using a dynamic model of
4480 /// thread-local storage.
4581 case initialExec
82+ /// This model is an optimization of the `localDynamic` model.
83+ ///
4684 /// This model can only reference thread-local variables which are part of the
47- /// thread-local storage block of the dynamic executable. The link-editor
85+ /// thread-local storage block of the dynamic executable. The linker
4886 /// calculates the thread pointer-relative offsets statically, without the
4987 /// need for dynamic relocations, or the extra reference to the GOT. This
5088 /// model can not be used to reference variables outside of the dynamic
0 commit comments