forked from Bananymous/banan-os
				
			Kernel: kmalloc uses now spinlock and fix kmalloc_fixed()
This commit is contained in:
		
							parent
							
								
									c9ea22f5e2
								
							
						
					
					
						commit
						4cd99c71ca
					
				| 
						 | 
					@ -4,12 +4,17 @@
 | 
				
			||||||
#include <kernel/kprint.h>
 | 
					#include <kernel/kprint.h>
 | 
				
			||||||
#include <kernel/multiboot.h>
 | 
					#include <kernel/multiboot.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <kernel/SpinLock.h>
 | 
				
			||||||
 | 
					#include <kernel/LockGuard.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define MB (1 << 20)
 | 
					#define MB (1 << 20)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static constexpr size_t s_kmalloc_min_align = alignof(max_align_t);
 | 
					static constexpr size_t s_kmalloc_min_align = alignof(max_align_t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Kernel::SpinLock s_lock;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct kmalloc_node
 | 
					struct kmalloc_node
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	void set_align(ptrdiff_t align)			{ m_align = align; }
 | 
						void set_align(ptrdiff_t align)			{ m_align = align; }
 | 
				
			||||||
| 
						 | 
					@ -57,7 +62,6 @@ private:
 | 
				
			||||||
	uint8_t		m_data[0];
 | 
						uint8_t		m_data[0];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
static_assert(sizeof(kmalloc_node) == s_kmalloc_min_align);
 | 
					static_assert(sizeof(kmalloc_node) == s_kmalloc_min_align);
 | 
				
			||||||
 | 
					 | 
				
			||||||
struct kmalloc_info
 | 
					struct kmalloc_info
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static constexpr uintptr_t	base = 0x00200000;
 | 
						static constexpr uintptr_t	base = 0x00200000;
 | 
				
			||||||
| 
						 | 
					@ -176,7 +180,7 @@ void kmalloc_initialize()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void kmalloc_dump_info()
 | 
					void kmalloc_dump_info()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	kprintln("kmalloc:         0x{8H}->0x{8H}", s_kmalloc_info.base, s_kmalloc_info.end);
 | 
						kprintln("kmalloc:               0x{8H}->0x{8H}", s_kmalloc_info.base, s_kmalloc_info.end);
 | 
				
			||||||
	kprintln("  used: 0x{8H}", s_kmalloc_info.used);
 | 
						kprintln("  used: 0x{8H}", s_kmalloc_info.used);
 | 
				
			||||||
	kprintln("  free: 0x{8H}", s_kmalloc_info.free);
 | 
						kprintln("  free: 0x{8H}", s_kmalloc_info.free);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -187,6 +191,8 @@ void kmalloc_dump_info()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void* kmalloc_fixed()
 | 
					static void* kmalloc_fixed()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						Kernel::LockGuard guard(s_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto& info = s_kmalloc_fixed_info;
 | 
						auto& info = s_kmalloc_fixed_info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!info.free_list_head)
 | 
						if (!info.free_list_head)
 | 
				
			||||||
| 
						 | 
					@ -197,8 +203,6 @@ static void* kmalloc_fixed()
 | 
				
			||||||
	ASSERT(node->next == kmalloc_fixed_info::node::invalid);
 | 
						ASSERT(node->next == kmalloc_fixed_info::node::invalid);
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	// remove the node from free list
 | 
						// remove the node from free list
 | 
				
			||||||
	node->prev = kmalloc_fixed_info::node::invalid;
 | 
					 | 
				
			||||||
	node->next = kmalloc_fixed_info::node::invalid;
 | 
					 | 
				
			||||||
	if (info.free_list_head->prev != kmalloc_fixed_info::node::invalid)
 | 
						if (info.free_list_head->prev != kmalloc_fixed_info::node::invalid)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		info.free_list_head = info.node_at(info.free_list_head->prev);
 | 
							info.free_list_head = info.node_at(info.free_list_head->prev);
 | 
				
			||||||
| 
						 | 
					@ -206,8 +210,11 @@ static void* kmalloc_fixed()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else
 | 
						else
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
 | 
							derrorln("removing free list, allocated {}", info.used);
 | 
				
			||||||
		info.free_list_head = nullptr;
 | 
							info.free_list_head = nullptr;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						node->prev = kmalloc_fixed_info::node::invalid;
 | 
				
			||||||
 | 
						node->next = kmalloc_fixed_info::node::invalid;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// move the node to the top of used nodes
 | 
						// move the node to the top of used nodes
 | 
				
			||||||
	if (info.used_list_head)
 | 
						if (info.used_list_head)
 | 
				
			||||||
| 
						 | 
					@ -225,6 +232,8 @@ static void* kmalloc_fixed()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void* kmalloc_impl(size_t size, size_t align)
 | 
					static void* kmalloc_impl(size_t size, size_t align)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						Kernel::LockGuard guard(s_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ASSERT(align % s_kmalloc_min_align == 0);
 | 
						ASSERT(align % s_kmalloc_min_align == 0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto& info = s_kmalloc_info;
 | 
						auto& info = s_kmalloc_info;
 | 
				
			||||||
| 
						 | 
					@ -283,7 +292,10 @@ static void* kmalloc_impl(size_t size, size_t align)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void* kmalloc(size_t size)
 | 
					void* kmalloc(size_t size)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return kmalloc(size, s_kmalloc_min_align);
 | 
						void* res = kmalloc(size, s_kmalloc_min_align);
 | 
				
			||||||
 | 
						if (res == nullptr)
 | 
				
			||||||
 | 
							dwarnln("could not allocate {} bytes", size);
 | 
				
			||||||
 | 
						return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void* kmalloc(size_t size, size_t align)
 | 
					void* kmalloc(size_t size, size_t align)
 | 
				
			||||||
| 
						 | 
					@ -312,6 +324,8 @@ void* kmalloc(size_t size, size_t align)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void kfree(void* address)
 | 
					void kfree(void* address)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						Kernel::LockGuard guard(s_lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (address == nullptr)
 | 
						if (address == nullptr)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -354,7 +368,8 @@ void kfree(void* address)
 | 
				
			||||||
		auto& info = s_kmalloc_info;
 | 
							auto& info = s_kmalloc_info;
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
		auto* node = info.from_address(address);
 | 
							auto* node = info.from_address(address);
 | 
				
			||||||
		ASSERT(node && node->data() == (uintptr_t)address);
 | 
							ASSERT(node);
 | 
				
			||||||
 | 
							ASSERT(node->data() == (uintptr_t)address);
 | 
				
			||||||
		ASSERT(node->used());
 | 
							ASSERT(node->used());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ptrdiff_t size = node->size_no_align();
 | 
							ptrdiff_t size = node->size_no_align();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue