diff options
| author | Raph Levien <raph@google.com> | 2016-10-18 13:43:18 -0700 |
|---|---|---|
| committer | Raph Levien <raph@google.com> | 2016-10-22 07:08:06 -0700 |
| commit | 76bac5d33e09e8ae1b243c045584646431147cce (patch) | |
| tree | e5a7e238441d821c4d5507cc71d5a2cdb6b6869e /src/libstd/thread | |
| parent | 4879166194ed63ebd2a8c3ce8db1ccde4a6a1920 (diff) | |
| download | rust-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.rs | 72 |
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 |
