From 7b48e7b363245fd88685f70c0ea39b4374688e3c Mon Sep 17 00:00:00 2001 From: german77 Date: Sat, 25 Jun 2022 23:15:31 -0500 Subject: core: kernel: Replace instances of KPageLinkedList with KPageGroup --- src/core/hle/kernel/k_page_group.h | 99 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 src/core/hle/kernel/k_page_group.h (limited to 'src/core/hle/kernel/k_page_group.h') diff --git a/src/core/hle/kernel/k_page_group.h b/src/core/hle/kernel/k_page_group.h new file mode 100644 index 000000000..968753992 --- /dev/null +++ b/src/core/hle/kernel/k_page_group.h @@ -0,0 +1,99 @@ +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include + +#include "common/assert.h" +#include "common/common_types.h" +#include "core/hle/kernel/memory_types.h" +#include "core/hle/result.h" + +namespace Kernel { + +class KPageGroup final { +public: + class Node final { + public: + constexpr Node(u64 addr_, std::size_t num_pages_) : addr{addr_}, num_pages{num_pages_} {} + + constexpr u64 GetAddress() const { + return addr; + } + + constexpr std::size_t GetNumPages() const { + return num_pages; + } + + constexpr std::size_t GetSize() const { + return GetNumPages() * PageSize; + } + + private: + u64 addr{}; + std::size_t num_pages{}; + }; + +public: + KPageGroup() = default; + KPageGroup(u64 address, u64 num_pages) { + ASSERT(AddBlock(address, num_pages).IsSuccess()); + } + + constexpr std::list& Nodes() { + return nodes; + } + + constexpr const std::list& Nodes() const { + return nodes; + } + + std::size_t GetNumPages() const { + std::size_t num_pages = 0; + for (const Node& node : nodes) { + num_pages += node.GetNumPages(); + } + return num_pages; + } + + bool IsEqual(KPageGroup& other) const { + auto this_node = nodes.begin(); + auto other_node = other.nodes.begin(); + while (this_node != nodes.end() && other_node != other.nodes.end()) { + if (this_node->GetAddress() != other_node->GetAddress() || + this_node->GetNumPages() != other_node->GetNumPages()) { + return false; + } + this_node = std::next(this_node); + other_node = std::next(other_node); + } + + return this_node == nodes.end() && other_node == other.nodes.end(); + } + + Result AddBlock(u64 address, u64 num_pages) { + if (!num_pages) { + return ResultSuccess; + } + if (!nodes.empty()) { + const auto node = nodes.back(); + if (node.GetAddress() + node.GetNumPages() * PageSize == address) { + address = node.GetAddress(); + num_pages += node.GetNumPages(); + nodes.pop_back(); + } + } + nodes.push_back({address, num_pages}); + return ResultSuccess; + } + + bool Empty() const { + return nodes.empty(); + } + +private: + std::list nodes; +}; + +} // namespace Kernel -- cgit v1.2.3