haz_alloc_core/backend.rs
1use core::cell::Cell;
2use core::ptr;
3
4pub struct TlsCallback {
5 pub func: Cell<Option<fn()>>,
6 pub next: Cell<*const TlsCallback>,
7}
8
9impl TlsCallback {
10 pub const fn new() -> Self {
11 Self {
12 func: Cell::new(None),
13 next: Cell::new(ptr::null()),
14 }
15 }
16}
17
18/// This trait contains external functions that are provided by the user
19/// in order for the library to perform system actions such as
20/// page allocation.
21///
22/// # Safety
23///
24/// The implementation must make sure the functions in the trait behave
25/// properly.
26pub unsafe trait Backend {
27 type Mutex: Mutex;
28
29 /// Reserve the block of memory starting at `ptr` if `ptr` is not null and
30 /// with `size`.
31 ///
32 /// If `ptr` is null, the block of memory can start at an offset determined
33 /// by the system.
34 ///
35 /// If the function fails null is returned.
36 fn mreserve(ptr: *mut u8, size: usize) -> *mut u8;
37
38 /// Commit memory starting at `ptr` with size `size`.
39 ///
40 /// If the function fails null is returned.
41 ///
42 /// # Safety
43 ///
44 /// The memory must be reserved.
45 unsafe fn mcommit(ptr: *mut u8, size: usize) -> bool;
46
47 /// Decommit memory starting at `ptr` with size `size`.
48 ///
49 /// # Safety
50 ///
51 /// The memory must be commited.
52 unsafe fn mdecommit(ptr: *mut u8, size: usize);
53
54 /// Unreserve memory starting at `ptr` with size `size`.
55 ///
56 /// # Safety
57 ///
58 /// The memory must be reserved.
59 ///
60 /// The size must be equals to the same size used for reserving.
61 unsafe fn munreserve(ptr: *mut u8, size: usize);
62
63 /// Returns the page size.
64 ///
65 /// It is a good idea to cache before returning.
66 fn pagesize() -> usize;
67
68 /// Attach the given callback to this thread, running it when the thread
69 /// is destroyed.
70 ///
71 /// # Safety
72 ///
73 /// The callback must be #[thread_local].
74 unsafe fn tls_attach(callback: *const TlsCallback);
75}
76
77/// # Safety
78///
79/// The implementation must make sure the functions in the trait behave
80/// properly.
81pub unsafe trait Mutex: 'static + Sync + Send {
82 type Guard<'a>;
83
84 /// Creates a mutex.
85 ///
86 /// # Safety
87 ///
88 /// The mutex must not be moved until dropped.
89 /// The mutex must not be initialized.
90 unsafe fn new(ptr: *mut Self);
91
92 /// Lock a mutex.
93 ///
94 /// # Safety
95 ///
96 /// The mutex must not be moved until dropped.
97 /// The mutex must be initialized.
98 #[must_use]
99 unsafe fn lock(&self) -> Self::Guard<'_>;
100}