Skip to content

Commit 1b5f9cb

Browse files
committed
std: Add an option to disable ELF based TLS
This commit adds a ./configure option called `--disable-elf-tls` which disables ELF based TLS (that which is communicated to LLVM) on platforms which already support it. OSX 10.6 does not support this form of TLS, and some users of Rust need to target 10.6 and are unable to do so due to the usage of TLS. The standard library will continue to use ELF based TLS on OSX by default (as the officially supported platform is 10.7+), but this adds an option to compile the standard library in a way that is compatible with 10.6.
1 parent efcc1d1 commit 1b5f9cb

File tree

4 files changed

+80
-27
lines changed

4 files changed

+80
-27
lines changed

configure

+1
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,7 @@ valopt musl-root "/usr/local" "MUSL root installation directory"
593593
opt_nosave manage-submodules 1 "let the build manage the git submodules"
594594
opt_nosave clang 0 "prefer clang to gcc for building the runtime"
595595
opt_nosave jemalloc 1 "build liballoc with jemalloc"
596+
opt elf-tls 1 "elf thread local storage on platforms where supported"
596597

597598
valopt_nosave prefix "/usr/local" "set installation prefix"
598599
valopt_nosave local-rust-root "/usr/local" "set prefix for local rust binary"

mk/crates.mk

+4
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,7 @@ TOOL_INPUTS_$(1) := $$(call rwildcard,$$(dir $$(TOOL_SOURCE_$(1))),*.rs)
150150
endef
151151

152152
$(foreach crate,$(TOOLS),$(eval $(call RUST_TOOL,$(crate))))
153+
154+
ifdef CFG_DISABLE_ELF_TLS
155+
RUSTFLAGS_std := --cfg no_elf_tls
156+
endif

src/libstd/thread/local.rs

+54-24
Original file line numberDiff line numberDiff line change
@@ -99,37 +99,60 @@ pub struct LocalKey<T> {
9999

100100
/// Declare a new thread local storage key of type `std::thread::LocalKey`.
101101
///
102-
/// See [LocalKey documentation](thread/struct.LocalKey.html) for more information.
102+
/// See [LocalKey documentation](thread/struct.LocalKey.html) for more
103+
/// information.
103104
#[macro_export]
104105
#[stable(feature = "rust1", since = "1.0.0")]
105106
#[allow_internal_unstable]
107+
#[cfg(not(no_elf_tls))]
106108
macro_rules! thread_local {
107109
(static $name:ident: $t:ty = $init:expr) => (
108-
static $name: ::std::thread::LocalKey<$t> = {
109-
#[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
110-
not(target_arch = "aarch64")),
111-
thread_local)]
112-
static __KEY: ::std::thread::__LocalKeyInner<$t> =
113-
::std::thread::__LocalKeyInner::new();
114-
fn __init() -> $t { $init }
115-
fn __getit() -> &'static ::std::thread::__LocalKeyInner<$t> { &__KEY }
116-
::std::thread::LocalKey::new(__getit, __init)
117-
};
110+
static $name: ::std::thread::LocalKey<$t> =
111+
__thread_local_inner!($t, $init,
112+
#[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
113+
not(target_arch = "aarch64")),
114+
thread_local)]);
118115
);
119116
(pub static $name:ident: $t:ty = $init:expr) => (
120-
pub static $name: ::std::thread::LocalKey<$t> = {
121-
#[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
122-
not(target_arch = "aarch64")),
123-
thread_local)]
124-
static __KEY: ::std::thread::__LocalKeyInner<$t> =
125-
::std::thread::__LocalKeyInner::new();
126-
fn __init() -> $t { $init }
127-
fn __getit() -> &'static ::std::thread::__LocalKeyInner<$t> { &__KEY }
128-
::std::thread::LocalKey::new(__getit, __init)
129-
};
117+
pub static $name: ::std::thread::LocalKey<$t> =
118+
__thread_local_inner!($t, $init,
119+
#[cfg_attr(all(any(target_os = "macos", target_os = "linux"),
120+
not(target_arch = "aarch64")),
121+
thread_local)]);
130122
);
131123
}
132124

125+
#[macro_export]
126+
#[stable(feature = "rust1", since = "1.0.0")]
127+
#[allow_internal_unstable]
128+
#[cfg(no_elf_tls)]
129+
macro_rules! thread_local {
130+
(static $name:ident: $t:ty = $init:expr) => (
131+
static $name: ::std::thread::LocalKey<$t> =
132+
__thread_local_inner!($t, $init, #[]);
133+
);
134+
(pub static $name:ident: $t:ty = $init:expr) => (
135+
pub static $name: ::std::thread::LocalKey<$t> =
136+
__thread_local_inner!($t, $init, #[]);
137+
);
138+
}
139+
140+
#[doc(hidden)]
141+
#[unstable(feature = "thread_local_internals",
142+
reason = "should not be necessary")]
143+
#[macro_export]
144+
#[allow_internal_unstable]
145+
macro_rules! __thread_local_inner {
146+
($t:ty, $init:expr, #[$($attr:meta),*]) => {{
147+
$(#[$attr])*
148+
static __KEY: ::std::thread::__LocalKeyInner<$t> =
149+
::std::thread::__LocalKeyInner::new();
150+
fn __init() -> $t { $init }
151+
fn __getit() -> &'static ::std::thread::__LocalKeyInner<$t> { &__KEY }
152+
::std::thread::LocalKey::new(__getit, __init)
153+
}}
154+
}
155+
133156
/// Indicator of the state of a thread local storage key.
134157
#[unstable(feature = "std_misc",
135158
reason = "state querying was recently added")]
@@ -163,7 +186,10 @@ pub enum LocalKeyState {
163186

164187
impl<T: 'static> LocalKey<T> {
165188
#[doc(hidden)]
166-
pub const fn new(inner: fn() -> &'static __KeyInner<T>, init: fn() -> T) -> LocalKey<T> {
189+
#[unstable(feature = "thread_local_internals",
190+
reason = "recently added to create a key")]
191+
pub const fn new(inner: fn() -> &'static __KeyInner<T>,
192+
init: fn() -> T) -> LocalKey<T> {
167193
LocalKey {
168194
inner: inner,
169195
init: init
@@ -240,7 +266,9 @@ impl<T: 'static> LocalKey<T> {
240266
}
241267
}
242268

243-
#[cfg(all(any(target_os = "macos", target_os = "linux"), not(target_arch = "aarch64")))]
269+
#[cfg(all(any(target_os = "macos", target_os = "linux"),
270+
not(target_arch = "aarch64"),
271+
not(no_elf_tls)))]
244272
#[doc(hidden)]
245273
mod imp {
246274
use prelude::v1::*;
@@ -371,7 +399,9 @@ mod imp {
371399
}
372400
}
373401

374-
#[cfg(any(not(any(target_os = "macos", target_os = "linux")), target_arch = "aarch64"))]
402+
#[cfg(any(not(any(target_os = "macos", target_os = "linux")),
403+
target_arch = "aarch64",
404+
no_elf_tls))]
375405
#[doc(hidden)]
376406
mod imp {
377407
use prelude::v1::*;

src/libstd/thread/scoped_tls.rs

+21-3
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,11 @@ pub struct ScopedKey<T> { inner: imp::KeyInner<T> }
6060
/// This macro declares a `static` item on which methods are used to get and
6161
/// set the value stored within.
6262
///
63-
/// See [ScopedKey documentation](thread/struct.ScopedKey.html) for more information.
63+
/// See [ScopedKey documentation](thread/struct.ScopedKey.html) for more
64+
/// information.
6465
#[macro_export]
6566
#[allow_internal_unstable]
67+
#[cfg(not(no_elf_tls))]
6668
macro_rules! scoped_thread_local {
6769
(static $name:ident: $t:ty) => (
6870
#[cfg_attr(not(any(windows,
@@ -86,6 +88,20 @@ macro_rules! scoped_thread_local {
8688
);
8789
}
8890

91+
#[macro_export]
92+
#[allow_internal_unstable]
93+
#[cfg(no_elf_tls)]
94+
macro_rules! scoped_thread_local {
95+
(static $name:ident: $t:ty) => (
96+
static $name: ::std::thread::ScopedKey<$t> =
97+
::std::thread::ScopedKey::new();
98+
);
99+
(pub static $name:ident: $t:ty) => (
100+
pub static $name: ::std::thread::ScopedKey<$t> =
101+
::std::thread::ScopedKey::new();
102+
);
103+
}
104+
89105
#[unstable(feature = "scoped_tls",
90106
reason = "scoped TLS has yet to have wide enough use to fully consider \
91107
stabilizing its interface")]
@@ -187,7 +203,8 @@ impl<T> ScopedKey<T> {
187203
target_os = "android",
188204
target_os = "ios",
189205
target_os = "openbsd",
190-
target_arch = "aarch64")))]
206+
target_arch = "aarch64",
207+
no_elf_tls)))]
191208
mod imp {
192209
use std::cell::Cell;
193210

@@ -208,7 +225,8 @@ mod imp {
208225
target_os = "android",
209226
target_os = "ios",
210227
target_os = "openbsd",
211-
target_arch = "aarch64"))]
228+
target_arch = "aarch64",
229+
no_elf_tls))]
212230
mod imp {
213231
use prelude::v1::*;
214232

0 commit comments

Comments
 (0)