Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Check target definitions to see if more should have cfg(target_thread_local) enabled. #91659

Open
thomcc opened this issue Dec 8, 2021 · 6 comments
Labels
A-thread-locals Area: Thread local storage (TLS) F-thread_local `#![feature(thread_local)]` O-dragonfly Operating system: DragonFly BSD O-freebsd Operating system: FreeBSD O-netbsd Operating system: NetBSD O-openbsd Operating system: OpenBSD O-windows-gnu Toolchain: GNU, Operating system: Windows

Comments

@thomcc
Copy link
Member

thomcc commented Dec 8, 2021

Out of curiosity, I ran a script to print out the list of targets where cfg(target_thread_local) (indicating support for #[thread_local]) is not true.

The results (and script) are available here: https://gist.github.com/thomcc/766d76e4da35ce1a73b93ccd548fd143

This looks somewhat wrong to me — I believe several of these should have support for static/linker thread local (or at least __thread/__declspec(thread) has worked there for me). Here are some items in that list which are... fairly suspicious to me.

  • All the x86_64 (and probably other arches) unix ELF targets, like the various BSDs.
  • i686-pc-windows-msvc, x86_64-pc-windows-gnu and i686-pc-windows-gnu
  • aarch64-apple-ios (probably), aarch64-apple-tvos (almost certainly)
  • ...

Playing around with1 clang, gcc, and msvc a bit indicates that (the ones I can easily test of these) should have it, and probably others.

My suspicion is:

  • Some of these are listed as not having thread locals by accident. It seems very easy to forget to change something like this when updating or adding a target
  • Some of these are listed as unsupported because technically we might support very old versions.

If the issue is about old versions, I guess a question would be what should the cfg do in situations where the support is version-dependent...

This sounds like a tricky thing to decide! Worth noting: support for TLS is what caused us to choose 10.7 as the minimum supported version for macOS: #11927, but I guess back then2 we might not have had a #[cfg(target_thread_local)]?.

But if nothing else, libstd probably has more concrete ideas about what it supports, and this causes it to be far more pessimistic in std::thread_local!.

And more concretely: I'm pretty sure if I used #[thread_local] in a malloc, I'd be pretty annoyed if it couldn't support, say, FreeBSD, since I know that at least GCC/Clang support __thread on that target.

Footnotes

  1. I think the correct thing to compare against would be _Thread_local/__thread/__declspec(thread) rather than C++'s thread_local — these don't have ctor/dtor support, and thus map more directly to Rust's #[thread_local]. That said, I don't really see a difference in what I've checked.

  2. I don't feel doing that much spelunking, seems likely that given the numeric gap between the macOS issue and the thread_local issue, that things probably worked very differently!

@thomcc
Copy link
Member Author

thomcc commented Dec 8, 2021

@rustbot modify labels: +A-thread-locals +F-thread_local

@rustbot rustbot added A-thread-locals Area: Thread local storage (TLS) F-thread_local `#![feature(thread_local)]` labels Dec 8, 2021
@ChrisDenton
Copy link
Member

Hm, yeah. I'm pretty sure there's no reason for any Windows targets not to support it. Or at least it's very inconsistent that i686-uwp-windows-msvc enables target_thread_local but i686-pc-windows-msvc doesn't. But perhaps there was a historic reason for being cautious here.

Btw, the name of the spec configuration option confused me. I initially overlooked that is_elf_tls can be true on non-elf targets. Perhaps the name should match the feature name? Is renaming possible?

@nagisa
Copy link
Member

nagisa commented Dec 17, 2021

Porting from the issue just above this comment…

We have a test ui/thread-local/tls.rs which only ignores emscripten targets and uses #[thread_local] unconditionally. This suggests to me that any target we test in CI actually supports #[thread_local] in some shape or form.

matthiaskrgr added a commit to matthiaskrgr/rust that referenced this issue Dec 19, 2021
Enable `#[thread_local]` for all windows-msvc targets

As it stands, `#[thread_local]` is enabled haphazardly for msvc. It seems all 64-bit targets have it enabled, but not 32-bit targets unless they're also UWP targets (perhaps because UWP was added more recently?). So this PR simply enables it for 32-bit targets as well. I can't think of a reason not to and I've confirmed by running tests locally which pass.

See also rust-lang#91659
@workingjubilee workingjubilee added O-windows Operating system: Windows O-ios Operating system: iOS O-freebsd Operating system: FreeBSD O-dragonfly Operating system: DragonFly BSD O-openbsd Operating system: OpenBSD O-netbsd Operating system: NetBSD labels Mar 2, 2023
@mati865
Copy link
Contributor

mati865 commented Jul 23, 2023

Fixing *-windows-gnu requires some skills and time.
Simply adding only has_thread_local: true to the spec will cause binaries to segfault (caught by multiple Rust ui tests) because LLVM uses native TLS and GCC uses emuTLS.
Using has_thread_local: true, force_emulated_tls: true (as it should be) looks better but symbols are not improperly exported. Linking of stage1 libstd will fail with:

  = note: D:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot export _ZN3std11collections4hash3map11RandomState3new4KEYS7__getit5__KEY17h8ff9f85561241dd2E: symbol not found
          D:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot export _ZN3std4sync4mpmc5waker17current_thread_id5DUMMY7__getit5__KEY17h6f5deddc9b6dd8b5E: symbol not found
          D:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/13.1.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot export _ZN3std4sync4mpmc7context7Context4with7CONTEXT7__getit5__KEY17h187f3f20404853d8E: symbol not found
          collect2.exe: error: ld returned 1 exit status

Contents of CGU (codegen-units = 1):

$ nm build/x86_64-pc-windows-gnu/stage1-std/x86_64-pc-windows-gnu/release/deps/std-154d45023a8fc9de.std.2e86e8a7446b6664-cgu.0.rcgu.o | grep __getit
0000000000006e10 R __emutls_t._ZN3std11collections4hash3map11RandomState3new4KEYS7__getit5__KEY17h8ff9f85561241dd2E
0000000000006df8 r __emutls_t._ZN3std2io5stdio14OUTPUT_CAPTURE7__getit5__KEY17hd19b7ce05ba9364eE
0000000000006dd8 R __emutls_t._ZN3std4sync4mpmc5waker17current_thread_id5DUMMY7__getit5__KEY17h6f5deddc9b6dd8b5E
0000000000006de0 R __emutls_t._ZN3std4sync4mpmc7context7Context4with7CONTEXT7__getit5__KEY17h187f3f20404853d8E
00000000000000e0 d __emutls_v._ZN3std10sys_common11thread_info11THREAD_INFO7__getit3VAL17h17909a63c4d176f1E
0000000000000100 d __emutls_v._ZN3std10sys_common11thread_info11THREAD_INFO7__getit5STATE17he8008f109cc934c5E.0
00000000000001a0 D __emutls_v._ZN3std11collections4hash3map11RandomState3new4KEYS7__getit5__KEY17h8ff9f85561241dd2E
0000000000000180 d __emutls_v._ZN3std2io5stdio14OUTPUT_CAPTURE7__getit5__KEY17hd19b7ce05ba9364eE
0000000000000140 D __emutls_v._ZN3std4sync4mpmc5waker17current_thread_id5DUMMY7__getit5__KEY17h6f5deddc9b6dd8b5E
0000000000000160 D __emutls_v._ZN3std4sync4mpmc7context7Context4with7CONTEXT7__getit5__KEY17h187f3f20404853d8E
0000000000000120 d __emutls_v._ZN3std4sync7remutex25current_thread_unique_ptr1X7__getit3VAL17hcfb11cc3f4c31de3E
00000000000000a0 d __emutls_v._ZN3std9panicking11panic_count17LOCAL_PANIC_COUNT7__getit3VAL17hc5769e16fdfac207E.0
00000000000000c0 d __emutls_v._ZN3std9panicking11panic_count17LOCAL_PANIC_COUNT7__getit3VAL17hc5769e16fdfac207E.1
0000000000000078 D __imp__ZN3std11collections4hash3map11RandomState3new4KEYS7__getit5__KEY17h8ff9f85561241dd2E
0000000000000068 D __imp__ZN3std4sync4mpmc5waker17current_thread_id5DUMMY7__getit5__KEY17h6f5deddc9b6dd8b5E
0000000000000070 D __imp__ZN3std4sync4mpmc7context7Context4with7CONTEXT7__getit5__KEY17h187f3f20404853d8E
000000000005e380 t _ZN3std10sys_common11thread_info11THREAD_INFO7__getit7destroy17hd4ee32f75d09ec2fE
0000000000000320 T _ZN3std11collections4hash3map11RandomState3new4KEYS7__getit33__KEY$u7b$$u7b$tls.shim$u7d$$u7d$17h5d7e7145e387a1f5E
                 U _ZN3std11collections4hash3map11RandomState3new4KEYS7__getit5__KEY17h8ff9f85561241dd2E
0000000000000340 T _ZN3std4sync4mpmc5waker17current_thread_id5DUMMY7__getit33__KEY$u7b$$u7b$tls.shim$u7d$$u7d$17h489562b46704f878E
                 U _ZN3std4sync4mpmc5waker17current_thread_id5DUMMY7__getit5__KEY17h6f5deddc9b6dd8b5E
0000000000000360 T _ZN3std4sync4mpmc7context7Context4with7CONTEXT7__getit33__KEY$u7b$$u7b$tls.shim$u7d$$u7d$17h3bc68e75fd1d924dE
                 U _ZN3std4sync4mpmc7context7Context4with7CONTEXT7__getit5__KEY17h187f3f20404853d8E

For this to work Rust would have to not try to export symbols without __emutls decoration and instead export only those with it. Analogical change would have be made for symbols importing and of course dllexport/dllimport has to be taken into account as well.

@madsmtm
Copy link
Contributor

madsmtm commented Aug 21, 2024

Thread locals were enabled for all Apple targets in #104385.

@rustbot label -O-ios

@rustbot rustbot removed the O-ios Operating system: iOS label Aug 21, 2024
@ChrisDenton
Copy link
Member

This is enabled for all windows-msvc and windows-gnullvm targets, I believe it's just windows-gnu that's left as far as Windows is concerned.

@ChrisDenton ChrisDenton added O-windows-gnu Toolchain: GNU, Operating system: Windows and removed O-windows Operating system: Windows labels Aug 22, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-thread-locals Area: Thread local storage (TLS) F-thread_local `#![feature(thread_local)]` O-dragonfly Operating system: DragonFly BSD O-freebsd Operating system: FreeBSD O-netbsd Operating system: NetBSD O-openbsd Operating system: OpenBSD O-windows-gnu Toolchain: GNU, Operating system: Windows
Projects
None yet
Development

No branches or pull requests

7 participants