Skip to content

Commit e5831c6

Browse files
authored
Merge pull request #22 from qwandor/size
Allow max order of FrameAllocator to be specified by const generic.
2 parents 434e857 + a545edf commit e5831c6

File tree

2 files changed

+40
-21
lines changed

2 files changed

+40
-21
lines changed

src/frame.rs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use super::prev_power_of_two;
22
use alloc::collections::BTreeSet;
3+
use core::array;
34
use core::cmp::min;
45
use core::ops::Range;
56

@@ -8,15 +9,18 @@ use core::ops::Deref;
89
#[cfg(feature = "use_spin")]
910
use spin::Mutex;
1011

11-
/// A frame allocator that uses buddy system,
12-
/// requiring a global allocator
12+
/// A frame allocator that uses buddy system, requiring a global allocator.
13+
///
14+
/// The max order of the allocator is specified via the const generic parameter `ORDER`. The frame
15+
/// allocator will only be able to allocate ranges of size up to 2<sup>ORDER</sup>, out of a total
16+
/// range of size at most 2<sup>ORDER + 1</sup> - 1.
1317
///
1418
/// # Usage
1519
///
1620
/// Create a frame allocator and add some frames to it:
1721
/// ```
1822
/// use buddy_system_allocator::*;
19-
/// let mut frame = FrameAllocator::new();
23+
/// let mut frame = FrameAllocator::<32>::new();
2024
/// assert!(frame.alloc(1).is_none());
2125
///
2226
/// frame.add_frame(0, 3);
@@ -25,20 +29,20 @@ use spin::Mutex;
2529
/// let num = frame.alloc(2);
2630
/// assert_eq!(num, Some(0));
2731
/// ```
28-
pub struct FrameAllocator {
29-
// buddy system with max order of 32
30-
free_list: [BTreeSet<usize>; 32],
32+
pub struct FrameAllocator<const ORDER: usize = 32> {
33+
// buddy system with max order of ORDER
34+
free_list: [BTreeSet<usize>; ORDER],
3135

3236
// statistics
3337
allocated: usize,
3438
total: usize,
3539
}
3640

37-
impl FrameAllocator {
41+
impl<const ORDER: usize> FrameAllocator<ORDER> {
3842
/// Create an empty frame allocator
3943
pub fn new() -> Self {
40-
FrameAllocator {
41-
free_list: Default::default(),
44+
Self {
45+
free_list: array::from_fn(|_| BTreeSet::default()),
4246
allocated: 0,
4347
total: 0,
4448
}
@@ -137,7 +141,7 @@ impl FrameAllocator {
137141
/// Create a locked frame allocator and add frames to it:
138142
/// ```
139143
/// use buddy_system_allocator::*;
140-
/// let mut frame = LockedFrameAllocator::new();
144+
/// let mut frame = LockedFrameAllocator::<32>::new();
141145
/// assert!(frame.lock().alloc(1).is_none());
142146
///
143147
/// frame.lock().add_frame(0, 3);
@@ -147,21 +151,21 @@ impl FrameAllocator {
147151
/// assert_eq!(num, Some(0));
148152
/// ```
149153
#[cfg(feature = "use_spin")]
150-
pub struct LockedFrameAllocator(Mutex<FrameAllocator>);
154+
pub struct LockedFrameAllocator<const ORDER: usize = 32>(Mutex<FrameAllocator<ORDER>>);
151155

152156
#[cfg(feature = "use_spin")]
153-
impl LockedFrameAllocator {
157+
impl<const ORDER: usize> LockedFrameAllocator<ORDER> {
154158
/// Creates an empty heap
155-
pub fn new() -> LockedFrameAllocator {
156-
LockedFrameAllocator(Mutex::new(FrameAllocator::new()))
159+
pub fn new() -> Self {
160+
Self(Mutex::new(FrameAllocator::new()))
157161
}
158162
}
159163

160164
#[cfg(feature = "use_spin")]
161-
impl Deref for LockedFrameAllocator {
162-
type Target = Mutex<FrameAllocator>;
165+
impl<const ORDER: usize> Deref for LockedFrameAllocator<ORDER> {
166+
type Target = Mutex<FrameAllocator<ORDER>>;
163167

164-
fn deref(&self) -> &Mutex<FrameAllocator> {
168+
fn deref(&self) -> &Mutex<FrameAllocator<ORDER>> {
165169
&self.0
166170
}
167171
}

src/test.rs

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -103,13 +103,13 @@ fn test_heap_alloc_and_free() {
103103

104104
#[test]
105105
fn test_empty_frame_allocator() {
106-
let mut frame = FrameAllocator::new();
106+
let mut frame = FrameAllocator::<32>::new();
107107
assert!(frame.alloc(1).is_none());
108108
}
109109

110110
#[test]
111111
fn test_frame_allocator_add() {
112-
let mut frame = FrameAllocator::new();
112+
let mut frame = FrameAllocator::<32>::new();
113113
assert!(frame.alloc(1).is_none());
114114

115115
frame.insert(0..3);
@@ -121,9 +121,24 @@ fn test_frame_allocator_add() {
121121
assert!(frame.alloc(2).is_none());
122122
}
123123

124+
#[test]
125+
#[should_panic]
126+
fn test_frame_allocator_add_large_size_panics() {
127+
let mut frame = FrameAllocator::<32>::new();
128+
129+
frame.insert(0..10_000_000_000);
130+
}
131+
132+
#[test]
133+
fn test_frame_allocator_add_large_size() {
134+
let mut frame = FrameAllocator::<33>::new();
135+
136+
frame.insert(0..10_000_000_000);
137+
}
138+
124139
#[test]
125140
fn test_frame_allocator_alloc_and_free() {
126-
let mut frame = FrameAllocator::new();
141+
let mut frame = FrameAllocator::<32>::new();
127142
assert!(frame.alloc(1).is_none());
128143

129144
frame.add_frame(0, 1024);
@@ -135,7 +150,7 @@ fn test_frame_allocator_alloc_and_free() {
135150

136151
#[test]
137152
fn test_frame_allocator_alloc_and_free_complex() {
138-
let mut frame = FrameAllocator::new();
153+
let mut frame = FrameAllocator::<32>::new();
139154
frame.add_frame(100, 1024);
140155
for _ in 0..10 {
141156
let addr = frame.alloc(1).unwrap();

0 commit comments

Comments
 (0)