about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2013-05-19 14:39:46 -0700
committerBrian Anderson <banderson@mozilla.com>2013-05-20 15:20:50 -0700
commit97c2fd1a965b3af037fa22c911dfb618f818c172 (patch)
tree86797ebd7d868d133f8a785c5f6ba48cc2deecac
parent86ba4573498ef251933fcc784d513c7586dfaae1 (diff)
downloadrust-97c2fd1a965b3af037fa22c911dfb618f818c172.tar.gz
rust-97c2fd1a965b3af037fa22c911dfb618f818c172.zip
core::rt: Move some TLS functions from local_sched to local_ptr
-rw-r--r--src/libcore/rt/local_ptr.rs63
-rw-r--r--src/libcore/rt/local_sched.rs58
-rw-r--r--src/libcore/rt/mod.rs13
-rw-r--r--src/libcore/rt/sched.rs7
4 files changed, 82 insertions, 59 deletions
diff --git a/src/libcore/rt/local_ptr.rs b/src/libcore/rt/local_ptr.rs
new file mode 100644
index 00000000000..3d706fbbdae
--- /dev/null
+++ b/src/libcore/rt/local_ptr.rs
@@ -0,0 +1,63 @@
+// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Access to a single thread-local pointer
+
+use libc::c_void;
+use cast;
+use option::{Option, Some, None};
+use tls = rt::thread_local_storage;
+
+/// Initialize the TLS key. Other ops will fail if this isn't executed first.
+pub fn init_tls_key() {
+    unsafe {
+        rust_initialize_rt_tls_key();
+        extern {
+            fn rust_initialize_rt_tls_key();
+        }
+    }
+}
+
+pub fn tls_key() -> tls::Key {
+    match maybe_tls_key() {
+        Some(key) => key,
+        None => abort!("runtime tls key not initialized")
+    }
+}
+
+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,
+        // we are not accessing the key under a mutex.  Threads that
+        // are not using the new Scheduler but still *want to check*
+        // whether they are running under a new Scheduler may see a 0
+        // value here that is in the process of being initialized in
+        // 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);
+        } else {
+            return None;
+        }
+    }
+}
+
+extern {
+    #[fast_ffi]
+    fn rust_get_rt_tls_key() -> *mut c_void;
+}
diff --git a/src/libcore/rt/local_sched.rs b/src/libcore/rt/local_sched.rs
index 5f7f8509a7b..6b3bc373d22 100644
--- a/src/libcore/rt/local_sched.rs
+++ b/src/libcore/rt/local_sched.rs
@@ -18,25 +18,16 @@ use cell::Cell;
 
 use rt::sched::Scheduler;
 use rt::rtio::{EventLoop, IoFactoryObject};
-use tls = rt::thread_local_storage;
 use unstable::finally::Finally;
+use rt::local_ptr;
+use tls = rt::thread_local_storage;
 
 #[cfg(test)] use rt::uv::uvio::UvEventLoop;
 
-/// Initialize the TLS key. Other ops will fail if this isn't executed first.
-pub fn init_tls_key() {
-    unsafe {
-        rust_initialize_rt_tls_key();
-        extern {
-            fn rust_initialize_rt_tls_key();
-        }
-    }
-}
-
 /// Give the Scheduler to thread-local storage
 pub fn put(sched: ~Scheduler) {
     unsafe {
-        let key = tls_key();
+        let key = local_ptr::tls_key();
         let void_sched: *mut c_void = cast::transmute(sched);
         tls::set(key, void_sched);
     }
@@ -45,7 +36,7 @@ pub fn put(sched: ~Scheduler) {
 /// Take ownership of the Scheduler from thread-local storage
 pub fn take() -> ~Scheduler {
     unsafe {
-        let key = tls_key();
+        let key = local_ptr::tls_key();
         let void_sched: *mut c_void = tls::get(key);
         rtassert!(void_sched.is_not_null());
         let sched: ~Scheduler = cast::transmute(void_sched);
@@ -57,7 +48,7 @@ pub fn take() -> ~Scheduler {
 /// Check whether there is a thread-local Scheduler attached to the running thread
 pub fn exists() -> bool {
     unsafe {
-        match maybe_tls_key() {
+        match local_ptr::maybe_tls_key() {
             Some(key) => tls::get(key).is_not_null(),
             None => false
         }
@@ -89,7 +80,7 @@ pub fn borrow(f: &fn(&mut Scheduler)) {
 /// Because this leaves the Scheduler in thread-local storage it is possible
 /// For the Scheduler pointer to be aliased
 pub unsafe fn unsafe_borrow() -> *mut Scheduler {
-    let key = tls_key();
+    let key = local_ptr::tls_key();
     let mut void_sched: *mut c_void = tls::get(key);
     rtassert!(void_sched.is_not_null());
     {
@@ -106,43 +97,6 @@ pub unsafe fn unsafe_borrow_io() -> *mut IoFactoryObject {
     return io;
 }
 
-fn tls_key() -> tls::Key {
-    match maybe_tls_key() {
-        Some(key) => key,
-        None => abort!("runtime tls key not initialized")
-    }
-}
-
-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,
-        // we are not accessing the key under a mutex.  Threads that
-        // are not using the new Scheduler but still *want to check*
-        // whether they are running under a new Scheduler may see a 0
-        // value here that is in the process of being initialized in
-        // 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);
-        } else {
-            return None;
-        }
-    }
-}
-
-extern {
-    #[fast_ffi]
-    fn rust_get_rt_tls_key() -> *mut c_void;
-}
-
 #[test]
 fn thread_local_scheduler_smoke_test() {
     let scheduler = ~UvEventLoop::new_scheduler();
diff --git a/src/libcore/rt/mod.rs b/src/libcore/rt/mod.rs
index 37ac6ad3365..bda44b4c67f 100644
--- a/src/libcore/rt/mod.rs
+++ b/src/libcore/rt/mod.rs
@@ -85,10 +85,6 @@ pub mod uv;
 /// or task-local storage.
 pub mod local;
 
-// FIXME #5248: The import in `sched` doesn't resolve unless this is pub!
-/// Bindings to pthread/windows thread-local storage.
-pub mod thread_local_storage;
-
 /// A parallel work-stealing deque.
 mod work_queue;
 
@@ -126,6 +122,15 @@ pub mod tube;
 /// Simple reimplementation of core::comm
 pub mod comm;
 
+// FIXME #5248 shouldn't be pub
+/// The runtime needs to be able to put a pointer into thread-local storage.
+pub mod local_ptr;
+
+// FIXME #5248: The import in `sched` doesn't resolve unless this is pub!
+/// Bindings to pthread/windows thread-local storage.
+pub mod thread_local_storage;
+
+
 /// Set up a default runtime configuration, given compiler-supplied arguments.
 ///
 /// This is invoked by the `start` _language item_ (unstable::lang) to
diff --git a/src/libcore/rt/sched.rs b/src/libcore/rt/sched.rs
index 0cdc4e9602b..8352993278c 100644
--- a/src/libcore/rt/sched.rs
+++ b/src/libcore/rt/sched.rs
@@ -11,13 +11,14 @@
 use option::*;
 use sys;
 use cast::transmute;
+use cell::Cell;
 
 use super::work_queue::WorkQueue;
 use super::stack::{StackPool, StackSegment};
 use super::rtio::{EventLoop, EventLoopObject};
 use super::context::Context;
 use super::task::Task;
-use cell::Cell;
+use rt::local_ptr;
 
 // A more convenient name for external callers, e.g. `local_sched::take()`
 pub mod local_sched;
@@ -64,8 +65,8 @@ pub impl Scheduler {
 
     fn new(event_loop: ~EventLoopObject) -> Scheduler {
 
-        // Lazily initialize the scheduler TLS key
-        local_sched::init_tls_key();
+        // Lazily initialize the runtime TLS key
+        local_ptr::init_tls_key();
 
         Scheduler {
             event_loop: event_loop,