mirror of
https://github.com/tokio-rs/bytes.git
synced 2026-08-11 00:00:23 +02:00
Move heap allocator into a module
This commit is contained in:
+1
-54
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -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() {
|
||||
|
||||
+58
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ mod alloc;
|
||||
mod byte_buf;
|
||||
mod byte_str;
|
||||
mod bytes;
|
||||
mod heap;
|
||||
mod ring;
|
||||
mod rope;
|
||||
mod slice;
|
||||
|
||||
+2
-2
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user