7575
7676extern crate alloc;
7777
78- use core:: alloc:: Layout ;
79- use core:: ptr:: NonNull ;
80-
8178// Logging support - conditionally import log crate
8279#[ cfg( feature = "log" ) ]
8380extern crate log;
@@ -105,40 +102,13 @@ macro_rules! trace {
105102 ( $( $arg: tt) * ) => { } ;
106103}
107104
105+ pub use axallocator:: {
106+ AllocError , AllocResult , BaseAllocator , ByteAllocator , IdAllocator , PageAllocator ,
107+ } ;
108+
108109/// Default page size for backward compatibility (4KB)
109110pub const DEFAULT_PAGE_SIZE : usize = 0x1000 ;
110111
111- /// The error type used for allocation operations.
112- ///
113- /// # Examples
114- ///
115- /// ```
116- /// use buddy_slab_allocator::AllocError;
117- ///
118- /// fn handle_error(error: AllocError) {
119- /// match error {
120- /// AllocError::InvalidParam => eprintln!("Invalid parameters"),
121- /// AllocError::MemoryOverlap => eprintln!("Memory regions overlap"),
122- /// AllocError::NoMemory => eprintln!("Out of memory"),
123- /// AllocError::NotAllocated => eprintln!("Double free detected"),
124- /// }
125- /// }
126- /// ```
127- #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
128- pub enum AllocError {
129- /// Invalid `size` or alignment (e.g. unaligned)
130- InvalidParam ,
131- /// Memory added by `add_memory` overlapped with existing memory
132- MemoryOverlap ,
133- /// No enough memory to allocate
134- NoMemory ,
135- /// Attempt to deallocate a memory region that was not allocated
136- NotAllocated ,
137- }
138-
139- /// A [`Result`] type with [`AllocError`] as the error type.
140- pub type AllocResult < T = ( ) > = Result < T , AllocError > ;
141-
142112/// Address translator used by allocators to reason about physical addresses.
143113///
144114/// Implementations should provide a stable virtual-to-physical mapping
@@ -165,243 +135,6 @@ pub trait AddrTranslator: Sync {
165135 fn virt_to_phys ( & self , va : usize ) -> Option < usize > ;
166136}
167137
168- /// The base allocator trait inherited by other allocator traits.
169- ///
170- /// Provides common initialization methods for all allocator types.
171- pub trait BaseAllocator {
172- /// Initialize the allocator with a free memory region.
173- ///
174- /// # Arguments
175- ///
176- /// * `start` - Starting address of the memory region
177- /// * `size` - Size of the memory region in bytes
178- ///
179- /// # Examples
180- ///
181- /// ```
182- /// # use buddy_slab_allocator::BaseAllocator;
183- /// # struct MyAllocator;
184- /// # impl BaseAllocator for MyAllocator {
185- /// # fn init(&mut self, start: usize, size: usize) {}
186- /// # fn add_memory(&mut self, start: usize, size: usize) -> buddy_slab_allocator::AllocResult { Ok(()) }
187- /// # }
188- /// let mut alloc = MyAllocator;
189- /// alloc.init(0x8000_0000, 16 * 1024 * 1024);
190- /// ```
191- fn init ( & mut self , start : usize , size : usize ) ;
192-
193- /// Add a free memory region to the allocator.
194- ///
195- /// # Arguments
196- ///
197- /// * `start` - Starting address of the memory region
198- /// * `size` - Size of the memory region in bytes
199- ///
200- /// # Returns
201- ///
202- /// Returns `Ok(())` on success, or an error if the region overlaps
203- /// with existing memory.
204- fn add_memory ( & mut self , start : usize , size : usize ) -> AllocResult ;
205- }
206-
207- /// Byte-granularity allocator for arbitrary-size allocations.
208- ///
209- /// Provides methods for allocating and deallocating memory with
210- /// byte-level granularity.
211- pub trait ByteAllocator {
212- /// Allocate memory with the given size (in bytes) and alignment.
213- ///
214- /// # Arguments
215- ///
216- /// * `layout` - Memory layout specifying size and alignment requirements
217- ///
218- /// # Returns
219- ///
220- /// Returns a pointer to the allocated memory on success, or an error
221- /// if allocation fails.
222- ///
223- /// # Examples
224- ///
225- /// ```
226- /// # use buddy_slab_allocator::ByteAllocator;
227- /// # use core::alloc::Layout;
228- /// # use core::ptr::NonNull;
229- /// # struct MyAllocator;
230- /// # impl ByteAllocator for MyAllocator {
231- /// # fn alloc(&mut self, layout: Layout) -> buddy_slab_allocator::AllocResult<NonNull<u8>> { Ok(NonNull::dangling()) }
232- /// # fn dealloc(&mut self, pos: NonNull<u8>, layout: Layout) {}
233- /// # fn total_bytes(&self) -> usize { 0 }
234- /// # fn used_bytes(&self) -> usize { 0 }
235- /// # fn available_bytes(&self) -> usize { 0 }
236- /// # }
237- /// let mut alloc = MyAllocator;
238- /// let layout = Layout::from_size_align(64, 8).unwrap();
239- /// let ptr = alloc.alloc(layout)?;
240- /// # Ok::<(), buddy_slab_allocator::AllocError>(())
241- /// ```
242- fn alloc ( & mut self , layout : Layout ) -> AllocResult < NonNull < u8 > > ;
243-
244- /// Deallocate memory at the given position, size, and alignment.
245- ///
246- /// # Arguments
247- ///
248- /// * `pos` - Pointer to the memory to deallocate
249- /// * `layout` - Memory layout specifying size and alignment requirements
250- ///
251- /// # Safety
252- ///
253- /// The pointer must have been previously allocated from this allocator
254- /// with the same layout.
255- fn dealloc ( & mut self , pos : NonNull < u8 > , layout : Layout ) ;
256-
257- /// Returns total memory size in bytes managed by this allocator.
258- fn total_bytes ( & self ) -> usize ;
259-
260- /// Returns allocated memory size in bytes.
261- fn used_bytes ( & self ) -> usize ;
262-
263- /// Returns available memory size in bytes.
264- fn available_bytes ( & self ) -> usize ;
265- }
266-
267- /// Page-granularity allocator for managing memory in pages.
268- ///
269- /// Provides methods for allocating and deallocating contiguous pages
270- /// of memory with specific alignment requirements.
271- pub trait PageAllocator : BaseAllocator {
272- /// The size of a memory page in bytes (must be a power of two).
273- const PAGE_SIZE : usize ;
274-
275- /// Allocate contiguous memory pages with given count and alignment (in bytes).
276- ///
277- /// # Arguments
278- ///
279- /// * `num_pages` - Number of pages to allocate
280- /// * `alignment` - Alignment requirement in bytes (must be power of two)
281- ///
282- /// # Returns
283- ///
284- /// Returns the starting address of the allocated pages on success,
285- /// or an error if allocation fails.
286- ///
287- /// # Examples
288- ///
289- /// ```
290- /// # use buddy_slab_allocator::{PageAllocator, BaseAllocator};
291- /// # struct MyAllocator;
292- /// # impl BaseAllocator for MyAllocator {
293- /// # fn init(&mut self, start: usize, size: usize) {}
294- /// # fn add_memory(&mut self, start: usize, size: usize) -> buddy_slab_allocator::AllocResult { Ok(()) }
295- /// # }
296- /// # impl PageAllocator for MyAllocator {
297- /// # const PAGE_SIZE: usize = 0x1000;
298- /// # fn alloc_pages(&mut self, num_pages: usize, alignment: usize) -> buddy_slab_allocator::AllocResult<usize> { Ok(0) }
299- /// # fn dealloc_pages(&mut self, pos: usize, num_pages: usize) {}
300- /// # fn alloc_pages_at(&mut self, base: usize, num_pages: usize, alignment: usize) -> buddy_slab_allocator::AllocResult<usize> { Ok(0) }
301- /// # fn total_pages(&self) -> usize { 0 }
302- /// # fn used_pages(&self) -> usize { 0 }
303- /// # fn available_pages(&self) -> usize { 0 }
304- /// # }
305- /// let mut alloc = MyAllocator;
306- /// let addr = alloc.alloc_pages(4, 0x1000)?;
307- /// # Ok::<(), buddy_slab_allocator::AllocError>(())
308- /// ```
309- fn alloc_pages ( & mut self , num_pages : usize , alignment : usize ) -> AllocResult < usize > ;
310-
311- /// Deallocate contiguous memory pages with given position and count.
312- ///
313- /// # Arguments
314- ///
315- /// * `pos` - Starting address of the pages to deallocate
316- /// * `num_pages` - Number of pages to deallocate
317- ///
318- /// # Safety
319- ///
320- /// The address range must have been previously allocated from this allocator.
321- fn dealloc_pages ( & mut self , pos : usize , num_pages : usize ) ;
322-
323- /// Allocate contiguous memory pages with given base address, count and alignment (in bytes).
324- ///
325- /// # Arguments
326- ///
327- /// * `base` - Desired starting address for allocation
328- /// * `num_pages` - Number of pages to allocate
329- /// * `alignment` - Alignment requirement in bytes (must be power of two)
330- ///
331- /// # Returns
332- ///
333- /// Returns the starting address of the allocated pages on success,
334- /// or an error if the region cannot be allocated at the specified base.
335- fn alloc_pages_at (
336- & mut self ,
337- base : usize ,
338- num_pages : usize ,
339- alignment : usize ,
340- ) -> AllocResult < usize > ;
341-
342- /// Returns the total number of memory pages managed by this allocator.
343- fn total_pages ( & self ) -> usize ;
344-
345- /// Returns the number of allocated memory pages.
346- fn used_pages ( & self ) -> usize ;
347-
348- /// Returns the number of available memory pages.
349- fn available_pages ( & self ) -> usize ;
350- }
351-
352- /// ID allocator for managing unique identifiers (e.g., thread IDs).
353- ///
354- /// Provides methods for allocating and deallocating unique IDs with
355- /// alignment constraints.
356- pub trait IdAllocator : BaseAllocator {
357- /// Allocate contiguous IDs with given count and alignment.
358- ///
359- /// # Arguments
360- ///
361- /// * `count` - Number of IDs to allocate
362- /// * `alignment` - Alignment requirement for the starting ID
363- ///
364- /// # Returns
365- ///
366- /// Returns the starting ID on success, or an error if allocation fails.
367- fn alloc_id ( & mut self , count : usize , alignment : usize ) -> AllocResult < usize > ;
368-
369- /// Deallocate contiguous IDs with given position and count.
370- ///
371- /// # Arguments
372- ///
373- /// * `start_id` - Starting ID of the range to deallocate
374- /// * `count` - Number of IDs to deallocate
375- ///
376- /// # Safety
377- ///
378- /// The ID range must have been previously allocated from this allocator.
379- fn dealloc_id ( & mut self , start_id : usize , count : usize ) ;
380-
381- /// Checks whether the given ID is currently allocated.
382- fn is_allocated ( & self , id : usize ) -> bool ;
383-
384- /// Mark the given ID as allocated and prevent it from being reallocated.
385- ///
386- /// # Arguments
387- ///
388- /// * `id` - The ID to mark as permanently allocated
389- ///
390- /// # Returns
391- ///
392- /// Returns `Ok(())` on success, or an error if the ID is already allocated.
393- fn alloc_fixed_id ( & mut self , id : usize ) -> AllocResult ;
394-
395- /// Returns the maximum number of IDs supported by this allocator.
396- fn size ( & self ) -> usize ;
397-
398- /// Returns the number of currently allocated IDs.
399- fn used ( & self ) -> usize ;
400-
401- /// Returns the number of available IDs.
402- fn available ( & self ) -> usize ;
403- }
404-
405138#[ inline]
406139#[ allow( dead_code) ]
407140const fn align_down ( pos : usize , align : usize ) -> usize {
0 commit comments