Skip to content

Commit 598cd61

Browse files
committed
add used() API to AddressAllocator
Signed-off-by: ylzh10 <[email protected]>
1 parent 6d540b7 commit 598cd61

File tree

2 files changed

+40
-3
lines changed

2 files changed

+40
-3
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
## Upcoming version
44

55
### Added
6+
7+
- Added `used()` API in `AddressAllocator` to allow
8+
getting the used memories after `allocate/free()`s
9+
610
### Changed
711
### Fixed
812
### Removed

src/address_allocator.rs

Lines changed: 36 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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

3436
impl 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

Comments
 (0)