[kernel] Move more from kutil to kernel
The moving of kernel-only code out of kutil continues. (See 042f061)
This commit moves the following:
- The heap allocator code
- memory.cpp/h which means:
- letting string.h be the right header for memset and memcpy, still
including an implementation of it for the kernel though, since
we're not linking libc to the kernel
- Changing calls to kalloc/kfree to new/delete in kutil containers
that aren't going to be merged into the kernel
- Fixing a problem with stdalign.h from libc, which was causing issues
for type_traits.
This commit is contained in:
62
src/kernel/heap_allocator.h
Normal file
62
src/kernel/heap_allocator.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
/// \file heap_allocator.h
|
||||
/// A buddy allocator for a memory heap
|
||||
|
||||
#include <stddef.h>
|
||||
#include "kutil/spinlock.h"
|
||||
|
||||
|
||||
/// Allocator for a given heap range
|
||||
class heap_allocator
|
||||
{
|
||||
public:
|
||||
/// Default constructor creates a valid but empty heap.
|
||||
heap_allocator();
|
||||
|
||||
/// Constructor. The given memory area must already have been reserved.
|
||||
/// \arg start Starting address of the heap
|
||||
/// \arg size Size of the heap in bytes
|
||||
heap_allocator(uintptr_t start, size_t size);
|
||||
|
||||
/// Allocate memory from the area managed.
|
||||
/// \arg length The amount of memory to allocate, in bytes
|
||||
/// \returns A pointer to the allocated memory, or nullptr if
|
||||
/// allocation failed.
|
||||
void * allocate(size_t length);
|
||||
|
||||
/// Free a previous allocation.
|
||||
/// \arg p A pointer previously retuned by allocate()
|
||||
void free(void *p);
|
||||
|
||||
/// Minimum block size is (2^min_order). Must be at least 6.
|
||||
static const unsigned min_order = 6;
|
||||
|
||||
/// Maximum block size is (2^max_order). Must be less than 64.
|
||||
static const unsigned max_order = 22;
|
||||
|
||||
protected:
|
||||
class mem_header;
|
||||
|
||||
/// Ensure there is a block of a given order, recursively splitting
|
||||
/// \arg order Order (2^N) of the block we want
|
||||
void ensure_block(unsigned order);
|
||||
|
||||
/// Helper accessor for the list of blocks of a given order
|
||||
/// \arg order Order (2^N) of the block we want
|
||||
/// \returns A mutable reference to the head of the list
|
||||
mem_header *& get_free(unsigned order) { return m_free[order - min_order]; }
|
||||
|
||||
/// Helper to get a block of the given order, growing if necessary
|
||||
/// \arg order Order (2^N) of the block we want
|
||||
/// \returns A detached block of the given order
|
||||
mem_header * pop_free(unsigned order);
|
||||
|
||||
uintptr_t m_start, m_end;
|
||||
size_t m_blocks;
|
||||
mem_header *m_free[max_order - min_order + 1];
|
||||
size_t m_allocated_size;
|
||||
|
||||
kutil::spinlock m_lock;
|
||||
|
||||
heap_allocator(const heap_allocator &) = delete;
|
||||
};
|
||||
Reference in New Issue
Block a user