std: store key-based TLS variables in a hashmap#156743
Conversation
|
r? @tgross35 rustbot has assigned @tgross35. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
@bors try job=x86_64-mingw-1,x86_64-mingw-2 |
This comment has been minimized.
This comment has been minimized.
std: store key-based TLS variables in a hashmap try-job: x86_64-mingw-1 try-job: x86_64-mingw-2
|
@rustbot label +I-libs-nominated |
|
FYI, it might be possible to get windows-gnu to use proper native TLS at some point this year: rust-lang/compiler-team#993 |
|
☔ The latest upstream changes (presumably #157616) made this pull request unmergeable. Please resolve the merge conflicts. |
|
We discussed this during today's T-libs meeting. |
|
There is some more detail at the meeting notes https://hackmd.io/@rust-libs/BJFCwR8Zfe#Nominated-rusttf156743-std-store-key-based-TLS-variables-in-a-hashmap, but it sounds like the team would like to see perf numbers. If this is slower then maybe we could do a hybrid on systems where the platform TLS is fast? Like using the system implementation by default then have the hashmap fallback if we run out of keys. |
|
@rustbot author |
TLS keys are quite a limited resource (typical systems only have a few hundred of them), leading to issues like #155758 for complex programs like rustc that utilise too many. Also, the order of destruction cannot be easily modified, leading to behavioural inconsistencies between linker- and key-based TLS; with linker-based TLS: With linker-based TLS, variables without destructors are always available during destructor execution and variables with destructors cannot be initialised again once destroyed. However, with key-based TLS, the destruction order is arbitrary and there is no mechanism to prevent variable reinitialisation.1
To fix these issues, this PR replaces the existing variable-per-key storage with a single hashmap for all variables, with the key into the hashmap being the address of a (non-thread-local)
static. Variable destructors are stored in a list alongside the hashmap, and executed before the storage for destructorless variables is freed, matching the behaviour of linker-based TLS.On GNU/Windows this will also simplify the destructor handling in the future by avoiding the need to keep track of destructors in the TLS key abstraction layer just to match the behaviour of the UNIX API. I've left that for a future PR, which means this PR will introduce some duplication; but I figured this PR is involved enough as-is.
On other systems like Fortanix SGX and Xous, this will improve things even further since they can now get rid of their manual TLS key implementation in favour of just storing a single pointer to the hashmap/destructor list state. But that's also not included here.
Fixes #155758
Footnotes
Aside from preventing reinitialisation during the execution of the variable's own destructor. ↩