summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/kernel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
-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 @@
7#include <bitset> 7#include <bitset>
8#include <functional> 8#include <functional>
9#include <memory> 9#include <memory>
10#include <mutex>
11#include <thread> 10#include <thread>
12#include <unordered_map> 11#include <unordered_map>
13#include <utility> 12#include <utility>
@@ -107,7 +106,11 @@ struct KernelCore::Impl {
107 cores.clear(); 106 cores.clear();
108 107
109 exclusive_monitor.reset(); 108 exclusive_monitor.reset();
110 host_thread_ids.clear(); 109
110 num_host_threads = 0;
111 std::fill(register_host_thread_keys.begin(), register_host_thread_keys.end(),
112 std::thread::id{});
113 std::fill(register_host_thread_values.begin(), register_host_thread_values.end(), 0);
111 } 114 }
112 115
113 void InitializePhysicalCores() { 116 void InitializePhysicalCores() {
@@ -177,54 +180,56 @@ struct KernelCore::Impl {
177 180
178 void MakeCurrentProcess(Process* process) { 181 void MakeCurrentProcess(Process* process) {
179 current_process = process; 182 current_process = process;
180
181 if (process == nullptr) { 183 if (process == nullptr) {
182 return; 184 return;
183 } 185 }
184 186 const u32 core_id = GetCurrentHostThreadID();
185 u32 core_id = GetCurrentHostThreadID();
186 if (core_id < Core::Hardware::NUM_CPU_CORES) { 187 if (core_id < Core::Hardware::NUM_CPU_CORES) {
187 system.Memory().SetCurrentPageTable(*process, core_id); 188 system.Memory().SetCurrentPageTable(*process, core_id);
188 } 189 }
189 } 190 }
190 191
191 void RegisterCoreThread(std::size_t core_id) { 192 void RegisterCoreThread(std::size_t core_id) {
192 std::unique_lock lock{register_thread_mutex}; 193 const std::thread::id this_id = std::this_thread::get_id();
193 if (!is_multicore) { 194 if (!is_multicore) {
194 single_core_thread_id = std::this_thread::get_id(); 195 single_core_thread_id = this_id;
195 } 196 }
196 const std::thread::id this_id = std::this_thread::get_id(); 197 const auto end = register_host_thread_keys.begin() + num_host_threads;
197 const auto it = host_thread_ids.find(this_id); 198 const auto it = std::find(register_host_thread_keys.begin(), end, this_id);
198 ASSERT(core_id < Core::Hardware::NUM_CPU_CORES); 199 ASSERT(core_id < Core::Hardware::NUM_CPU_CORES);
199 ASSERT(it == host_thread_ids.end()); 200 ASSERT(it == end);
200 ASSERT(!registered_core_threads[core_id]); 201 ASSERT(!registered_core_threads[core_id]);
201 host_thread_ids[this_id] = static_cast<u32>(core_id); 202 InsertHostThread(static_cast<u32>(core_id));
202 registered_core_threads.set(core_id); 203 registered_core_threads.set(core_id);
203 } 204 }
204 205
205 void RegisterHostThread() { 206 void RegisterHostThread() {
206 std::unique_lock lock{register_thread_mutex};
207 const std::thread::id this_id = std::this_thread::get_id(); 207 const std::thread::id this_id = std::this_thread::get_id();
208 const auto it = host_thread_ids.find(this_id); 208 const auto end = register_host_thread_keys.begin() + num_host_threads;
209 if (it != host_thread_ids.end()) { 209 const auto it = std::find(register_host_thread_keys.begin(), end, this_id);
210 return; 210 if (it == end) {
211 InsertHostThread(registered_thread_ids++);
211 } 212 }
212 host_thread_ids[this_id] = registered_thread_ids++;
213 } 213 }
214 214
215 u32 GetCurrentHostThreadID() const { 215 void InsertHostThread(u32 value) {
216 const size_t index = num_host_threads++;
217 ASSERT_MSG(index < NUM_REGISTRABLE_HOST_THREADS, "Too many host threads");
218 register_host_thread_values[index] = value;
219 register_host_thread_keys[index] = std::this_thread::get_id();
220 }
221
222 [[nodiscard]] u32 GetCurrentHostThreadID() const {
216 const std::thread::id this_id = std::this_thread::get_id(); 223 const std::thread::id this_id = std::this_thread::get_id();
217 if (!is_multicore) { 224 if (!is_multicore && single_core_thread_id == this_id) {
218 if (single_core_thread_id == this_id) { 225 return static_cast<u32>(system.GetCpuManager().CurrentCore());
219 return static_cast<u32>(system.GetCpuManager().CurrentCore());
220 }
221 } 226 }
222 std::unique_lock lock{register_thread_mutex}; 227 const auto end = register_host_thread_keys.begin() + num_host_threads;
223 const auto it = host_thread_ids.find(this_id); 228 const auto it = std::find(register_host_thread_keys.begin(), end, this_id);
224 if (it == host_thread_ids.end()) { 229 if (it == end) {
225 return Core::INVALID_HOST_THREAD_ID; 230 return Core::INVALID_HOST_THREAD_ID;
226 } 231 }
227 return it->second; 232 return register_host_thread_values[std::distance(register_host_thread_keys.begin(), it)];
228 } 233 }
229 234
230 Core::EmuThreadHandle GetCurrentEmuThreadID() const { 235 Core::EmuThreadHandle GetCurrentEmuThreadID() const {
@@ -322,10 +327,15 @@ struct KernelCore::Impl {
322 std::vector<Kernel::PhysicalCore> cores; 327 std::vector<Kernel::PhysicalCore> cores;
323 328
324 // 0-3 IDs represent core threads, >3 represent others 329 // 0-3 IDs represent core threads, >3 represent others
325 std::unordered_map<std::thread::id, u32> host_thread_ids; 330 std::atomic<u32> registered_thread_ids{Core::Hardware::NUM_CPU_CORES};
326 u32 registered_thread_ids{Core::Hardware::NUM_CPU_CORES};
327 std::bitset<Core::Hardware::NUM_CPU_CORES> registered_core_threads; 331 std::bitset<Core::Hardware::NUM_CPU_CORES> registered_core_threads;
328 mutable std::mutex register_thread_mutex; 332
333 // Number of host threads is a relatively high number to avoid overflowing
334 static constexpr size_t NUM_REGISTRABLE_HOST_THREADS = 64;
335 std::atomic<size_t> num_host_threads{0};
336 std::array<std::atomic<std::thread::id>, NUM_REGISTRABLE_HOST_THREADS>
337 register_host_thread_keys{};
338 std::array<std::atomic<u32>, NUM_REGISTRABLE_HOST_THREADS> register_host_thread_values{};
329 339
330 // Kernel memory management 340 // Kernel memory management
331 std::unique_ptr<Memory::MemoryManager> memory_manager; 341 std::unique_ptr<Memory::MemoryManager> memory_manager;