From f9f047f519d0100c40b914d3ce777ac2f8430b38 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matteo=20Gm=C3=BCr?= Date: Mon, 28 Oct 2024 15:18:31 +0000 Subject: Add is empty check method for page table --- arch/x86_64/src/memory/paging/page_table.cpp | 55 ++++++++++++---------------- 1 file changed, 23 insertions(+), 32 deletions(-) (limited to 'arch/x86_64/src/memory/paging') diff --git a/arch/x86_64/src/memory/paging/page_table.cpp b/arch/x86_64/src/memory/paging/page_table.cpp index a01c431..64a4fd9 100644 --- a/arch/x86_64/src/memory/paging/page_table.cpp +++ b/arch/x86_64/src/memory/paging/page_table.cpp @@ -1,5 +1,6 @@ #include "arch/memory/paging/page_table.hpp" +#include #include #include @@ -16,31 +17,16 @@ namespace teachos::arch::memory::paging */ struct page_table { - /** - * @brief Set every entry of the page to unused. - */ auto zero_entries() -> void; - /** - * @brief Returns the next page table level from the given page table index. Meaning we use an index into a Level 4 - * page table to get the according Level 3 page table. - * - * @note This method - * should not be called on a Level 1 page table, because there is no furthere page table and mangeling up and - * returning the physical address would cause hard to debug issues. - * - * @param table_index Index of this page table in the page table one level lower. - */ - auto next_table(std::size_t table_index) -> std::optional; + auto is_empty() const -> bool; + + auto next_table(std::size_t table_index) const -> std::optional; - /** - * @brief Index operator overload to access specific entries directy. - * - * @param index Index of the entry we want to access and read or write too. - * @return Entry at the given table index. - */ auto operator[](std::size_t index) -> entry &; + auto operator[](std::size_t index) const -> entry const &; + private: /** * @brief Calculates the address of the next page table level for the given table index. @@ -51,7 +37,7 @@ namespace teachos::arch::memory::paging * @param table_index Index of this page table in the page table one level higher. * @return An optional of the address of the next page table or null. */ - auto next_table_address(std::size_t table_index) -> std::optional; + auto next_table_address(std::size_t table_index) const -> std::optional; std::array entries = {}; ///< Entries containing addresses to page tables of a level below or @@ -60,16 +46,15 @@ namespace teachos::arch::memory::paging auto page_table::zero_entries() -> void { - std::size_t constexpr entry_amount = sizeof(entries) / sizeof(entries[0]); - static_assert(entry_amount == PAGE_TABLE_ENTRY_COUNT); - for (std::size_t i = 0; i < entry_amount; ++i) - { - auto entry = this->operator[](i); - entry.set_unused(); - } + std::ranges::for_each(entries, [](entry & entry) { entry.set_unused(); }); + } + + auto page_table::is_empty() const -> bool + { + return std::all_of(entries.begin(), entries.end(), [](entry const & entry) { return entry.is_unused(); }); } - auto page_table::next_table(std::size_t table_index) -> std::optional + auto page_table::next_table(std::size_t table_index) const -> std::optional { auto const address = next_table_address(table_index); if (address.has_value()) @@ -81,13 +66,17 @@ namespace teachos::arch::memory::paging auto page_table::operator[](std::size_t index) -> entry & { - // C array is not bounds checked, therefore we have to check ourselves, to ensure no out of bounds reads, which - // could be incredibly hard to debug later. exception_handling::assert(index < PAGE_TABLE_ENTRY_COUNT, "[Page Table] Index out of bounds"); return entries[index]; } - auto page_table::next_table_address(std::size_t table_index) -> std::optional + auto page_table::operator[](std::size_t index) const -> entry const & + { + exception_handling::assert(index < PAGE_TABLE_ENTRY_COUNT, "[Page Table] Index out of bounds"); + return entries[index]; + } + + auto page_table::next_table_address(std::size_t table_index) const -> std::optional { auto const entry = this->operator[](table_index); @@ -130,6 +119,8 @@ namespace teachos::arch::memory::paging auto page_table_handle::zero_entries() -> void { handle->zero_entries(); } + auto page_table_handle::is_empty() const -> bool { return handle->is_empty(); } + auto page_table_handle::next_table(std::size_t table_index) -> std::optional { exception_handling::assert(handle_level != page_table_handle::LEVEL1, -- cgit v1.2.3