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
use core::cell::Cell;
use core::ptr;
pub struct TlsCallback {
pub func: Cell<Option<fn()>>,
pub next: Cell<*const TlsCallback>,
}
impl TlsCallback {
pub const fn new() -> Self {
Self {
func: Cell::new(None),
next: Cell::new(ptr::null()),
}
}
}
/// This trait contains external functions that are provided by the user
/// in order for the library to perform system actions such as
/// page allocation.
///
/// # Safety
///
/// The implementation must make sure the functions in the trait behave
/// properly.
pub unsafe trait Backend {
type Mutex: Mutex;
/// Reserve the block of memory starting at `ptr` if `ptr` is not null and
/// with `size`.
///
/// If `ptr` is null, the block of memory can start at an offset determined
/// by the system.
///
/// If the function fails null is returned.
fn mreserve(ptr: *mut u8, size: usize) -> *mut u8;
/// Commit memory starting at `ptr` with size `size`.
///
/// If the function fails null is returned.
///
/// # Safety
///
/// The memory must be reserved.
unsafe fn mcommit(ptr: *mut u8, size: usize) -> bool;
/// Decommit memory starting at `ptr` with size `size`.
///
/// # Safety
///
/// The memory must be commited.
unsafe fn mdecommit(ptr: *mut u8, size: usize);
/// Unreserve memory starting at `ptr` with size `size`.
///
/// # Safety
///
/// The memory must be reserved.
///
/// The size must be equals to the same size used for reserving.
unsafe fn munreserve(ptr: *mut u8, size: usize);
/// Returns the page size.
///
/// It is a good idea to cache before returning.
fn pagesize() -> usize;
/// Attach the given callback to this thread, running it when the thread
/// is destroyed.
///
/// # Safety
///
/// The callback must be #[thread_local].
unsafe fn tls_attach(callback: *const TlsCallback);
}
/// # Safety
///
/// The implementation must make sure the functions in the trait behave
/// properly.
pub unsafe trait Mutex: 'static + Sync + Send {
type Guard<'a>;
/// Mutex initializer.
const INIT: Self;
/// Lock a mutex.
#[must_use]
fn lock(&self) -> Self::Guard<'_>;
}