outsource_heap/
file_backed.rs1use super::Store;
6use ::std::sync::Mutex;
7use ::std::io;
8use ::std::path::Path;
9use ::std::fs::OpenOptions;
10use ::std::alloc::Layout;
11use ::core::ptr::NonNull;
12use ::memmap2::MmapMut;
13use ::linked_list_allocator::Heap;
14
15pub struct FileBacked {
16 _mmap: MmapMut,
17 heap: Mutex<Heap>,
18}
19impl FileBacked {
20 pub fn open(capacity: u64, path: &Path) -> Result<Self, io::Error> {
21 let cap = capacity.try_into().map_err(|_| {
22 io::Error::new(io::ErrorKind::Unsupported, "tried to allocate more than usize::MAX")
23 })?;
24 let file = OpenOptions::new().read(true).write(true).create(true).open(&path)?;
25 file.set_len(capacity)?;
26 let mut mmap = unsafe { MmapMut::map_mut(&file)? };
27 let base = (&mut *mmap).as_mut_ptr();
28 let heap = Mutex::new(unsafe { Heap::new(base, cap) });
29 Ok(Self { _mmap: mmap, heap })
30 }
31}
32
33unsafe impl Store for FileBacked {
36 unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
37 self.heap.lock().unwrap()
38 .allocate_first_fit(layout)
39 .map(|x| x.as_ptr())
40 .unwrap_or(::core::ptr::null_mut())
41 }
42 unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
43 let ptr = unsafe { NonNull::new_unchecked(ptr) };
44 unsafe { self.heap.lock().unwrap().deallocate(ptr, layout); }
45 }
46}