@@ -5,11 +5,27 @@ use core::alloc::{GlobalAlloc, Layout};
5
5
use core:: cell:: RefCell ;
6
6
use core:: ptr:: { self , NonNull } ;
7
7
8
+ #[ cfg( feature = "tlsf" ) ]
9
+ use const_default:: ConstDefault ;
8
10
use critical_section:: Mutex ;
11
+
12
+ // Exactly one of these features must be enabled: "llff" or "tlsf"
13
+ #[ cfg( all( feature = "tlsf" , feature = "llff" ) ) ]
14
+ compile_error ! ( "You can't enable both 'tlsf' and 'llff' features simultaneously. Choose one allocator." ) ;
15
+
16
+ #[ cfg( feature = "llff" ) ]
9
17
use linked_list_allocator:: Heap as LLHeap ;
18
+ #[ cfg( feature = "tlsf" ) ]
19
+ use rlsf:: Tlsf ;
20
+
21
+ #[ cfg( feature = "tlsf" ) ]
22
+ type TlsfHeap = Tlsf < ' static , usize , usize , { usize:: BITS as usize } , { usize:: BITS as usize } > ;
10
23
11
24
pub struct Heap {
25
+ #[ cfg( feature = "llff" ) ]
12
26
heap : Mutex < RefCell < LLHeap > > ,
27
+ #[ cfg( feature = "tlsf" ) ]
28
+ heap : Mutex < RefCell < TlsfHeap > > ,
13
29
}
14
30
15
31
impl Heap {
@@ -19,7 +35,10 @@ impl Heap {
19
35
/// [`init`](Self::init) method before using the allocator.
20
36
pub const fn empty ( ) -> Heap {
21
37
Heap {
38
+ #[ cfg( feature = "llff" ) ]
22
39
heap : Mutex :: new ( RefCell :: new ( LLHeap :: empty ( ) ) ) ,
40
+ #[ cfg( feature = "tlsf" ) ]
41
+ heap : Mutex :: new ( RefCell :: new ( ConstDefault :: DEFAULT ) ) ,
23
42
}
24
43
}
25
44
@@ -49,19 +68,32 @@ impl Heap {
49
68
/// - `size > 0`
50
69
pub unsafe fn init ( & self , start_addr : usize , size : usize ) {
51
70
critical_section:: with ( |cs| {
52
- self . heap
53
- . borrow ( cs)
54
- . borrow_mut ( )
55
- . init ( start_addr as * mut u8 , size) ;
71
+ #[ cfg( feature = "llff" ) ]
72
+ {
73
+ self . heap
74
+ . borrow ( cs)
75
+ . borrow_mut ( )
76
+ . init ( start_addr as * mut u8 , size) ;
77
+ }
78
+ #[ cfg( feature = "tlsf" ) ]
79
+ {
80
+ let block: & [ u8 ] = core:: slice:: from_raw_parts ( start_addr as * const u8 , size) ;
81
+ self . heap
82
+ . borrow ( cs)
83
+ . borrow_mut ( )
84
+ . insert_free_block_ptr ( block. into ( ) ) ;
85
+ }
56
86
} ) ;
57
87
}
58
88
59
89
/// Returns an estimate of the amount of bytes in use.
90
+ #[ cfg( feature = "llff" ) ]
60
91
pub fn used ( & self ) -> usize {
61
92
critical_section:: with ( |cs| self . heap . borrow ( cs) . borrow_mut ( ) . used ( ) )
62
93
}
63
94
64
95
/// Returns an estimate of the amount of bytes available.
96
+ #[ cfg( feature = "llff" ) ]
65
97
pub fn free ( & self ) -> usize {
66
98
critical_section:: with ( |cs| self . heap . borrow ( cs) . borrow_mut ( ) . free ( ) )
67
99
}
@@ -70,21 +102,42 @@ impl Heap {
70
102
unsafe impl GlobalAlloc for Heap {
71
103
unsafe fn alloc ( & self , layout : Layout ) -> * mut u8 {
72
104
critical_section:: with ( |cs| {
73
- self . heap
74
- . borrow ( cs)
75
- . borrow_mut ( )
76
- . allocate_first_fit ( layout)
77
- . ok ( )
78
- . map_or ( ptr:: null_mut ( ) , |allocation| allocation. as_ptr ( ) )
105
+ #[ cfg( feature = "llff" ) ]
106
+ {
107
+ self . heap
108
+ . borrow ( cs)
109
+ . borrow_mut ( )
110
+ . allocate_first_fit ( layout)
111
+ . ok ( )
112
+ . map_or ( ptr:: null_mut ( ) , |allocation| allocation. as_ptr ( ) )
113
+ }
114
+ #[ cfg( feature = "tlsf" ) ]
115
+ {
116
+ self . heap
117
+ . borrow ( cs)
118
+ . borrow_mut ( )
119
+ . allocate ( layout)
120
+ . map_or ( ptr:: null_mut ( ) , |allocation| allocation. as_ptr ( ) )
121
+ }
79
122
} )
80
123
}
81
124
82
125
unsafe fn dealloc ( & self , ptr : * mut u8 , layout : Layout ) {
83
126
critical_section:: with ( |cs| {
84
- self . heap
85
- . borrow ( cs)
86
- . borrow_mut ( )
87
- . deallocate ( NonNull :: new_unchecked ( ptr) , layout)
127
+ #[ cfg( feature = "llff" ) ]
128
+ {
129
+ self . heap
130
+ . borrow ( cs)
131
+ . borrow_mut ( )
132
+ . deallocate ( NonNull :: new_unchecked ( ptr) , layout)
133
+ }
134
+ #[ cfg( feature = "tlsf" ) ]
135
+ {
136
+ self . heap
137
+ . borrow ( cs)
138
+ . borrow_mut ( )
139
+ . deallocate ( NonNull :: new_unchecked ( ptr) , layout. align ( ) )
140
+ }
88
141
} ) ;
89
142
}
90
143
}
0 commit comments