diff --git a/configure b/configure index 60f810f20be..9be47beeb91 100755 --- a/configure +++ b/configure @@ -593,6 +593,7 @@ valopt musl-root "/usr/local" "MUSL root installation directory" opt_nosave manage-submodules 1 "let the build manage the git submodules" opt_nosave clang 0 "prefer clang to gcc for building the runtime" opt_nosave jemalloc 1 "build liballoc with jemalloc" +opt elf-tls 1 "elf thread local storage on platforms where supported" valopt_nosave prefix "/usr/local" "set installation prefix" valopt_nosave local-rust-root "/usr/local" "set prefix for local rust binary" diff --git a/mk/crates.mk b/mk/crates.mk index 62dc1019066..93be1e6ba63 100644 --- a/mk/crates.mk +++ b/mk/crates.mk @@ -150,3 +150,7 @@ TOOL_INPUTS_$(1) := $$(call rwildcard,$$(dir $$(TOOL_SOURCE_$(1))),*.rs) endef $(foreach crate,$(TOOLS),$(eval $(call RUST_TOOL,$(crate)))) + +ifdef CFG_DISABLE_ELF_TLS +RUSTFLAGS_std := --cfg no_elf_tls +endif diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs index 0eafd4d5f12..cdd7dff0108 100644 --- a/src/libstd/thread/local.rs +++ b/src/libstd/thread/local.rs @@ -99,37 +99,60 @@ pub struct LocalKey { /// Declare a new thread local storage key of type `std::thread::LocalKey`. /// -/// See [LocalKey documentation](thread/struct.LocalKey.html) for more information. +/// See [LocalKey documentation](thread/struct.LocalKey.html) for more +/// information. #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] #[allow_internal_unstable] +#[cfg(not(no_elf_tls))] macro_rules! thread_local { (static $name:ident: $t:ty = $init:expr) => ( - static $name: ::std::thread::LocalKey<$t> = { - #[cfg_attr(all(any(target_os = "macos", target_os = "linux"), - not(target_arch = "aarch64")), - thread_local)] - static __KEY: ::std::thread::__LocalKeyInner<$t> = - ::std::thread::__LocalKeyInner::new(); - fn __init() -> $t { $init } - fn __getit() -> &'static ::std::thread::__LocalKeyInner<$t> { &__KEY } - ::std::thread::LocalKey::new(__getit, __init) - }; + static $name: ::std::thread::LocalKey<$t> = + __thread_local_inner!($t, $init, + #[cfg_attr(all(any(target_os = "macos", target_os = "linux"), + not(target_arch = "aarch64")), + thread_local)]); ); (pub static $name:ident: $t:ty = $init:expr) => ( - pub static $name: ::std::thread::LocalKey<$t> = { - #[cfg_attr(all(any(target_os = "macos", target_os = "linux"), - not(target_arch = "aarch64")), - thread_local)] - static __KEY: ::std::thread::__LocalKeyInner<$t> = - ::std::thread::__LocalKeyInner::new(); - fn __init() -> $t { $init } - fn __getit() -> &'static ::std::thread::__LocalKeyInner<$t> { &__KEY } - ::std::thread::LocalKey::new(__getit, __init) - }; + pub static $name: ::std::thread::LocalKey<$t> = + __thread_local_inner!($t, $init, + #[cfg_attr(all(any(target_os = "macos", target_os = "linux"), + not(target_arch = "aarch64")), + thread_local)]); ); } +#[macro_export] +#[stable(feature = "rust1", since = "1.0.0")] +#[allow_internal_unstable] +#[cfg(no_elf_tls)] +macro_rules! thread_local { + (static $name:ident: $t:ty = $init:expr) => ( + static $name: ::std::thread::LocalKey<$t> = + __thread_local_inner!($t, $init, #[]); + ); + (pub static $name:ident: $t:ty = $init:expr) => ( + pub static $name: ::std::thread::LocalKey<$t> = + __thread_local_inner!($t, $init, #[]); + ); +} + +#[doc(hidden)] +#[unstable(feature = "thread_local_internals", + reason = "should not be necessary")] +#[macro_export] +#[allow_internal_unstable] +macro_rules! __thread_local_inner { + ($t:ty, $init:expr, #[$($attr:meta),*]) => {{ + $(#[$attr])* + static __KEY: ::std::thread::__LocalKeyInner<$t> = + ::std::thread::__LocalKeyInner::new(); + fn __init() -> $t { $init } + fn __getit() -> &'static ::std::thread::__LocalKeyInner<$t> { &__KEY } + ::std::thread::LocalKey::new(__getit, __init) + }} +} + /// Indicator of the state of a thread local storage key. #[unstable(feature = "std_misc", reason = "state querying was recently added")] @@ -163,7 +186,10 @@ pub enum LocalKeyState { impl LocalKey { #[doc(hidden)] - pub const fn new(inner: fn() -> &'static __KeyInner, init: fn() -> T) -> LocalKey { + #[unstable(feature = "thread_local_internals", + reason = "recently added to create a key")] + pub const fn new(inner: fn() -> &'static __KeyInner, + init: fn() -> T) -> LocalKey { LocalKey { inner: inner, init: init @@ -240,7 +266,9 @@ impl LocalKey { } } -#[cfg(all(any(target_os = "macos", target_os = "linux"), not(target_arch = "aarch64")))] +#[cfg(all(any(target_os = "macos", target_os = "linux"), + not(target_arch = "aarch64"), + not(no_elf_tls)))] #[doc(hidden)] mod imp { use prelude::v1::*; @@ -371,7 +399,9 @@ mod imp { } } -#[cfg(any(not(any(target_os = "macos", target_os = "linux")), target_arch = "aarch64"))] +#[cfg(any(not(any(target_os = "macos", target_os = "linux")), + target_arch = "aarch64", + no_elf_tls))] #[doc(hidden)] mod imp { use prelude::v1::*; diff --git a/src/libstd/thread/scoped_tls.rs b/src/libstd/thread/scoped_tls.rs index dda1db9aece..f0a4c318d91 100644 --- a/src/libstd/thread/scoped_tls.rs +++ b/src/libstd/thread/scoped_tls.rs @@ -60,9 +60,11 @@ pub struct ScopedKey { inner: imp::KeyInner } /// This macro declares a `static` item on which methods are used to get and /// set the value stored within. /// -/// See [ScopedKey documentation](thread/struct.ScopedKey.html) for more information. +/// See [ScopedKey documentation](thread/struct.ScopedKey.html) for more +/// information. #[macro_export] #[allow_internal_unstable] +#[cfg(not(no_elf_tls))] macro_rules! scoped_thread_local { (static $name:ident: $t:ty) => ( #[cfg_attr(not(any(windows, @@ -86,6 +88,20 @@ macro_rules! scoped_thread_local { ); } +#[macro_export] +#[allow_internal_unstable] +#[cfg(no_elf_tls)] +macro_rules! scoped_thread_local { + (static $name:ident: $t:ty) => ( + static $name: ::std::thread::ScopedKey<$t> = + ::std::thread::ScopedKey::new(); + ); + (pub static $name:ident: $t:ty) => ( + pub static $name: ::std::thread::ScopedKey<$t> = + ::std::thread::ScopedKey::new(); + ); +} + #[unstable(feature = "scoped_tls", reason = "scoped TLS has yet to have wide enough use to fully consider \ stabilizing its interface")] @@ -187,7 +203,8 @@ impl ScopedKey { target_os = "android", target_os = "ios", target_os = "openbsd", - target_arch = "aarch64")))] + target_arch = "aarch64", + no_elf_tls)))] mod imp { use std::cell::Cell; @@ -208,7 +225,8 @@ mod imp { target_os = "android", target_os = "ios", target_os = "openbsd", - target_arch = "aarch64"))] + target_arch = "aarch64", + no_elf_tls))] mod imp { use prelude::v1::*;