std: Convert the runtime TLS key to a Rust global to avoid FFI

This commit is contained in:
Brian Anderson 2013-08-17 02:12:08 -07:00
parent a37bdde3f9
commit 8fc1d9db21
3 changed files with 24 additions and 28 deletions

View File

@ -23,14 +23,16 @@ use option::{Option, Some, None};
use unstable::finally::Finally;
use tls = rt::thread_local_storage;
static mut RT_TLS_KEY: tls::Key = -1;
/// Initialize the TLS key. Other ops will fail if this isn't executed first.
#[fixed_stack_segment]
#[inline(never)]
pub fn init_tls_key() {
unsafe {
rust_initialize_rt_tls_key();
rust_initialize_rt_tls_key(&mut RT_TLS_KEY);
extern {
fn rust_initialize_rt_tls_key();
fn rust_initialize_rt_tls_key(key: *mut tls::Key);
}
}
}
@ -151,15 +153,10 @@ fn tls_key() -> tls::Key {
}
}
#[fixed_stack_segment]
#[inline(never)]
fn maybe_tls_key() -> Option<tls::Key> {
#[inline]
#[cfg(not(test))]
pub fn maybe_tls_key() -> Option<tls::Key> {
unsafe {
let key: *mut c_void = rust_get_rt_tls_key();
let key: &mut tls::Key = cast::transmute(key);
let key = *key;
// Check that the key has been initialized.
// NB: This is a little racy because, while the key is
// initalized under a mutex and it's assumed to be initalized
// in the Scheduler ctor by any thread that needs to use it,
@ -170,14 +167,19 @@ fn maybe_tls_key() -> Option<tls::Key> {
// another thread. I think this is fine since the only action
// they could take if it was initialized would be to check the
// thread-local value and see that it's not set.
if key != -1 {
return Some(key);
if RT_TLS_KEY != -1 {
return Some(RT_TLS_KEY);
} else {
return None;
}
}
extern {
fn rust_get_rt_tls_key() -> *mut c_void;
}
}
// XXX: The boundary between the running runtime and the testing runtime
// seems to be fuzzy at the moment, and trying to use two different keys
// results in disaster. This should not be necessary.
#[inline]
#[cfg(test)]
pub fn maybe_tls_key() -> Option<tls::Key> {
unsafe { ::cast::transmute(::realstd::rt::local_ptr::maybe_tls_key()) }
}

View File

@ -447,19 +447,14 @@ rust_readdir() {
#endif
#ifndef _WIN32
pthread_key_t rt_key = -1;
typedef pthread_key_t tls_key;
#else
DWORD rt_key = -1;
typedef DWORD tls_key;
#endif
extern "C" void*
rust_get_rt_tls_key() {
return &rt_key;
}
// Initialize the TLS key used by the new scheduler
extern "C" CDECL void
rust_initialize_rt_tls_key() {
rust_initialize_rt_tls_key(tls_key *key) {
static lock_and_signal init_lock;
static bool initialized = false;
@ -469,10 +464,10 @@ rust_initialize_rt_tls_key() {
if (!initialized) {
#ifndef _WIN32
assert(!pthread_key_create(&rt_key, NULL));
assert(!pthread_key_create(key, NULL));
#else
rt_key = TlsAlloc();
assert(rt_key != TLS_OUT_OF_INDEXES);
*key = TlsAlloc();
assert(*key != TLS_OUT_OF_INDEXES);
#endif
initialized = true;

View File

@ -143,7 +143,6 @@ linenoiseHistoryLoad
rust_raw_thread_start
rust_raw_thread_join
rust_raw_thread_delete
rust_get_rt_tls_key
swap_registers
rust_readdir
rust_opendir