From c4f2e20eb1f5860f68ba6465128eaf0ff069f077 Mon Sep 17 00:00:00 2001 From: Carl Lerche <me@carllerche.com> Date: Tue, 7 Apr 2015 21:06:38 -0700 Subject: [PATCH] Move heap allocator into a module --- src/alloc.rs | 55 +--------------------------------------------- src/byte_buf.rs | 4 ++-- src/heap.rs | 58 +++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 1 + src/ring.rs | 4 ++-- 5 files changed, 64 insertions(+), 58 deletions(-) create mode 100644 src/heap.rs diff --git a/src/alloc.rs b/src/alloc.rs index 0be634f..39312f2 100644 --- a/src/alloc.rs +++ b/src/alloc.rs @@ -1,9 +1,5 @@ use std::{mem, ptr}; -use std::ops::DerefMut; use std::sync::atomic::{AtomicUsize, Ordering}; -use std::usize; - -const MAX_ALLOC_SIZE: usize = usize::MAX; /// Allocates memory to be used by Bufs or Bytes. Allows allocating memory /// using alternate stratgies than the default Rust heap allocator. Also does @@ -114,7 +110,7 @@ pub struct Mem { } impl Mem { - fn new(len: usize, allocator: *const Allocator) -> Mem { + pub fn new(len: usize, allocator: *const Allocator) -> Mem { Mem { allocator: allocator, refs: AtomicUsize::new(1), @@ -122,52 +118,3 @@ impl Mem { } } } - -pub static HEAP: Heap = Heap; - -pub struct Heap; - -impl Heap { - pub fn allocate(&self, len: usize) -> MemRef { - // Make sure that the allocation is within the permitted range - if len > MAX_ALLOC_SIZE { - return MemRef::none(); - } - - let alloc_len = len + - mem::size_of::<Mem>() + - mem::size_of::<Vec<u8>>(); - - unsafe { - let mut vec: Vec<u8> = Vec::with_capacity(alloc_len); - vec.set_len(alloc_len); - - let ptr = vec.deref_mut().as_mut_ptr(); - - ptr::write(ptr as *mut Vec<u8>, vec); - - let ptr = ptr.offset(mem::size_of::<Vec<u8>>() as isize); - ptr::write(ptr as *mut Mem, Mem::new(len, mem::transmute(self as &Allocator))); - - // Return the info - MemRef::new(ptr as *mut Mem) - } - } - - pub fn deallocate(&self, mem: *mut Mem) { - unsafe { - let ptr = mem as *mut u8; - let _ = ptr::read(ptr.offset(-(mem::size_of::<Vec<u8>>() as isize)) as *const Vec<u8>); - } - } -} - -impl Allocator for Heap { - fn allocate(&self, len: usize) -> MemRef { - Heap::allocate(self, len) - } - - fn deallocate(&self, mem: *mut Mem) { - Heap::deallocate(self, mem) - } -} diff --git a/src/byte_buf.rs b/src/byte_buf.rs index deb2a88..cf8fc4d 100644 --- a/src/byte_buf.rs +++ b/src/byte_buf.rs @@ -1,4 +1,4 @@ -use {alloc, Bytes, SeqByteStr, MAX_CAPACITY}; +use {alloc, heap, Bytes, SeqByteStr, MAX_CAPACITY}; use traits::{Buf, MutBuf, MutBufExt, ByteStr}; use std::{cmp, ptr}; @@ -59,7 +59,7 @@ impl ByteBuf { capacity = capacity.next_power_of_two(); // Allocate the memory - let mem = alloc::HEAP.allocate(capacity as usize); + let mem = heap::allocate(capacity as usize); // If the allocation failed, return a blank buf if mem.is_none() { diff --git a/src/heap.rs b/src/heap.rs new file mode 100644 index 0000000..d78ef6c --- /dev/null +++ b/src/heap.rs @@ -0,0 +1,58 @@ +use alloc::{Allocator, Mem, MemRef}; +use std::{mem, ptr, usize}; +use std::ops::DerefMut; + +const MAX_ALLOC_SIZE: usize = usize::MAX; + +pub fn allocate(len: usize) -> MemRef { + HEAP.allocate(len) +} + +pub struct Heap; + +pub static HEAP: Heap = Heap; + +impl Heap { + pub fn allocate(&self, len: usize) -> MemRef { + // Make sure that the allocation is within the permitted range + if len > MAX_ALLOC_SIZE { + return MemRef::none(); + } + + let alloc_len = len + + mem::size_of::<Mem>() + + mem::size_of::<Vec<u8>>(); + + unsafe { + let mut vec: Vec<u8> = Vec::with_capacity(alloc_len); + vec.set_len(alloc_len); + + let ptr = vec.deref_mut().as_mut_ptr(); + + ptr::write(ptr as *mut Vec<u8>, vec); + + let ptr = ptr.offset(mem::size_of::<Vec<u8>>() as isize); + ptr::write(ptr as *mut Mem, Mem::new(len, mem::transmute(self as &Allocator))); + + // Return the info + MemRef::new(ptr as *mut Mem) + } + } + + pub fn deallocate(&self, mem: *mut Mem) { + unsafe { + let ptr = mem as *mut u8; + let _ = ptr::read(ptr.offset(-(mem::size_of::<Vec<u8>>() as isize)) as *const Vec<u8>); + } + } +} + +impl Allocator for Heap { + fn allocate(&self, len: usize) -> MemRef { + Heap::allocate(self, len) + } + + fn deallocate(&self, mem: *mut Mem) { + Heap::deallocate(self, mem) + } +} diff --git a/src/lib.rs b/src/lib.rs index 1d66fd6..c4f66bb 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -15,6 +15,7 @@ mod alloc; mod byte_buf; mod byte_str; mod bytes; +mod heap; mod ring; mod rope; mod slice; diff --git a/src/ring.rs b/src/ring.rs index 20bab4a..e322e4d 100644 --- a/src/ring.rs +++ b/src/ring.rs @@ -1,4 +1,4 @@ -use {alloc, Buf, MutBuf}; +use {alloc, heap, Buf, MutBuf}; use std::{cmp, fmt, io, ptr}; /// Buf backed by a continous chunk of memory. Maintains a read cursor and a @@ -27,7 +27,7 @@ impl RingBuf { // Round to the next power of 2 for better alignment capacity = capacity.next_power_of_two(); - let mem = alloc::HEAP.allocate(capacity as usize); + let mem = heap::allocate(capacity as usize); RingBuf { ptr: mem, -- GitLab