about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2013-04-21 16:28:17 -0700
committerBrian Anderson <banderson@mozilla.com>2013-04-21 16:28:19 -0700
commitf9069baa70ea78117f2087fe6e359fb2ea0ae16a (patch)
tree10aa6c6aae411de29cac226b91827a0f0d005348
parent4eff3130c589b5fb256c537e90272646fd8406ab (diff)
downloadrust-f9069baa70ea78117f2087fe6e359fb2ea0ae16a.tar.gz
rust-f9069baa70ea78117f2087fe6e359fb2ea0ae16a.zip
core::rt: Add LocalServices for thread-local language services
Things like the GC heap and unwinding are desirable everywhere the language
might be used, not just in tasks. All Rust code should have access to
LocalServices.
-rw-r--r--src/libcore/rt/local_services.rs63
-rw-r--r--src/libcore/rt/mod.rs3
-rw-r--r--src/libcore/rt/sched/mod.rs6
3 files changed, 70 insertions, 2 deletions
diff --git a/src/libcore/rt/local_services.rs b/src/libcore/rt/local_services.rs
new file mode 100644
index 00000000000..8e386f80b77
--- /dev/null
+++ b/src/libcore/rt/local_services.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.
+
+//! Language-level runtime services that should reasonably expected
+//! to be available 'everywhere'. Local heaps, GC, unwinding,
+//! local storage, and logging. Even a 'freestanding' Rust would likely want
+//! to implement this.
+
+//! Local services may exist in at least three different contexts:
+//! when running as a task, when running in the scheduler's context,
+//! or when running outside of a scheduler but with local services
+//! (freestanding rust with local services?).
+
+use prelude::*;
+use super::sched::{Task, local_sched};
+
+pub struct LocalServices {
+    heap: LocalHeap,
+    gc: GarbageCollector,
+    storage: LocalStorage,
+    logger: Logger,
+    unwinder: Unwinder
+}
+
+pub struct LocalHeap;
+pub struct GarbageCollector;
+pub struct LocalStorage;
+pub struct Logger;
+pub struct Unwinder;
+
+impl LocalServices {
+    pub fn new() -> LocalServices {
+        LocalServices {
+            heap: LocalHeap,
+            gc: GarbageCollector,
+            storage: LocalStorage,
+            logger: Logger,
+            unwinder: Unwinder
+        }
+    }
+}
+
+/// Borrow a pointer to the installed local services.
+/// Fails (likely aborting the process) if local services are not available.
+pub fn borrow_local_services(f: &fn(&mut LocalServices)) {
+    do local_sched::borrow |sched| {
+        match sched.current_task {
+            Some(~ref mut task) => {
+                f(&mut task.local_services)
+            }
+            None => {
+                fail!(~"no local services for schedulers yet")
+            }
+        }
+    }
+}
diff --git a/src/libcore/rt/mod.rs b/src/libcore/rt/mod.rs
index cf896dd18f3..e0190418b13 100644
--- a/src/libcore/rt/mod.rs
+++ b/src/libcore/rt/mod.rs
@@ -48,6 +48,7 @@ mod stack;
 mod context;
 mod thread;
 pub mod env;
+pub mod local_services;
 
 /// Tools for testing the runtime
 #[cfg(test)]
@@ -97,7 +98,7 @@ pub fn start(main: *u8, _argc: int, _argv: **c_char, _crate_map: *u8) -> int {
 /// Different runtime services are available depending on context.
 #[deriving(Eq)]
 pub enum RuntimeContext {
-    // Only default services, e.g. exchange heap
+    // Only the exchange heap is available
     GlobalContext,
     // The scheduler may be accessed
     SchedulerContext,
diff --git a/src/libcore/rt/sched/mod.rs b/src/libcore/rt/sched/mod.rs
index 28946281628..30136e443ee 100644
--- a/src/libcore/rt/sched/mod.rs
+++ b/src/libcore/rt/sched/mod.rs
@@ -16,6 +16,7 @@ use super::work_queue::WorkQueue;
 use super::stack::{StackPool, StackSegment};
 use super::rtio::{EventLoop, EventLoopObject};
 use super::context::Context;
+use super::local_services::LocalServices;
 use cell::Cell;
 
 #[cfg(test)] use super::uvio::UvEventLoop;
@@ -38,7 +39,7 @@ pub struct Scheduler {
     /// Always valid when a task is executing, otherwise not
     priv saved_context: Context,
     /// The currently executing task
-    priv current_task: Option<~Task>,
+    current_task: Option<~Task>,
     /// An action performed after a context switch on behalf of the
     /// code running before the context switch
     priv cleanup_job: Option<CleanupJob>
@@ -326,6 +327,8 @@ pub struct Task {
     /// These are always valid when the task is not running, unless
     /// the task is dead
     priv saved_context: Context,
+    /// The heap, GC, unwinding, local storage, logging
+    local_services: LocalServices
 }
 
 pub impl Task {
@@ -337,6 +340,7 @@ pub impl Task {
         return Task {
             current_stack_segment: stack,
             saved_context: initial_context,
+            local_services: LocalServices::new()
         };
     }