diff --git a/src/alloc.rs b/src/alloc.rs index 0be634f0818de6a64e714c5229f1a4a41ec3c931..39312f2a571fa30614561334595dc2dbe7afd315 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 deb2a8888def62416d40da86dcda74aff68d2513..cf8fc4d47aa46d613eb43853107bacafb36da6ab 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 0000000000000000000000000000000000000000..d78ef6c8e7b519715ba5ac5407fb3cbb73495701 --- /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 1d66fd65915869ca5551d6753d7def7e0fa68148..c4f66bb02a37cf72fb7052860f5e58d55dc0f8aa 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 20bab4ac13c59f93589168f997793ac3b14edcfd..e322e4d5a880a4c2a2e654cd0a626c19268fdce9 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,