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.
63 lines
2.0 KiB
C++
63 lines
2.0 KiB
C++
#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;
|
|
};
|