Kernel: FixedWidthAllocator creation can now fail

This commit is contained in:
Bananymous 2023-07-19 18:07:24 +03:00
parent 88e3998664
commit 98cedf155c
2 changed files with 35 additions and 14 deletions

View File

@ -1,5 +1,6 @@
#pragma once
#include <BAN/Errors.h>
#include <BAN/UniqPtr.h>
#include <kernel/Memory/Heap.h>
#include <kernel/Memory/PageTable.h>
@ -28,6 +29,8 @@ namespace Kernel
private:
FixedWidthAllocator(PageTable&, uint32_t);
BAN::ErrorOr<void> initialize();
bool allocate_page_if_needed(vaddr_t, uint8_t flags);
struct node

View File

@ -5,10 +5,12 @@ namespace Kernel
BAN::ErrorOr<BAN::UniqPtr<FixedWidthAllocator>> FixedWidthAllocator::create(PageTable& page_table, uint32_t allocation_size)
{
auto* allocator = new FixedWidthAllocator(page_table, allocation_size);
if (allocator == nullptr)
auto* allocator_ptr = new FixedWidthAllocator(page_table, allocation_size);
if (allocator_ptr == nullptr)
return BAN::Error::from_errno(ENOMEM);
return BAN::UniqPtr<FixedWidthAllocator>::adopt(allocator);
auto allocator = BAN::UniqPtr<FixedWidthAllocator>::adopt(allocator_ptr);
TRY(allocator->initialize());
return allocator;
}
FixedWidthAllocator::FixedWidthAllocator(PageTable& page_table, uint32_t allocation_size)
@ -16,12 +18,21 @@ namespace Kernel
, m_allocation_size(BAN::Math::max(allocation_size, m_min_allocation_size))
{
ASSERT(BAN::Math::is_power_of_two(allocation_size));
}
BAN::ErrorOr<void> FixedWidthAllocator::initialize()
{
m_nodes_page = (vaddr_t)kmalloc(PAGE_SIZE);
ASSERT(m_nodes_page);
if (!m_nodes_page)
return BAN::Error::from_errno(ENOMEM);
m_allocated_pages = (vaddr_t)kmalloc(PAGE_SIZE);
ASSERT(m_allocated_pages);
if (!m_allocated_pages)
{
kfree((void*)m_nodes_page);
m_nodes_page = 0;
return BAN::Error::from_errno(ENOMEM);
}
memset((void*)m_nodes_page, 0, PAGE_SIZE);
memset((void*)m_allocated_pages, 0, PAGE_SIZE);
@ -37,23 +48,30 @@ namespace Kernel
m_free_list = node_table;
m_used_list = nullptr;
return {};
}
FixedWidthAllocator::~FixedWidthAllocator()
{
for (uint32_t page_index = 0; page_index < PAGE_SIZE / sizeof(vaddr_t); page_index++)
if (m_nodes_page && m_allocated_pages)
{
vaddr_t page_vaddr = ((vaddr_t*)m_allocated_pages)[page_index];
if (page_vaddr == 0)
continue;
for (uint32_t page_index = 0; page_index < PAGE_SIZE / sizeof(vaddr_t); page_index++)
{
vaddr_t page_vaddr = ((vaddr_t*)m_allocated_pages)[page_index];
if (page_vaddr == 0)
continue;
ASSERT(!m_page_table.is_page_free(page_vaddr));
Heap::get().release_page(m_page_table.physical_address_of(page_vaddr));
m_page_table.unmap_page(page_vaddr);
ASSERT(!m_page_table.is_page_free(page_vaddr));
Heap::get().release_page(m_page_table.physical_address_of(page_vaddr));
m_page_table.unmap_page(page_vaddr);
}
}
kfree((void*)m_nodes_page);
kfree((void*)m_allocated_pages);
if (m_nodes_page)
kfree((void*)m_nodes_page);
if (m_allocated_pages)
kfree((void*)m_allocated_pages);
}
paddr_t FixedWidthAllocator::allocate()