mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 08:24:32 -08:00
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);
|
||||
|
||||
memory_manager::create(
|
||||
memory_initialize_managers(
|
||||
header->memory_map,
|
||||
header->memory_map_length,
|
||||
header->memory_map_desc_size);
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
#include "memory.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
|
||||
/// \file memory.h
|
||||
/// The block memory manager and related definitions.
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct page_block;
|
||||
|
||||
/// Manager for allocation of virtual memory.
|
||||
class memory_manager
|
||||
{
|
||||
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;
|
||||
|
||||
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
|
||||
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();
|
||||
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
#include "assert.h"
|
||||
#include "console.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::list_consolidate()
|
||||
{
|
||||
page_block *cur = this;
|
||||
page_block *freed_head = nullptr, **freed = &freed_head;
|
||||
|
||||
while (cur) {
|
||||
for (page_block *cur = this; cur; cur = cur->next) {
|
||||
page_block *next = cur->next;
|
||||
|
||||
if (next && cur->flags == next->flags &&
|
||||
@@ -21,8 +31,6 @@ page_block::list_consolidate()
|
||||
freed = &next->next;
|
||||
continue;
|
||||
}
|
||||
|
||||
cur = next;
|
||||
}
|
||||
|
||||
return freed_head;
|
||||
|
||||
@@ -1,25 +1,51 @@
|
||||
#pragma once
|
||||
/// \file memory_pages.h
|
||||
/// Structures related to handling memory paging.
|
||||
/// The page memory manager and related definitions.
|
||||
|
||||
#include <stdint.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`.
|
||||
enum class page_block_flags : uint32_t
|
||||
{
|
||||
// Not a flag value, but for comparison
|
||||
free = 0x00000000,
|
||||
free = 0x00000000, ///< Not a flag, value for free memory
|
||||
used = 0x00000001, ///< Memory is in use
|
||||
mapped = 0x00000002, ///< Memory is mapped to virtual address
|
||||
pending_free = 0x00000004, ///< Memory should be freed
|
||||
|
||||
used = 0x00000001,
|
||||
mapped = 0x00000002,
|
||||
pending_free = 0x00000004,
|
||||
|
||||
nonvolatile = 0x00000010,
|
||||
acpi_wait = 0x00000020,
|
||||
|
||||
permanent = 0x80000000,
|
||||
nonvolatile = 0x00000010, ///< Memory is non-volatile storage
|
||||
acpi_wait = 0x00000020, ///< Memory should be freed after ACPI init
|
||||
permanent = 0x80000000, ///< Memory is permanently unusable
|
||||
|
||||
max_flags
|
||||
};
|
||||
@@ -67,6 +93,7 @@ struct page_table_indices
|
||||
uint64_t index[4]; ///< Indices for each level of tables.
|
||||
};
|
||||
|
||||
|
||||
/// Calculate a page-aligned address.
|
||||
/// \arg p The address to align.
|
||||
/// \returns The next page-aligned address _after_ `p`.
|
||||
|
||||
Reference in New Issue
Block a user