diff options
| author | Daniel Micay <danielmicay@gmail.com> | 2014-04-25 02:19:34 -0400 |
|---|---|---|
| committer | Daniel Micay <danielmicay@gmail.com> | 2014-05-10 19:58:17 -0400 |
| commit | 1b1ca6d5465ef4de12b1adf25cd4598f261c660d (patch) | |
| tree | 29c49a2ad0b6fdb69610019f84a5fa70ca62319e /src/libstd | |
| parent | 11571cd9c1cde63c3b46ca65e608b84647785ac8 (diff) | |
| download | rust-1b1ca6d5465ef4de12b1adf25cd4598f261c660d.tar.gz rust-1b1ca6d5465ef4de12b1adf25cd4598f261c660d.zip | |
add back jemalloc to the tree
This adds a `std::rt::heap` module with a nice allocator API. It's a step towards fixing #13094 and is a starting point for working on a generic allocator trait. The revision used for the jemalloc submodule is the stable 3.6.0 release. Closes #11807
Diffstat (limited to 'src/libstd')
| -rw-r--r-- | src/libstd/rt/heap.rs | 97 | ||||
| -rw-r--r-- | src/libstd/rt/mod.rs | 5 |
2 files changed, 101 insertions, 1 deletions
diff --git a/src/libstd/rt/heap.rs b/src/libstd/rt/heap.rs new file mode 100644 index 00000000000..b4b44fbf5c7 --- /dev/null +++ b/src/libstd/rt/heap.rs @@ -0,0 +1,97 @@ +// Copyright 2014 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. + +use intrinsics::{abort, cttz32}; +use libc::{c_int, c_void, size_t}; +use ptr::RawPtr; + +#[link(name = "jemalloc", kind = "static")] +extern { + fn je_mallocx(size: size_t, flags: c_int) -> *mut c_void; + fn je_rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void; + fn je_xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t; + fn je_dallocx(ptr: *mut c_void, flags: c_int); + fn je_nallocx(size: size_t, flags: c_int) -> size_t; +} + +// -lpthread needs to occur after -ljemalloc, the earlier argument isn't enough +#[cfg(not(windows))] +#[link(name = "pthread")] +extern {} + +// MALLOCX_ALIGN(a) macro +#[inline(always)] +fn mallocx_align(a: uint) -> c_int { unsafe { cttz32(a as u32) as c_int } } + +/// Return a pointer to `size` bytes of memory. +/// +/// Behavior is undefined if the requested size is 0 or the alignment is not a power of 2. The +/// alignment must be no larger than the largest supported page size on the platform. +#[inline] +pub unsafe fn allocate(size: uint, align: uint) -> *mut u8 { + let ptr = je_mallocx(size as size_t, mallocx_align(align)) as *mut u8; + if ptr.is_null() { + abort() + } + ptr +} + +/// Extend or shrink the allocation referenced by `ptr` to `size` bytes of memory. +/// +/// Behavior is undefined if the requested size is 0 or the alignment is not a power of 2. The +/// alignment must be no larger than the largest supported page size on the platform. +/// +/// The `old_size` and `align` parameters are the parameters that were used to create the +/// allocation referenced by `ptr`. The `old_size` parameter may also be the value returned by +/// `usable_size` for the requested size. +#[inline] +#[allow(unused_variable)] // for the parameter names in the documentation +pub unsafe fn reallocate(ptr: *mut u8, size: uint, align: uint, old_size: uint) -> *mut u8 { + let ptr = je_rallocx(ptr as *mut c_void, size as size_t, mallocx_align(align)) as *mut u8; + if ptr.is_null() { + abort() + } + ptr +} + +/// Extend or shrink the allocation referenced by `ptr` to `size` bytes of memory in-place. +/// +/// Return true if successful, otherwise false if the allocation was not altered. +/// +/// Behavior is undefined if the requested size is 0 or the alignment is not a power of 2. The +/// alignment must be no larger than the largest supported page size on the platform. +/// +/// The `old_size` and `align` parameters are the parameters that were used to +/// create the allocation referenced by `ptr`. The `old_size` parameter may be +/// any value in range_inclusive(requested_size, usable_size). +#[inline] +#[allow(unused_variable)] // for the parameter names in the documentation +pub unsafe fn reallocate_inplace(ptr: *mut u8, size: uint, align: uint, old_size: uint) -> bool { + je_xallocx(ptr as *mut c_void, size as size_t, 0, mallocx_align(align)) == size as size_t +} + +/// Deallocate the memory referenced by `ptr`. +/// +/// The `ptr` parameter must not be null. +/// +/// The `size` and `align` parameters are the parameters that were used to create the +/// allocation referenced by `ptr`. The `size` parameter may also be the value returned by +/// `usable_size` for the requested size. +#[inline] +#[allow(unused_variable)] // for the parameter names in the documentation +pub unsafe fn deallocate(ptr: *mut u8, size: uint, align: uint) { + je_dallocx(ptr as *mut c_void, mallocx_align(align)) +} + +/// Return the usable size of an allocation created with the specified the `size` and `align`. +#[inline] +pub fn usable_size(size: uint, align: uint) -> uint { + unsafe { je_nallocx(size as size_t, mallocx_align(align)) as uint } +} diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 5b9c314d42b..904921cfa18 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -89,7 +89,10 @@ mod macros; // The global (exchange) heap. pub mod global_heap; -// Implementations of language-critical runtime features like @. +/// The low-level memory allocation API. +pub mod heap; + +/// Implementations of language-critical runtime features like @. pub mod task; // The EventLoop and internal synchronous I/O interface. |
