summaryrefslogtreecommitdiffstats
path: root/src/core/hle/kernel/k_page_group.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/k_page_group.h')
-rw-r--r--src/core/hle/kernel/k_page_group.h163
1 files changed, 71 insertions, 92 deletions
diff --git a/src/core/hle/kernel/k_page_group.h b/src/core/hle/kernel/k_page_group.h
index c07f17663..316f172f2 100644
--- a/src/core/hle/kernel/k_page_group.h
+++ b/src/core/hle/kernel/k_page_group.h
@@ -1,4 +1,4 @@
-// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
+// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
@@ -13,23 +13,24 @@
namespace Kernel {
-class KBlockInfoManager;
-class KernelCore;
class KPageGroup;
class KBlockInfo {
+private:
+ friend class KPageGroup;
+
public:
- constexpr explicit KBlockInfo() : m_next(nullptr) {}
+ constexpr KBlockInfo() = default;
- constexpr void Initialize(KPhysicalAddress addr, size_t np) {
+ constexpr void Initialize(PAddr addr, size_t np) {
ASSERT(Common::IsAligned(addr, PageSize));
ASSERT(static_cast<u32>(np) == np);
- m_page_index = static_cast<u32>(addr / PageSize);
+ m_page_index = static_cast<u32>(addr) / PageSize;
m_num_pages = static_cast<u32>(np);
}
- constexpr KPhysicalAddress GetAddress() const {
+ constexpr PAddr GetAddress() const {
return m_page_index * PageSize;
}
constexpr size_t GetNumPages() const {
@@ -38,10 +39,10 @@ public:
constexpr size_t GetSize() const {
return this->GetNumPages() * PageSize;
}
- constexpr KPhysicalAddress GetEndAddress() const {
+ constexpr PAddr GetEndAddress() const {
return (m_page_index + m_num_pages) * PageSize;
}
- constexpr KPhysicalAddress GetLastAddress() const {
+ constexpr PAddr GetLastAddress() const {
return this->GetEndAddress() - 1;
}
@@ -61,8 +62,8 @@ public:
return !(*this == rhs);
}
- constexpr bool IsStrictlyBefore(KPhysicalAddress addr) const {
- const KPhysicalAddress end = this->GetEndAddress();
+ constexpr bool IsStrictlyBefore(PAddr addr) const {
+ const PAddr end = this->GetEndAddress();
if (m_page_index != 0 && end == 0) {
return false;
@@ -71,11 +72,11 @@ public:
return end < addr;
}
- constexpr bool operator<(KPhysicalAddress addr) const {
+ constexpr bool operator<(PAddr addr) const {
return this->IsStrictlyBefore(addr);
}
- constexpr bool TryConcatenate(KPhysicalAddress addr, size_t np) {
+ constexpr bool TryConcatenate(PAddr addr, size_t np) {
if (addr != 0 && addr == this->GetEndAddress()) {
m_num_pages += static_cast<u32>(np);
return true;
@@ -89,118 +90,96 @@ private:
}
private:
- friend class KPageGroup;
-
KBlockInfo* m_next{};
u32 m_page_index{};
u32 m_num_pages{};
};
static_assert(sizeof(KBlockInfo) <= 0x10);
-class KPageGroup {
+class KPageGroup final {
public:
- class Iterator {
+ class Node final {
public:
- using iterator_category = std::forward_iterator_tag;
- using value_type = const KBlockInfo;
- using difference_type = std::ptrdiff_t;
- using pointer = value_type*;
- using reference = value_type&;
-
- constexpr explicit Iterator(pointer n) : m_node(n) {}
-
- constexpr bool operator==(const Iterator& rhs) const {
- return m_node == rhs.m_node;
- }
- constexpr bool operator!=(const Iterator& rhs) const {
- return !(*this == rhs);
- }
+ constexpr Node(u64 addr_, std::size_t num_pages_) : addr{addr_}, num_pages{num_pages_} {}
- constexpr pointer operator->() const {
- return m_node;
- }
- constexpr reference operator*() const {
- return *m_node;
+ constexpr u64 GetAddress() const {
+ return addr;
}
- constexpr Iterator& operator++() {
- m_node = m_node->GetNext();
- return *this;
+ constexpr std::size_t GetNumPages() const {
+ return num_pages;
}
- constexpr Iterator operator++(int) {
- const Iterator it{*this};
- ++(*this);
- return it;
+ constexpr std::size_t GetSize() const {
+ return GetNumPages() * PageSize;
}
private:
- pointer m_node{};
+ u64 addr{};
+ std::size_t num_pages{};
};
- explicit KPageGroup(KernelCore& kernel, KBlockInfoManager* m)
- : m_kernel{kernel}, m_manager{m} {}
- ~KPageGroup() {
- this->Finalize();
+public:
+ KPageGroup() = default;
+ KPageGroup(u64 address, u64 num_pages) {
+ ASSERT(AddBlock(address, num_pages).IsSuccess());
}
- void CloseAndReset();
- void Finalize();
-
- Iterator begin() const {
- return Iterator{m_first_block};
- }
- Iterator end() const {
- return Iterator{nullptr};
- }
- bool empty() const {
- return m_first_block == nullptr;
+ constexpr std::list<Node>& Nodes() {
+ return nodes;
}
- Result AddBlock(KPhysicalAddress addr, size_t num_pages);
- void Open() const;
- void OpenFirst() const;
- void Close() const;
-
- size_t GetNumPages() const;
-
- bool IsEquivalentTo(const KPageGroup& rhs) const;
-
- bool operator==(const KPageGroup& rhs) const {
- return this->IsEquivalentTo(rhs);
+ constexpr const std::list<Node>& Nodes() const {
+ return nodes;
}
- bool operator!=(const KPageGroup& rhs) const {
- return !(*this == rhs);
- }
+ 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);
+ }
-private:
- KernelCore& m_kernel;
- KBlockInfo* m_first_block{};
- KBlockInfo* m_last_block{};
- KBlockInfoManager* m_manager{};
-};
+ return this_node == nodes.end() && other_node == other.nodes.end();
+ }
-class KScopedPageGroup {
-public:
- explicit KScopedPageGroup(const KPageGroup* gp) : m_pg(gp) {
- if (m_pg) {
- m_pg->Open();
+ Result AddBlock(u64 address, u64 num_pages) {
+ if (!num_pages) {
+ return ResultSuccess;
}
- }
- explicit KScopedPageGroup(const KPageGroup& gp) : KScopedPageGroup(std::addressof(gp)) {}
- ~KScopedPageGroup() {
- if (m_pg) {
- m_pg->Close();
+ 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;
}
- void CancelClose() {
- m_pg = nullptr;
+ bool Empty() const {
+ return nodes.empty();
}
+ void Finalize() {}
+
private:
- const KPageGroup* m_pg{};
+ std::list<Node> nodes;
};
} // namespace Kernel