sel4_root_task/
heap.rs

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
//
// Copyright 2023, Colias Group, LLC
//
// SPDX-License-Identifier: BSD-2-Clause
//

use sel4_immediate_sync_once_cell::ImmediateSyncOnceCell;
use sel4_panicking_env::abort;

static GLOBAL_ALLOCATOR_MUTEX_NOTIFICATION: ImmediateSyncOnceCell<sel4::cap::Notification> =
    ImmediateSyncOnceCell::new();

/// Provides the global allocator with a [`sel4::cap::Notification`] to use as a mutex..
///
/// Until this function is used, contention in the global allocator will result in a panic. This is
/// only useful for multi-threaded root tasks.
pub fn set_global_allocator_mutex_notification(nfn: sel4::cap::Notification) {
    GLOBAL_ALLOCATOR_MUTEX_NOTIFICATION
        .set(nfn)
        .unwrap_or_else(|_| abort!("global allocator mutex notification already initialized"))
}

#[doc(hidden)]
pub fn get_global_allocator_mutex_notification() -> sel4::cap::Notification {
    *GLOBAL_ALLOCATOR_MUTEX_NOTIFICATION
        .get()
        .unwrap_or_else(|| {
            abort!("global allocator contention before mutex notification initialization")
        })
}

#[doc(hidden)]
#[macro_export]
macro_rules! declare_heap {
    ($size:expr) => {
        const _: () = {
            mod outer_scope {
                use super::*;

                const _SIZE: usize = $size;

                mod inner_scope {
                    use $crate::_private::heap::*;

                    use super::_SIZE as SIZE;

                    static STATIC_HEAP: StaticHeap<{ SIZE }> = StaticHeap::new();

                    #[global_allocator]
                    static GLOBAL_ALLOCATOR: StaticDlmallocGlobalAlloc<
                        GenericRawMutex<fn() -> sel4::cap::Notification>,
                        &'static StaticHeap<{ SIZE }>,
                    > = StaticDlmallocGlobalAlloc::new(
                        GenericRawMutex::new(get_global_allocator_mutex_notification),
                        &STATIC_HEAP,
                    );
                }
            }
        };
    };
}

pub mod _private {
    pub use sel4_dlmalloc::{StaticDlmallocGlobalAlloc, StaticHeap};
    pub use sel4_sync::GenericRawMutex;

    pub use super::get_global_allocator_mutex_notification;
}