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

Tracking issue for `thread_local` stabilization #29594

Open
aturon opened this Issue Nov 5, 2015 · 18 comments

Comments

Projects
None yet
10 participants
@aturon
Copy link
Member

aturon commented Nov 5, 2015

The #[thread_local] attribute is currently feature-gated. This issue tracks its stabilization.

Known problems:

  • #[thread_local] translates directly to the thread_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. 10.6 doesn'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.
  • Statics that are thread local shouldn't require Sync - #18001
  • Statics that are thread local should either not borrow for the 'static lifetime or should be unsafe to access - #17954
  • Statics can currently reference other thread local statics, but this is a bug - #18712
  • Unsound with generators #49682
  • static mut can be given 'static lifetime with NLL (#54366)
@aturon

This comment was marked as resolved.

Copy link
Member Author

aturon commented Nov 5, 2015

@alexcrichton Can you elaborate on the blockers?

@alexcrichton

This comment was marked as resolved.

Copy link
Member

alexcrichton commented Nov 5, 2015

Certainly! Known issues to me:

  • #[thread_local] translates directly to the thread_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. 10.6 doesn'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.
  • Statics that are thread local shouldn't require Sync - #18001
  • Statics that are thread local should either not borrow for the 'static lifetime or should be unsafe to access - #17954
  • Statics can currently reference other thread local statics, but this is a bug - #18712

That's at least what I can think of at this time!

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Feb 17, 2016

A note, we've since implemented cfg(target_thread_local) which is in turn itself feature gated, but this may ease the "this isn't implemented on all platforms" worry.

@alexandermerritt

This comment has been minimized.

Copy link
Contributor

alexandermerritt commented Aug 30, 2016

Hi! Is there any update on the status? Nightly still requires statics to be Sync. I tried with:

rustc 1.13.0-nightly (acd3f796d 2016-08-28)
binary: rustc
commit-hash: acd3f796d26e9295db1eba1ef16e0d4cc3b96dd5
commit-date: 2016-08-28
host: x86_64-unknown-linux-gnu
release: 1.13.0-nightly

@SimonSapin SimonSapin referenced this issue Feb 19, 2017

Open

Tracking issue for 1.0.0 tracking issues #39954

13 of 38 tasks complete
@mneumann

This comment has been minimized.

Copy link
Contributor

mneumann commented Jul 10, 2017

@alexcrichton Any news on #[thread_local] becoming stabilized? AFAIK, at the moment it is impossible on DragonFly to access errno variable from stable code, other than directly from libstd. This blocks crates like nix on DragonFly, which want to access errno as well, but libstd is not exposing it, and stable code is not allowed to use feature(thread_local).

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Jul 10, 2017

@mneumann no, no progress. I'd recommend a C shim for now.

@mneumann

This comment has been minimized.

Copy link
Contributor

mneumann commented Jul 10, 2017

@Boiethios

This comment has been minimized.

Copy link

Boiethios commented Sep 8, 2017

The optimizations are too aggressive ;)

See this code:

#![feature(thread_local)]

#[thread_local]
pub static FOO: [&str; 1] = [ "Hello" ];

fn change_foo(s: &'static str) {
    FOO[0] = s;
}

fn main() {
    println!("{}", FOO[0]);
    change_foo("Test");
    println!("{}", FOO[0]);
}

The compiler does not detect the side effect in change_foo and removes the call in release. The output is:

Hello
Hello
@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Sep 8, 2017

cc @eddyb, @Boiethios your example shouldn't actually compile because it should require static mut, not just static

@Boiethios

This comment has been minimized.

Copy link

Boiethios commented Sep 8, 2017

It compiles with the last nightly rustc.

@eddyb

This comment has been minimized.

Copy link
Member

eddyb commented Sep 8, 2017

Oh, drat, this is from my shortening of the lifetime, i.e

// `#[thread_local]` statics may not outlive the current function.
for attr in &self.tcx.get_attrs(def_id)[..] {
if attr.check_name("thread_local") {
return Ok(self.cat_rvalue_node(id, span, expr_ty));
}
}

@nikomatsakis what should we do here? I want a static lvalue, with a non-'static lifetime.

mneumann added a commit to mneumann/nix-rust that referenced this issue Nov 20, 2017

Fix errno on DragonFly
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.21.0). We have to use a C extension (src/errno_dragonfly.c) to access
it.

Tracking issue for `thread_local` stabilization:

    rust-lang/rust#29594

Once this becomes stable, we can remove build.rs, src/errno_dragonfly.c,
remove the build-dependency from Cargo.toml, and use:

    extern {
        #[thread_local]
        static errno: c_int;
    }

Now all targets will use the build.rs script, but only on DragonFly this
will do something. Also, there are no additional dependencies for
targets other than DragonFly (no gcc dep).

mneumann added a commit to mneumann/nix-rust that referenced this issue Dec 5, 2017

Fix errno on DragonFly
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.21.0). We have to use a C extension (src/errno_dragonfly.c) to access
it.

Tracking issue for `thread_local` stabilization:

    rust-lang/rust#29594

Once this becomes stable, we can remove build.rs, src/errno_dragonfly.c,
remove the build-dependency from Cargo.toml, and use:

    extern {
        #[thread_local]
        static errno: c_int;
    }

Now all targets will use the build.rs script, but only on DragonFly this
will do something. Also, there are no additional dependencies for
targets other than DragonFly (no gcc dep).

mneumann added a commit to mneumann/nix-rust that referenced this issue Dec 19, 2017

Fix support for DragonFly
* DragonFly does not have a O_DSYNC flag
* Fix type_of_cmsg_data on DragonFly
* No fexecve() on DragonFly
* Do not run aio test cases on DragonFly
* Keep target lists in alphabetical order
* Unscrable #[cfg] directives and use cfg_if! macro instead
* Fix errno on DragonFly

Below follows an explanation why we have to use a C extension
to get errno working on DragonFly:

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.21.0). We have to use a C extension (src/errno_dragonfly.c) to access
it.

Tracking issue for `thread_local` stabilization:

    rust-lang/rust#29594

Once this becomes stable, we can remove build.rs, src/errno_dragonfly.c,
remove the build-dependency from Cargo.toml, and use:

    extern {
        #[thread_local]
        static errno: c_int;
    }

Now all targets will use the build.rs script, but only on DragonFly this
will do something. Also, there are no additional dependencies for
targets other than DragonFly (no gcc dep).
@cramertj

This comment has been minimized.

Copy link
Member

cramertj commented Jan 17, 2018

#18001, #17954 and #18712 were fixed by #43746.

@alexcrichton @eddyb Do you know any other blockers, or is this ready for stabilization?

@eddyb

This comment has been minimized.

Copy link
Member

eddyb commented Jan 17, 2018

There's some emulation clang does IIRC, that we might want to do ourselves, to support #[thread_local] everywhere.

And there's #47053 which results from my initial attempt to limit references to thread-local statics to the function they were created in.

@alexcrichton

This comment has been minimized.

Copy link
Member

alexcrichton commented Jan 17, 2018

@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.

@Amanieu

This comment has been minimized.

Copy link
Contributor

Amanieu commented Jan 17, 2018

I am using #[thread_local] in my code in a no_std context: I allocate space for the TLS segment and set up the architecture TLS register to point to it. Therefore I think that it is important to expose the #[thread_local] attribute so that it can at least be used by low-level code.

The only thing that I'm not too happy about is that Sync is no longer required for #[thread_local]: this makes it more difficult to write signal-safe code, since all communication between signal handlers and the main thread should be done through atomic types.

@eddyb

This comment has been minimized.

Copy link
Member

eddyb commented Jan 17, 2018

@Amanieu Signal/interrupt-safe code has other requirements which are not satisfied by current Rust.

@Amanieu

This comment has been minimized.

Copy link
Contributor

Amanieu commented Jan 17, 2018

@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 Sync.

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.

dcuddeback added a commit to dcuddeback/serial-rs that referenced this issue Jun 22, 2018

Fix errno location on DragonFly BSD
DragonFlyBSD uses a thread-local variable for errno. libstd uses a
feature (`thread_local`) which is not stablized [1].

[1] rust-lang/rust#29594
@dtolnay

This comment has been minimized.

Copy link
Member

dtolnay commented Oct 8, 2018

@cramertj regarding remaining blockers, I would consider the behavior that @Boiethios reported above needs to be fixed before stabilization. I filed #54901 to follow up.

jackpot51 pushed a commit to redox-os/ion that referenced this issue Dec 29, 2018

Fix errno on DragonFly
__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; }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.