1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//! # The Allocation Bridge: System Integration Hooks
//!
//! This module defines the "Pluggable" foundation of the entire slab allocator.
//!
//! ## The Problem: Where does the memory come from?
//! The `Slab` and `SlabCache` modules know how to *divide* memory into slots, but they
//! do not know how to *acquire* the raw blocks (slabs) from the operating system or hardware.
//!
//! ## The Solution: The Linker Contract
//! This file uses `extern "Rust"` blocks to declare two specific functions:
//! 1. `__attachable_slab_allocator_slab_allocation_func`
//! 2. `__attachable_slab_allocator_slab_free_func`
//!
//! These are **Required Symbols**. If you try to use this crate without defining these
//! functions, the compiler's **linker will fail** with an "undefined reference" error.
//! This ensures that you, the user, explicitly choose how raw memory is sourced.
//!
//! ## Using the Hooks
//! To "plug in" your allocator (e.g., `dlmalloc`, `buddy_allocator`, or even `std::alloc`),
//! you must use the [`define_allocation_hooks!`] macro exactly once in your project.
//!
//! ### Example: Connecting to the Rust Standard Heap
//! ```ignore
//! use std::alloc::{alloc, dealloc, Layout};
//! use core::ptr::NonNull;
//! use my_slab_crate::{define_allocation_hooks, Result};
//!
//! // 1. Define your raw allocation functions
//! unsafe fn my_alloc(layout: Layout) -> Option<NonNull<u8>> {
//! let ptr = unsafe { alloc(layout) };
//! NonNull::new(ptr)
//! }
//!
//! unsafe fn my_free(ptr: NonNull<u8>, layout: Layout) -> Result<()> {
//! unsafe { dealloc(ptr.as_ptr(), layout) };
//! Ok(())
//! }
//!
//! // 2. Register them globally using the macro
//! define_allocation_hooks!(my_alloc, my_free);
//! ```
use crateResult;
use ;
// External symbols that MUST be provided by the user at link-time.
//
// These are declared as `unsafe extern "Rust"` to allow for seamless integration
// with other Rust modules without C-style ABI overhead.
unsafe extern "Rust"
/// Internal wrapper to call the system allocation hook.
///
/// This is used by `Slab::alloc_slab_ptr` when the cache needs to grow.
/// Internal wrapper to call the system deallocation hook.
///
/// This is used when a Master or Slave slab is fully empty and being retired.
/// The primary macro used to satisfy the allocator's linker requirements.
///
/// This macro defines the specific symbols the crate expects.
///
/// # Arguments
/// * `$alloc`: A function or path with signature `unsafe fn(Layout) -> Option<NonNull<u8>>`
/// * `$free`: A function or path with signature `unsafe fn(NonNull<u8>, Layout) -> Result<()>`
///
/// # Safety
/// The functions provided to this macro must correctly handle the `Layout` alignment
/// requirements. Slabs are typically page-aligned; your provided allocator must respect
/// the `layout.align()` property.