Files
jsix_import/src/kernel/heap_allocator.h
Justin C. Miller a6ec294f63 [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.
2022-01-01 23:23:51 -08:00

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;
};