mirror of
https://github.com/justinian/jsix.git
synced 2025-12-10 08:24:32 -08:00
This ended up being unused, but still probably useful: Refactor out the "find" logic of page_tree::find_or_add (note that this is different than the "find" logic of page_tree::find, as it potentially modifies the tree to add a location to accommodate the page being searched for) into a new page_tree::get_entry method. That was then used to add an add_existing method for inserting pages into the page_tree.
60 lines
2.3 KiB
C++
60 lines
2.3 KiB
C++
#pragma once
|
|
/// \file page_tree.h
|
|
/// Definition of mapped page tracking structure and related definitions
|
|
|
|
#include <stdint.h>
|
|
|
|
/// A radix tree node that tracks mapped pages
|
|
class page_tree
|
|
{
|
|
public:
|
|
/// Get the physical address of the page at the given offset.
|
|
/// \arg root The root node of the tree
|
|
/// \arg offset Offset into the VMA, in bytes
|
|
/// \arg page [out] Receives the page physical address, if found
|
|
/// \returns True if a page was found
|
|
static bool find(const page_tree *root, uint64_t offset, uintptr_t &page);
|
|
|
|
/// Get the physical address of the page at the given offset. If one does
|
|
/// not exist yet, allocate a page, insert it, and return that.
|
|
/// \arg root [inout] The root node of the tree. This pointer may be updated.
|
|
/// \arg offset Offset into the VMA, in bytes
|
|
/// \arg page [out] Receives the page physical address, if found
|
|
/// \returns True if a page was found
|
|
static bool find_or_add(page_tree * &root, uint64_t offset, uintptr_t &page);
|
|
|
|
/// Add an existing mapping not allocated via find_or_add.
|
|
/// \arg root [inout] The root node of the tree. This pointer may be updated.
|
|
/// \arg offset Offset into the VMA, in bytes
|
|
/// \arg page The mapped page physical address
|
|
static void add_existing(page_tree * &root, uint64_t offset, uintptr_t page);
|
|
|
|
~page_tree();
|
|
|
|
private:
|
|
page_tree(uint64_t base, uint8_t level);
|
|
|
|
/// Check if this node should contain the given virtual address
|
|
/// \arg offset The offset into the VMA, in bytes
|
|
/// \arg index [out] If found, what entry index should contain addr
|
|
/// \returns True if the address is contained
|
|
bool contains(uintptr_t offset, uint8_t &index) const;
|
|
|
|
/// Get a (writable) reference to a page in the tree
|
|
static uintptr_t & get_entry(page_tree * &root, uint64_t offset);
|
|
|
|
/// Stores the page offset of the start of this node's pages virtual addresses
|
|
uint64_t m_base;
|
|
|
|
/// Level of this node: 0 maps actual physical pages. Other levels N point to
|
|
/// nodes of level N-1.
|
|
uint8_t m_level;
|
|
|
|
/// For a level 0 node, the entries area all physical page addresses.
|
|
/// Other nodes contain pointers to child tree nodes.
|
|
union {
|
|
uintptr_t entry;
|
|
page_tree *child;
|
|
} m_entries[64];
|
|
};
|