summaryrefslogtreecommitdiffstats
path: root/src/core/hle
diff options
context:
space:
mode:
authorbunnei <bunneidev@gmail.com>2020-10-20 07:31:52 +0200
committerGitHub <noreply@github.com>2020-10-20 07:31:52 +0200
commit60bd54776adbc9c243fbd9702828b21a4c8570f2 (patch)
tree595dccda53a6fd1d75c6e1f5acd6f815e9f1850c /src/core/hle
parentMerge pull request #4785 from Morph1984/fs-hades (diff)
parentkernel: Implement host thread register methods without locking (diff)
downloadyuzu-60bd54776adbc9c243fbd9702828b21a4c8570f2.tar
yuzu-60bd54776adbc9c243fbd9702828b21a4c8570f2.tar.gz
yuzu-60bd54776adbc9c243fbd9702828b21a4c8570f2.tar.bz2
yuzu-60bd54776adbc9c243fbd9702828b21a4c8570f2.tar.lz
yuzu-60bd54776adbc9c243fbd9702828b21a4c8570f2.tar.xz
yuzu-60bd54776adbc9c243fbd9702828b21a4c8570f2.tar.zst
yuzu-60bd54776adbc9c243fbd9702828b21a4c8570f2.zip
Diffstat (limited to 'src/core/hle')
-rw-r--r--src/core/hle/kernel/kernel.cpp66
1 files changed, 38 insertions, 28 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index f2b0fe2fd..96ca01194 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -7,7 +7,6 @@
#include <bitset>
#include <functional>
#include <memory>
-#include <mutex>
#include <thread>
#include <unordered_map>
#include <utility>
@@ -107,7 +106,11 @@ struct KernelCore::Impl {
cores.clear();
exclusive_monitor.reset();
- host_thread_ids.clear();
+
+ num_host_threads = 0;
+ std::fill(register_host_thread_keys.begin(), register_host_thread_keys.end(),
+ std::thread::id{});
+ std::fill(register_host_thread_values.begin(), register_host_thread_values.end(), 0);
}
void InitializePhysicalCores() {
@@ -177,54 +180,56 @@ struct KernelCore::Impl {
void MakeCurrentProcess(Process* process) {
current_process = process;
-
if (process == nullptr) {
return;
}
-
- u32 core_id = GetCurrentHostThreadID();
+ const u32 core_id = GetCurrentHostThreadID();
if (core_id < Core::Hardware::NUM_CPU_CORES) {
system.Memory().SetCurrentPageTable(*process, core_id);
}
}
void RegisterCoreThread(std::size_t core_id) {
- std::unique_lock lock{register_thread_mutex};
+ const std::thread::id this_id = std::this_thread::get_id();
if (!is_multicore) {
- single_core_thread_id = std::this_thread::get_id();
+ single_core_thread_id = this_id;
}
- const std::thread::id this_id = std::this_thread::get_id();
- const auto it = host_thread_ids.find(this_id);
+ const auto end = register_host_thread_keys.begin() + num_host_threads;
+ const auto it = std::find(register_host_thread_keys.begin(), end, this_id);
ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
- ASSERT(it == host_thread_ids.end());
+ ASSERT(it == end);
ASSERT(!registered_core_threads[core_id]);
- host_thread_ids[this_id] = static_cast<u32>(core_id);
+ InsertHostThread(static_cast<u32>(core_id));
registered_core_threads.set(core_id);
}
void RegisterHostThread() {
- std::unique_lock lock{register_thread_mutex};
const std::thread::id this_id = std::this_thread::get_id();
- const auto it = host_thread_ids.find(this_id);
- if (it != host_thread_ids.end()) {
- return;
+ const auto end = register_host_thread_keys.begin() + num_host_threads;
+ const auto it = std::find(register_host_thread_keys.begin(), end, this_id);
+ if (it == end) {
+ InsertHostThread(registered_thread_ids++);
}
- host_thread_ids[this_id] = registered_thread_ids++;
}
- u32 GetCurrentHostThreadID() const {
+ void InsertHostThread(u32 value) {
+ const size_t index = num_host_threads++;
+ ASSERT_MSG(index < NUM_REGISTRABLE_HOST_THREADS, "Too many host threads");
+ register_host_thread_values[index] = value;
+ register_host_thread_keys[index] = std::this_thread::get_id();
+ }
+
+ [[nodiscard]] u32 GetCurrentHostThreadID() const {
const std::thread::id this_id = std::this_thread::get_id();
- if (!is_multicore) {
- if (single_core_thread_id == this_id) {
- return static_cast<u32>(system.GetCpuManager().CurrentCore());
- }
+ if (!is_multicore && single_core_thread_id == this_id) {
+ return static_cast<u32>(system.GetCpuManager().CurrentCore());
}
- std::unique_lock lock{register_thread_mutex};
- const auto it = host_thread_ids.find(this_id);
- if (it == host_thread_ids.end()) {
+ const auto end = register_host_thread_keys.begin() + num_host_threads;
+ const auto it = std::find(register_host_thread_keys.begin(), end, this_id);
+ if (it == end) {
return Core::INVALID_HOST_THREAD_ID;
}
- return it->second;
+ return register_host_thread_values[std::distance(register_host_thread_keys.begin(), it)];
}
Core::EmuThreadHandle GetCurrentEmuThreadID() const {
@@ -322,10 +327,15 @@ struct KernelCore::Impl {
std::vector<Kernel::PhysicalCore> cores;
// 0-3 IDs represent core threads, >3 represent others
- std::unordered_map<std::thread::id, u32> host_thread_ids;
- u32 registered_thread_ids{Core::Hardware::NUM_CPU_CORES};
+ std::atomic<u32> registered_thread_ids{Core::Hardware::NUM_CPU_CORES};
std::bitset<Core::Hardware::NUM_CPU_CORES> registered_core_threads;
- mutable std::mutex register_thread_mutex;
+
+ // Number of host threads is a relatively high number to avoid overflowing
+ static constexpr size_t NUM_REGISTRABLE_HOST_THREADS = 64;
+ std::atomic<size_t> num_host_threads{0};
+ std::array<std::atomic<std::thread::id>, NUM_REGISTRABLE_HOST_THREADS>
+ register_host_thread_keys{};
+ std::array<std::atomic<u32>, NUM_REGISTRABLE_HOST_THREADS> register_host_thread_values{};
// Kernel memory management
std::unique_ptr<Memory::MemoryManager> memory_manager;