forked from Bananymous/banan-os
Kernel: FixedWidthAllocator creation can now fail
This commit is contained in:
parent
88e3998664
commit
98cedf155c
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <BAN/Errors.h>
|
||||||
#include <BAN/UniqPtr.h>
|
#include <BAN/UniqPtr.h>
|
||||||
#include <kernel/Memory/Heap.h>
|
#include <kernel/Memory/Heap.h>
|
||||||
#include <kernel/Memory/PageTable.h>
|
#include <kernel/Memory/PageTable.h>
|
||||||
|
@ -28,6 +29,8 @@ namespace Kernel
|
||||||
|
|
||||||
private:
|
private:
|
||||||
FixedWidthAllocator(PageTable&, uint32_t);
|
FixedWidthAllocator(PageTable&, uint32_t);
|
||||||
|
BAN::ErrorOr<void> initialize();
|
||||||
|
|
||||||
bool allocate_page_if_needed(vaddr_t, uint8_t flags);
|
bool allocate_page_if_needed(vaddr_t, uint8_t flags);
|
||||||
|
|
||||||
struct node
|
struct node
|
||||||
|
|
|
@ -5,10 +5,12 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<BAN::UniqPtr<FixedWidthAllocator>> FixedWidthAllocator::create(PageTable& page_table, uint32_t allocation_size)
|
BAN::ErrorOr<BAN::UniqPtr<FixedWidthAllocator>> FixedWidthAllocator::create(PageTable& page_table, uint32_t allocation_size)
|
||||||
{
|
{
|
||||||
auto* allocator = new FixedWidthAllocator(page_table, allocation_size);
|
auto* allocator_ptr = new FixedWidthAllocator(page_table, allocation_size);
|
||||||
if (allocator == nullptr)
|
if (allocator_ptr == nullptr)
|
||||||
return BAN::Error::from_errno(ENOMEM);
|
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)
|
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))
|
, m_allocation_size(BAN::Math::max(allocation_size, m_min_allocation_size))
|
||||||
{
|
{
|
||||||
ASSERT(BAN::Math::is_power_of_two(allocation_size));
|
ASSERT(BAN::Math::is_power_of_two(allocation_size));
|
||||||
|
}
|
||||||
|
|
||||||
|
BAN::ErrorOr<void> FixedWidthAllocator::initialize()
|
||||||
|
{
|
||||||
m_nodes_page = (vaddr_t)kmalloc(PAGE_SIZE);
|
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);
|
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_nodes_page, 0, PAGE_SIZE);
|
||||||
memset((void*)m_allocated_pages, 0, PAGE_SIZE);
|
memset((void*)m_allocated_pages, 0, PAGE_SIZE);
|
||||||
|
@ -37,23 +48,30 @@ namespace Kernel
|
||||||
|
|
||||||
m_free_list = node_table;
|
m_free_list = node_table;
|
||||||
m_used_list = nullptr;
|
m_used_list = nullptr;
|
||||||
|
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
FixedWidthAllocator::~FixedWidthAllocator()
|
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];
|
for (uint32_t page_index = 0; page_index < PAGE_SIZE / sizeof(vaddr_t); page_index++)
|
||||||
if (page_vaddr == 0)
|
{
|
||||||
continue;
|
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));
|
ASSERT(!m_page_table.is_page_free(page_vaddr));
|
||||||
Heap::get().release_page(m_page_table.physical_address_of(page_vaddr));
|
Heap::get().release_page(m_page_table.physical_address_of(page_vaddr));
|
||||||
m_page_table.unmap_page(page_vaddr);
|
m_page_table.unmap_page(page_vaddr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kfree((void*)m_nodes_page);
|
if (m_nodes_page)
|
||||||
kfree((void*)m_allocated_pages);
|
kfree((void*)m_nodes_page);
|
||||||
|
if (m_allocated_pages)
|
||||||
|
kfree((void*)m_allocated_pages);
|
||||||
}
|
}
|
||||||
|
|
||||||
paddr_t FixedWidthAllocator::allocate()
|
paddr_t FixedWidthAllocator::allocate()
|
||||||
|
|
Loading…
Reference in New Issue