summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar --author=Liam2023-11-17 20:25:23 +0200
committerGravatar t8952023-11-25 00:46:15 -0500
commit29e7d79a869090a39127442cb9553bf46a8cd009 (patch)
treeab78918937ec14a0559312411d944aec18cfb659 /src
parentcommon: Add libc sigaction hook (diff)
downloadyuzu-29e7d79a869090a39127442cb9553bf46a8cd009.tar.gz
yuzu-29e7d79a869090a39127442cb9553bf46a8cd009.tar.xz
yuzu-29e7d79a869090a39127442cb9553bf46a8cd009.zip
common: Add free region manager
* Abstraction for placeholder region tracking in host_memory
Diffstat (limited to 'src')
-rw-r--r--src/common/CMakeLists.txt1
-rw-r--r--src/common/free_region_manager.h55
2 files changed, 56 insertions, 0 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 7107f4f78..98fd5f1e4 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -52,6 +52,7 @@ add_library(common STATIC
52 fiber.cpp 52 fiber.cpp
53 fiber.h 53 fiber.h
54 fixed_point.h 54 fixed_point.h
55 free_region_manager.h
55 fs/file.cpp 56 fs/file.cpp
56 fs/file.h 57 fs/file.h
57 fs/fs.cpp 58 fs/fs.cpp
diff --git a/src/common/free_region_manager.h b/src/common/free_region_manager.h
new file mode 100644
index 000000000..2e590d609
--- /dev/null
+++ b/src/common/free_region_manager.h
@@ -0,0 +1,55 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <mutex>
7#include <boost/icl/interval_set.hpp>
8
9namespace Common {
10
11class FreeRegionManager {
12public:
13 explicit FreeRegionManager() = default;
14 ~FreeRegionManager() = default;
15
16 void SetAddressSpace(void* start, size_t size) {
17 this->FreeBlock(start, size);
18 }
19
20 std::pair<void*, size_t> FreeBlock(void* block_ptr, size_t size) {
21 std::scoped_lock lk(m_mutex);
22
23 // Check to see if we are adjacent to any regions.
24 auto start_address = reinterpret_cast<uintptr_t>(block_ptr);
25 auto end_address = start_address + size;
26 auto it = m_free_regions.find({start_address - 1, end_address + 1});
27
28 // If we are, join with them, ensuring we stay in bounds.
29 if (it != m_free_regions.end()) {
30 start_address = std::min(start_address, it->lower());
31 end_address = std::max(end_address, it->upper());
32 }
33
34 // Free the relevant region.
35 m_free_regions.insert({start_address, end_address});
36
37 // Return the adjusted pointers.
38 block_ptr = reinterpret_cast<void*>(start_address);
39 size = end_address - start_address;
40 return {block_ptr, size};
41 }
42
43 void AllocateBlock(void* block_ptr, size_t size) {
44 std::scoped_lock lk(m_mutex);
45
46 auto address = reinterpret_cast<uintptr_t>(block_ptr);
47 m_free_regions.subtract({address, address + size});
48 }
49
50private:
51 std::mutex m_mutex;
52 boost::icl::interval_set<uintptr_t> m_free_regions;
53};
54
55} // namespace Common