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

Recognize #[thread_local] attr on extern static. Fixes #30795. #30856

Merged
merged 6 commits into from
Feb 25, 2016
Merged

Recognize #[thread_local] attr on extern static. Fixes #30795. #30856

merged 6 commits into from
Feb 25, 2016

Conversation

mneumann
Copy link
Contributor

This will correctly add the thread_local attribute to the external static variable errno:

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

Before this commit, the thread_local attribute is ignored. Fixes #30795.

Thanks @alexcrichton for pointing out the solution.

This will correctly add the thread_local attribute to the external static
variable "errno":

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

Before this commit, the thread_local attribute is ignored.
@rust-highfive
Copy link
Collaborator

r? @brson

(rust_highfive has picked a reviewer for you, use r? to override)

@alexcrichton
Copy link
Member

Thanks! Could you add a run-pass test for this as well? Something like:

// auxiliary/foo.rs
#[thread_local]
pub static FOO: u32 = 3;

// run-pass/foo.rs
extern crate foo;

extern {
    #[thread_local]
    static FOO: u32;
}

fn main() {
    assert_eq!(FOO, 3);
}

@brson brson added the relnotes Marks issues that should be documented in the release notes of the next release. label Jan 12, 2016
@brson
Copy link
Contributor

brson commented Jan 12, 2016

It looks like this is adding a new language feature (thread-local externs). Seems like it should get some more eyes. cc @rust-lang/lang

Isn't it true that not all platforms support #[thread_local]? If so, is there an alternative formulation for those?

@mneumann
Copy link
Contributor Author

@brson: AFAIK it's only required (at the moment) to support DragonFly, which defines errno as thread_local. It's only required to link to a thread-local external global variable. This only makes sense if your system supports thread locals. So I don't see an issue with other systems.

@alexcrichton
Copy link
Member

To be clear, #[thread_local] is already feature gated for many other reasons, and to me this seems like it's just a natural extension of that feature gate. I partly requested a run-pass test to verify that the feature gate is working in this context as well (as I suspect it'll need some extra support).

Platform support is a good point, however, and the test should probably only run on Linux for now to be safe. Either that or it could use the new #[cfg(target_thread_local)] cfg which can detect if the #[thread_local] attribute will work.

@nikomatsakis
Copy link
Contributor

@alexcrichton

Platform support is a good point, however, and the test should probably only run on Linux for now to be safe.

I'm a bit confused. What is the expected behavior on platforms that don't support #[thread-local]? Seems like we should test that too (this applies equally to extern and non-extern thread-locals).

@nikomatsakis
Copy link
Contributor

For the record, I agree that this feels like a sensible extension of #[thread_local] that doesn't seem to add any particular complications. That is, it's always been a "use this feature of your target" kind of thing; if that feature is present, presumably it works in C and we should be able to interoperate. If it is not present, then this is no different. Right?

@alexcrichton
Copy link
Member

That's actually a good question about what happens if the target doesn't support thread_local, and the answer to that is I'm not sure! I suspect that at runtime the program will segfault or just give really weird responses (e.g. the variable isn't actually thread loal)

From what I understand, support for thread_local involves cooperation between the binary itself and the OS. In many cases the OS doesn't support it (such as OSX 10.6 and before) despite the binary format supporting it. I'm not sure what the failure mode is on Android, it may involve various runtime symbols as well there.

Note that we have pretty exhaustive tests of #[thread_local] because it's used by the thread_local! macro, so I'm not sure we need that much in the way of tests here.

@@ -0,0 +1,2 @@
#[thread_local]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These tests will need license header blocks, and I would expect at least that each test would require #![feature(thread_local)], although I suspect the one below may not require it (could you make sure?)

@brson
Copy link
Contributor

brson commented Jan 20, 2016

@bors r+

@bors
Copy link
Contributor

bors commented Jan 20, 2016

📌 Commit ca76cf1 has been approved by brson

@bors
Copy link
Contributor

bors commented Jan 20, 2016

⌛ Testing commit ca76cf1 with merge b4f697c...

@bors
Copy link
Contributor

bors commented Jan 20, 2016

💔 Test failed - auto-mac-64-nopt-t

@brson
Copy link
Contributor

brson commented Jan 27, 2016

Error is legit.

@mneumann
Copy link
Contributor Author

@alexcrichton @brson I think those last two commits need to go it to fix running the test case. At least, without the no_mangle and aux-build it doesn't run on my box. Sorry for the long delay.

@alexcrichton
Copy link
Member

@bors: r+ c2c58a3

No worries!

@bors
Copy link
Contributor

bors commented Feb 20, 2016

⌛ Testing commit c2c58a3 with merge 9646537...

@bors
Copy link
Contributor

bors commented Feb 20, 2016

💔 Test failed - auto-win-gnu-64-nopt-t

@alexcrichton
Copy link
Member

Oh, right! This will probably want to use #[cfg(target_thread_local)] to figure out when the test can actually run

@mneumann
Copy link
Contributor Author

@alexcrichton : I am not sure if I understand #[cfg(target_thread_local)] correctly. It distinguishes ELF and OS TLS implementations. The test passes on DragonFly, which is #[cfg(not(target_thread_local))]. Linux on the other hand has #[cfg(target_thread_local)] and also passes the test... ?

@alexcrichton
Copy link
Member

Ah yeah to clarify #[cfg(target_thread_local)] tests whether the target supports the #[thread_local] attribute. You may want to change the target spec for dragonfly to enable #[thread_local] as it sounds like it's enabled there?

Basically this test won't work on platforms that don't support #[thread_local] so we may want to turn it off for now.

@mneumann
Copy link
Contributor Author

@alexcrichton : Understood! You are talking about the has_elf_tls of TargetOptions in src/librustc_back/target/dragonfly_base.rs. None of the BSDs have set this to true. If I set it to true, rust fails to compile in libstd/thread/local.rs on module elf. I assume the correct way is to implement a register_dtor for DragonFly in this case to make it work. But this is another issue.

@alexcrichton
Copy link
Member

Ah yeah this looks good to me now, sorry for the runaround!

@bors: r+ 4ef60a2

@bors
Copy link
Contributor

bors commented Feb 21, 2016

⌛ Testing commit 4ef60a2 with merge cbe4e88...

@bors
Copy link
Contributor

bors commented Feb 21, 2016

💔 Test failed - auto-win-msvc-64-opt

@mneumann
Copy link
Contributor Author

@alexcrichton : I wonder why this fails on win-msvc-64. This platform doesn't seem to be target_thread_local, so it should just link the static variable.

@alexcrichton
Copy link
Member

That is indeed weird... I guess // ignore-windows for now? seems benign...

Windows is not #[cfg(target_thread_local)] and as such should link
to the external symbol. But it fails with:

    thread '<main>' panicked at 'assertion failed: `(left == right)` (left: `272246271`, right: `3`)', C:/bot/slave/auto-win-msvc-64-opt/build/src/test/run-pass/thread-local-extern-static.rs:24
@mneumann
Copy link
Contributor Author

@alexcrichton : now all tests pass :)

@alexcrichton
Copy link
Member

@bors: r+ 78d9544

@bors
Copy link
Contributor

bors commented Feb 24, 2016

⌛ Testing commit 78d9544 with merge 490987e...

@bors
Copy link
Contributor

bors commented Feb 24, 2016

💔 Test failed - auto-linux-64-nopt-t

@mneumann
Copy link
Contributor Author

@alexcrichton : This failure doesn't seem to be related to my commits (buildslave/rust-buildbot/slave/auto-linux-64-nopt-t/build/src/test/run-make/issue-26995/foo.rs:1: line longer than 100 chars).

@alexcrichton
Copy link
Member

@bors: retry

indeed!

On Thu, Feb 25, 2016 at 2:06 AM, Michael Neumann notifications@github.com
wrote:

@alexcrichton https://github.com/alexcrichton : This failure doesn't
seem to be related to my commits (
buildslave/rust-buildbot/slave/auto-linux-64-nopt-t/build/src/test/run-make/issue-26995/
foo.rs:1: line longer than 100 chars).


Reply to this email directly or view it on GitHub
#30856 (comment).

@bors
Copy link
Contributor

bors commented Feb 25, 2016

⌛ Testing commit 78d9544 with merge 798ce4a...

bors added a commit that referenced this pull request Feb 25, 2016
This will correctly add the thread_local attribute to the external static variable ```errno```:

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

Before this commit, the thread_local attribute is ignored. Fixes #30795.

Thanks @alexcrichton for pointing out the solution.
@bors bors merged commit 78d9544 into rust-lang:master Feb 25, 2016
@mneumann mneumann deleted the thread_local_extern branch February 26, 2016 15:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
relnotes Marks issues that should be documented in the release notes of the next release.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants