Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions src/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use crate::{error::Error, header::Header, size_classes::size_class_index};
use core::mem::offset_of;
use core::ptr::NonNull;
use core::sync::atomic::Ordering;
use std::path::Path;
use std::fs::File;

pub struct Allocator {
header: NonNull<Header>,
Expand All @@ -19,9 +19,9 @@ pub struct Allocator {
}

impl Allocator {
/// Create a new `Allocator` with new file and given parameters.
/// Create a new `Allocator` in the provided file with the given parameters.
pub fn create(
path: impl AsRef<Path>,
file: &File,
file_size: usize,
num_workers: u32,
slab_size: u32,
Expand All @@ -30,18 +30,18 @@ impl Allocator {
if worker_index >= num_workers {
return Err(Error::InvalidWorkerIndex);
}
let header = crate::init::create(path, file_size, num_workers, slab_size)?;
let header = crate::init::create(file, file_size, num_workers, slab_size)?;

// SAFETY: The header is guaranteed to be valid and initialized.
unsafe { Allocator::new(header, file_size, worker_index) }
}

/// Join an existing allocator at the given path.
/// Join an existing allocator in the provided file.
///
/// # Safety
/// - `worker_index` must be uniquely assigned to this worker thread/process.
pub unsafe fn join(path: impl AsRef<Path>, worker_index: u32) -> Result<Self, Error> {
let (header, file_size) = crate::init::join(path)?;
pub unsafe fn join(file: &File, worker_index: u32) -> Result<Self, Error> {
let (header, file_size) = crate::init::join(file)?;

// Check if the worker index is valid.
// SAFETY: The header is guaranteed to be valid and initialized.
Expand Down
7 changes: 7 additions & 0 deletions src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,14 @@ pub enum Error {
InvalidNumWorkers,
InvalidWorkerIndex,
InvalidFileSize,
AlreadyInitialized,
InvalidHeader,
IoError(std::io::Error),
MMapError(std::io::Error),
}

impl From<std::io::Error> for Error {
fn from(value: std::io::Error) -> Self {
Self::IoError(value)
}
}
46 changes: 12 additions & 34 deletions src/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,14 @@ use std::{
fs::File,
mem::offset_of,
os::{fd::AsRawFd, raw::c_void},
path::Path,
ptr::NonNull,
sync::atomic::Ordering,
};

/// Create and initialize the allocator's backing file.
/// Returns pointer to header.
pub fn create(
path: impl AsRef<Path>,
file: &File,
file_size: usize,
num_workers: u32,
slab_size: u32,
Expand All @@ -36,15 +35,19 @@ pub fn create(
return Err(Error::InvalidFileSize);
}

// Create the file and mmap it.
let file = create_file(path, file_size)?;
let mmap = open_mmap(&file, file_size)?;
// Resize the file if it's currently 0 sized, else error.
if file.metadata()?.len() != 0 {
return Err(Error::AlreadyInitialized);
}
file.set_len(file_size as u64)?;

let header = NonNull::new(mmap.cast::<Header>()).expect("mmap already checked for null");
// Map the file into memory.
let mmap = open_mmap(file, file_size)?;

// Initialize the header.
// SAFETY: The header is valid for any byte pattern.
// There is sufficient space for a `Header` and trailing data.
let header = NonNull::new(mmap.cast::<Header>()).expect("mmap already checked for null");
unsafe {
initialize::allocator(header, slab_size, num_workers, layout);
}
Expand All @@ -53,10 +56,9 @@ pub fn create(
}

/// Join an existing allocator, returning a pointer to the header and size.
pub fn join(path: impl AsRef<Path>) -> Result<(NonNull<Header>, usize), Error> {
let file = open_file(path)?;
let file_size = file.metadata().map_err(Error::IoError)?.len() as usize;
let mmap = open_mmap(&file, file_size)?;
pub fn join(file: &File) -> Result<(NonNull<Header>, usize), Error> {
let file_size = file.metadata()?.len() as usize;
let mmap = open_mmap(file, file_size)?;
let header = NonNull::new(mmap.cast::<Header>()).expect("mmap already checked for null");

// Verify header
Expand Down Expand Up @@ -122,30 +124,6 @@ fn open_mmap(file: &File, size: usize) -> Result<*mut c_void, Error> {
Ok(mmap)
}

fn create_file(file_path: impl AsRef<Path>, size: usize) -> Result<File, Error> {
let file_path = file_path.as_ref();
let file = std::fs::OpenOptions::new()
.read(true)
.write(true)
.create_new(true)
.open(file_path)
.map_err(Error::IoError)?;
file.set_len(size as u64).map_err(Error::IoError)?;

Ok(file)
}

fn open_file(file_path: impl AsRef<Path>) -> Result<File, Error> {
let file_path = file_path.as_ref();
let file = std::fs::OpenOptions::new()
.read(true)
.write(true)
.open(file_path)
.map_err(Error::IoError)?;

Ok(file)
}

pub mod initialize {
use super::*;
use crate::{
Expand Down