From 7bf28e8e7cf5b7d5f659d283f50193783a93fd6c Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 17 May 2016 16:09:11 +0200 Subject: [PATCH 1/3] Add failing test for phil-opp/blog_os#160 --- src/test.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/test.rs b/src/test.rs index 11a2e55..ae70e41 100644 --- a/src/test.rs +++ b/src/test.rs @@ -171,7 +171,6 @@ fn allocate_usize() { assert!(heap.allocate_first_fit(size_of::(), 1).is_some()); } - #[test] fn allocate_usize_in_bigger_block() { let mut heap = new_heap(); @@ -192,3 +191,14 @@ fn allocate_usize_in_bigger_block() { heap.deallocate(z, size_of::(), 1); } } + +#[test] +// see https://github.com/phil-opp/blog_os/issues/160 +fn align_from_small_to_big() { + let mut heap = new_heap(); + + // allocate 28 bytes so that the heap end is only 4 byte aligned + assert!(heap.allocate_first_fit(28, 4).is_some()); + // try to allocate a 8 byte aligned block + assert!(heap.allocate_first_fit(8, 8).is_some()); +} From 9add9b9fcc2a5d8c5dda12893b22146550fa758e Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 17 May 2016 16:51:36 +0200 Subject: [PATCH 2/3] Rewrite split_hole in order to fix `align_from_small_to_big` test The new code guarantees that the front padding is at least HoleList::min_size() if it's needed. The important line is: ``` let aligned_addr = align_up(hole.addr + HoleList::min_size(), required_align) ``` --- src/hole.rs | 33 +++++++++++++++------------------ 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/src/hole.rs b/src/hole.rs index 4227d21..a42bcd1 100644 --- a/src/hole.rs +++ b/src/hole.rs @@ -130,32 +130,29 @@ struct Allocation { /// padding occurs if the required size is smaller than the size of the aligned hole. All padding /// must be at least `HoleList::min_size()` big or the hole is unusable. fn split_hole(hole: HoleInfo, required_size: usize, required_align: usize) -> Option { + let (aligned_addr, front_padding) = if hole.addr == align_up(hole.addr, required_align) { + // hole has already the required alignment + (hole.addr, None) + } else { + // the required alignment causes some padding before the allocation + let aligned_addr = align_up(hole.addr + HoleList::min_size(), required_align); + (aligned_addr, Some(HoleInfo { + addr: hole.addr, + size: aligned_addr - hole.addr, + })) + }; + let aligned_hole = { - let aligned_hole_addr = align_up(hole.addr, required_align); - if aligned_hole_addr + required_size > hole.addr + hole.size { + if aligned_addr + required_size > hole.addr + hole.size { // hole is too small return None; } HoleInfo { - addr: aligned_hole_addr, - size: hole.size - (aligned_hole_addr - hole.addr), + addr: aligned_addr, + size: hole.size - (aligned_addr - hole.addr), } }; - let front_padding = if aligned_hole.addr == hole.addr { - // hole has already the required alignment - None - } else if aligned_hole.addr < hole.addr + HoleList::min_size() { - // we can't use this hole because the required padding would create a new, too small hole - return None; - } else { - // the required alignment causes some padding before the allocation - Some(HoleInfo { - addr: hole.addr, - size: aligned_hole.addr - hole.addr, - }) - }; - let back_padding = if aligned_hole.size == required_size { // the aligned hole has exactly the size that's needed, no padding accrues None From 560873df10550187f7557e5452ee5f1cc79fc8b3 Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 17 May 2016 16:54:38 +0200 Subject: [PATCH 3/3] Bump version to 0.2.2 --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 9bec8ea..ec7781c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "linked_list_allocator" -version = "0.2.1" +version = "0.2.2" authors = ["Philipp Oppermann "] license = "Apache-2.0/MIT"