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:
Justin C. Miller
2018-04-21 17:34:33 -07:00
parent 4a38a74b16
commit 57abb03deb
6 changed files with 68 additions and 30 deletions

View File

@@ -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);

View File

@@ -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.");
} }

View File

@@ -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);

View File

@@ -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();

View File

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

View File

@@ -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`.