@@ -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+ // Available memory space
33+ available : 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+ available : aux_range. len ( ) as usize ,
4649 } )
4750 }
4851
@@ -63,13 +66,22 @@ 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 . available -= allocated. len ( ) as usize ;
71+ Ok ( allocated)
6772 }
6873
6974 /// Deletes the specified memory slot or returns `ResourceNotAvailable` if
7075 /// the node was not allocated before.
7176 pub fn free ( & mut self , key : & RangeInclusive ) -> Result < ( ) > {
72- self . interval_tree . free ( key)
77+ self . interval_tree . free ( key) ?;
78+ self . available += key. len ( ) as usize ;
79+ Ok ( ( ) )
80+ }
81+
82+ /// Returns the available memory size in this allocator.
83+ pub fn available ( & self ) -> usize {
84+ self . available
7385 }
7486}
7587
@@ -158,20 +170,27 @@ mod tests {
158170 #[ test]
159171 fn test_allocate_with_alignment_first_ok ( ) {
160172 let mut pool = AddressAllocator :: new ( 0x1000 , 0x1000 ) . unwrap ( ) ;
173+ assert_eq ! ( pool. available( ) , 0x1000 ) ;
174+ // Allocate 0x110
161175 assert_eq ! (
162176 pool. allocate( 0x110 , 0x100 , AllocPolicy :: FirstMatch )
163177 . unwrap( ) ,
164178 RangeInclusive :: new( 0x1000 , 0x110F ) . unwrap( )
165179 ) ;
180+ assert_eq ! ( pool. available( ) , 0x1000 - 0x110 ) ;
181+ // Allocate 0x100
166182 assert_eq ! (
167183 pool. allocate( 0x100 , 0x100 , AllocPolicy :: FirstMatch )
168184 . unwrap( ) ,
169185 RangeInclusive :: new( 0x1200 , 0x12FF ) . unwrap( )
170186 ) ;
187+ assert_eq ! ( pool. available( ) , 0x1000 - 0x110 - 0x100 ) ;
188+ // Allocate 0x10
171189 assert_eq ! (
172190 pool. allocate( 0x10 , 0x100 , AllocPolicy :: FirstMatch ) . unwrap( ) ,
173191 RangeInclusive :: new( 0x1300 , 0x130F ) . unwrap( )
174192 ) ;
193+ assert_eq ! ( pool. available( ) , 0x1000 - 0x110 - 0x100 - 0x10 ) ;
175194 }
176195
177196 #[ test]
@@ -230,18 +249,24 @@ mod tests {
230249 #[ test]
231250 fn test_tree_allocate_address_free_and_realloc ( ) {
232251 let mut pool = AddressAllocator :: new ( 0x1000 , 0x1000 ) . unwrap ( ) ;
252+ assert_eq ! ( pool. available( ) , 0x1000 ) ;
253+ // Allocate 0x800
233254 assert_eq ! (
234255 pool. allocate( 0x800 , 0x100 , AllocPolicy :: FirstMatch )
235256 . unwrap( ) ,
236257 RangeInclusive :: new( 0x1000 , 0x17FF ) . unwrap( )
237258 ) ;
238-
259+ assert_eq ! ( pool. available( ) , 0x1000 - 0x800 ) ;
260+ // Free 0x800
239261 let _ = pool. free ( & RangeInclusive :: new ( 0x1000 , 0x17FF ) . unwrap ( ) ) ;
262+ assert_eq ! ( pool. available( ) , 0x1000 ) ;
263+ // Allocate 0x800 again
240264 assert_eq ! (
241265 pool. allocate( 0x800 , 0x100 , AllocPolicy :: FirstMatch )
242266 . unwrap( ) ,
243267 RangeInclusive :: new( 0x1000 , 0x17FF ) . unwrap( )
244268 ) ;
269+ assert_eq ! ( pool. available( ) , 0x1000 - 0x800 ) ;
245270 }
246271
247272 #[ test]
0 commit comments