1#![doc = include_str!("../README.md")]
2#![cfg_attr(not(feature = "std"), no_std)]
3#![cfg_attr(feature = "nightly", feature(allocator_api))]
4#![warn(unsafe_op_in_unsafe_fn)]
5
6#[cfg(feature = "alloc")]
7extern crate alloc;
8
9mod chunk;
10mod local;
11
12#[cfg(feature = "std")]
13mod global;
14
15use core::{alloc::Layout, cell::Cell, sync::atomic::Ordering};
16
17pub use self::local::RingAlloc;
18
19#[cfg(feature = "std")]
20pub use self::global::OneRingAlloc;
21
22#[allow(clippy::transmutes_expressible_as_ptr_casts)]
23fn addr<T: ?Sized>(ptr: *const T) -> usize {
24 unsafe { core::mem::transmute(ptr.cast::<()>()) }
26}
27
28unsafe fn with_addr_mut<T>(ptr: *mut T, dest_addr: usize) -> *mut T {
34 let ptr_addr = addr(ptr) as isize;
35 let offset = (dest_addr as isize).wrapping_sub(ptr_addr);
36 ptr.cast::<u8>().wrapping_offset(offset).cast()
37}
38
39trait ImUsize {
40 fn new(value: usize) -> Self;
41 fn load(&self, ordering: Ordering) -> usize;
42 fn store(&self, value: usize, ordering: Ordering);
43 fn fetch_add(&self, value: usize, ordering: Ordering) -> usize;
44}
45
46impl ImUsize for Cell<usize> {
47 #[inline(always)]
48 fn new(value: usize) -> Self {
49 Cell::new(value)
50 }
51
52 #[inline(always)]
53 fn load(&self, _ordering: Ordering) -> usize {
54 self.get()
55 }
56
57 #[inline(always)]
58 fn store(&self, value: usize, _ordering: Ordering) {
59 self.set(value)
60 }
61
62 #[inline(always)]
63 fn fetch_add(&self, value: usize, _ordering: Ordering) -> usize {
64 let old_value = self.get();
65 self.set(old_value.wrapping_add(value));
66 old_value
67 }
68}
69
70#[cfg(feature = "std")]
71impl ImUsize for core::sync::atomic::AtomicUsize {
72 #[inline(always)]
73 fn new(value: usize) -> Self {
74 Self::new(value)
75 }
76
77 #[inline(always)]
78 fn load(&self, ordering: Ordering) -> usize {
79 self.load(ordering)
80 }
81
82 #[inline(always)]
83 fn store(&self, value: usize, ordering: Ordering) {
84 self.store(value, ordering)
85 }
86
87 #[inline(always)]
88 fn fetch_add(&self, value: usize, ordering: Ordering) -> usize {
89 self.fetch_add(value, ordering)
90 }
91}
92
93#[inline(always)]
94fn layout_max(layout: Layout) -> usize {
95 layout.align().max(layout.size())
96}
97
98#[inline(always)]
99#[cold]
100fn cold() {}
101
102#[cfg(test)]
103mod tests;