1
1
use core:: alloc:: { GlobalAlloc , Layout } ;
2
- use core:: cell:: RefCell ;
2
+ use core:: cell:: { OnceCell , RefCell } ;
3
3
use core:: ptr:: { self , NonNull } ;
4
4
5
5
use critical_section:: Mutex ;
6
6
use linked_list_allocator:: Heap as LLHeap ;
7
7
8
8
/// A linked list first fit heap.
9
9
pub struct Heap {
10
- heap : Mutex < RefCell < LLHeap > > ,
10
+ heap : Mutex < RefCell < OnceCell < LLHeap > > > ,
11
11
}
12
12
13
13
impl Heap {
@@ -17,7 +17,7 @@ impl Heap {
17
17
/// [`init`](Self::init) method before using the allocator.
18
18
pub const fn empty ( ) -> Heap {
19
19
Heap {
20
- heap : Mutex :: new ( RefCell :: new ( LLHeap :: empty ( ) ) ) ,
20
+ heap : Mutex :: new ( RefCell :: new ( OnceCell :: new ( ) ) ) ,
21
21
}
22
22
}
23
23
@@ -39,36 +39,36 @@ impl Heap {
39
39
/// `0x1000` and `size` is `0x30000` then the allocator won't use memory at
40
40
/// addresses `0x31000` and larger.
41
41
///
42
- /// # Safety
42
+ /// # Panics
43
43
///
44
- /// Obey these or Bad Stuff will happen.
45
- ///
46
- /// - This function must be called exactly ONCE.
47
- /// - `size > 0`
44
+ /// Calling this function multiple times or with `size == 0` will cause a panic.
48
45
pub unsafe fn init ( & self , start_addr : usize , size : usize ) {
46
+ assert ! ( size > 0 ) ;
49
47
critical_section:: with ( |cs| {
50
- self . heap
51
- . borrow ( cs)
52
- . borrow_mut ( )
53
- . init ( start_addr as * mut u8 , size) ;
48
+ assert ! ( self
49
+ . heap
50
+ . borrow_ref_mut( cs)
51
+ . set( LLHeap :: new( start_addr as * mut u8 , size) )
52
+ . is_ok( ) ) ;
54
53
} ) ;
55
54
}
56
55
57
56
/// Returns an estimate of the amount of bytes in use.
58
57
pub fn used ( & self ) -> usize {
59
- critical_section:: with ( |cs| self . heap . borrow ( cs) . borrow_mut ( ) . used ( ) )
58
+ critical_section:: with ( |cs| self . heap . borrow_ref_mut ( cs) . get_mut ( ) . unwrap ( ) . used ( ) )
60
59
}
61
60
62
61
/// Returns an estimate of the amount of bytes available.
63
62
pub fn free ( & self ) -> usize {
64
- critical_section:: with ( |cs| self . heap . borrow ( cs) . borrow_mut ( ) . free ( ) )
63
+ critical_section:: with ( |cs| self . heap . borrow_ref_mut ( cs) . get_mut ( ) . unwrap ( ) . free ( ) )
65
64
}
66
65
67
66
fn alloc ( & self , layout : Layout ) -> Option < NonNull < u8 > > {
68
67
critical_section:: with ( |cs| {
69
68
self . heap
70
- . borrow ( cs)
71
- . borrow_mut ( )
69
+ . borrow_ref_mut ( cs)
70
+ . get_mut ( )
71
+ . unwrap ( )
72
72
. allocate_first_fit ( layout)
73
73
. ok ( )
74
74
} )
@@ -77,8 +77,9 @@ impl Heap {
77
77
unsafe fn dealloc ( & self , ptr : * mut u8 , layout : Layout ) {
78
78
critical_section:: with ( |cs| {
79
79
self . heap
80
- . borrow ( cs)
81
- . borrow_mut ( )
80
+ . borrow_ref_mut ( cs)
81
+ . get_mut ( )
82
+ . unwrap ( )
82
83
. deallocate ( NonNull :: new_unchecked ( ptr) , layout)
83
84
} ) ;
84
85
}
0 commit comments