about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-06-01 19:51:57 +0000
committerbors <bors@rust-lang.org>2015-06-01 19:51:57 +0000
commita49ae5bd4378cb47fd5cfdcd0c31e04d55373696 (patch)
tree14163a282e9219494242beff9b9506a62461d0f8
parent3e561f05c00cd180ec02db4ccab2840a4aba93d2 (diff)
parent1b5f9cb1f1529e03cd9a1d60a40d17624baffa65 (diff)
downloadrust-a49ae5bd4378cb47fd5cfdcd0c31e04d55373696.tar.gz
rust-a49ae5bd4378cb47fd5cfdcd0c31e04d55373696.zip
Auto merge of #25858 - alexcrichton:disable-os-tls, r=brson
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.

Closes #25342
-rwxr-xr-xconfigure1
-rw-r--r--mk/crates.mk4
-rw-r--r--src/libstd/thread/local.rs78
-rw-r--r--src/libstd/thread/scoped_tls.rs24
4 files changed, 80 insertions, 27 deletions
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<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")]
@@ -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
@@ -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::*;
@@ -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<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,
@@ -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<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;
 
@@ -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::*;