@@ -29,6 +29,8 @@ pub struct AddressAllocator {
2929 // tree will represent a memory location and can have two states either
3030 // `NodeState::Free` or `NodeState::Allocated`.
3131 interval_tree : IntervalTree ,
32+ // Used memory space in the address space.
33+ used : usize ,
3234}
3335
3436impl AddressAllocator {
@@ -43,6 +45,7 @@ impl AddressAllocator {
4345 Ok ( AddressAllocator {
4446 address_space : aux_range,
4547 interval_tree : IntervalTree :: new ( aux_range) ,
48+ used : 0 ,
4649 } )
4750 }
4851
@@ -63,13 +66,30 @@ impl AddressAllocator {
6366 policy : AllocPolicy ,
6467 ) -> Result < RangeInclusive > {
6568 let constraint = Constraint :: new ( size, alignment, policy) ?;
66- self . interval_tree . allocate ( constraint)
69+ let allocated = self . interval_tree . allocate ( constraint) ?;
70+ self . used = self
71+ . used
72+ . checked_add ( allocated. len ( ) as usize )
73+ . expect ( "Failed to calculate used memory" ) ;
74+ Ok ( allocated)
6775 }
6876
6977 /// Deletes the specified memory slot or returns `ResourceNotAvailable` if
7078 /// the node was not allocated before.
7179 pub fn free ( & mut self , key : & RangeInclusive ) -> Result < ( ) > {
72- self . interval_tree . free ( key)
80+ self . interval_tree . free ( key) ?;
81+ self . used = self
82+ . used
83+ . checked_sub ( key. len ( ) as usize )
84+ . expect ( "Failed to calculate used memory" ) ;
85+ Ok ( ( ) )
86+ }
87+
88+ /// Returns the used memory size in this allocator.
89+ /// NOTE that due to fragmentations, not all unused memory may be available
90+ /// for next `allocate()` call!
91+ pub fn used ( & self ) -> usize {
92+ self . used
7393 }
7494}
7595
@@ -158,20 +178,27 @@ mod tests {
158178 #[ test]
159179 fn test_allocate_with_alignment_first_ok ( ) {
160180 let mut pool = AddressAllocator :: new ( 0x1000 , 0x1000 ) . unwrap ( ) ;
181+ assert_eq ! ( pool. used( ) , 0 ) ;
182+ // Allocate 0x110
161183 assert_eq ! (
162184 pool. allocate( 0x110 , 0x100 , AllocPolicy :: FirstMatch )
163185 . unwrap( ) ,
164186 RangeInclusive :: new( 0x1000 , 0x110F ) . unwrap( )
165187 ) ;
188+ assert_eq ! ( pool. used( ) , 0x110 ) ;
189+ // Allocate 0x100
166190 assert_eq ! (
167191 pool. allocate( 0x100 , 0x100 , AllocPolicy :: FirstMatch )
168192 . unwrap( ) ,
169193 RangeInclusive :: new( 0x1200 , 0x12FF ) . unwrap( )
170194 ) ;
195+ assert_eq ! ( pool. used( ) , 0x110 + 0x100 ) ;
196+ // Allocate 0x10
171197 assert_eq ! (
172198 pool. allocate( 0x10 , 0x100 , AllocPolicy :: FirstMatch ) . unwrap( ) ,
173199 RangeInclusive :: new( 0x1300 , 0x130F ) . unwrap( )
174200 ) ;
201+ assert_eq ! ( pool. used( ) , 0x110 + 0x100 + 0x10 ) ;
175202 }
176203
177204 #[ test]
@@ -230,18 +257,24 @@ mod tests {
230257 #[ test]
231258 fn test_tree_allocate_address_free_and_realloc ( ) {
232259 let mut pool = AddressAllocator :: new ( 0x1000 , 0x1000 ) . unwrap ( ) ;
260+ assert_eq ! ( pool. used( ) , 0 ) ;
261+ // Allocate 0x800
233262 assert_eq ! (
234263 pool. allocate( 0x800 , 0x100 , AllocPolicy :: FirstMatch )
235264 . unwrap( ) ,
236265 RangeInclusive :: new( 0x1000 , 0x17FF ) . unwrap( )
237266 ) ;
238-
267+ assert_eq ! ( pool. used( ) , 0x800 ) ;
268+ // Free 0x800
239269 let _ = pool. free ( & RangeInclusive :: new ( 0x1000 , 0x17FF ) . unwrap ( ) ) ;
270+ assert_eq ! ( pool. used( ) , 0 ) ;
271+ // Allocate 0x800 again
240272 assert_eq ! (
241273 pool. allocate( 0x800 , 0x100 , AllocPolicy :: FirstMatch )
242274 . unwrap( ) ,
243275 RangeInclusive :: new( 0x1000 , 0x17FF ) . unwrap( )
244276 ) ;
277+ assert_eq ! ( pool. used( ) , 0x800 ) ;
245278 }
246279
247280 #[ test]
0 commit comments