about summary refs log tree commit diff
path: root/src/libstd/rt
diff options
context:
space:
mode:
authorBrian Anderson <banderson@mozilla.com>2013-06-22 01:09:06 -0700
committerBrian Anderson <banderson@mozilla.com>2013-06-24 17:07:03 -0700
commit5e7c5d6c3d532e7b536b76044cd47b72b8eadaad (patch)
tree4293df31a4276cc3d477ece661fe30debc7da63a /src/libstd/rt
parenta09972db3545344048b90e90d1f1821b621a38b9 (diff)
downloadrust-5e7c5d6c3d532e7b536b76044cd47b72b8eadaad.tar.gz
rust-5e7c5d6c3d532e7b536b76044cd47b72b8eadaad.zip
std: Make box annihilator work with newsched
Diffstat (limited to 'src/libstd/rt')
-rw-r--r--src/libstd/rt/comm.rs12
-rw-r--r--src/libstd/rt/local_heap.rs50
-rw-r--r--src/libstd/rt/mod.rs2
-rw-r--r--src/libstd/rt/task.rs21
4 files changed, 71 insertions, 14 deletions
diff --git a/src/libstd/rt/comm.rs b/src/libstd/rt/comm.rs
index 82e6d44fe62..dd27c03ff51 100644
--- a/src/libstd/rt/comm.rs
+++ b/src/libstd/rt/comm.rs
@@ -399,12 +399,6 @@ impl<T: Owned> GenericChan<T> for SharedChan<T> {
 }
 
 impl<T: Owned> GenericSmartChan<T> for SharedChan<T> {
-    #[cfg(stage0)] // odd type checking errors
-    fn try_send(&self, _val: T) -> bool {
-        fail!()
-    }
-
-    #[cfg(not(stage0))]
     fn try_send(&self, val: T) -> bool {
         unsafe {
             let (next_pone, next_cone) = oneshot();
@@ -448,12 +442,6 @@ impl<T: Owned> GenericPort<T> for SharedPort<T> {
         }
     }
 
-    #[cfg(stage0)] // odd type checking errors
-    fn try_recv(&self) -> Option<T> {
-        fail!()
-    }
-
-    #[cfg(not(stage0))]
     fn try_recv(&self) -> Option<T> {
         unsafe {
             let (next_link_port, next_link_chan) = oneshot();
diff --git a/src/libstd/rt/local_heap.rs b/src/libstd/rt/local_heap.rs
index 38cd25f9da5..f62c9fb2c66 100644
--- a/src/libstd/rt/local_heap.rs
+++ b/src/libstd/rt/local_heap.rs
@@ -10,11 +10,24 @@
 
 //! The local, garbage collected heap
 
+use libc;
 use libc::{c_void, uintptr_t, size_t};
 use ops::Drop;
+use repr::BoxRepr;
+use rt;
+use rt::OldTaskContext;
+use rt::local::Local;
+use rt::task::Task;
 
 type MemoryRegion = c_void;
-type BoxedRegion = c_void;
+
+struct Env { priv opaque: () }
+
+struct BoxedRegion {
+    env: *Env,
+    backing_region: *MemoryRegion,
+    live_allocs: *BoxRepr
+}
 
 pub type OpaqueBox = c_void;
 pub type TypeDesc = c_void;
@@ -71,6 +84,40 @@ impl Drop for LocalHeap {
     }
 }
 
+// A little compatibility function
+pub unsafe fn local_free(ptr: *libc::c_char) {
+    match rt::context() {
+        OldTaskContext => {
+            rust_upcall_free_noswitch(ptr);
+
+            extern {
+                #[fast_ffi]
+                unsafe fn rust_upcall_free_noswitch(ptr: *libc::c_char);
+            }
+        }
+        _ => {
+            do Local::borrow::<Task,()> |task| {
+                task.heap.free(ptr as *libc::c_void);
+            }
+        }
+    }
+}
+
+pub fn live_allocs() -> *BoxRepr {
+    let region = match rt::context() {
+        OldTaskContext => {
+            unsafe { rust_current_boxed_region() }
+        }
+        _ => {
+            do Local::borrow::<Task, *BoxedRegion> |task| {
+                task.heap.boxed_region
+            }
+        }
+    };
+
+    return unsafe { (*region).live_allocs };
+}
+
 extern {
     fn rust_new_memory_region(synchronized: uintptr_t,
                                detailed_leaks: uintptr_t,
@@ -86,4 +133,5 @@ extern {
                                  ptr: *OpaqueBox,
                                  size: size_t) -> *OpaqueBox;
     fn rust_boxed_region_free(region: *BoxedRegion, box: *OpaqueBox);
+    fn rust_current_boxed_region() -> *BoxedRegion;
 }
diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs
index 6c4e5742eb3..fec555e8afd 100644
--- a/src/libstd/rt/mod.rs
+++ b/src/libstd/rt/mod.rs
@@ -124,7 +124,7 @@ mod thread;
 pub mod env;
 
 /// The local, managed heap
-mod local_heap;
+pub mod local_heap;
 
 /// The Logger trait and implementations
 pub mod logging;
diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs
index 833f25b253c..68f7eb659b0 100644
--- a/src/libstd/rt/task.rs
+++ b/src/libstd/rt/task.rs
@@ -15,6 +15,7 @@
 
 use borrow;
 use cast::transmute;
+use cleanup;
 use libc::{c_void, uintptr_t};
 use ptr;
 use prelude::*;
@@ -118,6 +119,10 @@ impl Task {
             }
             _ => ()
         }
+
+        // Destroy remaining boxes
+        unsafe { cleanup::annihilate(); }
+
         self.destroyed = true;
     }
 }
@@ -269,4 +274,20 @@ mod test {
             assert!(res.is_err());
         }
     }
+
+    #[test]
+    fn heap_cycles() {
+        use option::{Option, Some, None};
+
+        do run_in_newsched_task {
+            struct List {
+                next: Option<@mut List>,
+            }
+
+            let a = @mut List { next: None };
+            let b = @mut List { next: Some(a) };
+
+            a.next = Some(b);
+        }
+    }
 }