Move memory_manager and assert into kutil.
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
|
#include "kutil/assert.h"
|
||||||
#include "apic.h"
|
#include "apic.h"
|
||||||
#include "assert.h"
|
|
||||||
#include "interrupts.h"
|
#include "interrupts.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "memory_pages.h"
|
#include "page_manager.h"
|
||||||
|
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "assert.h"
|
#include "kutil/assert.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
|
|
||||||
[[noreturn]] void
|
[[noreturn]] void
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
[[noreturn]] void __kernel_assert(const char *file, unsigned line, const char *message);
|
|
||||||
|
|
||||||
#define kassert(stmt, message) if(!(stmt)) { __kernel_assert(__FILE__, __LINE__, (message)); } else {}
|
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "kutil/assert.h"
|
||||||
#include "kutil/memory.h"
|
#include "kutil/memory.h"
|
||||||
#include "acpi_tables.h"
|
#include "acpi_tables.h"
|
||||||
#include "apic.h"
|
#include "apic.h"
|
||||||
#include "assert.h"
|
|
||||||
#include "device_manager.h"
|
#include "device_manager.h"
|
||||||
#include "interrupts.h"
|
#include "interrupts.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "memory_pages.h"
|
#include "page_manager.h"
|
||||||
|
|
||||||
static const char expected_signature[] = "RSD PTR ";
|
static const char expected_signature[] = "RSD PTR ";
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "assert.h"
|
#include "kutil/assert.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
|
|
||||||
/* PSF2 header format
|
/* PSF2 header format
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "interrupts.h"
|
#include "interrupts.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "memory_pages.h"
|
#include "page_manager.h"
|
||||||
|
|
||||||
enum class gdt_flags : uint8_t
|
enum class gdt_flags : uint8_t
|
||||||
{
|
{
|
||||||
|
|||||||
10
src/kernel/kalloc.cpp
Normal file
10
src/kernel/kalloc.cpp
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#include "kutil/memory_manager.h"
|
||||||
|
|
||||||
|
kutil::memory_manager g_kernel_memory_manager;
|
||||||
|
|
||||||
|
void * kalloc(size_t length) { return g_kernel_memory_manager.allocate(length); }
|
||||||
|
void kfree(void *p) { g_kernel_memory_manager.free(p); }
|
||||||
|
void * operator new (size_t n) { return g_kernel_memory_manager.allocate(n); }
|
||||||
|
void * operator new[] (size_t n) { return g_kernel_memory_manager.allocate(n); }
|
||||||
|
void operator delete (void *p) { return g_kernel_memory_manager.free(p); }
|
||||||
|
void operator delete[] (void *p){ return g_kernel_memory_manager.free(p); }
|
||||||
17
src/kernel/kalloc.h
Normal file
17
src/kernel/kalloc.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
/// \file kalloc.h
|
||||||
|
/// Definitions of kalloc() and kfree()
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
|
||||||
|
/// Allocate kernel space memory.
|
||||||
|
/// \arg length The amount of memory to allocate, in bytes
|
||||||
|
/// \returns A pointer to the allocated memory, or nullptr if
|
||||||
|
/// allocation failed.
|
||||||
|
inline void * kalloc(size_t length);
|
||||||
|
|
||||||
|
/// Free kernel space memory.
|
||||||
|
/// \arg p The pointer to free
|
||||||
|
inline void kfree(void *p);
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
#include "kutil/assert.h"
|
||||||
#include "kutil/memory.h"
|
#include "kutil/memory.h"
|
||||||
#include "assert.h"
|
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "kutil/assert.h"
|
||||||
#include "kutil/memory.h"
|
#include "kutil/memory.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
@@ -11,7 +12,7 @@
|
|||||||
#include "kernel_data.h"
|
#include "kernel_data.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "memory_pages.h"
|
#include "page_manager.h"
|
||||||
#include "screen.h"
|
#include "screen.h"
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
|
|
||||||
@@ -22,6 +23,9 @@ extern "C" {
|
|||||||
void *__bss_start, *__bss_end;
|
void *__bss_start, *__bss_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern [[noreturn]] void
|
||||||
|
__kernel_assert(const char *file, unsigned line, const char *message);
|
||||||
|
|
||||||
void
|
void
|
||||||
init_console(const popcorn_data *header)
|
init_console(const popcorn_data *header)
|
||||||
{
|
{
|
||||||
@@ -58,9 +62,11 @@ void do_error_1() { do_error_2(); }
|
|||||||
void
|
void
|
||||||
kernel_main(popcorn_data *header)
|
kernel_main(popcorn_data *header)
|
||||||
{
|
{
|
||||||
|
kutil::assert_set_callback(__kernel_assert);
|
||||||
|
|
||||||
page_manager *pager = new (&g_page_manager) page_manager;
|
page_manager *pager = new (&g_page_manager) page_manager;
|
||||||
|
|
||||||
memory_initialize_managers(
|
memory_initialize(
|
||||||
header->memory_map,
|
header->memory_map,
|
||||||
header->memory_map_length,
|
header->memory_map_length,
|
||||||
header->memory_map_desc_size);
|
header->memory_map_desc_size);
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
|
#include "kutil/assert.h"
|
||||||
#include "kutil/memory.h"
|
#include "kutil/memory.h"
|
||||||
#include "assert.h"
|
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "memory_pages.h"
|
#include "page_manager.h"
|
||||||
|
|
||||||
const unsigned efi_page_size = 0x1000;
|
const unsigned efi_page_size = 0x1000;
|
||||||
|
|
||||||
@@ -407,7 +407,7 @@ page_in_ident(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
memory_initialize_managers(const void *memory_map, size_t map_length, size_t desc_length)
|
memory_initialize(const void *memory_map, size_t map_length, size_t desc_length)
|
||||||
{
|
{
|
||||||
// The bootloader reserved 16 pages for page tables, which we'll use to bootstrap.
|
// The bootloader reserved 16 pages for page tables, which we'll use to bootstrap.
|
||||||
// The first one is the already-installed PML4, so grab it from CR3.
|
// The first one is the already-installed PML4, so grab it from CR3.
|
||||||
|
|||||||
@@ -1,14 +1,12 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "assert.h"
|
#include "kutil/assert.h"
|
||||||
|
#include "kutil/memory_manager.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "memory.h"
|
#include "page_manager.h"
|
||||||
#include "memory_pages.h"
|
|
||||||
|
|
||||||
page_manager g_page_manager;
|
page_manager g_page_manager;
|
||||||
|
|
||||||
using addr_t = page_manager::addr_t;
|
|
||||||
|
|
||||||
|
|
||||||
static addr_t
|
static addr_t
|
||||||
pt_to_phys(page_table *pt)
|
pt_to_phys(page_table *pt)
|
||||||
@@ -16,6 +14,7 @@ pt_to_phys(page_table *pt)
|
|||||||
return reinterpret_cast<addr_t>(pt) - page_manager::page_offset;
|
return reinterpret_cast<addr_t>(pt) - page_manager::page_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static page_table *
|
static page_table *
|
||||||
pt_from_phys(addr_t p)
|
pt_from_phys(addr_t p)
|
||||||
{
|
{
|
||||||
@@ -29,6 +28,18 @@ struct free_page_header
|
|||||||
size_t count;
|
size_t count;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
void mm_grow_callback(void *next, size_t length)
|
||||||
|
{
|
||||||
|
kassert(length % page_manager::page_size == 0,
|
||||||
|
"Heap manager requested a fractional page.");
|
||||||
|
|
||||||
|
size_t pages = length / page_manager::page_size;
|
||||||
|
log::info(logs::memory, "Heap manager growing heap by %d pages.", pages);
|
||||||
|
g_page_manager.map_pages(reinterpret_cast<addr_t>(next), pages);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
page_block::length(page_block *list)
|
page_block::length(page_block *list)
|
||||||
{
|
{
|
||||||
@@ -203,7 +214,10 @@ page_manager::init(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
new (&g_kernel_memory_manager) memory_manager(reinterpret_cast<void *>(end));
|
extern kutil::memory_manager g_kernel_memory_manager;
|
||||||
|
new (&g_kernel_memory_manager) kutil::memory_manager(
|
||||||
|
reinterpret_cast<void *>(end),
|
||||||
|
mm_grow_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -1,10 +1,11 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/// \file memory_pages.h
|
/// \file page_manager.h
|
||||||
/// The page memory manager and related definitions.
|
/// The page memory manager and related definitions.
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include "kutil/memory.h"
|
||||||
#include "kutil/enum_bitfields.h"
|
#include "kutil/enum_bitfields.h"
|
||||||
|
|
||||||
struct page_block;
|
struct page_block;
|
||||||
@@ -16,8 +17,6 @@ struct free_page_header;
|
|||||||
class page_manager
|
class page_manager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using addr_t = uint64_t;
|
|
||||||
|
|
||||||
/// Size of a single page.
|
/// Size of a single page.
|
||||||
static const size_t page_size = 0x1000;
|
static const size_t page_size = 0x1000;
|
||||||
|
|
||||||
@@ -53,8 +52,6 @@ public:
|
|||||||
static page_manager * get();
|
static page_manager * get();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend void memory_initialize_managers(const void *, size_t, size_t);
|
|
||||||
|
|
||||||
/// Set up the memory manager from bootstraped memory
|
/// Set up the memory manager from bootstraped memory
|
||||||
void init(
|
void init(
|
||||||
page_block *free,
|
page_block *free,
|
||||||
@@ -143,6 +140,7 @@ private:
|
|||||||
page_block *m_block_cache; ///< Cache of unused page_block structs
|
page_block *m_block_cache; ///< Cache of unused page_block structs
|
||||||
free_page_header *m_page_cache; ///< Cache of free pages to use for tables
|
free_page_header *m_page_cache; ///< Cache of free pages to use for tables
|
||||||
|
|
||||||
|
friend void memory_initialize(const void *, size_t, size_t);
|
||||||
page_manager(const page_manager &) = delete;
|
page_manager(const page_manager &) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -175,8 +173,6 @@ IS_BITFIELD(page_block_flags);
|
|||||||
/// linked list of such structures.
|
/// linked list of such structures.
|
||||||
struct page_block
|
struct page_block
|
||||||
{
|
{
|
||||||
using addr_t = page_manager::addr_t;
|
|
||||||
|
|
||||||
addr_t physical_address;
|
addr_t physical_address;
|
||||||
addr_t virtual_address;
|
addr_t virtual_address;
|
||||||
uint32_t count;
|
uint32_t count;
|
||||||
@@ -294,3 +290,6 @@ template <typename T> inline T page_align(T p)
|
|||||||
/// \returns The next page-table-aligned address _after_ `p`.
|
/// \returns The next page-table-aligned address _after_ `p`.
|
||||||
template <typename T> inline T page_table_align(T p) { return ((p - 1) & ~0x1fffffull) + 0x200000; }
|
template <typename T> inline T page_table_align(T p) { return ((p - 1) & ~0x1fffffull) + 0x200000; }
|
||||||
|
|
||||||
|
|
||||||
|
/// Bootstrap the memory managers.
|
||||||
|
void memory_initialize(const void *memory_map, size_t map_length, size_t desc_length);
|
||||||
16
src/modules/kutil/assert.cpp
Normal file
16
src/modules/kutil/assert.cpp
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#include "assert.h"
|
||||||
|
|
||||||
|
namespace kutil {
|
||||||
|
|
||||||
|
assert_callback __kernel_assert_p = nullptr;
|
||||||
|
|
||||||
|
assert_callback
|
||||||
|
assert_set_callback(assert_callback f)
|
||||||
|
{
|
||||||
|
assert_callback old = __kernel_assert_p;
|
||||||
|
__kernel_assert_p = f;
|
||||||
|
return old;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace kutil
|
||||||
19
src/modules/kutil/assert.h
Normal file
19
src/modules/kutil/assert.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace kutil {
|
||||||
|
|
||||||
|
using assert_callback =
|
||||||
|
[[noreturn]] void (*)
|
||||||
|
(const char *file, unsigned line, const char *message);
|
||||||
|
|
||||||
|
/// Set the global kernel assert callback
|
||||||
|
/// \args f The new callback
|
||||||
|
/// \returns The old callback
|
||||||
|
assert_callback assert_set_callback(assert_callback f);
|
||||||
|
|
||||||
|
extern assert_callback __kernel_assert_p;
|
||||||
|
|
||||||
|
} // namespace kutil
|
||||||
|
|
||||||
|
|
||||||
|
#define kassert(stmt, message) if(!(stmt)) { ::kutil::__kernel_assert_p(__FILE__, __LINE__, (message)); } else {}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
|
||||||
|
void * operator new (size_t, void *p) { return p; }
|
||||||
|
|
||||||
namespace kutil {
|
namespace kutil {
|
||||||
|
|
||||||
void *
|
void *
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
|
|
||||||
|
|
||||||
using addr_t = uint64_t;
|
using addr_t = uint64_t;
|
||||||
|
void * operator new (size_t, void *p);
|
||||||
|
|
||||||
|
|
||||||
namespace kutil {
|
namespace kutil {
|
||||||
|
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
#include "kutil/enum_bitfields.h"
|
#include <stdint.h>
|
||||||
#include "kutil/memory.h"
|
|
||||||
#include "assert.h"
|
#include "assert.h"
|
||||||
#include "log.h"
|
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "memory_pages.h"
|
#include "memory_manager.h"
|
||||||
|
|
||||||
|
namespace kutil {
|
||||||
|
|
||||||
memory_manager g_kernel_memory_manager;
|
|
||||||
|
|
||||||
struct memory_manager::mem_header
|
struct memory_manager::mem_header
|
||||||
{
|
{
|
||||||
@@ -70,14 +69,16 @@ private:
|
|||||||
|
|
||||||
memory_manager::memory_manager() :
|
memory_manager::memory_manager() :
|
||||||
m_start(nullptr),
|
m_start(nullptr),
|
||||||
m_length(0)
|
m_length(0),
|
||||||
|
m_grow(nullptr)
|
||||||
{
|
{
|
||||||
kutil::memset(m_free, 0, sizeof(m_free));
|
kutil::memset(m_free, 0, sizeof(m_free));
|
||||||
}
|
}
|
||||||
|
|
||||||
memory_manager::memory_manager(void *start) :
|
memory_manager::memory_manager(void *start, grow_callback grow_cb) :
|
||||||
m_start(start),
|
m_start(start),
|
||||||
m_length(0)
|
m_length(0),
|
||||||
|
m_grow(grow_cb)
|
||||||
{
|
{
|
||||||
kutil::memset(m_free, 0, sizeof(m_free));
|
kutil::memset(m_free, 0, sizeof(m_free));
|
||||||
grow_memory();
|
grow_memory();
|
||||||
@@ -89,13 +90,10 @@ memory_manager::allocate(size_t length)
|
|||||||
size_t total = length + sizeof(mem_header);
|
size_t total = length + sizeof(mem_header);
|
||||||
unsigned size = min_size;
|
unsigned size = min_size;
|
||||||
while (total > (1 << size)) size++;
|
while (total > (1 << size)) size++;
|
||||||
kassert(size < max_size, "Tried to allocate a block bigger than max_size");
|
kassert(size <= max_size, "Tried to allocate a block bigger than max_size");
|
||||||
log::debug(logs::memory, "Allocating %d bytes, which is size %d", total, size);
|
|
||||||
|
|
||||||
mem_header *header = pop_free(size);
|
mem_header *header = pop_free(size);
|
||||||
header->set_used(true);
|
header->set_used(true);
|
||||||
|
|
||||||
log::debug(logs::memory, " Returning %d bytes at %lx", length, header + 1);
|
|
||||||
return header + 1;
|
return header + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -106,16 +104,12 @@ memory_manager::free(void *p)
|
|||||||
header -= 1; // p points after the header
|
header -= 1; // p points after the header
|
||||||
header->set_used(false);
|
header->set_used(false);
|
||||||
|
|
||||||
log::debug(logs::memory, "Freeing a block of size %2d at %lx", header->size(), header);
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
mem_header *buddy = header->buddy();
|
mem_header *buddy = header->buddy();
|
||||||
if (buddy->used() || buddy->size() != header->size()) break;
|
if (buddy->used() || buddy->size() != header->size()) break;
|
||||||
log::debug(logs::memory, " buddy is same size at %lx", buddy);
|
|
||||||
buddy->remove();
|
buddy->remove();
|
||||||
header = header->eldest() ? header : buddy;
|
header = header->eldest() ? header : buddy;
|
||||||
header->set_size(header->size() + 1);
|
header->set_size(header->size() + 1);
|
||||||
log::debug(logs::memory, " joined into size %2d at %lx", header->size(), header);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t size = header->size();
|
uint8_t size = header->size();
|
||||||
@@ -131,19 +125,14 @@ memory_manager::grow_memory()
|
|||||||
size_t length = (1 << max_size);
|
size_t length = (1 << max_size);
|
||||||
|
|
||||||
void *next = kutil::offset_pointer(m_start, m_length);
|
void *next = kutil::offset_pointer(m_start, m_length);
|
||||||
|
kassert(m_grow, "Tried to grow heap without a growth callback");
|
||||||
g_page_manager.map_pages(
|
m_grow(next, length);
|
||||||
reinterpret_cast<page_manager::addr_t>(next),
|
|
||||||
length / page_manager::page_size);
|
|
||||||
|
|
||||||
mem_header *block = new (next) mem_header(nullptr, get_free(max_size), max_size);
|
mem_header *block = new (next) mem_header(nullptr, get_free(max_size), max_size);
|
||||||
get_free(max_size) = block;
|
get_free(max_size) = block;
|
||||||
if (block->next())
|
if (block->next())
|
||||||
block->next()->set_prev(block);
|
block->next()->set_prev(block);
|
||||||
m_length += length;
|
m_length += length;
|
||||||
|
|
||||||
log::debug(logs::memory, "Allocated new block at %lx: size %d next %lx",
|
|
||||||
block, max_size, block->next());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -163,10 +152,6 @@ memory_manager::ensure_block(unsigned size)
|
|||||||
orig->set_next(next);
|
orig->set_next(next);
|
||||||
orig->set_size(size);
|
orig->set_size(size);
|
||||||
get_free(size) = orig;
|
get_free(size) = orig;
|
||||||
|
|
||||||
log::debug(logs::memory, "ensure_block[%2d] split blocks:", size);
|
|
||||||
log::debug(logs::memory, " %lx: size %d next %lx", orig, size, orig->next());
|
|
||||||
log::debug(logs::memory, " %lx: size %d next %lx", next, size, next->next());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memory_manager::mem_header *
|
memory_manager::mem_header *
|
||||||
@@ -180,8 +165,4 @@ memory_manager::pop_free(unsigned size)
|
|||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
void * operator new (size_t, void *p) { return p; }
|
} // namespace kutil
|
||||||
void * operator new (size_t n) { return g_kernel_memory_manager.allocate(n); }
|
|
||||||
void * operator new[] (size_t n) { return g_kernel_memory_manager.allocate(n); }
|
|
||||||
void operator delete (void *p) { return g_kernel_memory_manager.free(p); }
|
|
||||||
void operator delete[] (void *p){ return g_kernel_memory_manager.free(p); }
|
|
||||||
@@ -1,17 +1,25 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/// \file memory.h
|
/// \file memory_manager.h
|
||||||
/// The block memory manager and related definitions.
|
/// A buddy allocator and related definitions.
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
|
||||||
|
namespace kutil {
|
||||||
|
|
||||||
|
|
||||||
/// Manager for allocation of virtual memory.
|
/// Manager for allocation of virtual memory.
|
||||||
class memory_manager
|
class memory_manager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using grow_callback = void (*)(void *start, size_t length);
|
||||||
|
|
||||||
|
/// Default constructor. Creates an invalid manager.
|
||||||
memory_manager();
|
memory_manager();
|
||||||
memory_manager(void *start);
|
|
||||||
|
/// Constructor.
|
||||||
|
/// \arg start Pointer to the start of the heap to be managed
|
||||||
|
/// \arg grow_cb Function pointer to grow the heap size
|
||||||
|
memory_manager(void *start, grow_callback grow_cb);
|
||||||
|
|
||||||
/// Allocate memory from the area managed.
|
/// Allocate memory from the area managed.
|
||||||
/// \arg length The amount of memory to allocate, in bytes
|
/// \arg length The amount of memory to allocate, in bytes
|
||||||
@@ -23,6 +31,7 @@ public:
|
|||||||
/// \arg p A pointer previously retuned by allocate()
|
/// \arg p A pointer previously retuned by allocate()
|
||||||
void free(void *p);
|
void free(void *p);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class mem_header;
|
class mem_header;
|
||||||
|
|
||||||
@@ -49,23 +58,9 @@ private:
|
|||||||
void *m_start;
|
void *m_start;
|
||||||
size_t m_length;
|
size_t m_length;
|
||||||
|
|
||||||
friend class page_manager;
|
grow_callback m_grow;
|
||||||
|
|
||||||
memory_manager(const memory_manager &) = delete;
|
memory_manager(const memory_manager &) = delete;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern memory_manager g_kernel_memory_manager;
|
} // namespace kutil
|
||||||
|
|
||||||
/// Bootstrap the memory managers.
|
|
||||||
void memory_initialize_managers(const void *memory_map, size_t map_length, size_t desc_length);
|
|
||||||
|
|
||||||
/// Allocate kernel space memory.
|
|
||||||
/// \arg length The amount of memory to allocate, in bytes
|
|
||||||
/// \returns A pointer to the allocated memory, or nullptr if
|
|
||||||
/// allocation failed.
|
|
||||||
inline void * kalloc(size_t length) { return g_kernel_memory_manager.allocate(length); }
|
|
||||||
|
|
||||||
/// Free kernel space memory.
|
|
||||||
/// \arg p The pointer to free
|
|
||||||
inline void kfree(void *p) { g_kernel_memory_manager.free(p); }
|
|
||||||
|
|
||||||
void * operator new (size_t, void *p);
|
|
||||||
Reference in New Issue
Block a user