Rearrange memory manager into two classes.
page_manager and memory_manager are now separate, and are also pre allocated in the kernel so they don't have to allocate themselves.
This commit is contained in:
@@ -42,7 +42,7 @@ kernel_main(popcorn_data *header)
|
|||||||
{
|
{
|
||||||
console cons = load_console(header);
|
console cons = load_console(header);
|
||||||
|
|
||||||
memory_manager::create(
|
memory_initialize_managers(
|
||||||
header->memory_map,
|
header->memory_map,
|
||||||
header->memory_map_length,
|
header->memory_map_length,
|
||||||
header->memory_map_desc_size);
|
header->memory_map_desc_size);
|
||||||
|
|||||||
@@ -3,8 +3,9 @@
|
|||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
#include "memory_pages.h"
|
#include "memory_pages.h"
|
||||||
|
|
||||||
memory_manager *memory_manager::s_instance = nullptr;
|
memory_manager g_memory_manager;
|
||||||
|
|
||||||
memory_manager::memory_manager(page_block *free, page_block *used, void *scratch, size_t scratch_len)
|
memory_manager::memory_manager()
|
||||||
{
|
{
|
||||||
|
kassert(this == &g_memory_manager, "Attempt to create another memory_manager.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +1,23 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
/// \file memory.h
|
||||||
|
/// The block memory manager and related definitions.
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
struct page_block;
|
/// Manager for allocation of virtual memory.
|
||||||
|
|
||||||
class memory_manager
|
class memory_manager
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
memory_manager();
|
||||||
|
|
||||||
static void create(const void *memory_map, size_t map_length, size_t desc_length);
|
|
||||||
static memory_manager * get() { return s_instance; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
memory_manager(page_block *free, page_block *used, void *scratch, size_t scratch_len);
|
|
||||||
|
|
||||||
memory_manager() = delete;
|
|
||||||
memory_manager(const memory_manager &) = delete;
|
memory_manager(const memory_manager &) = delete;
|
||||||
|
|
||||||
static memory_manager * s_instance;
|
private:
|
||||||
|
friend class page_manager;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
extern memory_manager g_memory_manager;
|
||||||
|
|
||||||
|
/// Bootstrap the memory managers.
|
||||||
|
void memory_initialize_managers(const void *memory_map, size_t map_length, size_t desc_length);
|
||||||
|
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ gather_block_lists(
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
memory_manager::create(const void *memory_map, size_t map_length, size_t desc_length)
|
memory_initialize_managers(const void *memory_map, size_t map_length, size_t desc_length)
|
||||||
{
|
{
|
||||||
console *cons = console::get();
|
console *cons = console::get();
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,23 @@
|
|||||||
|
#include "assert.h"
|
||||||
#include "console.h"
|
#include "console.h"
|
||||||
#include "memory_pages.h"
|
#include "memory_pages.h"
|
||||||
|
|
||||||
|
page_manager g_page_manager;
|
||||||
|
|
||||||
|
page_manager::page_manager() :
|
||||||
|
m_free(nullptr),
|
||||||
|
m_used(nullptr),
|
||||||
|
m_pool(nullptr)
|
||||||
|
{
|
||||||
|
kassert(this == &g_page_manager, "Attempt to create another page_manager.");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
page_block *
|
page_block *
|
||||||
page_block::list_consolidate()
|
page_block::list_consolidate()
|
||||||
{
|
{
|
||||||
page_block *cur = this;
|
|
||||||
page_block *freed_head = nullptr, **freed = &freed_head;
|
page_block *freed_head = nullptr, **freed = &freed_head;
|
||||||
|
for (page_block *cur = this; cur; cur = cur->next) {
|
||||||
while (cur) {
|
|
||||||
page_block *next = cur->next;
|
page_block *next = cur->next;
|
||||||
|
|
||||||
if (next && cur->flags == next->flags &&
|
if (next && cur->flags == next->flags &&
|
||||||
@@ -21,8 +31,6 @@ page_block::list_consolidate()
|
|||||||
freed = &next->next;
|
freed = &next->next;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur = next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return freed_head;
|
return freed_head;
|
||||||
|
|||||||
@@ -1,25 +1,51 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
/// \file memory_pages.h
|
/// \file memory_pages.h
|
||||||
/// Structures related to handling memory paging.
|
/// The page memory manager and related definitions.
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#include "kutil/enum_bitfields.h"
|
#include "kutil/enum_bitfields.h"
|
||||||
|
|
||||||
|
class page_block;
|
||||||
|
|
||||||
|
|
||||||
|
/// Manager for allocation of physical pages.
|
||||||
|
class page_manager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
page_manager();
|
||||||
|
|
||||||
|
page_manager(const page_manager &) = delete;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend void memory_initialize_managers(const void *, size_t, size_t);
|
||||||
|
|
||||||
|
/// Set up the memory manager from bootstraped memory
|
||||||
|
static void init(page_block *free, page_block *used, uint64_t scratch);
|
||||||
|
|
||||||
|
/// Initialize the virtual memory manager based on this object's state
|
||||||
|
void init_memory_manager();
|
||||||
|
|
||||||
|
page_block *m_free; ///< Free pages list
|
||||||
|
page_block *m_used; ///< In-use pages list
|
||||||
|
page_block *m_pool; ///< Cache of unused page_block structs
|
||||||
|
};
|
||||||
|
|
||||||
|
/// Global page manager.
|
||||||
|
extern page_manager g_page_manager;
|
||||||
|
|
||||||
|
|
||||||
/// Flags used by `page_block`.
|
/// Flags used by `page_block`.
|
||||||
enum class page_block_flags : uint32_t
|
enum class page_block_flags : uint32_t
|
||||||
{
|
{
|
||||||
// Not a flag value, but for comparison
|
free = 0x00000000, ///< Not a flag, value for free memory
|
||||||
free = 0x00000000,
|
used = 0x00000001, ///< Memory is in use
|
||||||
|
mapped = 0x00000002, ///< Memory is mapped to virtual address
|
||||||
|
pending_free = 0x00000004, ///< Memory should be freed
|
||||||
|
|
||||||
used = 0x00000001,
|
nonvolatile = 0x00000010, ///< Memory is non-volatile storage
|
||||||
mapped = 0x00000002,
|
acpi_wait = 0x00000020, ///< Memory should be freed after ACPI init
|
||||||
pending_free = 0x00000004,
|
permanent = 0x80000000, ///< Memory is permanently unusable
|
||||||
|
|
||||||
nonvolatile = 0x00000010,
|
|
||||||
acpi_wait = 0x00000020,
|
|
||||||
|
|
||||||
permanent = 0x80000000,
|
|
||||||
|
|
||||||
max_flags
|
max_flags
|
||||||
};
|
};
|
||||||
@@ -67,6 +93,7 @@ struct page_table_indices
|
|||||||
uint64_t index[4]; ///< Indices for each level of tables.
|
uint64_t index[4]; ///< Indices for each level of tables.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/// Calculate a page-aligned address.
|
/// Calculate a page-aligned address.
|
||||||
/// \arg p The address to align.
|
/// \arg p The address to align.
|
||||||
/// \returns The next page-aligned address _after_ `p`.
|
/// \returns The next page-aligned address _after_ `p`.
|
||||||
|
|||||||
Reference in New Issue
Block a user