diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-03-16 14:31:52 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-03-16 14:31:52 +0100 |
| commit | b014f1cd12262afee9933d7c07d61242edc28a95 (patch) | |
| tree | 5eef66367fbd634df6cfe49c7462eb8e58a43cab | |
| parent | 72a54c9eb186735cad3f9e0b98cc2b2385220fee (diff) | |
| download | teachos-b014f1cd12262afee9933d7c07d61242edc28a95.tar.xz teachos-b014f1cd12262afee9933d7c07d61242edc28a95.zip | |
kernel/heap: fix infinite allocation loop
| -rw-r--r-- | kernel/src/memory/block_list_allocator.cpp | 64 |
1 files changed, 31 insertions, 33 deletions
diff --git a/kernel/src/memory/block_list_allocator.cpp b/kernel/src/memory/block_list_allocator.cpp index 1bd17ff..5d870d8 100644 --- a/kernel/src/memory/block_list_allocator.cpp +++ b/kernel/src/memory/block_list_allocator.cpp @@ -42,51 +42,49 @@ namespace kernel::memory auto current = m_block_list; while (current != nullptr) { - if (!current->free) + if (current->free) { - current = current->next; - continue; - } + auto const raw_block = reinterpret_cast<std::byte *>(current); + auto const unaligned_payload = raw_block + allocated_metadata_size; + auto const aligned_payload = align_up(unaligned_payload, alignment); + auto const required_padding = static_cast<std::size_t>(aligned_payload - unaligned_payload); + auto const total_required_size = required_padding + allocated_metadata_size + size; - auto const raw_block = reinterpret_cast<std::byte *>(current); - auto const unaligned_payload = raw_block + allocated_metadata_size; - auto const aligned_payload = align_up(unaligned_payload, alignment); - auto const required_padding = static_cast<std::size_t>(aligned_payload - unaligned_payload); - auto const total_required_size = required_padding + allocated_metadata_size + size; + if (current->usable_size >= total_required_size) + { + auto const payload_header = aligned_payload - sizeof(block_header *) - sizeof(block_header); + auto const front_padding = static_cast<std::size_t>(payload_header - raw_block); - if (current->usable_size >= total_required_size) - { - auto const payload_header = aligned_payload - sizeof(block_header *) - sizeof(block_header); - auto const front_padding = static_cast<std::size_t>(payload_header - raw_block); + auto payload_block = current; - auto payload_block = current; + if (front_padding >= allocated_metadata_size + minimum_allocation_size) + { + payload_block = reinterpret_cast<block_header *>(payload_header); + std::construct_at(payload_block, current->usable_size - front_padding, true, current->next); - if (front_padding >= allocated_metadata_size + minimum_allocation_size) - { - payload_block = reinterpret_cast<block_header *>(payload_header); - std::construct_at(payload_block, current->usable_size - front_padding, true, current->next); + if (payload_block->next) + { + payload_block->next->prev = payload_block; + } - if (payload_block->next) - { - payload_block->next->prev = payload_block; + current->usable_size = front_padding - allocated_metadata_size; + current->next = payload_block; + payload_block->prev = current; } - current->usable_size = front_padding - allocated_metadata_size; - current->next = payload_block; - payload_block->prev = current; - } - - auto const payload_size = - aligned_payload - reinterpret_cast<std::byte *>(payload_block) - allocated_metadata_size + size; - split(payload_block, payload_size, 0uz); + auto const payload_size = + aligned_payload - reinterpret_cast<std::byte *>(payload_block) - allocated_metadata_size + size; + split(payload_block, payload_size, 0uz); - payload_block->free = false; + payload_block->free = false; - auto back_pointer = reinterpret_cast<block_header **>(aligned_payload - sizeof(block_header *)); - *back_pointer = payload_block; + auto back_pointer = reinterpret_cast<block_header **>(aligned_payload - sizeof(block_header *)); + *back_pointer = payload_block; - return reinterpret_cast<void *>(aligned_payload); + return reinterpret_cast<void *>(aligned_payload); + } } + current = current->next; } auto const search_size = size + static_cast<std::size_t>(alignment); |
