Skip to content

std: Add an option to disable ELF based TLS #25858

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

Merged
merged 1 commit into from
Jun 1, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
4 changes: 4 additions & 0 deletions mk/crates.mk
Original file line number Diff line number Diff line change
Expand Up @@ -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
78 changes: 54 additions & 24 deletions src/libstd/thread/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,37 +99,60 @@ pub struct LocalKey<T> {

/// 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")]
Expand Down Expand Up @@ -163,7 +186,10 @@ pub enum LocalKeyState {

impl<T: 'static> LocalKey<T> {
#[doc(hidden)]
pub const fn new(inner: fn() -> &'static __KeyInner<T>, init: fn() -> T) -> LocalKey<T> {
#[unstable(feature = "thread_local_internals",
reason = "recently added to create a key")]
pub const fn new(inner: fn() -> &'static __KeyInner<T>,
init: fn() -> T) -> LocalKey<T> {
LocalKey {
inner: inner,
init: init
Expand Down Expand Up @@ -240,7 +266,9 @@ impl<T: 'static> LocalKey<T> {
}
}

#[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::*;
Expand Down Expand Up @@ -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::*;
Expand Down
24 changes: 21 additions & 3 deletions src/libstd/thread/scoped_tls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,11 @@ pub struct ScopedKey<T> { inner: imp::KeyInner<T> }
/// 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,
Expand All @@ -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")]
Expand Down Expand Up @@ -187,7 +203,8 @@ impl<T> ScopedKey<T> {
target_os = "android",
target_os = "ios",
target_os = "openbsd",
target_arch = "aarch64")))]
target_arch = "aarch64",
no_elf_tls)))]
mod imp {
use std::cell::Cell;

Expand All @@ -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::*;

Expand Down