Files
jsix/src/kernel/heap_allocator.h
Justin C. Miller cd9b85b555 [util] Replace kutil with util
Now that kutil has no kernel-specific code in it anymore, it can
actually be linked to by anything, so I'm renaming it 'util'.

Also, I've tried to unify the way that the system libraries from
src/libraries are #included using <> instead of "".

Other small change: util::bip_buffer got a spinlock to guard against
state corruption.
2022-01-03 00:03:29 -08:00

64 lines
2.0 KiB
C++

#pragma once
/// \file heap_allocator.h
/// A buddy allocator for a memory heap
#include <stddef.h>
#include <util/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;
util::spinlock m_lock;
heap_allocator(const heap_allocator &) = delete;
};