Skip to content

Commit

Permalink
Use NonZeroUsize for slab_capacity
Browse files Browse the repository at this point in the history
  • Loading branch information
marc0246 committed Oct 20, 2024
1 parent d86c687 commit 207a3f7
Showing 1 changed file with 19 additions and 16 deletions.
35 changes: 19 additions & 16 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ use core::{
cell::Cell,
fmt,
mem::{self, ManuallyDrop, MaybeUninit},
num::NonZeroUsize,
ptr::{self, NonNull},
};

Expand Down Expand Up @@ -140,7 +141,7 @@ pub struct SlabAllocator<T> {
/// Points to the end of the slab of the head of the slab list. If the slab list is empty then
/// this is dangling.
free_end: Cell<NonNull<Slot<T>>>,
slab_capacity: usize,
slab_capacity: NonZeroUsize,
}

// SAFETY: The pointers we hold are not referencing the stack or TLS or anything like that, they
Expand Down Expand Up @@ -168,16 +169,18 @@ impl<T> SlabAllocator<T> {
#[inline]
#[must_use]
pub const fn new(slab_capacity: usize) -> Self {
assert!(slab_capacity != 0);

let dangling = NonNull::dangling();

SlabAllocator {
free_list_head: Cell::new(None),
slab_list_head: Cell::new(None),
free_start: Cell::new(dangling),
free_end: Cell::new(dangling),
slab_capacity,
if let Some(slab_capacity) = NonZeroUsize::new(slab_capacity) {
let dangling = NonNull::dangling();

SlabAllocator {
free_list_head: Cell::new(None),
slab_list_head: Cell::new(None),
free_start: Cell::new(dangling),
free_end: Cell::new(dangling),
slab_capacity,
}
} else {
panic!("`slab_capacity` must be non-zero");
}
}

Expand Down Expand Up @@ -297,16 +300,16 @@ impl<T> SlabAllocator<T> {

// SAFETY:
// * We know that the offset must be in bounds of the allocated object because we allocated
// `self.slab_capacity` slots, and by our own invariant, `self.slab_capacity` must be
// non-zero.
// `self.slab_capacity` slots and `self.slab_capacity` is non-zero.
// * The computed offset cannot overflow an `isize` because we used `Layout` for the layout
// calculation.
// * The computed offset cannot wrap around the address space for the same reason as the
// previous.
let free_start = unsafe { NonNull::new_unchecked(slots.as_ptr().add(1)) };

// SAFETY: Same as the previous.
let free_end = unsafe { NonNull::new_unchecked(slots.as_ptr().add(self.slab_capacity)) };
let free_end =
unsafe { NonNull::new_unchecked(slots.as_ptr().add(self.slab_capacity.get())) };

self.free_start.set(free_start);
self.free_end.set(free_end);
Expand All @@ -333,7 +336,7 @@ impl<T> SlabAllocator<T> {

fn slab_layout(&self) -> Layout {
Layout::new::<Option<NonNull<Slab<T>>>>()
.extend(Layout::array::<Slot<T>>(self.slab_capacity).unwrap())
.extend(Layout::array::<Slot<T>>(self.slab_capacity.get()).unwrap())
.unwrap()
.0
.pad_to_align()
Expand Down Expand Up @@ -383,7 +386,7 @@ impl<T> SlabAllocator<T> {
// the layout calculation.
// * The computed offset cannot wrap around the address space for the same reason
// as the previous.
let slots_end = unsafe { slots_start.add(self.slab_capacity) };
let slots_end = unsafe { slots_start.add(self.slab_capacity.get()) };

if (slots_start..slots_end).contains(&ptr.as_ptr()) {
break;
Expand Down

0 comments on commit 207a3f7

Please sign in to comment.