about summary refs log tree commit diff
path: root/src/libstd/thread
diff options
context:
space:
mode:
authorRaph Levien <raph@google.com>2016-10-18 13:43:18 -0700
committerRaph Levien <raph@google.com>2016-10-22 07:08:06 -0700
commit76bac5d33e09e8ae1b243c045584646431147cce (patch)
treee5a7e238441d821c4d5507cc71d5a2cdb6b6869e /src/libstd/thread
parent4879166194ed63ebd2a8c3ce8db1ccde4a6a1920 (diff)
downloadrust-76bac5d33e09e8ae1b243c045584646431147cce.tar.gz
rust-76bac5d33e09e8ae1b243c045584646431147cce.zip
Add Fuchsia support
Adds support for the x86_64-unknown-fuchsia target, which covers the
Fuchsia operating system.
Diffstat (limited to 'src/libstd/thread')
-rw-r--r--src/libstd/thread/local.rs72
1 files changed, 42 insertions, 30 deletions
diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs
index a333a7d967d..54d3f793045 100644
--- a/src/libstd/thread/local.rs
+++ b/src/libstd/thread/local.rs
@@ -358,36 +358,8 @@ pub mod elf {
         }
     }
 
-    // Since what appears to be glibc 2.18 this symbol has been shipped which
-    // GCC and clang both use to invoke destructors in thread_local globals, so
-    // let's do the same!
-    //
-    // Note, however, that we run on lots older linuxes, as well as cross
-    // compiling from a newer linux to an older linux, so we also have a
-    // fallback implementation to use as well.
-    //
-    // Due to rust-lang/rust#18804, make sure this is not generic!
-    #[cfg(target_os = "linux")]
-    unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
-        use mem;
-        use libc;
-        use sys_common::thread_local as os;
-
-        extern {
-            #[linkage = "extern_weak"]
-            static __dso_handle: *mut u8;
-            #[linkage = "extern_weak"]
-            static __cxa_thread_atexit_impl: *const libc::c_void;
-        }
-        if !__cxa_thread_atexit_impl.is_null() {
-            type F = unsafe extern fn(dtor: unsafe extern fn(*mut u8),
-                                      arg: *mut u8,
-                                      dso_handle: *mut u8) -> libc::c_int;
-            mem::transmute::<*const libc::c_void, F>(__cxa_thread_atexit_impl)
-            (dtor, t, &__dso_handle as *const _ as *mut _);
-            return
-        }
-
+    #[cfg(any(target_os = "linux", target_os = "fuchsia"))]
+    unsafe fn register_dtor_fallback(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
         // The fallback implementation uses a vanilla OS-based TLS key to track
         // the list of destructors that need to be run for this thread. The key
         // then has its own destructor which runs all the other destructors.
@@ -397,6 +369,8 @@ pub mod elf {
         // *should* be the case that this loop always terminates because we
         // provide the guarantee that a TLS key cannot be set after it is
         // flagged for destruction.
+        use sys_common::thread_local as os;
+
         static DTORS: os::StaticKey = os::StaticKey::new(Some(run_dtors));
         type List = Vec<(*mut u8, unsafe extern fn(*mut u8))>;
         if DTORS.get().is_null() {
@@ -418,6 +392,37 @@ pub mod elf {
         }
     }
 
+    // Since what appears to be glibc 2.18 this symbol has been shipped which
+    // GCC and clang both use to invoke destructors in thread_local globals, so
+    // let's do the same!
+    //
+    // Note, however, that we run on lots older linuxes, as well as cross
+    // compiling from a newer linux to an older linux, so we also have a
+    // fallback implementation to use as well.
+    //
+    // Due to rust-lang/rust#18804, make sure this is not generic!
+    #[cfg(target_os = "linux")]
+    unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
+        use mem;
+        use libc;
+
+        extern {
+            #[linkage = "extern_weak"]
+            static __dso_handle: *mut u8;
+            #[linkage = "extern_weak"]
+            static __cxa_thread_atexit_impl: *const libc::c_void;
+        }
+        if !__cxa_thread_atexit_impl.is_null() {
+            type F = unsafe extern fn(dtor: unsafe extern fn(*mut u8),
+                                      arg: *mut u8,
+                                      dso_handle: *mut u8) -> libc::c_int;
+            mem::transmute::<*const libc::c_void, F>(__cxa_thread_atexit_impl)
+            (dtor, t, &__dso_handle as *const _ as *mut _);
+            return
+        }
+        register_dtor_fallback(t, dtor);
+    }
+
     // OSX's analog of the above linux function is this _tlv_atexit function.
     // The disassembly of thread_local globals in C++ (at least produced by
     // clang) will have this show up in the output.
@@ -430,6 +435,13 @@ pub mod elf {
         _tlv_atexit(dtor, t);
     }
 
+    // Just use the thread_local fallback implementation, at least until there's
+    // a more direct implementation.
+    #[cfg(target_os = "fuchsia")]
+    unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
+        register_dtor_fallback(t, dtor);
+    }
+
     pub unsafe extern fn destroy_value<T>(ptr: *mut u8) {
         let ptr = ptr as *mut Key<T>;
         // Right before we run the user destructor be sure to flag the