-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Tracking issue for thread_local
stabilization
#29594
Comments
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
A note, we've since implemented |
Hi! Is there any update on the status? Nightly still requires statics to be
|
@alexcrichton Any news on |
@mneumann no, no progress. I'd recommend a C shim for now. |
@alexcrichton thanks. I am doing a shim now https://github.com/mneumann/errno-dragonfly-rs. |
The optimizations are too aggressive ;) See this code:
The compiler does not detect the side effect in
|
cc @eddyb, @Boiethios your example shouldn't actually compile because it should require |
It compiles with the last nightly rustc. |
Oh, drat, this is from my shortening of the lifetime, i.e rust/src/librustc/middle/mem_categorization.rs Lines 657 to 662 in dead08c
@nikomatsakis what should we do here? I want a static lvalue, with a non- 'static lifetime.
|
There's some emulation And there's #47053 which results from my initial attempt to limit references to thread-local statics to the function they were created in. |
@cramertj I've personally been under the impression that we're holding out on stabilizing this for as long as possible. We've stabilized very few (AFAIK) platform-specific attributes like this and I at least personally haven't ever looked to hard into stabilizing this. One blocker (in my mind at least) is what @eddyb mentioned where this is a "portable" attribute yet LLVM has a bunch of emulation on targets that don't actually support it (I think MinGW is an example). I don't believe we should allow the attribute on such targets, but we'd have to do a lot of investigation to figure out those targets. Is there motivation for stabilizing this though? That'd certainly provide some good motivation for digging out any remaining issues and looking at it very closely. I'd just personally been under the impression that there's little motivation to stabilize this other than it'd be a "nice to have" in situations here and there. |
I am using The only thing that I'm not too happy about is that |
@Amanieu Signal/interrupt-safe code has other requirements which are not satisfied by current Rust. |
@eddyb Not really, all you need to do is treat the signal handler as a separate thread of execution. The only requirement you need to enforce safety is that objects which are accessed by both the main thread and the signal handler must be Of course you can still cause deadlocks if the main thread and signal handler both try to grab the same lock, but that's not a safety issue. |
DragonFlyBSD uses a thread-local variable for errno. libstd uses a feature (`thread_local`) which is not stablized [1]. [1] rust-lang/rust#29594
__dfly_error() was removed from Rust many years ago. DragonFly uses a thread-local errno variable, but #[thread_local] is feature-gated and not available in stable Rust as of this writing (Rust 1.31.0). We have to use a C extension to access it. Tracking issue for `thread_local` stabilization: rust-lang/rust#29594 Once this becomes stable, we can simply use: extern { #[thread_local] static errno: c_int; }
Thread-local storage is commonly needed in all sorts of places, from storing a harts `TrapFrame`, ID or other state that should be statically available but still per-hart. Instead of coming up with something homegrown here we use Rusts/LLVMs [`thread_local` attribute](rust-lang/rust#29594). This requires us to do a couple things: 1. allocate one or more frames for TLS 2. (identity) map the frames 3. *on each hart* set the `tp` register to point to the TLS base
I wonder if there's a path towards a minimal E.g.:
|
What is the motivation for that? Doesn't |
|
Does that form of the macro need anything that requires |
We could make a macro I guess. It'd be pretty redundant though when/if |
The API provided by |
The "two ways to do things" will occur whatever happens unless we simply don't stabilize |
That is true. If the usecases are covered I don't see a reason to stabilize |
|
IIRC generated assembly for |
For the new EDIT: assuming the type of |
If they only work for And taking references would be unsound. |
Borrowck limits those references to the current function already I believe. |
Yes. The goal would be to eventually make full |
Oh interesting, I wasn't aware that borrowck had special treatment for thread_local statics. |
I'd be very interested in seeing this stablized. In general, being able to import an external TLS var without shim code written in C is useful (for example, if you want to grab |
How about introducing a pointer-based variant of // Creates TLS value which stores 42 and creates "pointer" `FOO` to it.
#[thread_local_ptr]
static FOO: *mut u64 = 42u64;
fn increment_foo() {
// SAFETY: reference to `FOO`does not escape execution thread
let foo: &mut u64 = unsafe { &mut *FOO };
*foo += 1;
} |
@newpavlov it seems someone already taught the borrow checker about thread_local so taking references to them is actually sound. That's pretty cool. I don't like there being this API duplication and inconsistency between that and the We'd have to be rather careful where we enable this feature; in the past, I think on some Windows targets we switched back-and-forth between "true" thread-local statics and some other implementation for the I'm slightly bothered by thread-local statics pretending to be statics. They have very little in common with regular |
I have a few use cases for
|
What's the status of this? I see a lot of discussion around a hypothetical |
It's not hypothetical,
If we just allow asm blocks to reference thread-locals, I worry it will lead to much confusion and errors. A thread-local is not just a normal symbol, after all -- but a Rust programmer might think it is, since in Rust code it behaves much like a static, but that's a sweet lie. Unfortunately the inline asm docs don't even give an example for how
Presumably, it is UB to try to access that symbol without the exactly right set of relocations matching the current target and build flags? Seems like a pretty big footgun. |
It's always safe to use the most general relocations (which involve calling |
Using |
Just curious, are there any thread-local modes that aren't based on ELF's thread structure system? e.g. on x86_64 will we eventually be able to simply emit instructions that use FS/GS segments directly instead of reading a pointer from a negative offset and de-referencing it? As far as I can tell that's GNU's/ELF's TLS model that doesn't really translate nicely to |
The
#[thread_local]
attribute is currently feature-gated. This issue tracks its stabilization.Known problems:
#[thread_local]
translates directly to thethread_local
attribute in LLVM. This isn't supported on all platforms, and it's not even supported on all distributions within the same platform (e.g. macOS 10.6 didn't support it but 10.7 does). I don't think this is necessarily a blocker, but I also don't think we have many attributes and such which are so platform specific like this.Sync
- #[thread_local] statics shouldn't require Sync #18001'static
lifetime or should be unsafe to access - Safe access to a#[thread_local]
should be disallowed #17954'static
lifetime with NLL (#[thread_local] static mut
is allowed to have'static
lifetime #54366)The text was updated successfully, but these errors were encountered: