From aaead93c4554b685935b70565fc1bb54edd945d6 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 10 Feb 2014 14:41:57 -0800 Subject: Don't allocate in LocalHeap::new() One of these is allocated for every task, trying to cut down on allocations cc #11389 --- src/libstd/rt/local_heap.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'src/libstd/rt') diff --git a/src/libstd/rt/local_heap.rs b/src/libstd/rt/local_heap.rs index 023f712d3a0..7acce2ecb5b 100644 --- a/src/libstd/rt/local_heap.rs +++ b/src/libstd/rt/local_heap.rs @@ -23,6 +23,7 @@ use rt::local::Local; use rt::task::Task; use unstable::raw; use vec::ImmutableVector; +use vec_ng::Vec; // This has no meaning with out rtdebug also turned on. #[cfg(rtdebug)] @@ -33,7 +34,7 @@ static MAGIC: u32 = 0xbadc0ffe; pub type Box = raw::Box<()>; pub struct MemoryRegion { - priv allocations: ~[*AllocHeader], + priv allocations: Vec<*AllocHeader>, priv live_allocations: uint, } @@ -48,7 +49,7 @@ impl LocalHeap { #[inline] pub fn new() -> LocalHeap { let region = MemoryRegion { - allocations: ~[], + allocations: Vec::new(), live_allocations: 0, }; LocalHeap { @@ -248,8 +249,8 @@ impl MemoryRegion { fn release(&mut self, alloc: &AllocHeader) { alloc.assert_sane(); if TRACK_ALLOCATIONS > 1 { - rtassert!(self.allocations[alloc.index] == alloc as *AllocHeader); - self.allocations[alloc.index] = ptr::null(); + rtassert!(self.allocations.as_slice()[alloc.index] == alloc as *AllocHeader); + self.allocations.as_mut_slice()[alloc.index] = ptr::null(); } } #[cfg(not(rtdebug))] @@ -260,8 +261,8 @@ impl MemoryRegion { fn update(&mut self, alloc: &mut AllocHeader, orig: *AllocHeader) { alloc.assert_sane(); if TRACK_ALLOCATIONS > 1 { - rtassert!(self.allocations[alloc.index] == orig); - self.allocations[alloc.index] = &*alloc as *AllocHeader; + rtassert!(self.allocations.as_slice()[alloc.index] == orig); + self.allocations.as_mut_slice()[alloc.index] = &*alloc as *AllocHeader; } } #[cfg(not(rtdebug))] @@ -274,7 +275,7 @@ impl Drop for MemoryRegion { if self.live_allocations != 0 { rtabort!("leaked managed memory ({} objects)", self.live_allocations); } - rtassert!(self.allocations.iter().all(|s| s.is_null())); + rtassert!(self.allocations.as_slice().iter().all(|s| s.is_null())); } } -- cgit 1.4.1-3-g733a5 From 21a064d5a340a00042c81745cc7d2a65691e84be Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 10 Feb 2014 14:49:56 -0800 Subject: Don't require an allocation for on_exit messages Instead, use an enum to allow running both a procedure and sending the task result over a channel. I expect the common case to be sending on a channel (e.g. task::try), so don't require an extra allocation in the common case. cc #11389 --- src/libgreen/task.rs | 5 ++--- src/libnative/task.rs | 7 ++----- src/libstd/rt/task.rs | 16 ++++++++++++---- 3 files changed, 16 insertions(+), 12 deletions(-) (limited to 'src/libstd/rt') diff --git a/src/libgreen/task.rs b/src/libgreen/task.rs index e492acb4468..6d61f8e3919 100644 --- a/src/libgreen/task.rs +++ b/src/libgreen/task.rs @@ -22,7 +22,7 @@ use std::cast; use std::rt::Runtime; use std::rt::rtio; use std::rt::local::Local; -use std::rt::task::{Task, BlockedTask}; +use std::rt::task::{Task, BlockedTask, SendMessage}; use std::task::TaskOpts; use std::unstable::mutex::Mutex; @@ -131,8 +131,7 @@ impl GreenTask { task.stdout = stdout; match notify_chan { Some(chan) => { - let on_exit = proc(task_result) { chan.send(task_result) }; - task.death.on_exit = Some(on_exit); + task.death.on_exit = Some(SendMessage(chan)); } None => {} } diff --git a/src/libnative/task.rs b/src/libnative/task.rs index d0ca8364aa7..a9c3afbbb16 100644 --- a/src/libnative/task.rs +++ b/src/libnative/task.rs @@ -18,7 +18,7 @@ use std::cast; use std::rt::env; use std::rt::local::Local; use std::rt::rtio; -use std::rt::task::{Task, BlockedTask}; +use std::rt::task::{Task, BlockedTask, SendMessage}; use std::rt::thread::Thread; use std::rt; use std::task::TaskOpts; @@ -68,10 +68,7 @@ pub fn spawn_opts(opts: TaskOpts, f: proc()) { task.stderr = stderr; task.stdout = stdout; match notify_chan { - Some(chan) => { - let on_exit = proc(task_result) { chan.send(task_result) }; - task.death.on_exit = Some(on_exit); - } + Some(chan) => { task.death.on_exit = Some(SendMessage(chan)); } None => {} } diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs index e2b94e655e8..0719523af77 100644 --- a/src/libstd/rt/task.rs +++ b/src/libstd/rt/task.rs @@ -17,6 +17,7 @@ use any::AnyOwnExt; use cast; use cleanup; use clone::Clone; +use comm::Chan; use io::Writer; use iter::{Iterator, Take}; use local_data; @@ -67,11 +68,17 @@ pub enum BlockedTask { Shared(UnsafeArc), } +pub enum DeathAction { + /// Action to be done with the exit code. If set, also makes the task wait + /// until all its watched children exit before collecting the status. + Execute(proc(TaskResult)), + /// A channel to send the result of the task on when the task exits + SendMessage(Chan), +} + /// Per-task state related to task death, killing, failure, etc. pub struct Death { - // Action to be done with the exit code. If set, also makes the task wait - // until all its watched children exit before collecting the status. - on_exit: Option, + on_exit: Option, } pub struct BlockedTasks { @@ -381,7 +388,8 @@ impl Death { /// Collect failure exit codes from children and propagate them to a parent. pub fn collect_failure(&mut self, result: TaskResult) { match self.on_exit.take() { - Some(f) => f(result), + Some(Execute(f)) => f(result), + Some(SendMessage(ch)) => { ch.try_send(result); } None => {} } } -- cgit 1.4.1-3-g733a5