@@ -5,27 +5,63 @@ import cllvm
5
5
/// Enumerates the supported models of reference of thread-local variables.
6
6
///
7
7
/// 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.
9
10
///
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.
12
27
public enum ThreadLocalModel {
13
28
/// The variable is not thread local and hence has no associated model.
14
29
case notThreadLocal
15
30
/// Allows reference of all thread-local variables, from either a shared
16
31
/// object or a dynamic executable. This model also supports the deferred
17
32
/// 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.
19
46
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
21
48
/// 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.
24
51
///
25
52
/// 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.
29
65
case localDynamic
30
66
/// This model can only reference thread-local variables which are available
31
67
/// as part of the initial static thread-local template. This template is
@@ -43,8 +79,10 @@ public enum ThreadLocalModel {
43
79
/// objects should reference thread-local variables using a dynamic model of
44
80
/// thread-local storage.
45
81
case initialExec
82
+ /// This model is an optimization of the `localDynamic` model.
83
+ ///
46
84
/// 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
48
86
/// calculates the thread pointer-relative offsets statically, without the
49
87
/// need for dynamic relocations, or the extra reference to the GOT. This
50
88
/// model can not be used to reference variables outside of the dynamic
0 commit comments