Kernel: FixedWidthAllocator creation can now fail
This commit is contained in:
		
							parent
							
								
									88e3998664
								
							
						
					
					
						commit
						98cedf155c
					
				|  | @ -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 | ||||
|  |  | |||
|  | @ -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() | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue