diff options
| author | Brian Anderson <banderson@mozilla.com> | 2013-06-22 01:09:06 -0700 |
|---|---|---|
| committer | Brian Anderson <banderson@mozilla.com> | 2013-06-24 17:07:03 -0700 |
| commit | 5e7c5d6c3d532e7b536b76044cd47b72b8eadaad (patch) | |
| tree | 4293df31a4276cc3d477ece661fe30debc7da63a /src/libstd/rt | |
| parent | a09972db3545344048b90e90d1f1821b621a38b9 (diff) | |
| download | rust-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.rs | 12 | ||||
| -rw-r--r-- | src/libstd/rt/local_heap.rs | 50 | ||||
| -rw-r--r-- | src/libstd/rt/mod.rs | 2 | ||||
| -rw-r--r-- | src/libstd/rt/task.rs | 21 |
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); + } + } } |
