Skip to content

Commit a71d6cb

Browse files
committed
Merge pull request #1 from phil-opp/fix-too-small-holes
Increase front_padding to min_size instead of skipping the whole hole
2 parents fcb9b61 + 560873d commit a71d6cb

File tree

3 files changed

+27
-20
lines changed

3 files changed

+27
-20
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "linked_list_allocator"
3-
version = "0.2.1"
3+
version = "0.2.2"
44
authors = ["Philipp Oppermann <[email protected]>"]
55
license = "Apache-2.0/MIT"
66

src/hole.rs

Lines changed: 15 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -130,32 +130,29 @@ struct Allocation {
130130
/// padding occurs if the required size is smaller than the size of the aligned hole. All padding
131131
/// must be at least `HoleList::min_size()` big or the hole is unusable.
132132
fn split_hole(hole: HoleInfo, required_size: usize, required_align: usize) -> Option<Allocation> {
133+
let (aligned_addr, front_padding) = if hole.addr == align_up(hole.addr, required_align) {
134+
// hole has already the required alignment
135+
(hole.addr, None)
136+
} else {
137+
// the required alignment causes some padding before the allocation
138+
let aligned_addr = align_up(hole.addr + HoleList::min_size(), required_align);
139+
(aligned_addr, Some(HoleInfo {
140+
addr: hole.addr,
141+
size: aligned_addr - hole.addr,
142+
}))
143+
};
144+
133145
let aligned_hole = {
134-
let aligned_hole_addr = align_up(hole.addr, required_align);
135-
if aligned_hole_addr + required_size > hole.addr + hole.size {
146+
if aligned_addr + required_size > hole.addr + hole.size {
136147
// hole is too small
137148
return None;
138149
}
139150
HoleInfo {
140-
addr: aligned_hole_addr,
141-
size: hole.size - (aligned_hole_addr - hole.addr),
151+
addr: aligned_addr,
152+
size: hole.size - (aligned_addr - hole.addr),
142153
}
143154
};
144155

145-
let front_padding = if aligned_hole.addr == hole.addr {
146-
// hole has already the required alignment
147-
None
148-
} else if aligned_hole.addr < hole.addr + HoleList::min_size() {
149-
// we can't use this hole because the required padding would create a new, too small hole
150-
return None;
151-
} else {
152-
// the required alignment causes some padding before the allocation
153-
Some(HoleInfo {
154-
addr: hole.addr,
155-
size: aligned_hole.addr - hole.addr,
156-
})
157-
};
158-
159156
let back_padding = if aligned_hole.size == required_size {
160157
// the aligned hole has exactly the size that's needed, no padding accrues
161158
None

src/test.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ fn allocate_usize() {
171171
assert!(heap.allocate_first_fit(size_of::<usize>(), 1).is_some());
172172
}
173173

174-
175174
#[test]
176175
fn allocate_usize_in_bigger_block() {
177176
let mut heap = new_heap();
@@ -192,3 +191,14 @@ fn allocate_usize_in_bigger_block() {
192191
heap.deallocate(z, size_of::<usize>(), 1);
193192
}
194193
}
194+
195+
#[test]
196+
// see https://github.com/phil-opp/blog_os/issues/160
197+
fn align_from_small_to_big() {
198+
let mut heap = new_heap();
199+
200+
// allocate 28 bytes so that the heap end is only 4 byte aligned
201+
assert!(heap.allocate_first_fit(28, 4).is_some());
202+
// try to allocate a 8 byte aligned block
203+
assert!(heap.allocate_first_fit(8, 8).is_some());
204+
}

0 commit comments

Comments
 (0)