Skip to content

Commit

Permalink
core::rt: Add the local heap to newsched tasks
Browse files Browse the repository at this point in the history
Reusing the existing boxed_region implementation from the runtime
  • Loading branch information
brson committed Apr 22, 2013
1 parent 2fe118b commit d7f5e43
Show file tree
Hide file tree
Showing 7 changed files with 170 additions and 10 deletions.
81 changes: 81 additions & 0 deletions src/libcore/rt/local_heap.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// 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.

//! The local, garbage collected heap

use libc::{c_void, uintptr_t, size_t};
use ops::Drop;

type MemoryRegion = c_void;
type BoxedRegion = c_void;

pub type OpaqueBox = c_void;
pub type TypeDesc = c_void;

pub struct LocalHeap {
memory_region: *MemoryRegion,
boxed_region: *BoxedRegion
}

impl LocalHeap {
pub fn new() -> LocalHeap {
unsafe {
// Don't need synchronization for the single-threaded local heap
let synchronized = false as uintptr_t;
// XXX: These usually come from the environment
let detailed_leaks = false as uintptr_t;
let poison_on_free = false as uintptr_t;
let region = rust_new_memory_region(synchronized, detailed_leaks, poison_on_free);
assert!(region.is_not_null());
let boxed = rust_new_boxed_region(region, poison_on_free);
assert!(boxed.is_not_null());
LocalHeap {
memory_region: region,
boxed_region: boxed
}
}
}

pub fn alloc(&mut self, td: *TypeDesc, size: uint) -> *OpaqueBox {
unsafe {
return rust_boxed_region_malloc(self.boxed_region, td, size as size_t);
}
}

pub fn free(&mut self, box: *OpaqueBox) {
unsafe {
return rust_boxed_region_free(self.boxed_region, box);
}
}
}

impl Drop for LocalHeap {
fn finalize(&self) {
unsafe {
rust_delete_boxed_region(self.boxed_region);
rust_delete_memory_region(self.memory_region);
}
}
}

extern {
fn rust_new_memory_region(synchronized: uintptr_t,
detailed_leaks: uintptr_t,
poison_on_free: uintptr_t) -> *MemoryRegion;
fn rust_delete_memory_region(region: *MemoryRegion);
fn rust_new_boxed_region(region: *MemoryRegion,
poison_on_free: uintptr_t) -> *BoxedRegion;
fn rust_delete_boxed_region(region: *BoxedRegion);
fn rust_boxed_region_malloc(region: *BoxedRegion,
td: *TypeDesc,
size: size_t) -> *OpaqueBox;
fn rust_boxed_region_free(region: *BoxedRegion, box: *OpaqueBox);
}

19 changes: 17 additions & 2 deletions src/libcore/rt/local_services.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

use prelude::*;
use super::sched::{Task, local_sched};
use super::local_heap::LocalHeap;

pub struct LocalServices {
heap: LocalHeap,
Expand All @@ -29,7 +30,6 @@ pub struct LocalServices {
unwinder: Unwinder
}

pub struct LocalHeap;
pub struct GarbageCollector;
pub struct LocalStorage;
pub struct Logger;
Expand All @@ -38,7 +38,7 @@ pub struct Unwinder;
impl LocalServices {
pub fn new() -> LocalServices {
LocalServices {
heap: LocalHeap,
heap: LocalHeap::new(),
gc: GarbageCollector,
storage: LocalStorage,
logger: Logger,
Expand All @@ -61,3 +61,18 @@ pub fn borrow_local_services(f: &fn(&mut LocalServices)) {
}
}
}

#[cfg(test)]
mod test {
use rt::test::*;

#[test]
fn local_heap() {
do run_in_newsched_task() {
let a = @5;
let b = a;
assert!(*a == 5);
assert!(*b == 5);
}
}
}
1 change: 1 addition & 0 deletions src/libcore/rt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ mod context;
mod thread;
pub mod env;
pub mod local_services;
mod local_heap;

/// Tools for testing the runtime
#[cfg(test)]
Expand Down
26 changes: 24 additions & 2 deletions src/libcore/unstable/lang.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ use str;
use sys;
use unstable::exchange_alloc;
use cast::transmute;
use rt::{context, OldTaskContext};
use rt::local_services::borrow_local_services;

#[allow(non_camel_case_types)]
pub type rust_task = c_void;
Expand Down Expand Up @@ -81,7 +83,18 @@ pub unsafe fn exchange_free(ptr: *c_char) {
#[lang="malloc"]
#[inline(always)]
pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
return rustrt::rust_upcall_malloc(td, size);
match context() {
OldTaskContext => {
return rustrt::rust_upcall_malloc(td, size);
}
_ => {
let mut alloc = ::ptr::null();
do borrow_local_services |srv| {
alloc = srv.heap.alloc(td as *c_void, size as uint) as *c_char;
}
return alloc;
}
}
}

// NB: Calls to free CANNOT be allowed to fail, as throwing an exception from
Expand All @@ -90,7 +103,16 @@ pub unsafe fn local_malloc(td: *c_char, size: uintptr_t) -> *c_char {
#[lang="free"]
#[inline(always)]
pub unsafe fn local_free(ptr: *c_char) {
rustrt::rust_upcall_free(ptr);
match context() {
OldTaskContext => {
rustrt::rust_upcall_free(ptr);
}
_ => {
do borrow_local_services |srv| {
srv.heap.free(ptr as *c_void);
}
}
}
}

#[lang="borrow_as_imm"]
Expand Down
12 changes: 6 additions & 6 deletions src/rt/boxed_region.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ rust_opaque_box *boxed_region::malloc(type_desc *td, size_t body_size) {
if (live_allocs) live_allocs->prev = box;
live_allocs = box;

LOG(rust_get_current_task(), box,
/*LOG(rust_get_current_task(), box,
"@malloc()=%p with td %p, size %lu==%lu+%lu, "
"align %lu, prev %p, next %p\n",
box, td, total_size, sizeof(rust_opaque_box), body_size,
td->align, box->prev, box->next);
td->align, box->prev, box->next);*/

return box;
}
Expand All @@ -50,9 +50,9 @@ rust_opaque_box *boxed_region::realloc(rust_opaque_box *box,
if (new_box->next) new_box->next->prev = new_box;
if (live_allocs == box) live_allocs = new_box;

LOG(rust_get_current_task(), box,
/*LOG(rust_get_current_task(), box,
"@realloc()=%p with orig=%p, size %lu==%lu+%lu",
new_box, box, total_size, sizeof(rust_opaque_box), new_size);
new_box, box, total_size, sizeof(rust_opaque_box), new_size);*/

return new_box;
}
Expand All @@ -74,9 +74,9 @@ void boxed_region::free(rust_opaque_box *box) {
// double frees (kind of).
assert(box->td != NULL);

LOG(rust_get_current_task(), box,
/*LOG(rust_get_current_task(), box,
"@free(%p) with td %p, prev %p, next %p\n",
box, box->td, box->prev, box->next);
box, box->td, box->prev, box->next);*/

if (box->prev) box->prev->next = box->next;
if (box->next) box->next->prev = box->prev;
Expand Down
35 changes: 35 additions & 0 deletions src/rt/rust_builtin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -851,6 +851,41 @@ rust_initialize_global_state() {
}
}

extern "C" CDECL memory_region*
rust_new_memory_region(uintptr_t synchronized,
uintptr_t detailed_leaks,
uintptr_t poison_on_free) {
return new memory_region((bool)synchronized,
(bool)detailed_leaks,
(bool)poison_on_free);
}

extern "C" CDECL void
rust_delete_memory_region(memory_region *region) {
delete region;
}

extern "C" CDECL boxed_region*
rust_new_boxed_region(memory_region *region,
uintptr_t poison_on_free) {
return new boxed_region(region, poison_on_free);
}

extern "C" CDECL void
rust_delete_boxed_region(boxed_region *region) {
delete region;
}

extern "C" CDECL rust_opaque_box*
rust_boxed_region_malloc(boxed_region *region, type_desc *td, size_t size) {
return region->malloc(td, size);
}

extern "C" CDECL void
rust_boxed_region_free(boxed_region *region, rust_opaque_box *box) {
region->free(box);
}

//
// Local Variables:
// mode: C++
Expand Down
6 changes: 6 additions & 0 deletions src/rt/rustrt.def.in
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,9 @@ rust_uv_free_ip6_addr
rust_call_nullary_fn
rust_initialize_global_state
rust_dbg_next_port
rust_new_memory_region
rust_delete_memory_region
rust_new_boxed_region
rust_delete_boxed_region
rust_boxed_region_malloc
rust_boxed_region_free

0 comments on commit d7f5e43

Please sign in to comment.