summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/core/core.cpp16
-rw-r--r--src/core/core.h8
-rw-r--r--src/core/hle/ipc_helpers.h5
-rw-r--r--src/core/hle/kernel/client_port.cpp4
-rw-r--r--src/core/hle/kernel/client_port.h5
-rw-r--r--src/core/hle/kernel/client_session.cpp2
-rw-r--r--src/core/hle/kernel/client_session.h5
-rw-r--r--src/core/hle/kernel/event.cpp8
-rw-r--r--src/core/hle/kernel/event.h8
-rw-r--r--src/core/hle/kernel/handle_table.cpp2
-rw-r--r--src/core/hle/kernel/handle_table.h2
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp17
-rw-r--r--src/core/hle/kernel/kernel.cpp283
-rw-r--r--src/core/hle/kernel/kernel.h89
-rw-r--r--src/core/hle/kernel/mutex.cpp6
-rw-r--r--src/core/hle/kernel/mutex.h5
-rw-r--r--src/core/hle/kernel/object.cpp2
-rw-r--r--src/core/hle/kernel/object.h10
-rw-r--r--src/core/hle/kernel/process.cpp40
-rw-r--r--src/core/hle/kernel/process.h21
-rw-r--r--src/core/hle/kernel/resource_limit.cpp85
-rw-r--r--src/core/hle/kernel/resource_limit.h19
-rw-r--r--src/core/hle/kernel/server_port.cpp10
-rw-r--r--src/core/hle/kernel/server_port.h6
-rw-r--r--src/core/hle/kernel/server_session.cpp17
-rw-r--r--src/core/hle/kernel/server_session.h14
-rw-r--r--src/core/hle/kernel/shared_memory.cpp20
-rw-r--r--src/core/hle/kernel/shared_memory.h13
-rw-r--r--src/core/hle/kernel/svc.cpp80
-rw-r--r--src/core/hle/kernel/thread.cpp119
-rw-r--r--src/core/hle/kernel/thread.h22
-rw-r--r--src/core/hle/kernel/timer.cpp45
-rw-r--r--src/core/hle/kernel/timer.h13
-rw-r--r--src/core/hle/kernel/wait_object.cpp3
-rw-r--r--src/core/hle/kernel/wait_object.h4
-rw-r--r--src/core/hle/service/am/am.cpp9
-rw-r--r--src/core/hle/service/audio/audout_u.cpp4
-rw-r--r--src/core/hle/service/audio/audren_u.cpp8
-rw-r--r--src/core/hle/service/hid/hid.cpp9
-rw-r--r--src/core/hle/service/nfp/nfp.cpp10
-rw-r--r--src/core/hle/service/nifm/nifm.cpp6
-rw-r--r--src/core/hle/service/ns/pl_u.cpp3
-rw-r--r--src/core/hle/service/nvdrv/interface.cpp4
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue.cpp4
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.cpp3
-rw-r--r--src/core/hle/service/service.cpp9
-rw-r--r--src/core/hle/service/sm/sm.cpp5
-rw-r--r--src/core/loader/deconstructed_rom_directory.cpp4
-rw-r--r--src/core/loader/elf.cpp7
-rw-r--r--src/core/loader/nro.cpp6
-rw-r--r--src/core/loader/nso.cpp6
-rw-r--r--src/tests/core/arm/arm_test_common.cpp2
-rw-r--r--src/tests/core/arm/arm_test_common.h2
-rw-r--r--src/yuzu/debugger/wait_tree.cpp4
54 files changed, 671 insertions, 442 deletions
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 07da4c493..2293669e5 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -171,6 +171,14 @@ const std::shared_ptr<Kernel::Scheduler>& System::Scheduler(size_t core_index) {
171 return cpu_cores[core_index]->Scheduler(); 171 return cpu_cores[core_index]->Scheduler();
172} 172}
173 173
174Kernel::KernelCore& System::Kernel() {
175 return kernel;
176}
177
178const Kernel::KernelCore& System::Kernel() const {
179 return kernel;
180}
181
174ARM_Interface& System::ArmInterface(size_t core_index) { 182ARM_Interface& System::ArmInterface(size_t core_index) {
175 ASSERT(core_index < NUM_CPU_CORES); 183 ASSERT(core_index < NUM_CPU_CORES);
176 return cpu_cores[core_index]->ArmInterface(); 184 return cpu_cores[core_index]->ArmInterface();
@@ -185,12 +193,13 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) {
185 LOG_DEBUG(HW_Memory, "initialized OK"); 193 LOG_DEBUG(HW_Memory, "initialized OK");
186 194
187 CoreTiming::Init(); 195 CoreTiming::Init();
196 kernel.Initialize();
188 197
189 // Create a default fs if one doesn't already exist. 198 // Create a default fs if one doesn't already exist.
190 if (virtual_filesystem == nullptr) 199 if (virtual_filesystem == nullptr)
191 virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>(); 200 virtual_filesystem = std::make_shared<FileSys::RealVfsFilesystem>();
192 201
193 current_process = Kernel::Process::Create("main"); 202 current_process = Kernel::Process::Create(kernel, "main");
194 203
195 cpu_barrier = std::make_shared<CpuBarrier>(); 204 cpu_barrier = std::make_shared<CpuBarrier>();
196 cpu_exclusive_monitor = Cpu::MakeExclusiveMonitor(cpu_cores.size()); 205 cpu_exclusive_monitor = Cpu::MakeExclusiveMonitor(cpu_cores.size());
@@ -201,7 +210,6 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) {
201 telemetry_session = std::make_unique<Core::TelemetrySession>(); 210 telemetry_session = std::make_unique<Core::TelemetrySession>();
202 service_manager = std::make_shared<Service::SM::ServiceManager>(); 211 service_manager = std::make_shared<Service::SM::ServiceManager>();
203 212
204 Kernel::Init();
205 Service::Init(service_manager, virtual_filesystem); 213 Service::Init(service_manager, virtual_filesystem);
206 GDBStub::Init(); 214 GDBStub::Init();
207 215
@@ -246,7 +254,6 @@ void System::Shutdown() {
246 renderer.reset(); 254 renderer.reset();
247 GDBStub::Shutdown(); 255 GDBStub::Shutdown();
248 Service::Shutdown(); 256 Service::Shutdown();
249 Kernel::Shutdown();
250 service_manager.reset(); 257 service_manager.reset();
251 telemetry_session.reset(); 258 telemetry_session.reset();
252 gpu_core.reset(); 259 gpu_core.reset();
@@ -265,7 +272,8 @@ void System::Shutdown() {
265 } 272 }
266 cpu_barrier.reset(); 273 cpu_barrier.reset();
267 274
268 // Close core timing 275 // Shutdown kernel and core timing
276 kernel.Shutdown();
269 CoreTiming::Shutdown(); 277 CoreTiming::Shutdown();
270 278
271 // Close app loader 279 // Close app loader
diff --git a/src/core/core.h b/src/core/core.h
index 321104585..2c18f7193 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -12,6 +12,7 @@
12#include "common/common_types.h" 12#include "common/common_types.h"
13#include "core/arm/exclusive_monitor.h" 13#include "core/arm/exclusive_monitor.h"
14#include "core/core_cpu.h" 14#include "core/core_cpu.h"
15#include "core/hle/kernel/kernel.h"
15#include "core/hle/kernel/object.h" 16#include "core/hle/kernel/object.h"
16#include "core/hle/kernel/scheduler.h" 17#include "core/hle/kernel/scheduler.h"
17#include "core/loader/loader.h" 18#include "core/loader/loader.h"
@@ -188,6 +189,12 @@ public:
188 return current_process; 189 return current_process;
189 } 190 }
190 191
192 /// Provides a reference to the kernel instance.
193 Kernel::KernelCore& Kernel();
194
195 /// Provides a constant reference to the kernel instance.
196 const Kernel::KernelCore& Kernel() const;
197
191 /// Gets the name of the current game 198 /// Gets the name of the current game
192 Loader::ResultStatus GetGameName(std::string& out) const { 199 Loader::ResultStatus GetGameName(std::string& out) const {
193 if (app_loader == nullptr) 200 if (app_loader == nullptr)
@@ -246,6 +253,7 @@ private:
246 */ 253 */
247 ResultStatus Init(Frontend::EmuWindow& emu_window); 254 ResultStatus Init(Frontend::EmuWindow& emu_window);
248 255
256 Kernel::KernelCore kernel;
249 /// RealVfsFilesystem instance 257 /// RealVfsFilesystem instance
250 FileSys::VirtualFilesystem virtual_filesystem; 258 FileSys::VirtualFilesystem virtual_filesystem;
251 /// AppLoader used to load the current executing application 259 /// AppLoader used to load the current executing application
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h
index d3a734831..0f3ffdb60 100644
--- a/src/core/hle/ipc_helpers.h
+++ b/src/core/hle/ipc_helpers.h
@@ -12,6 +12,7 @@
12#include <utility> 12#include <utility>
13#include "common/assert.h" 13#include "common/assert.h"
14#include "common/common_types.h" 14#include "common/common_types.h"
15#include "core/core.h"
15#include "core/hle/ipc.h" 16#include "core/hle/ipc.h"
16#include "core/hle/kernel/client_port.h" 17#include "core/hle/kernel/client_port.h"
17#include "core/hle/kernel/client_session.h" 18#include "core/hle/kernel/client_session.h"
@@ -135,7 +136,9 @@ public:
135 if (context->Session()->IsDomain()) { 136 if (context->Session()->IsDomain()) {
136 context->AddDomainObject(std::move(iface)); 137 context->AddDomainObject(std::move(iface));
137 } else { 138 } else {
138 auto sessions = Kernel::ServerSession::CreateSessionPair(iface->GetServiceName()); 139 auto& kernel = Core::System::GetInstance().Kernel();
140 auto sessions =
141 Kernel::ServerSession::CreateSessionPair(kernel, iface->GetServiceName());
139 auto server = std::get<Kernel::SharedPtr<Kernel::ServerSession>>(sessions); 142 auto server = std::get<Kernel::SharedPtr<Kernel::ServerSession>>(sessions);
140 auto client = std::get<Kernel::SharedPtr<Kernel::ClientSession>>(sessions); 143 auto client = std::get<Kernel::SharedPtr<Kernel::ClientSession>>(sessions);
141 iface->ClientConnected(server); 144 iface->ClientConnected(server);
diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp
index 134e41ebc..873d6c516 100644
--- a/src/core/hle/kernel/client_port.cpp
+++ b/src/core/hle/kernel/client_port.cpp
@@ -14,7 +14,7 @@
14 14
15namespace Kernel { 15namespace Kernel {
16 16
17ClientPort::ClientPort() = default; 17ClientPort::ClientPort(KernelCore& kernel) : Object{kernel} {}
18ClientPort::~ClientPort() = default; 18ClientPort::~ClientPort() = default;
19 19
20ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { 20ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
@@ -27,7 +27,7 @@ ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
27 active_sessions++; 27 active_sessions++;
28 28
29 // Create a new session pair, let the created sessions inherit the parent port's HLE handler. 29 // Create a new session pair, let the created sessions inherit the parent port's HLE handler.
30 auto sessions = ServerSession::CreateSessionPair(server_port->GetName(), this); 30 auto sessions = ServerSession::CreateSessionPair(kernel, server_port->GetName(), this);
31 31
32 if (server_port->hle_handler) 32 if (server_port->hle_handler)
33 server_port->hle_handler->ClientConnected(std::get<SharedPtr<ServerSession>>(sessions)); 33 server_port->hle_handler->ClientConnected(std::get<SharedPtr<ServerSession>>(sessions));
diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h
index b1269ea5c..f3dfebbb1 100644
--- a/src/core/hle/kernel/client_port.h
+++ b/src/core/hle/kernel/client_port.h
@@ -11,8 +11,9 @@
11 11
12namespace Kernel { 12namespace Kernel {
13 13
14class ServerPort;
15class ClientSession; 14class ClientSession;
15class KernelCore;
16class ServerPort;
16 17
17class ClientPort final : public Object { 18class ClientPort final : public Object {
18public: 19public:
@@ -44,7 +45,7 @@ public:
44 void ConnectionClosed(); 45 void ConnectionClosed();
45 46
46private: 47private:
47 ClientPort(); 48 explicit ClientPort(KernelCore& kernel);
48 ~ClientPort() override; 49 ~ClientPort() override;
49 50
50 SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port. 51 SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port.
diff --git a/src/core/hle/kernel/client_session.cpp b/src/core/hle/kernel/client_session.cpp
index fdffc648d..c114eaf99 100644
--- a/src/core/hle/kernel/client_session.cpp
+++ b/src/core/hle/kernel/client_session.cpp
@@ -11,7 +11,7 @@
11 11
12namespace Kernel { 12namespace Kernel {
13 13
14ClientSession::ClientSession() = default; 14ClientSession::ClientSession(KernelCore& kernel) : Object{kernel} {}
15ClientSession::~ClientSession() { 15ClientSession::~ClientSession() {
16 // This destructor will be called automatically when the last ClientSession handle is closed by 16 // This destructor will be called automatically when the last ClientSession handle is closed by
17 // the emulated application. 17 // the emulated application.
diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h
index dabd93ed7..439fbdb35 100644
--- a/src/core/hle/kernel/client_session.h
+++ b/src/core/hle/kernel/client_session.h
@@ -12,8 +12,9 @@
12 12
13namespace Kernel { 13namespace Kernel {
14 14
15class ServerSession; 15class KernelCore;
16class Session; 16class Session;
17class ServerSession;
17class Thread; 18class Thread;
18 19
19class ClientSession final : public Object { 20class ClientSession final : public Object {
@@ -41,7 +42,7 @@ public:
41 std::shared_ptr<Session> parent; 42 std::shared_ptr<Session> parent;
42 43
43private: 44private:
44 ClientSession(); 45 explicit ClientSession(KernelCore& kernel);
45 ~ClientSession() override; 46 ~ClientSession() override;
46}; 47};
47 48
diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/event.cpp
index 5623c4b6a..8967e602e 100644
--- a/src/core/hle/kernel/event.cpp
+++ b/src/core/hle/kernel/event.cpp
@@ -10,11 +10,11 @@
10 10
11namespace Kernel { 11namespace Kernel {
12 12
13Event::Event() {} 13Event::Event(KernelCore& kernel) : WaitObject{kernel} {}
14Event::~Event() {} 14Event::~Event() = default;
15 15
16SharedPtr<Event> Event::Create(ResetType reset_type, std::string name) { 16SharedPtr<Event> Event::Create(KernelCore& kernel, ResetType reset_type, std::string name) {
17 SharedPtr<Event> evt(new Event); 17 SharedPtr<Event> evt(new Event(kernel));
18 18
19 evt->signaled = false; 19 evt->signaled = false;
20 evt->reset_type = reset_type; 20 evt->reset_type = reset_type;
diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/event.h
index 3c20c05e8..27d6126b0 100644
--- a/src/core/hle/kernel/event.h
+++ b/src/core/hle/kernel/event.h
@@ -10,14 +10,18 @@
10 10
11namespace Kernel { 11namespace Kernel {
12 12
13class KernelCore;
14
13class Event final : public WaitObject { 15class Event final : public WaitObject {
14public: 16public:
15 /** 17 /**
16 * Creates an event 18 * Creates an event
19 * @param kernel The kernel instance to create this event under.
17 * @param reset_type ResetType describing how to create event 20 * @param reset_type ResetType describing how to create event
18 * @param name Optional name of event 21 * @param name Optional name of event
19 */ 22 */
20 static SharedPtr<Event> Create(ResetType reset_type, std::string name = "Unknown"); 23 static SharedPtr<Event> Create(KernelCore& kernel, ResetType reset_type,
24 std::string name = "Unknown");
21 25
22 std::string GetTypeName() const override { 26 std::string GetTypeName() const override {
23 return "Event"; 27 return "Event";
@@ -44,7 +48,7 @@ public:
44 void Clear(); 48 void Clear();
45 49
46private: 50private:
47 Event(); 51 explicit Event(KernelCore& kernel);
48 ~Event() override; 52 ~Event() override;
49 53
50 ResetType reset_type; ///< Current ResetType 54 ResetType reset_type; ///< Current ResetType
diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp
index 6d9f7a02b..3a079b9a9 100644
--- a/src/core/hle/kernel/handle_table.cpp
+++ b/src/core/hle/kernel/handle_table.cpp
@@ -13,8 +13,6 @@
13 13
14namespace Kernel { 14namespace Kernel {
15 15
16HandleTable g_handle_table;
17
18HandleTable::HandleTable() { 16HandleTable::HandleTable() {
19 next_generation = 1; 17 next_generation = 1;
20 Clear(); 18 Clear();
diff --git a/src/core/hle/kernel/handle_table.h b/src/core/hle/kernel/handle_table.h
index aee3583e8..cac928adb 100644
--- a/src/core/hle/kernel/handle_table.h
+++ b/src/core/hle/kernel/handle_table.h
@@ -121,6 +121,4 @@ private:
121 u16 next_free_slot; 121 u16 next_free_slot;
122}; 122};
123 123
124extern HandleTable g_handle_table;
125
126} // namespace Kernel 124} // namespace Kernel
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index 82a3fb5a8..db7aef766 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -13,6 +13,7 @@
13#include "common/common_funcs.h" 13#include "common/common_funcs.h"
14#include "common/common_types.h" 14#include "common/common_types.h"
15#include "common/logging/log.h" 15#include "common/logging/log.h"
16#include "core/core.h"
16#include "core/hle/ipc_helpers.h" 17#include "core/hle/ipc_helpers.h"
17#include "core/hle/kernel/event.h" 18#include "core/hle/kernel/event.h"
18#include "core/hle/kernel/handle_table.h" 19#include "core/hle/kernel/handle_table.h"
@@ -51,7 +52,9 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread,
51 52
52 if (!event) { 53 if (!event) {
53 // Create event if not provided 54 // Create event if not provided
54 event = Kernel::Event::Create(Kernel::ResetType::OneShot, "HLE Pause Event: " + reason); 55 auto& kernel = Core::System::GetInstance().Kernel();
56 event =
57 Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "HLE Pause Event: " + reason);
55 } 58 }
56 59
57 event->Clear(); 60 event->Clear();
@@ -90,12 +93,14 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
90 rp.Skip(2, false); 93 rp.Skip(2, false);
91 } 94 }
92 if (incoming) { 95 if (incoming) {
96 auto& handle_table = Core::System::GetInstance().Kernel().HandleTable();
97
93 // Populate the object lists with the data in the IPC request. 98 // Populate the object lists with the data in the IPC request.
94 for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_copy; ++handle) { 99 for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_copy; ++handle) {
95 copy_objects.push_back(Kernel::g_handle_table.GetGeneric(rp.Pop<Handle>())); 100 copy_objects.push_back(handle_table.GetGeneric(rp.Pop<Handle>()));
96 } 101 }
97 for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_move; ++handle) { 102 for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_move; ++handle) {
98 move_objects.push_back(Kernel::g_handle_table.GetGeneric(rp.Pop<Handle>())); 103 move_objects.push_back(handle_table.GetGeneric(rp.Pop<Handle>()));
99 } 104 }
100 } else { 105 } else {
101 // For responses we just ignore the handles, they're empty and will be populated when 106 // For responses we just ignore the handles, they're empty and will be populated when
@@ -230,17 +235,19 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(const Thread& thread)
230 ASSERT(copy_objects.size() == handle_descriptor_header->num_handles_to_copy); 235 ASSERT(copy_objects.size() == handle_descriptor_header->num_handles_to_copy);
231 ASSERT(move_objects.size() == handle_descriptor_header->num_handles_to_move); 236 ASSERT(move_objects.size() == handle_descriptor_header->num_handles_to_move);
232 237
238 auto& handle_table = Core::System::GetInstance().Kernel().HandleTable();
239
233 // We don't make a distinction between copy and move handles when translating since HLE 240 // We don't make a distinction between copy and move handles when translating since HLE
234 // services don't deal with handles directly. However, the guest applications might check 241 // services don't deal with handles directly. However, the guest applications might check
235 // for specific values in each of these descriptors. 242 // for specific values in each of these descriptors.
236 for (auto& object : copy_objects) { 243 for (auto& object : copy_objects) {
237 ASSERT(object != nullptr); 244 ASSERT(object != nullptr);
238 dst_cmdbuf[current_offset++] = Kernel::g_handle_table.Create(object).Unwrap(); 245 dst_cmdbuf[current_offset++] = handle_table.Create(object).Unwrap();
239 } 246 }
240 247
241 for (auto& object : move_objects) { 248 for (auto& object : move_objects) {
242 ASSERT(object != nullptr); 249 ASSERT(object != nullptr);
243 dst_cmdbuf[current_offset++] = Kernel::g_handle_table.Create(object).Unwrap(); 250 dst_cmdbuf[current_offset++] = handle_table.Create(object).Unwrap();
244 } 251 }
245 } 252 }
246 253
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index 8c19e86d3..615d7901a 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -2,38 +2,291 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <array>
6#include <atomic>
7#include <memory>
8#include <mutex>
9#include <utility>
10
11#include "common/assert.h"
12#include "common/logging/log.h"
13
14#include "core/core.h"
15#include "core/core_timing.h"
5#include "core/hle/kernel/handle_table.h" 16#include "core/hle/kernel/handle_table.h"
6#include "core/hle/kernel/kernel.h" 17#include "core/hle/kernel/kernel.h"
7#include "core/hle/kernel/process.h" 18#include "core/hle/kernel/process.h"
8#include "core/hle/kernel/resource_limit.h" 19#include "core/hle/kernel/resource_limit.h"
9#include "core/hle/kernel/thread.h" 20#include "core/hle/kernel/thread.h"
10#include "core/hle/kernel/timer.h" 21#include "core/hle/kernel/timer.h"
22#include "core/hle/lock.h"
23#include "core/hle/result.h"
11 24
12namespace Kernel { 25namespace Kernel {
13 26
14std::atomic<u32> Object::next_object_id{0}; 27/**
28 * Callback that will wake up the thread it was scheduled for
29 * @param thread_handle The handle of the thread that's been awoken
30 * @param cycles_late The number of CPU cycles that have passed since the desired wakeup time
31 */
32static void ThreadWakeupCallback(u64 thread_handle, [[maybe_unused]] int cycles_late) {
33 const auto proper_handle = static_cast<Handle>(thread_handle);
34 auto& system = Core::System::GetInstance();
35
36 // Lock the global kernel mutex when we enter the kernel HLE.
37 std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock);
38
39 SharedPtr<Thread> thread =
40 system.Kernel().RetrieveThreadFromWakeupCallbackHandleTable(proper_handle);
41 if (thread == nullptr) {
42 LOG_CRITICAL(Kernel, "Callback fired for invalid thread {:08X}", proper_handle);
43 return;
44 }
45
46 bool resume = true;
47
48 if (thread->status == ThreadStatus::WaitSynchAny ||
49 thread->status == ThreadStatus::WaitSynchAll ||
50 thread->status == ThreadStatus::WaitHLEEvent) {
51 // Remove the thread from each of its waiting objects' waitlists
52 for (auto& object : thread->wait_objects) {
53 object->RemoveWaitingThread(thread.get());
54 }
55 thread->wait_objects.clear();
56
57 // Invoke the wakeup callback before clearing the wait objects
58 if (thread->wakeup_callback) {
59 resume = thread->wakeup_callback(ThreadWakeupReason::Timeout, thread, nullptr, 0);
60 }
61 }
62
63 if (thread->mutex_wait_address != 0 || thread->condvar_wait_address != 0 ||
64 thread->wait_handle) {
65 ASSERT(thread->status == ThreadStatus::WaitMutex);
66 thread->mutex_wait_address = 0;
67 thread->condvar_wait_address = 0;
68 thread->wait_handle = 0;
69
70 auto lock_owner = thread->lock_owner;
71 // Threads waking up by timeout from WaitProcessWideKey do not perform priority inheritance
72 // and don't have a lock owner unless SignalProcessWideKey was called first and the thread
73 // wasn't awakened due to the mutex already being acquired.
74 if (lock_owner) {
75 lock_owner->RemoveMutexWaiter(thread);
76 }
77 }
78
79 if (thread->arb_wait_address != 0) {
80 ASSERT(thread->status == ThreadStatus::WaitArb);
81 thread->arb_wait_address = 0;
82 }
83
84 if (resume) {
85 thread->ResumeFromWait();
86 }
87}
88
89/// The timer callback event, called when a timer is fired
90static void TimerCallback(u64 timer_handle, int cycles_late) {
91 const auto proper_handle = static_cast<Handle>(timer_handle);
92 auto& system = Core::System::GetInstance();
93 SharedPtr<Timer> timer = system.Kernel().RetrieveTimerFromCallbackHandleTable(proper_handle);
94
95 if (timer == nullptr) {
96 LOG_CRITICAL(Kernel, "Callback fired for invalid timer {:016X}", timer_handle);
97 return;
98 }
99
100 timer->Signal(cycles_late);
101}
15 102
16/// Initialize the kernel 103struct KernelCore::Impl {
17void Init() { 104 void Initialize(KernelCore& kernel) {
18 Kernel::ResourceLimitsInit(); 105 Shutdown();
19 Kernel::ThreadingInit();
20 Kernel::TimersInit();
21 106
22 Object::next_object_id = 0; 107 InitializeResourceLimits(kernel);
108 InitializeThreads();
109 InitializeTimers();
110 }
111
112 void Shutdown() {
113 next_object_id = 0;
114 next_process_id = 10;
115 next_thread_id = 1;
116
117 process_list.clear();
118
119 handle_table.Clear();
120 resource_limits.fill(nullptr);
121
122 thread_wakeup_callback_handle_table.Clear();
123 thread_wakeup_event_type = nullptr;
124
125 timer_callback_handle_table.Clear();
126 timer_callback_event_type = nullptr;
127 }
128
129 void InitializeResourceLimits(KernelCore& kernel) {
130 // Create the four resource limits that the system uses
131 // Create the APPLICATION resource limit
132 SharedPtr<ResourceLimit> resource_limit = ResourceLimit::Create(kernel, "Applications");
133 resource_limit->max_priority = 0x18;
134 resource_limit->max_commit = 0x4000000;
135 resource_limit->max_threads = 0x20;
136 resource_limit->max_events = 0x20;
137 resource_limit->max_mutexes = 0x20;
138 resource_limit->max_semaphores = 0x8;
139 resource_limit->max_timers = 0x8;
140 resource_limit->max_shared_mems = 0x10;
141 resource_limit->max_address_arbiters = 0x2;
142 resource_limit->max_cpu_time = 0x1E;
143 resource_limits[static_cast<u8>(ResourceLimitCategory::APPLICATION)] = resource_limit;
144
145 // Create the SYS_APPLET resource limit
146 resource_limit = ResourceLimit::Create(kernel, "System Applets");
147 resource_limit->max_priority = 0x4;
148 resource_limit->max_commit = 0x5E00000;
149 resource_limit->max_threads = 0x1D;
150 resource_limit->max_events = 0xB;
151 resource_limit->max_mutexes = 0x8;
152 resource_limit->max_semaphores = 0x4;
153 resource_limit->max_timers = 0x4;
154 resource_limit->max_shared_mems = 0x8;
155 resource_limit->max_address_arbiters = 0x3;
156 resource_limit->max_cpu_time = 0x2710;
157 resource_limits[static_cast<u8>(ResourceLimitCategory::SYS_APPLET)] = resource_limit;
158
159 // Create the LIB_APPLET resource limit
160 resource_limit = ResourceLimit::Create(kernel, "Library Applets");
161 resource_limit->max_priority = 0x4;
162 resource_limit->max_commit = 0x600000;
163 resource_limit->max_threads = 0xE;
164 resource_limit->max_events = 0x8;
165 resource_limit->max_mutexes = 0x8;
166 resource_limit->max_semaphores = 0x4;
167 resource_limit->max_timers = 0x4;
168 resource_limit->max_shared_mems = 0x8;
169 resource_limit->max_address_arbiters = 0x1;
170 resource_limit->max_cpu_time = 0x2710;
171 resource_limits[static_cast<u8>(ResourceLimitCategory::LIB_APPLET)] = resource_limit;
172
173 // Create the OTHER resource limit
174 resource_limit = ResourceLimit::Create(kernel, "Others");
175 resource_limit->max_priority = 0x4;
176 resource_limit->max_commit = 0x2180000;
177 resource_limit->max_threads = 0xE1;
178 resource_limit->max_events = 0x108;
179 resource_limit->max_mutexes = 0x25;
180 resource_limit->max_semaphores = 0x43;
181 resource_limit->max_timers = 0x2C;
182 resource_limit->max_shared_mems = 0x1F;
183 resource_limit->max_address_arbiters = 0x2D;
184 resource_limit->max_cpu_time = 0x3E8;
185 resource_limits[static_cast<u8>(ResourceLimitCategory::OTHER)] = resource_limit;
186 }
187
188 void InitializeThreads() {
189 thread_wakeup_event_type =
190 CoreTiming::RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback);
191 }
192
193 void InitializeTimers() {
194 timer_callback_handle_table.Clear();
195 timer_callback_event_type = CoreTiming::RegisterEvent("TimerCallback", TimerCallback);
196 }
197
198 std::atomic<u32> next_object_id{0};
23 // TODO(Subv): Start the process ids from 10 for now, as lower PIDs are 199 // TODO(Subv): Start the process ids from 10 for now, as lower PIDs are
24 // reserved for low-level services 200 // reserved for low-level services
25 Process::next_process_id = 10; 201 std::atomic<u32> next_process_id{10};
202 std::atomic<u32> next_thread_id{1};
203
204 // Lists all processes that exist in the current session.
205 std::vector<SharedPtr<Process>> process_list;
206
207 Kernel::HandleTable handle_table;
208 std::array<SharedPtr<ResourceLimit>, 4> resource_limits;
209
210 /// The event type of the generic timer callback event
211 CoreTiming::EventType* timer_callback_event_type = nullptr;
212 // TODO(yuriks): This can be removed if Timer objects are explicitly pooled in the future,
213 // allowing us to simply use a pool index or similar.
214 Kernel::HandleTable timer_callback_handle_table;
215
216 CoreTiming::EventType* thread_wakeup_event_type = nullptr;
217 // TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future,
218 // allowing us to simply use a pool index or similar.
219 Kernel::HandleTable thread_wakeup_callback_handle_table;
220};
221
222KernelCore::KernelCore() : impl{std::make_unique<Impl>()} {}
223KernelCore::~KernelCore() {
224 Shutdown();
225}
226
227void KernelCore::Initialize() {
228 impl->Initialize(*this);
229}
230
231void KernelCore::Shutdown() {
232 impl->Shutdown();
233}
234
235Kernel::HandleTable& KernelCore::HandleTable() {
236 return impl->handle_table;
237}
238
239const Kernel::HandleTable& KernelCore::HandleTable() const {
240 return impl->handle_table;
241}
242
243SharedPtr<ResourceLimit> KernelCore::ResourceLimitForCategory(
244 ResourceLimitCategory category) const {
245 return impl->resource_limits.at(static_cast<std::size_t>(category));
246}
247
248SharedPtr<Thread> KernelCore::RetrieveThreadFromWakeupCallbackHandleTable(Handle handle) const {
249 return impl->thread_wakeup_callback_handle_table.Get<Thread>(handle);
250}
251
252SharedPtr<Timer> KernelCore::RetrieveTimerFromCallbackHandleTable(Handle handle) const {
253 return impl->timer_callback_handle_table.Get<Timer>(handle);
254}
255
256void KernelCore::AppendNewProcess(SharedPtr<Process> process) {
257 impl->process_list.push_back(std::move(process));
258}
259
260u32 KernelCore::CreateNewObjectID() {
261 return impl->next_object_id++;
262}
263
264u32 KernelCore::CreateNewThreadID() {
265 return impl->next_thread_id++;
26} 266}
27 267
28/// Shutdown the kernel 268u32 KernelCore::CreateNewProcessID() {
29void Shutdown() { 269 return impl->next_process_id++;
30 // Free all kernel objects 270}
31 g_handle_table.Clear();
32 271
33 Kernel::ThreadingShutdown(); 272ResultVal<Handle> KernelCore::CreateTimerCallbackHandle(const SharedPtr<Timer>& timer) {
273 return impl->timer_callback_handle_table.Create(timer);
274}
275
276CoreTiming::EventType* KernelCore::ThreadWakeupCallbackEventType() const {
277 return impl->thread_wakeup_event_type;
278}
279
280CoreTiming::EventType* KernelCore::TimerCallbackEventType() const {
281 return impl->timer_callback_event_type;
282}
283
284Kernel::HandleTable& KernelCore::ThreadWakeupCallbackHandleTable() {
285 return impl->thread_wakeup_callback_handle_table;
286}
34 287
35 Kernel::TimersShutdown(); 288const Kernel::HandleTable& KernelCore::ThreadWakeupCallbackHandleTable() const {
36 Kernel::ResourceLimitsShutdown(); 289 return impl->thread_wakeup_callback_handle_table;
37} 290}
38 291
39} // namespace Kernel 292} // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index 131311472..089e959ac 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -4,14 +4,93 @@
4 4
5#pragma once 5#pragma once
6 6
7#include "common/common_types.h" 7#include "core/hle/kernel/object.h"
8
9template <typename T>
10class ResultVal;
11
12namespace CoreTiming {
13struct EventType;
14}
8 15
9namespace Kernel { 16namespace Kernel {
10 17
11/// Initialize the kernel with the specified system mode. 18class HandleTable;
12void Init(); 19class Process;
20class ResourceLimit;
21class Thread;
22class Timer;
23
24enum class ResourceLimitCategory : u8;
25
26/// Represents a single instance of the kernel.
27class KernelCore {
28public:
29 KernelCore();
30 ~KernelCore();
31
32 KernelCore(const KernelCore&) = delete;
33 KernelCore& operator=(const KernelCore&) = delete;
34
35 KernelCore(KernelCore&&) = delete;
36 KernelCore& operator=(KernelCore&&) = delete;
37
38 /// Resets the kernel to a clean slate for use.
39 void Initialize();
40
41 /// Clears all resources in use by the kernel instance.
42 void Shutdown();
43
44 /// Provides a reference to the handle table.
45 Kernel::HandleTable& HandleTable();
46
47 /// Provides a const reference to the handle table.
48 const Kernel::HandleTable& HandleTable() const;
49
50 /// Retrieves a shared pointer to a ResourceLimit identified by the given category.
51 SharedPtr<ResourceLimit> ResourceLimitForCategory(ResourceLimitCategory category) const;
52
53 /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table.
54 SharedPtr<Thread> RetrieveThreadFromWakeupCallbackHandleTable(Handle handle) const;
55
56 /// Retrieves a shared pointer to a Timer instance within the timer callback handle table.
57 SharedPtr<Timer> RetrieveTimerFromCallbackHandleTable(Handle handle) const;
58
59 /// Adds the given shared pointer to an internal list of active processes.
60 void AppendNewProcess(SharedPtr<Process> process);
61
62private:
63 friend class Object;
64 friend class Process;
65 friend class Thread;
66 friend class Timer;
67
68 /// Creates a new object ID, incrementing the internal object ID counter.
69 u32 CreateNewObjectID();
70
71 /// Creates a new process ID, incrementing the internal process ID counter;
72 u32 CreateNewProcessID();
73
74 /// Creates a new thread ID, incrementing the internal thread ID counter.
75 u32 CreateNewThreadID();
76
77 /// Creates a timer callback handle for the given timer.
78 ResultVal<Handle> CreateTimerCallbackHandle(const SharedPtr<Timer>& timer);
79
80 /// Retrieves the event type used for thread wakeup callbacks.
81 CoreTiming::EventType* ThreadWakeupCallbackEventType() const;
82
83 /// Retrieves the event type used for timer callbacks.
84 CoreTiming::EventType* TimerCallbackEventType() const;
85
86 /// Provides a reference to the thread wakeup callback handle table.
87 Kernel::HandleTable& ThreadWakeupCallbackHandleTable();
88
89 /// Provides a const reference to the thread wakeup callback handle table.
90 const Kernel::HandleTable& ThreadWakeupCallbackHandleTable() const;
13 91
14/// Shutdown the kernel 92 struct Impl;
15void Shutdown(); 93 std::unique_ptr<Impl> impl;
94};
16 95
17} // namespace Kernel 96} // namespace Kernel
diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp
index cb7f58b35..36bf0b677 100644
--- a/src/core/hle/kernel/mutex.cpp
+++ b/src/core/hle/kernel/mutex.cpp
@@ -58,15 +58,15 @@ static void TransferMutexOwnership(VAddr mutex_addr, SharedPtr<Thread> current_t
58 } 58 }
59} 59}
60 60
61ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle, 61ResultCode Mutex::TryAcquire(HandleTable& handle_table, VAddr address, Handle holding_thread_handle,
62 Handle requesting_thread_handle) { 62 Handle requesting_thread_handle) {
63 // The mutex address must be 4-byte aligned 63 // The mutex address must be 4-byte aligned
64 if ((address % sizeof(u32)) != 0) { 64 if ((address % sizeof(u32)) != 0) {
65 return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidAddress); 65 return ResultCode(ErrorModule::Kernel, ErrCodes::InvalidAddress);
66 } 66 }
67 67
68 SharedPtr<Thread> holding_thread = g_handle_table.Get<Thread>(holding_thread_handle); 68 SharedPtr<Thread> holding_thread = handle_table.Get<Thread>(holding_thread_handle);
69 SharedPtr<Thread> requesting_thread = g_handle_table.Get<Thread>(requesting_thread_handle); 69 SharedPtr<Thread> requesting_thread = handle_table.Get<Thread>(requesting_thread_handle);
70 70
71 // TODO(Subv): It is currently unknown if it is possible to lock a mutex in behalf of another 71 // TODO(Subv): It is currently unknown if it is possible to lock a mutex in behalf of another
72 // thread. 72 // thread.
diff --git a/src/core/hle/kernel/mutex.h b/src/core/hle/kernel/mutex.h
index 45268bbe9..81e62d497 100644
--- a/src/core/hle/kernel/mutex.h
+++ b/src/core/hle/kernel/mutex.h
@@ -11,6 +11,7 @@ union ResultCode;
11 11
12namespace Kernel { 12namespace Kernel {
13 13
14class HandleTable;
14class Thread; 15class Thread;
15 16
16class Mutex final { 17class Mutex final {
@@ -21,8 +22,8 @@ public:
21 static constexpr u32 MutexOwnerMask = 0xBFFFFFFF; 22 static constexpr u32 MutexOwnerMask = 0xBFFFFFFF;
22 23
23 /// Attempts to acquire a mutex at the specified address. 24 /// Attempts to acquire a mutex at the specified address.
24 static ResultCode TryAcquire(VAddr address, Handle holding_thread_handle, 25 static ResultCode TryAcquire(HandleTable& handle_table, VAddr address,
25 Handle requesting_thread_handle); 26 Handle holding_thread_handle, Handle requesting_thread_handle);
26 27
27 /// Releases the mutex at the specified address. 28 /// Releases the mutex at the specified address.
28 static ResultCode Release(VAddr address); 29 static ResultCode Release(VAddr address);
diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp
index cdba272f5..d51562d92 100644
--- a/src/core/hle/kernel/object.cpp
+++ b/src/core/hle/kernel/object.cpp
@@ -3,10 +3,12 @@
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/assert.h" 5#include "common/assert.h"
6#include "core/hle/kernel/kernel.h"
6#include "core/hle/kernel/object.h" 7#include "core/hle/kernel/object.h"
7 8
8namespace Kernel { 9namespace Kernel {
9 10
11Object::Object(KernelCore& kernel) : kernel{kernel}, object_id{kernel.CreateNewObjectID()} {}
10Object::~Object() = default; 12Object::~Object() = default;
11 13
12bool Object::IsWaitable() const { 14bool Object::IsWaitable() const {
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h
index 526ac9cc3..b054cbf7d 100644
--- a/src/core/hle/kernel/object.h
+++ b/src/core/hle/kernel/object.h
@@ -14,6 +14,8 @@
14 14
15namespace Kernel { 15namespace Kernel {
16 16
17class KernelCore;
18
17using Handle = u32; 19using Handle = u32;
18 20
19enum class HandleType : u32 { 21enum class HandleType : u32 {
@@ -40,6 +42,7 @@ enum class ResetType {
40 42
41class Object : NonCopyable { 43class Object : NonCopyable {
42public: 44public:
45 explicit Object(KernelCore& kernel);
43 virtual ~Object(); 46 virtual ~Object();
44 47
45 /// Returns a unique identifier for the object. For debugging purposes only. 48 /// Returns a unique identifier for the object. For debugging purposes only.
@@ -61,15 +64,16 @@ public:
61 */ 64 */
62 bool IsWaitable() const; 65 bool IsWaitable() const;
63 66
64public: 67protected:
65 static std::atomic<u32> next_object_id; 68 /// The kernel instance this object was created under.
69 KernelCore& kernel;
66 70
67private: 71private:
68 friend void intrusive_ptr_add_ref(Object*); 72 friend void intrusive_ptr_add_ref(Object*);
69 friend void intrusive_ptr_release(Object*); 73 friend void intrusive_ptr_release(Object*);
70 74
71 std::atomic<u32> ref_count{0}; 75 std::atomic<u32> ref_count{0};
72 std::atomic<u32> object_id{next_object_id++}; 76 std::atomic<u32> object_id{0};
73}; 77};
74 78
75// Special functions used by boost::instrusive_ptr to do automatic ref-counting 79// Special functions used by boost::instrusive_ptr to do automatic ref-counting
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index edf34c5a3..b025e323f 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -8,6 +8,7 @@
8#include "common/common_funcs.h" 8#include "common/common_funcs.h"
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "core/hle/kernel/errors.h" 10#include "core/hle/kernel/errors.h"
11#include "core/hle/kernel/kernel.h"
11#include "core/hle/kernel/process.h" 12#include "core/hle/kernel/process.h"
12#include "core/hle/kernel/resource_limit.h" 13#include "core/hle/kernel/resource_limit.h"
13#include "core/hle/kernel/thread.h" 14#include "core/hle/kernel/thread.h"
@@ -16,30 +17,26 @@
16 17
17namespace Kernel { 18namespace Kernel {
18 19
19// Lists all processes that exist in the current session. 20SharedPtr<CodeSet> CodeSet::Create(KernelCore& kernel, std::string name) {
20static std::vector<SharedPtr<Process>> process_list; 21 SharedPtr<CodeSet> codeset(new CodeSet(kernel));
21
22SharedPtr<CodeSet> CodeSet::Create(std::string name) {
23 SharedPtr<CodeSet> codeset(new CodeSet);
24 codeset->name = std::move(name); 22 codeset->name = std::move(name);
25 return codeset; 23 return codeset;
26} 24}
27 25
28CodeSet::CodeSet() {} 26CodeSet::CodeSet(KernelCore& kernel) : Object{kernel} {}
29CodeSet::~CodeSet() {} 27CodeSet::~CodeSet() = default;
30
31u32 Process::next_process_id;
32 28
33SharedPtr<Process> Process::Create(std::string&& name) { 29SharedPtr<Process> Process::Create(KernelCore& kernel, std::string&& name) {
34 SharedPtr<Process> process(new Process); 30 SharedPtr<Process> process(new Process(kernel));
35 31
36 process->name = std::move(name); 32 process->name = std::move(name);
37 process->flags.raw = 0; 33 process->flags.raw = 0;
38 process->flags.memory_region.Assign(MemoryRegion::APPLICATION); 34 process->flags.memory_region.Assign(MemoryRegion::APPLICATION);
39 process->status = ProcessStatus::Created; 35 process->status = ProcessStatus::Created;
40 process->program_id = 0; 36 process->program_id = 0;
37 process->process_id = kernel.CreateNewProcessID();
41 38
42 process_list.push_back(process); 39 kernel.AppendNewProcess(process);
43 return process; 40 return process;
44} 41}
45 42
@@ -128,7 +125,7 @@ void Process::Run(VAddr entry_point, s32 main_thread_priority, u32 stack_size) {
128 vm_manager.LogLayout(); 125 vm_manager.LogLayout();
129 status = ProcessStatus::Running; 126 status = ProcessStatus::Running;
130 127
131 Kernel::SetupMainThread(entry_point, main_thread_priority, this); 128 Kernel::SetupMainThread(kernel, entry_point, main_thread_priority, this);
132} 129}
133 130
134void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) { 131void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) {
@@ -231,22 +228,7 @@ ResultCode Process::UnmapMemory(VAddr dst_addr, VAddr /*src_addr*/, u64 size) {
231 return vm_manager.UnmapRange(dst_addr, size); 228 return vm_manager.UnmapRange(dst_addr, size);
232} 229}
233 230
234Kernel::Process::Process() {} 231Kernel::Process::Process(KernelCore& kernel) : Object{kernel} {}
235Kernel::Process::~Process() {} 232Kernel::Process::~Process() {}
236 233
237void ClearProcessList() {
238 process_list.clear();
239}
240
241SharedPtr<Process> GetProcessById(u32 process_id) {
242 auto itr = std::find_if(
243 process_list.begin(), process_list.end(),
244 [&](const SharedPtr<Process>& process) { return process->process_id == process_id; });
245
246 if (itr == process_list.end())
247 return nullptr;
248
249 return *itr;
250}
251
252} // namespace Kernel 234} // namespace Kernel
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index 992689186..1587d40c1 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -19,6 +19,8 @@
19 19
20namespace Kernel { 20namespace Kernel {
21 21
22class KernelCore;
23
22struct AddressMapping { 24struct AddressMapping {
23 // Address and size must be page-aligned 25 // Address and size must be page-aligned
24 VAddr address; 26 VAddr address;
@@ -62,7 +64,7 @@ struct CodeSet final : public Object {
62 u32 size = 0; 64 u32 size = 0;
63 }; 65 };
64 66
65 static SharedPtr<CodeSet> Create(std::string name); 67 static SharedPtr<CodeSet> Create(KernelCore& kernel, std::string name);
66 68
67 std::string GetTypeName() const override { 69 std::string GetTypeName() const override {
68 return "CodeSet"; 70 return "CodeSet";
@@ -109,13 +111,13 @@ struct CodeSet final : public Object {
109 std::string name; 111 std::string name;
110 112
111private: 113private:
112 CodeSet(); 114 explicit CodeSet(KernelCore& kernel);
113 ~CodeSet() override; 115 ~CodeSet() override;
114}; 116};
115 117
116class Process final : public Object { 118class Process final : public Object {
117public: 119public:
118 static SharedPtr<Process> Create(std::string&& name); 120 static SharedPtr<Process> Create(KernelCore& kernel, std::string&& name);
119 121
120 std::string GetTypeName() const override { 122 std::string GetTypeName() const override {
121 return "Process"; 123 return "Process";
@@ -129,8 +131,6 @@ public:
129 return HANDLE_TYPE; 131 return HANDLE_TYPE;
130 } 132 }
131 133
132 static u32 next_process_id;
133
134 /// Title ID corresponding to the process 134 /// Title ID corresponding to the process
135 u64 program_id; 135 u64 program_id;
136 136
@@ -157,8 +157,8 @@ public:
157 /// Current status of the process 157 /// Current status of the process
158 ProcessStatus status; 158 ProcessStatus status;
159 159
160 /// The id of this process 160 /// The ID of this process
161 u32 process_id = next_process_id++; 161 u32 process_id = 0;
162 162
163 /** 163 /**
164 * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them 164 * Parses a list of kernel capability descriptors (as found in the ExHeader) and applies them
@@ -206,13 +206,8 @@ public:
206 ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size); 206 ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size);
207 207
208private: 208private:
209 Process(); 209 explicit Process(KernelCore& kernel);
210 ~Process() override; 210 ~Process() override;
211}; 211};
212 212
213void ClearProcessList();
214
215/// Retrieves a process from the current list of processes.
216SharedPtr<Process> GetProcessById(u32 process_id);
217
218} // namespace Kernel 213} // namespace Kernel
diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp
index 17a3e8a74..b253a680f 100644
--- a/src/core/hle/kernel/resource_limit.cpp
+++ b/src/core/hle/kernel/resource_limit.cpp
@@ -9,31 +9,16 @@
9 9
10namespace Kernel { 10namespace Kernel {
11 11
12static SharedPtr<ResourceLimit> resource_limits[4]; 12ResourceLimit::ResourceLimit(KernelCore& kernel) : Object{kernel} {}
13ResourceLimit::~ResourceLimit() = default;
13 14
14ResourceLimit::ResourceLimit() {} 15SharedPtr<ResourceLimit> ResourceLimit::Create(KernelCore& kernel, std::string name) {
15ResourceLimit::~ResourceLimit() {} 16 SharedPtr<ResourceLimit> resource_limit(new ResourceLimit(kernel));
16
17SharedPtr<ResourceLimit> ResourceLimit::Create(std::string name) {
18 SharedPtr<ResourceLimit> resource_limit(new ResourceLimit);
19 17
20 resource_limit->name = std::move(name); 18 resource_limit->name = std::move(name);
21 return resource_limit; 19 return resource_limit;
22} 20}
23 21
24SharedPtr<ResourceLimit> ResourceLimit::GetForCategory(ResourceLimitCategory category) {
25 switch (category) {
26 case ResourceLimitCategory::APPLICATION:
27 case ResourceLimitCategory::SYS_APPLET:
28 case ResourceLimitCategory::LIB_APPLET:
29 case ResourceLimitCategory::OTHER:
30 return resource_limits[static_cast<u8>(category)];
31 default:
32 LOG_CRITICAL(Kernel, "Unknown resource limit category");
33 UNREACHABLE();
34 }
35}
36
37s32 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const { 22s32 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const {
38 switch (resource) { 23 switch (resource) {
39 case ResourceType::Commit: 24 case ResourceType::Commit:
@@ -89,66 +74,4 @@ u32 ResourceLimit::GetMaxResourceValue(ResourceType resource) const {
89 return 0; 74 return 0;
90 } 75 }
91} 76}
92
93void ResourceLimitsInit() {
94 // Create the four resource limits that the system uses
95 // Create the APPLICATION resource limit
96 SharedPtr<ResourceLimit> resource_limit = ResourceLimit::Create("Applications");
97 resource_limit->max_priority = 0x18;
98 resource_limit->max_commit = 0x4000000;
99 resource_limit->max_threads = 0x20;
100 resource_limit->max_events = 0x20;
101 resource_limit->max_mutexes = 0x20;
102 resource_limit->max_semaphores = 0x8;
103 resource_limit->max_timers = 0x8;
104 resource_limit->max_shared_mems = 0x10;
105 resource_limit->max_address_arbiters = 0x2;
106 resource_limit->max_cpu_time = 0x1E;
107 resource_limits[static_cast<u8>(ResourceLimitCategory::APPLICATION)] = resource_limit;
108
109 // Create the SYS_APPLET resource limit
110 resource_limit = ResourceLimit::Create("System Applets");
111 resource_limit->max_priority = 0x4;
112 resource_limit->max_commit = 0x5E00000;
113 resource_limit->max_threads = 0x1D;
114 resource_limit->max_events = 0xB;
115 resource_limit->max_mutexes = 0x8;
116 resource_limit->max_semaphores = 0x4;
117 resource_limit->max_timers = 0x4;
118 resource_limit->max_shared_mems = 0x8;
119 resource_limit->max_address_arbiters = 0x3;
120 resource_limit->max_cpu_time = 0x2710;
121 resource_limits[static_cast<u8>(ResourceLimitCategory::SYS_APPLET)] = resource_limit;
122
123 // Create the LIB_APPLET resource limit
124 resource_limit = ResourceLimit::Create("Library Applets");
125 resource_limit->max_priority = 0x4;
126 resource_limit->max_commit = 0x600000;
127 resource_limit->max_threads = 0xE;
128 resource_limit->max_events = 0x8;
129 resource_limit->max_mutexes = 0x8;
130 resource_limit->max_semaphores = 0x4;
131 resource_limit->max_timers = 0x4;
132 resource_limit->max_shared_mems = 0x8;
133 resource_limit->max_address_arbiters = 0x1;
134 resource_limit->max_cpu_time = 0x2710;
135 resource_limits[static_cast<u8>(ResourceLimitCategory::LIB_APPLET)] = resource_limit;
136
137 // Create the OTHER resource limit
138 resource_limit = ResourceLimit::Create("Others");
139 resource_limit->max_priority = 0x4;
140 resource_limit->max_commit = 0x2180000;
141 resource_limit->max_threads = 0xE1;
142 resource_limit->max_events = 0x108;
143 resource_limit->max_mutexes = 0x25;
144 resource_limit->max_semaphores = 0x43;
145 resource_limit->max_timers = 0x2C;
146 resource_limit->max_shared_mems = 0x1F;
147 resource_limit->max_address_arbiters = 0x2D;
148 resource_limit->max_cpu_time = 0x3E8;
149 resource_limits[static_cast<u8>(ResourceLimitCategory::OTHER)] = resource_limit;
150}
151
152void ResourceLimitsShutdown() {}
153
154} // namespace Kernel 77} // namespace Kernel
diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h
index 0fa141db3..219e49562 100644
--- a/src/core/hle/kernel/resource_limit.h
+++ b/src/core/hle/kernel/resource_limit.h
@@ -9,6 +9,8 @@
9 9
10namespace Kernel { 10namespace Kernel {
11 11
12class KernelCore;
13
12enum class ResourceLimitCategory : u8 { 14enum class ResourceLimitCategory : u8 {
13 APPLICATION = 0, 15 APPLICATION = 0,
14 SYS_APPLET = 1, 16 SYS_APPLET = 1,
@@ -34,14 +36,7 @@ public:
34 /** 36 /**
35 * Creates a resource limit object. 37 * Creates a resource limit object.
36 */ 38 */
37 static SharedPtr<ResourceLimit> Create(std::string name = "Unknown"); 39 static SharedPtr<ResourceLimit> Create(KernelCore& kernel, std::string name = "Unknown");
38
39 /**
40 * Retrieves the resource limit associated with the specified resource limit category.
41 * @param category The resource limit category
42 * @returns The resource limit associated with the category
43 */
44 static SharedPtr<ResourceLimit> GetForCategory(ResourceLimitCategory category);
45 40
46 std::string GetTypeName() const override { 41 std::string GetTypeName() const override {
47 return "ResourceLimit"; 42 return "ResourceLimit";
@@ -113,14 +108,8 @@ public:
113 s32 current_cpu_time = 0; 108 s32 current_cpu_time = 0;
114 109
115private: 110private:
116 ResourceLimit(); 111 explicit ResourceLimit(KernelCore& kernel);
117 ~ResourceLimit() override; 112 ~ResourceLimit() override;
118}; 113};
119 114
120/// Initializes the resource limits
121void ResourceLimitsInit();
122
123// Destroys the resource limits
124void ResourceLimitsShutdown();
125
126} // namespace Kernel 115} // namespace Kernel
diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp
index 7b6211fd8..3792e3e18 100644
--- a/src/core/hle/kernel/server_port.cpp
+++ b/src/core/hle/kernel/server_port.cpp
@@ -13,8 +13,8 @@
13 13
14namespace Kernel { 14namespace Kernel {
15 15
16ServerPort::ServerPort() {} 16ServerPort::ServerPort(KernelCore& kernel) : WaitObject{kernel} {}
17ServerPort::~ServerPort() {} 17ServerPort::~ServerPort() = default;
18 18
19ResultVal<SharedPtr<ServerSession>> ServerPort::Accept() { 19ResultVal<SharedPtr<ServerSession>> ServerPort::Accept() {
20 if (pending_sessions.empty()) { 20 if (pending_sessions.empty()) {
@@ -36,10 +36,10 @@ void ServerPort::Acquire(Thread* thread) {
36} 36}
37 37
38std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> ServerPort::CreatePortPair( 38std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> ServerPort::CreatePortPair(
39 u32 max_sessions, std::string name) { 39 KernelCore& kernel, u32 max_sessions, std::string name) {
40 40
41 SharedPtr<ServerPort> server_port(new ServerPort); 41 SharedPtr<ServerPort> server_port(new ServerPort(kernel));
42 SharedPtr<ClientPort> client_port(new ClientPort); 42 SharedPtr<ClientPort> client_port(new ClientPort(kernel));
43 43
44 server_port->name = name + "_Server"; 44 server_port->name = name + "_Server";
45 client_port->name = name + "_Client"; 45 client_port->name = name + "_Client";
diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h
index 7f6d6b3eb..62fb51349 100644
--- a/src/core/hle/kernel/server_port.h
+++ b/src/core/hle/kernel/server_port.h
@@ -15,6 +15,7 @@
15namespace Kernel { 15namespace Kernel {
16 16
17class ClientPort; 17class ClientPort;
18class KernelCore;
18class ServerSession; 19class ServerSession;
19class SessionRequestHandler; 20class SessionRequestHandler;
20 21
@@ -23,12 +24,13 @@ public:
23 /** 24 /**
24 * Creates a pair of ServerPort and an associated ClientPort. 25 * Creates a pair of ServerPort and an associated ClientPort.
25 * 26 *
27 * @param kernel The kernel instance to create the port pair under.
26 * @param max_sessions Maximum number of sessions to the port 28 * @param max_sessions Maximum number of sessions to the port
27 * @param name Optional name of the ports 29 * @param name Optional name of the ports
28 * @return The created port tuple 30 * @return The created port tuple
29 */ 31 */
30 static std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> CreatePortPair( 32 static std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> CreatePortPair(
31 u32 max_sessions, std::string name = "UnknownPort"); 33 KernelCore& kernel, u32 max_sessions, std::string name = "UnknownPort");
32 34
33 std::string GetTypeName() const override { 35 std::string GetTypeName() const override {
34 return "ServerPort"; 36 return "ServerPort";
@@ -69,7 +71,7 @@ public:
69 void Acquire(Thread* thread) override; 71 void Acquire(Thread* thread) override;
70 72
71private: 73private:
72 ServerPort(); 74 explicit ServerPort(KernelCore& kernel);
73 ~ServerPort() override; 75 ~ServerPort() override;
74}; 76};
75 77
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp
index 51a1ec160..90c9a5aff 100644
--- a/src/core/hle/kernel/server_session.cpp
+++ b/src/core/hle/kernel/server_session.cpp
@@ -20,7 +20,7 @@
20 20
21namespace Kernel { 21namespace Kernel {
22 22
23ServerSession::ServerSession() = default; 23ServerSession::ServerSession(KernelCore& kernel) : WaitObject{kernel} {}
24ServerSession::~ServerSession() { 24ServerSession::~ServerSession() {
25 // This destructor will be called automatically when the last ServerSession handle is closed by 25 // This destructor will be called automatically when the last ServerSession handle is closed by
26 // the emulated application. 26 // the emulated application.
@@ -35,8 +35,8 @@ ServerSession::~ServerSession() {
35 parent->server = nullptr; 35 parent->server = nullptr;
36} 36}
37 37
38ResultVal<SharedPtr<ServerSession>> ServerSession::Create(std::string name) { 38ResultVal<SharedPtr<ServerSession>> ServerSession::Create(KernelCore& kernel, std::string name) {
39 SharedPtr<ServerSession> server_session(new ServerSession); 39 SharedPtr<ServerSession> server_session(new ServerSession(kernel));
40 40
41 server_session->name = std::move(name); 41 server_session->name = std::move(name);
42 server_session->parent = nullptr; 42 server_session->parent = nullptr;
@@ -105,10 +105,10 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {
105 // from its ClientSession, so wake up any threads that may be waiting on a svcReplyAndReceive or 105 // from its ClientSession, so wake up any threads that may be waiting on a svcReplyAndReceive or
106 // similar. 106 // similar.
107 107
108 auto& handle_table = Core::System::GetInstance().Kernel().HandleTable();
108 Kernel::HLERequestContext context(this); 109 Kernel::HLERequestContext context(this);
109 u32* cmd_buf = (u32*)Memory::GetPointer(thread->GetTLSAddress()); 110 u32* cmd_buf = (u32*)Memory::GetPointer(thread->GetTLSAddress());
110 context.PopulateFromIncomingCommandBuffer(cmd_buf, *Core::CurrentProcess(), 111 context.PopulateFromIncomingCommandBuffer(cmd_buf, *Core::CurrentProcess(), handle_table);
111 Kernel::g_handle_table);
112 112
113 ResultCode result = RESULT_SUCCESS; 113 ResultCode result = RESULT_SUCCESS;
114 // If the session has been converted to a domain, handle the domain request 114 // If the session has been converted to a domain, handle the domain request
@@ -160,10 +160,11 @@ ResultCode ServerSession::HandleSyncRequest(SharedPtr<Thread> thread) {
160 return result; 160 return result;
161} 161}
162 162
163ServerSession::SessionPair ServerSession::CreateSessionPair(const std::string& name, 163ServerSession::SessionPair ServerSession::CreateSessionPair(KernelCore& kernel,
164 const std::string& name,
164 SharedPtr<ClientPort> port) { 165 SharedPtr<ClientPort> port) {
165 auto server_session = ServerSession::Create(name + "_Server").Unwrap(); 166 auto server_session = ServerSession::Create(kernel, name + "_Server").Unwrap();
166 SharedPtr<ClientSession> client_session(new ClientSession); 167 SharedPtr<ClientSession> client_session(new ClientSession(kernel));
167 client_session->name = name + "_Client"; 168 client_session->name = name + "_Client";
168 169
169 std::shared_ptr<Session> parent(new Session); 170 std::shared_ptr<Session> parent(new Session);
diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h
index 1a88e66b9..e068db2bf 100644
--- a/src/core/hle/kernel/server_session.h
+++ b/src/core/hle/kernel/server_session.h
@@ -15,13 +15,14 @@
15 15
16namespace Kernel { 16namespace Kernel {
17 17
18class ClientSession;
19class ClientPort; 18class ClientPort;
19class ClientSession;
20class HLERequestContext;
21class KernelCore;
20class ServerSession; 22class ServerSession;
21class Session; 23class Session;
22class SessionRequestHandler; 24class SessionRequestHandler;
23class Thread; 25class Thread;
24class HLERequestContext;
25 26
26/** 27/**
27 * Kernel object representing the server endpoint of an IPC session. Sessions are the basic CTR-OS 28 * Kernel object representing the server endpoint of an IPC session. Sessions are the basic CTR-OS
@@ -50,11 +51,12 @@ public:
50 51
51 /** 52 /**
52 * Creates a pair of ServerSession and an associated ClientSession. 53 * Creates a pair of ServerSession and an associated ClientSession.
54 * @param kernel The kernal instance to create the session pair under.
53 * @param name Optional name of the ports. 55 * @param name Optional name of the ports.
54 * @param client_port Optional The ClientPort that spawned this session. 56 * @param client_port Optional The ClientPort that spawned this session.
55 * @return The created session tuple 57 * @return The created session tuple
56 */ 58 */
57 static SessionPair CreateSessionPair(const std::string& name = "Unknown", 59 static SessionPair CreateSessionPair(KernelCore& kernel, const std::string& name = "Unknown",
58 SharedPtr<ClientPort> client_port = nullptr); 60 SharedPtr<ClientPort> client_port = nullptr);
59 61
60 /** 62 /**
@@ -111,16 +113,18 @@ public:
111 } 113 }
112 114
113private: 115private:
114 ServerSession(); 116 explicit ServerSession(KernelCore& kernel);
115 ~ServerSession() override; 117 ~ServerSession() override;
116 118
117 /** 119 /**
118 * Creates a server session. The server session can have an optional HLE handler, 120 * Creates a server session. The server session can have an optional HLE handler,
119 * which will be invoked to handle the IPC requests that this session receives. 121 * which will be invoked to handle the IPC requests that this session receives.
122 * @param kernel The kernel instance to create this server session under.
120 * @param name Optional name of the server session. 123 * @param name Optional name of the server session.
121 * @return The created server session 124 * @return The created server session
122 */ 125 */
123 static ResultVal<SharedPtr<ServerSession>> Create(std::string name = "Unknown"); 126 static ResultVal<SharedPtr<ServerSession>> Create(KernelCore& kernel,
127 std::string name = "Unknown");
124 128
125 /// Handles a SyncRequest to a domain, forwarding the request to the proper object or closing an 129 /// Handles a SyncRequest to a domain, forwarding the request to the proper object or closing an
126 /// object handle. 130 /// object handle.
diff --git a/src/core/hle/kernel/shared_memory.cpp b/src/core/hle/kernel/shared_memory.cpp
index fc168d2b5..abb1d09cd 100644
--- a/src/core/hle/kernel/shared_memory.cpp
+++ b/src/core/hle/kernel/shared_memory.cpp
@@ -13,14 +13,14 @@
13 13
14namespace Kernel { 14namespace Kernel {
15 15
16SharedMemory::SharedMemory() {} 16SharedMemory::SharedMemory(KernelCore& kernel) : Object{kernel} {}
17SharedMemory::~SharedMemory() {} 17SharedMemory::~SharedMemory() = default;
18 18
19SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u64 size, 19SharedPtr<SharedMemory> SharedMemory::Create(KernelCore& kernel, SharedPtr<Process> owner_process,
20 MemoryPermission permissions, 20 u64 size, MemoryPermission permissions,
21 MemoryPermission other_permissions, VAddr address, 21 MemoryPermission other_permissions, VAddr address,
22 MemoryRegion region, std::string name) { 22 MemoryRegion region, std::string name) {
23 SharedPtr<SharedMemory> shared_memory(new SharedMemory); 23 SharedPtr<SharedMemory> shared_memory(new SharedMemory(kernel));
24 24
25 shared_memory->owner_process = std::move(owner_process); 25 shared_memory->owner_process = std::move(owner_process);
26 shared_memory->name = std::move(name); 26 shared_memory->name = std::move(name);
@@ -59,12 +59,10 @@ SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u
59 return shared_memory; 59 return shared_memory;
60} 60}
61 61
62SharedPtr<SharedMemory> SharedMemory::CreateForApplet(std::shared_ptr<std::vector<u8>> heap_block, 62SharedPtr<SharedMemory> SharedMemory::CreateForApplet(
63 u32 offset, u32 size, 63 KernelCore& kernel, std::shared_ptr<std::vector<u8>> heap_block, u32 offset, u32 size,
64 MemoryPermission permissions, 64 MemoryPermission permissions, MemoryPermission other_permissions, std::string name) {
65 MemoryPermission other_permissions, 65 SharedPtr<SharedMemory> shared_memory(new SharedMemory(kernel));
66 std::string name) {
67 SharedPtr<SharedMemory> shared_memory(new SharedMemory);
68 66
69 shared_memory->owner_process = nullptr; 67 shared_memory->owner_process = nullptr;
70 shared_memory->name = std::move(name); 68 shared_memory->name = std::move(name);
diff --git a/src/core/hle/kernel/shared_memory.h b/src/core/hle/kernel/shared_memory.h
index c50fee615..2c729afe3 100644
--- a/src/core/hle/kernel/shared_memory.h
+++ b/src/core/hle/kernel/shared_memory.h
@@ -15,6 +15,8 @@
15 15
16namespace Kernel { 16namespace Kernel {
17 17
18class KernelCore;
19
18/// Permissions for mapped shared memory blocks 20/// Permissions for mapped shared memory blocks
19enum class MemoryPermission : u32 { 21enum class MemoryPermission : u32 {
20 None = 0, 22 None = 0,
@@ -32,6 +34,7 @@ class SharedMemory final : public Object {
32public: 34public:
33 /** 35 /**
34 * Creates a shared memory object. 36 * Creates a shared memory object.
37 * @param kernel The kernel instance to create a shared memory instance under.
35 * @param owner_process Process that created this shared memory object. 38 * @param owner_process Process that created this shared memory object.
36 * @param size Size of the memory block. Must be page-aligned. 39 * @param size Size of the memory block. Must be page-aligned.
37 * @param permissions Permission restrictions applied to the process which created the block. 40 * @param permissions Permission restrictions applied to the process which created the block.
@@ -42,14 +45,15 @@ public:
42 * linear heap. 45 * linear heap.
43 * @param name Optional object name, used for debugging purposes. 46 * @param name Optional object name, used for debugging purposes.
44 */ 47 */
45 static SharedPtr<SharedMemory> Create(SharedPtr<Process> owner_process, u64 size, 48 static SharedPtr<SharedMemory> Create(KernelCore& kernel, SharedPtr<Process> owner_process,
46 MemoryPermission permissions, 49 u64 size, MemoryPermission permissions,
47 MemoryPermission other_permissions, VAddr address = 0, 50 MemoryPermission other_permissions, VAddr address = 0,
48 MemoryRegion region = MemoryRegion::BASE, 51 MemoryRegion region = MemoryRegion::BASE,
49 std::string name = "Unknown"); 52 std::string name = "Unknown");
50 53
51 /** 54 /**
52 * Creates a shared memory object from a block of memory managed by an HLE applet. 55 * Creates a shared memory object from a block of memory managed by an HLE applet.
56 * @param kernel The kernel instance to create a shared memory instance under.
53 * @param heap_block Heap block of the HLE applet. 57 * @param heap_block Heap block of the HLE applet.
54 * @param offset The offset into the heap block that the SharedMemory will map. 58 * @param offset The offset into the heap block that the SharedMemory will map.
55 * @param size Size of the memory block. Must be page-aligned. 59 * @param size Size of the memory block. Must be page-aligned.
@@ -58,7 +62,8 @@ public:
58 * block. 62 * block.
59 * @param name Optional object name, used for debugging purposes. 63 * @param name Optional object name, used for debugging purposes.
60 */ 64 */
61 static SharedPtr<SharedMemory> CreateForApplet(std::shared_ptr<std::vector<u8>> heap_block, 65 static SharedPtr<SharedMemory> CreateForApplet(KernelCore& kernel,
66 std::shared_ptr<std::vector<u8>> heap_block,
62 u32 offset, u32 size, 67 u32 offset, u32 size,
63 MemoryPermission permissions, 68 MemoryPermission permissions,
64 MemoryPermission other_permissions, 69 MemoryPermission other_permissions,
@@ -125,7 +130,7 @@ public:
125 std::string name; 130 std::string name;
126 131
127private: 132private:
128 SharedMemory(); 133 explicit SharedMemory(KernelCore& kernel);
129 ~SharedMemory() override; 134 ~SharedMemory() override;
130}; 135};
131 136
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index cb6253398..099d1053f 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -87,13 +87,15 @@ static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address
87 CASCADE_RESULT(client_session, client_port->Connect()); 87 CASCADE_RESULT(client_session, client_port->Connect());
88 88
89 // Return the client session 89 // Return the client session
90 CASCADE_RESULT(*out_handle, g_handle_table.Create(client_session)); 90 auto& kernel = Core::System::GetInstance().Kernel();
91 CASCADE_RESULT(*out_handle, kernel.HandleTable().Create(client_session));
91 return RESULT_SUCCESS; 92 return RESULT_SUCCESS;
92} 93}
93 94
94/// Makes a blocking IPC call to an OS service. 95/// Makes a blocking IPC call to an OS service.
95static ResultCode SendSyncRequest(Handle handle) { 96static ResultCode SendSyncRequest(Handle handle) {
96 SharedPtr<ClientSession> session = g_handle_table.Get<ClientSession>(handle); 97 auto& kernel = Core::System::GetInstance().Kernel();
98 SharedPtr<ClientSession> session = kernel.HandleTable().Get<ClientSession>(handle);
97 if (!session) { 99 if (!session) {
98 LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle); 100 LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle);
99 return ERR_INVALID_HANDLE; 101 return ERR_INVALID_HANDLE;
@@ -112,7 +114,8 @@ static ResultCode SendSyncRequest(Handle handle) {
112static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) { 114static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) {
113 LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); 115 LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
114 116
115 const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); 117 auto& kernel = Core::System::GetInstance().Kernel();
118 const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(thread_handle);
116 if (!thread) { 119 if (!thread) {
117 return ERR_INVALID_HANDLE; 120 return ERR_INVALID_HANDLE;
118 } 121 }
@@ -125,7 +128,8 @@ static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) {
125static ResultCode GetProcessId(u32* process_id, Handle process_handle) { 128static ResultCode GetProcessId(u32* process_id, Handle process_handle) {
126 LOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle); 129 LOG_TRACE(Kernel_SVC, "called process=0x{:08X}", process_handle);
127 130
128 const SharedPtr<Process> process = g_handle_table.Get<Process>(process_handle); 131 auto& kernel = Core::System::GetInstance().Kernel();
132 const SharedPtr<Process> process = kernel.HandleTable().Get<Process>(process_handle);
129 if (!process) { 133 if (!process) {
130 return ERR_INVALID_HANDLE; 134 return ERR_INVALID_HANDLE;
131 } 135 }
@@ -168,10 +172,11 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64
168 172
169 using ObjectPtr = SharedPtr<WaitObject>; 173 using ObjectPtr = SharedPtr<WaitObject>;
170 std::vector<ObjectPtr> objects(handle_count); 174 std::vector<ObjectPtr> objects(handle_count);
175 auto& kernel = Core::System::GetInstance().Kernel();
171 176
172 for (u64 i = 0; i < handle_count; ++i) { 177 for (u64 i = 0; i < handle_count; ++i) {
173 const Handle handle = Memory::Read32(handles_address + i * sizeof(Handle)); 178 const Handle handle = Memory::Read32(handles_address + i * sizeof(Handle));
174 const auto object = g_handle_table.Get<WaitObject>(handle); 179 const auto object = kernel.HandleTable().Get<WaitObject>(handle);
175 180
176 if (object == nullptr) { 181 if (object == nullptr) {
177 return ERR_INVALID_HANDLE; 182 return ERR_INVALID_HANDLE;
@@ -219,7 +224,8 @@ static ResultCode WaitSynchronization(Handle* index, VAddr handles_address, u64
219static ResultCode CancelSynchronization(Handle thread_handle) { 224static ResultCode CancelSynchronization(Handle thread_handle) {
220 LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle); 225 LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle);
221 226
222 const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); 227 auto& kernel = Core::System::GetInstance().Kernel();
228 const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(thread_handle);
223 if (!thread) { 229 if (!thread) {
224 return ERR_INVALID_HANDLE; 230 return ERR_INVALID_HANDLE;
225 } 231 }
@@ -239,7 +245,9 @@ static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr,
239 "requesting_current_thread_handle=0x{:08X}", 245 "requesting_current_thread_handle=0x{:08X}",
240 holding_thread_handle, mutex_addr, requesting_thread_handle); 246 holding_thread_handle, mutex_addr, requesting_thread_handle);
241 247
242 return Mutex::TryAcquire(mutex_addr, holding_thread_handle, requesting_thread_handle); 248 auto& handle_table = Core::System::GetInstance().Kernel().HandleTable();
249 return Mutex::TryAcquire(handle_table, mutex_addr, holding_thread_handle,
250 requesting_thread_handle);
243} 251}
244 252
245/// Unlock a mutex 253/// Unlock a mutex
@@ -352,7 +360,8 @@ static ResultCode GetThreadContext(Handle handle, VAddr addr) {
352 360
353/// Gets the priority for the specified thread 361/// Gets the priority for the specified thread
354static ResultCode GetThreadPriority(u32* priority, Handle handle) { 362static ResultCode GetThreadPriority(u32* priority, Handle handle) {
355 const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(handle); 363 auto& kernel = Core::System::GetInstance().Kernel();
364 const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(handle);
356 if (!thread) 365 if (!thread)
357 return ERR_INVALID_HANDLE; 366 return ERR_INVALID_HANDLE;
358 367
@@ -366,7 +375,8 @@ static ResultCode SetThreadPriority(Handle handle, u32 priority) {
366 return ERR_OUT_OF_RANGE; 375 return ERR_OUT_OF_RANGE;
367 } 376 }
368 377
369 SharedPtr<Thread> thread = g_handle_table.Get<Thread>(handle); 378 auto& kernel = Core::System::GetInstance().Kernel();
379 SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(handle);
370 if (!thread) 380 if (!thread)
371 return ERR_INVALID_HANDLE; 381 return ERR_INVALID_HANDLE;
372 382
@@ -395,7 +405,8 @@ static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 s
395 "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", 405 "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}",
396 shared_memory_handle, addr, size, permissions); 406 shared_memory_handle, addr, size, permissions);
397 407
398 SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle); 408 auto& kernel = Core::System::GetInstance().Kernel();
409 auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle);
399 if (!shared_memory) { 410 if (!shared_memory) {
400 return ERR_INVALID_HANDLE; 411 return ERR_INVALID_HANDLE;
401 } 412 }
@@ -423,7 +434,8 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64
423 LOG_WARNING(Kernel_SVC, "called, shared_memory_handle=0x{:08X}, addr=0x{:X}, size=0x{:X}", 434 LOG_WARNING(Kernel_SVC, "called, shared_memory_handle=0x{:08X}, addr=0x{:X}, size=0x{:X}",
424 shared_memory_handle, addr, size); 435 shared_memory_handle, addr, size);
425 436
426 SharedPtr<SharedMemory> shared_memory = g_handle_table.Get<SharedMemory>(shared_memory_handle); 437 auto& kernel = Core::System::GetInstance().Kernel();
438 auto shared_memory = kernel.HandleTable().Get<SharedMemory>(shared_memory_handle);
427 439
428 return shared_memory->Unmap(Core::CurrentProcess().get(), addr); 440 return shared_memory->Unmap(Core::CurrentProcess().get(), addr);
429} 441}
@@ -431,7 +443,9 @@ static ResultCode UnmapSharedMemory(Handle shared_memory_handle, VAddr addr, u64
431/// Query process memory 443/// Query process memory
432static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_info*/, 444static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_info*/,
433 Handle process_handle, u64 addr) { 445 Handle process_handle, u64 addr) {
434 SharedPtr<Process> process = g_handle_table.Get<Process>(process_handle); 446
447 auto& kernel = Core::System::GetInstance().Kernel();
448 SharedPtr<Process> process = kernel.HandleTable().Get<Process>(process_handle);
435 if (!process) { 449 if (!process) {
436 return ERR_INVALID_HANDLE; 450 return ERR_INVALID_HANDLE;
437 } 451 }
@@ -528,10 +542,11 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
528 break; 542 break;
529 } 543 }
530 544
545 auto& kernel = Core::System::GetInstance().Kernel();
531 CASCADE_RESULT(SharedPtr<Thread> thread, 546 CASCADE_RESULT(SharedPtr<Thread> thread,
532 Thread::Create(name, entry_point, priority, arg, processor_id, stack_top, 547 Thread::Create(kernel, name, entry_point, priority, arg, processor_id, stack_top,
533 Core::CurrentProcess())); 548 Core::CurrentProcess()));
534 CASCADE_RESULT(thread->guest_handle, g_handle_table.Create(thread)); 549 CASCADE_RESULT(thread->guest_handle, kernel.HandleTable().Create(thread));
535 *out_handle = thread->guest_handle; 550 *out_handle = thread->guest_handle;
536 551
537 Core::System::GetInstance().CpuCore(thread->processor_id).PrepareReschedule(); 552 Core::System::GetInstance().CpuCore(thread->processor_id).PrepareReschedule();
@@ -548,7 +563,8 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
548static ResultCode StartThread(Handle thread_handle) { 563static ResultCode StartThread(Handle thread_handle) {
549 LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); 564 LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle);
550 565
551 const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); 566 auto& kernel = Core::System::GetInstance().Kernel();
567 const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(thread_handle);
552 if (!thread) { 568 if (!thread) {
553 return ERR_INVALID_HANDLE; 569 return ERR_INVALID_HANDLE;
554 } 570 }
@@ -595,7 +611,8 @@ static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr condition_var
595 "called mutex_addr={:X}, condition_variable_addr={:X}, thread_handle=0x{:08X}, timeout={}", 611 "called mutex_addr={:X}, condition_variable_addr={:X}, thread_handle=0x{:08X}, timeout={}",
596 mutex_addr, condition_variable_addr, thread_handle, nano_seconds); 612 mutex_addr, condition_variable_addr, thread_handle, nano_seconds);
597 613
598 SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); 614 auto& kernel = Core::System::GetInstance().Kernel();
615 SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(thread_handle);
599 ASSERT(thread); 616 ASSERT(thread);
600 617
601 CASCADE_CODE(Mutex::Release(mutex_addr)); 618 CASCADE_CODE(Mutex::Release(mutex_addr));
@@ -704,8 +721,9 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
704 mutex_val | Mutex::MutexHasWaitersFlag)); 721 mutex_val | Mutex::MutexHasWaitersFlag));
705 722
706 // The mutex is already owned by some other thread, make this thread wait on it. 723 // The mutex is already owned by some other thread, make this thread wait on it.
724 auto& kernel = Core::System::GetInstance().Kernel();
707 Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask); 725 Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask);
708 auto owner = g_handle_table.Get<Thread>(owner_handle); 726 auto owner = kernel.HandleTable().Get<Thread>(owner_handle);
709 ASSERT(owner); 727 ASSERT(owner);
710 ASSERT(thread->status == ThreadStatus::WaitMutex); 728 ASSERT(thread->status == ThreadStatus::WaitMutex);
711 thread->wakeup_callback = nullptr; 729 thread->wakeup_callback = nullptr;
@@ -783,14 +801,20 @@ static u64 GetSystemTick() {
783/// Close a handle 801/// Close a handle
784static ResultCode CloseHandle(Handle handle) { 802static ResultCode CloseHandle(Handle handle) {
785 LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle); 803 LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle);
786 return g_handle_table.Close(handle); 804
805 auto& kernel = Core::System::GetInstance().Kernel();
806 return kernel.HandleTable().Close(handle);
787} 807}
788 808
789/// Reset an event 809/// Reset an event
790static ResultCode ResetSignal(Handle handle) { 810static ResultCode ResetSignal(Handle handle) {
791 LOG_WARNING(Kernel_SVC, "(STUBBED) called handle 0x{:08X}", handle); 811 LOG_WARNING(Kernel_SVC, "(STUBBED) called handle 0x{:08X}", handle);
792 auto event = g_handle_table.Get<Event>(handle); 812
813 auto& kernel = Core::System::GetInstance().Kernel();
814 auto event = kernel.HandleTable().Get<Event>(handle);
815
793 ASSERT(event != nullptr); 816 ASSERT(event != nullptr);
817
794 event->Clear(); 818 event->Clear();
795 return RESULT_SUCCESS; 819 return RESULT_SUCCESS;
796} 820}
@@ -806,7 +830,8 @@ static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32
806static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) { 830static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) {
807 LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle); 831 LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle);
808 832
809 const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); 833 auto& kernel = Core::System::GetInstance().Kernel();
834 const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(thread_handle);
810 if (!thread) { 835 if (!thread) {
811 return ERR_INVALID_HANDLE; 836 return ERR_INVALID_HANDLE;
812 } 837 }
@@ -821,7 +846,8 @@ static ResultCode SetThreadCoreMask(Handle thread_handle, u32 core, u64 mask) {
821 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:16X}, core=0x{:X}", thread_handle, 846 LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, mask=0x{:16X}, core=0x{:X}", thread_handle,
822 mask, core); 847 mask, core);
823 848
824 const SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); 849 auto& kernel = Core::System::GetInstance().Kernel();
850 const SharedPtr<Thread> thread = kernel.HandleTable().Get<Thread>(thread_handle);
825 if (!thread) { 851 if (!thread) {
826 return ERR_INVALID_HANDLE; 852 return ERR_INVALID_HANDLE;
827 } 853 }
@@ -861,19 +887,23 @@ static ResultCode CreateSharedMemory(Handle* handle, u64 size, u32 local_permiss
861 u32 remote_permissions) { 887 u32 remote_permissions) {
862 LOG_TRACE(Kernel_SVC, "called, size=0x{:X}, localPerms=0x{:08X}, remotePerms=0x{:08X}", size, 888 LOG_TRACE(Kernel_SVC, "called, size=0x{:X}, localPerms=0x{:08X}, remotePerms=0x{:08X}", size,
863 local_permissions, remote_permissions); 889 local_permissions, remote_permissions);
864 auto sharedMemHandle = 890
865 SharedMemory::Create(g_handle_table.Get<Process>(KernelHandle::CurrentProcess), size, 891 auto& kernel = Core::System::GetInstance().Kernel();
892 auto& handle_table = kernel.HandleTable();
893 auto shared_mem_handle =
894 SharedMemory::Create(kernel, handle_table.Get<Process>(KernelHandle::CurrentProcess), size,
866 static_cast<MemoryPermission>(local_permissions), 895 static_cast<MemoryPermission>(local_permissions),
867 static_cast<MemoryPermission>(remote_permissions)); 896 static_cast<MemoryPermission>(remote_permissions));
868 897
869 CASCADE_RESULT(*handle, g_handle_table.Create(sharedMemHandle)); 898 CASCADE_RESULT(*handle, handle_table.Create(shared_mem_handle));
870 return RESULT_SUCCESS; 899 return RESULT_SUCCESS;
871} 900}
872 901
873static ResultCode ClearEvent(Handle handle) { 902static ResultCode ClearEvent(Handle handle) {
874 LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle); 903 LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle);
875 904
876 SharedPtr<Event> evt = g_handle_table.Get<Event>(handle); 905 auto& kernel = Core::System::GetInstance().Kernel();
906 SharedPtr<Event> evt = kernel.HandleTable().Get<Event>(handle);
877 if (evt == nullptr) 907 if (evt == nullptr)
878 return ERR_INVALID_HANDLE; 908 return ERR_INVALID_HANDLE;
879 evt->Clear(); 909 evt->Clear();
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 4ffd8d5cc..520ea0853 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -20,6 +20,7 @@
20#include "core/core_timing_util.h" 20#include "core/core_timing_util.h"
21#include "core/hle/kernel/errors.h" 21#include "core/hle/kernel/errors.h"
22#include "core/hle/kernel/handle_table.h" 22#include "core/hle/kernel/handle_table.h"
23#include "core/hle/kernel/kernel.h"
23#include "core/hle/kernel/object.h" 24#include "core/hle/kernel/object.h"
24#include "core/hle/kernel/process.h" 25#include "core/hle/kernel/process.h"
25#include "core/hle/kernel/thread.h" 26#include "core/hle/kernel/thread.h"
@@ -29,9 +30,6 @@
29 30
30namespace Kernel { 31namespace Kernel {
31 32
32/// Event type for the thread wake up event
33static CoreTiming::EventType* ThreadWakeupEventType = nullptr;
34
35bool Thread::ShouldWait(Thread* thread) const { 33bool Thread::ShouldWait(Thread* thread) const {
36 return status != ThreadStatus::Dead; 34 return status != ThreadStatus::Dead;
37} 35}
@@ -40,32 +38,17 @@ void Thread::Acquire(Thread* thread) {
40 ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); 38 ASSERT_MSG(!ShouldWait(thread), "object unavailable!");
41} 39}
42 40
43// TODO(yuriks): This can be removed if Thread objects are explicitly pooled in the future, allowing 41Thread::Thread(KernelCore& kernel) : WaitObject{kernel} {}
44// us to simply use a pool index or similar. 42Thread::~Thread() = default;
45static Kernel::HandleTable wakeup_callback_handle_table;
46
47// The first available thread id at startup
48static u32 next_thread_id;
49
50/**
51 * Creates a new thread ID
52 * @return The new thread ID
53 */
54inline static u32 const NewThreadId() {
55 return next_thread_id++;
56}
57
58Thread::Thread() {}
59Thread::~Thread() {}
60 43
61void Thread::Stop() { 44void Thread::Stop() {
62 // Cancel any outstanding wakeup events for this thread 45 // Cancel any outstanding wakeup events for this thread
63 CoreTiming::UnscheduleEvent(ThreadWakeupEventType, callback_handle); 46 CoreTiming::UnscheduleEvent(kernel.ThreadWakeupCallbackEventType(), callback_handle);
64 wakeup_callback_handle_table.Close(callback_handle); 47 kernel.ThreadWakeupCallbackHandleTable().Close(callback_handle);
65 callback_handle = 0; 48 callback_handle = 0;
66 49
67 // Clean up thread from ready queue 50 // Clean up thread from ready queue
68 // This is only needed when the thread is termintated forcefully (SVC TerminateProcess) 51 // This is only needed when the thread is terminated forcefully (SVC TerminateProcess)
69 if (status == ThreadStatus::Ready) { 52 if (status == ThreadStatus::Ready) {
70 scheduler->UnscheduleThread(this, current_priority); 53 scheduler->UnscheduleThread(this, current_priority);
71 } 54 }
@@ -98,63 +81,6 @@ void ExitCurrentThread() {
98 Core::System::GetInstance().CurrentScheduler().RemoveThread(thread); 81 Core::System::GetInstance().CurrentScheduler().RemoveThread(thread);
99} 82}
100 83
101/**
102 * Callback that will wake up the thread it was scheduled for
103 * @param thread_handle The handle of the thread that's been awoken
104 * @param cycles_late The number of CPU cycles that have passed since the desired wakeup time
105 */
106static void ThreadWakeupCallback(u64 thread_handle, int cycles_late) {
107 const auto proper_handle = static_cast<Handle>(thread_handle);
108
109 // Lock the global kernel mutex when we enter the kernel HLE.
110 std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock);
111
112 SharedPtr<Thread> thread = wakeup_callback_handle_table.Get<Thread>(proper_handle);
113 if (thread == nullptr) {
114 LOG_CRITICAL(Kernel, "Callback fired for invalid thread {:08X}", proper_handle);
115 return;
116 }
117
118 bool resume = true;
119
120 if (thread->status == ThreadStatus::WaitSynchAny ||
121 thread->status == ThreadStatus::WaitSynchAll ||
122 thread->status == ThreadStatus::WaitHLEEvent) {
123 // Remove the thread from each of its waiting objects' waitlists
124 for (auto& object : thread->wait_objects)
125 object->RemoveWaitingThread(thread.get());
126 thread->wait_objects.clear();
127
128 // Invoke the wakeup callback before clearing the wait objects
129 if (thread->wakeup_callback)
130 resume = thread->wakeup_callback(ThreadWakeupReason::Timeout, thread, nullptr, 0);
131 }
132
133 if (thread->mutex_wait_address != 0 || thread->condvar_wait_address != 0 ||
134 thread->wait_handle) {
135 ASSERT(thread->status == ThreadStatus::WaitMutex);
136 thread->mutex_wait_address = 0;
137 thread->condvar_wait_address = 0;
138 thread->wait_handle = 0;
139
140 auto lock_owner = thread->lock_owner;
141 // Threads waking up by timeout from WaitProcessWideKey do not perform priority inheritance
142 // and don't have a lock owner unless SignalProcessWideKey was called first and the thread
143 // wasn't awakened due to the mutex already being acquired.
144 if (lock_owner) {
145 lock_owner->RemoveMutexWaiter(thread);
146 }
147 }
148
149 if (thread->arb_wait_address != 0) {
150 ASSERT(thread->status == ThreadStatus::WaitArb);
151 thread->arb_wait_address = 0;
152 }
153
154 if (resume)
155 thread->ResumeFromWait();
156}
157
158void Thread::WakeAfterDelay(s64 nanoseconds) { 84void Thread::WakeAfterDelay(s64 nanoseconds) {
159 // Don't schedule a wakeup if the thread wants to wait forever 85 // Don't schedule a wakeup if the thread wants to wait forever
160 if (nanoseconds == -1) 86 if (nanoseconds == -1)
@@ -162,12 +88,12 @@ void Thread::WakeAfterDelay(s64 nanoseconds) {
162 88
163 // This function might be called from any thread so we have to be cautious and use the 89 // This function might be called from any thread so we have to be cautious and use the
164 // thread-safe version of ScheduleEvent. 90 // thread-safe version of ScheduleEvent.
165 CoreTiming::ScheduleEventThreadsafe(CoreTiming::nsToCycles(nanoseconds), ThreadWakeupEventType, 91 CoreTiming::ScheduleEventThreadsafe(CoreTiming::nsToCycles(nanoseconds),
166 callback_handle); 92 kernel.ThreadWakeupCallbackEventType(), callback_handle);
167} 93}
168 94
169void Thread::CancelWakeupTimer() { 95void Thread::CancelWakeupTimer() {
170 CoreTiming::UnscheduleEventThreadsafe(ThreadWakeupEventType, callback_handle); 96 CoreTiming::UnscheduleEventThreadsafe(kernel.ThreadWakeupCallbackEventType(), callback_handle);
171} 97}
172 98
173static boost::optional<s32> GetNextProcessorId(u64 mask) { 99static boost::optional<s32> GetNextProcessorId(u64 mask) {
@@ -294,9 +220,9 @@ static void ResetThreadContext(Core::ARM_Interface::ThreadContext& context, VAdd
294 context.fpscr = 0; 220 context.fpscr = 0;
295} 221}
296 222
297ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, u32 priority, 223ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name, VAddr entry_point,
298 u64 arg, s32 processor_id, VAddr stack_top, 224 u32 priority, u64 arg, s32 processor_id,
299 SharedPtr<Process> owner_process) { 225 VAddr stack_top, SharedPtr<Process> owner_process) {
300 // Check if priority is in ranged. Lowest priority -> highest priority id. 226 // Check if priority is in ranged. Lowest priority -> highest priority id.
301 if (priority > THREADPRIO_LOWEST) { 227 if (priority > THREADPRIO_LOWEST) {
302 LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority); 228 LOG_ERROR(Kernel_SVC, "Invalid thread priority: {}", priority);
@@ -316,9 +242,9 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
316 return ResultCode(-1); 242 return ResultCode(-1);
317 } 243 }
318 244
319 SharedPtr<Thread> thread(new Thread); 245 SharedPtr<Thread> thread(new Thread(kernel));
320 246
321 thread->thread_id = NewThreadId(); 247 thread->thread_id = kernel.CreateNewThreadID();
322 thread->status = ThreadStatus::Dormant; 248 thread->status = ThreadStatus::Dormant;
323 thread->entry_point = entry_point; 249 thread->entry_point = entry_point;
324 thread->stack_top = stack_top; 250 thread->stack_top = stack_top;
@@ -333,7 +259,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,
333 thread->condvar_wait_address = 0; 259 thread->condvar_wait_address = 0;
334 thread->wait_handle = 0; 260 thread->wait_handle = 0;
335 thread->name = std::move(name); 261 thread->name = std::move(name);
336 thread->callback_handle = wakeup_callback_handle_table.Create(thread).Unwrap(); 262 thread->callback_handle = kernel.ThreadWakeupCallbackHandleTable().Create(thread).Unwrap();
337 thread->owner_process = owner_process; 263 thread->owner_process = owner_process;
338 thread->scheduler = Core::System::GetInstance().Scheduler(processor_id); 264 thread->scheduler = Core::System::GetInstance().Scheduler(processor_id);
339 thread->scheduler->AddThread(thread, priority); 265 thread->scheduler->AddThread(thread, priority);
@@ -383,19 +309,19 @@ void Thread::BoostPriority(u32 priority) {
383 current_priority = priority; 309 current_priority = priority;
384} 310}
385 311
386SharedPtr<Thread> SetupMainThread(VAddr entry_point, u32 priority, 312SharedPtr<Thread> SetupMainThread(KernelCore& kernel, VAddr entry_point, u32 priority,
387 SharedPtr<Process> owner_process) { 313 SharedPtr<Process> owner_process) {
388 // Setup page table so we can write to memory 314 // Setup page table so we can write to memory
389 SetCurrentPageTable(&Core::CurrentProcess()->vm_manager.page_table); 315 SetCurrentPageTable(&Core::CurrentProcess()->vm_manager.page_table);
390 316
391 // Initialize new "main" thread 317 // Initialize new "main" thread
392 auto thread_res = Thread::Create("main", entry_point, priority, 0, THREADPROCESSORID_0, 318 auto thread_res = Thread::Create(kernel, "main", entry_point, priority, 0, THREADPROCESSORID_0,
393 Memory::STACK_AREA_VADDR_END, std::move(owner_process)); 319 Memory::STACK_AREA_VADDR_END, std::move(owner_process));
394 320
395 SharedPtr<Thread> thread = std::move(thread_res).Unwrap(); 321 SharedPtr<Thread> thread = std::move(thread_res).Unwrap();
396 322
397 // Register 1 must be a handle to the main thread 323 // Register 1 must be a handle to the main thread
398 thread->guest_handle = Kernel::g_handle_table.Create(thread).Unwrap(); 324 thread->guest_handle = kernel.HandleTable().Create(thread).Unwrap();
399 325
400 thread->context.cpu_registers[1] = thread->guest_handle; 326 thread->context.cpu_registers[1] = thread->guest_handle;
401 327
@@ -528,13 +454,4 @@ Thread* GetCurrentThread() {
528 return Core::System::GetInstance().CurrentScheduler().GetCurrentThread(); 454 return Core::System::GetInstance().CurrentScheduler().GetCurrentThread();
529} 455}
530 456
531void ThreadingInit() {
532 ThreadWakeupEventType = CoreTiming::RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback);
533 next_thread_id = 1;
534}
535
536void ThreadingShutdown() {
537 Kernel::ClearProcessList();
538}
539
540} // namespace Kernel 457} // namespace Kernel
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 06edc296d..20f50458b 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -56,6 +56,7 @@ enum class ThreadWakeupReason {
56 56
57namespace Kernel { 57namespace Kernel {
58 58
59class KernelCore;
59class Process; 60class Process;
60class Scheduler; 61class Scheduler;
61 62
@@ -63,6 +64,7 @@ class Thread final : public WaitObject {
63public: 64public:
64 /** 65 /**
65 * Creates and returns a new thread. The new thread is immediately scheduled 66 * Creates and returns a new thread. The new thread is immediately scheduled
67 * @param kernel The kernel instance this thread will be created under.
66 * @param name The friendly name desired for the thread 68 * @param name The friendly name desired for the thread
67 * @param entry_point The address at which the thread should start execution 69 * @param entry_point The address at which the thread should start execution
68 * @param priority The thread's priority 70 * @param priority The thread's priority
@@ -72,8 +74,9 @@ public:
72 * @param owner_process The parent process for the thread 74 * @param owner_process The parent process for the thread
73 * @return A shared pointer to the newly created thread 75 * @return A shared pointer to the newly created thread
74 */ 76 */
75 static ResultVal<SharedPtr<Thread>> Create(std::string name, VAddr entry_point, u32 priority, 77 static ResultVal<SharedPtr<Thread>> Create(KernelCore& kernel, std::string name,
76 u64 arg, s32 processor_id, VAddr stack_top, 78 VAddr entry_point, u32 priority, u64 arg,
79 s32 processor_id, VAddr stack_top,
77 SharedPtr<Process> owner_process); 80 SharedPtr<Process> owner_process);
78 81
79 std::string GetName() const override { 82 std::string GetName() const override {
@@ -263,7 +266,7 @@ public:
263 u64 affinity_mask{0x1}; 266 u64 affinity_mask{0x1};
264 267
265private: 268private:
266 Thread(); 269 explicit Thread(KernelCore& kernel);
267 ~Thread() override; 270 ~Thread() override;
268 271
269 std::shared_ptr<std::vector<u8>> tls_memory = std::make_shared<std::vector<u8>>(); 272 std::shared_ptr<std::vector<u8>> tls_memory = std::make_shared<std::vector<u8>>();
@@ -271,12 +274,13 @@ private:
271 274
272/** 275/**
273 * Sets up the primary application thread 276 * Sets up the primary application thread
277 * @param kernel The kernel instance to create the main thread under.
274 * @param entry_point The address at which the thread should start execution 278 * @param entry_point The address at which the thread should start execution
275 * @param priority The priority to give the main thread 279 * @param priority The priority to give the main thread
276 * @param owner_process The parent process for the main thread 280 * @param owner_process The parent process for the main thread
277 * @return A shared pointer to the main thread 281 * @return A shared pointer to the main thread
278 */ 282 */
279SharedPtr<Thread> SetupMainThread(VAddr entry_point, u32 priority, 283SharedPtr<Thread> SetupMainThread(KernelCore& kernel, VAddr entry_point, u32 priority,
280 SharedPtr<Process> owner_process); 284 SharedPtr<Process> owner_process);
281 285
282/** 286/**
@@ -294,14 +298,4 @@ void WaitCurrentThread_Sleep();
294 */ 298 */
295void ExitCurrentThread(); 299void ExitCurrentThread();
296 300
297/**
298 * Initialize threading
299 */
300void ThreadingInit();
301
302/**
303 * Shutdown threading
304 */
305void ThreadingShutdown();
306
307} // namespace Kernel 301} // namespace Kernel
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp
index 282360745..6957b16e0 100644
--- a/src/core/hle/kernel/timer.cpp
+++ b/src/core/hle/kernel/timer.cpp
@@ -2,36 +2,31 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <cinttypes>
6#include "common/assert.h" 5#include "common/assert.h"
7#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/core.h"
8#include "core/core_timing.h" 8#include "core/core_timing.h"
9#include "core/core_timing_util.h" 9#include "core/core_timing_util.h"
10#include "core/hle/kernel/handle_table.h" 10#include "core/hle/kernel/handle_table.h"
11#include "core/hle/kernel/kernel.h"
11#include "core/hle/kernel/object.h" 12#include "core/hle/kernel/object.h"
12#include "core/hle/kernel/thread.h" 13#include "core/hle/kernel/thread.h"
13#include "core/hle/kernel/timer.h" 14#include "core/hle/kernel/timer.h"
14 15
15namespace Kernel { 16namespace Kernel {
16 17
17/// The event type of the generic timer callback event 18Timer::Timer(KernelCore& kernel) : WaitObject{kernel} {}
18static CoreTiming::EventType* timer_callback_event_type = nullptr; 19Timer::~Timer() = default;
19// TODO(yuriks): This can be removed if Timer objects are explicitly pooled in the future, allowing
20// us to simply use a pool index or similar.
21static Kernel::HandleTable timer_callback_handle_table;
22 20
23Timer::Timer() {} 21SharedPtr<Timer> Timer::Create(KernelCore& kernel, ResetType reset_type, std::string name) {
24Timer::~Timer() {} 22 SharedPtr<Timer> timer(new Timer(kernel));
25
26SharedPtr<Timer> Timer::Create(ResetType reset_type, std::string name) {
27 SharedPtr<Timer> timer(new Timer);
28 23
29 timer->reset_type = reset_type; 24 timer->reset_type = reset_type;
30 timer->signaled = false; 25 timer->signaled = false;
31 timer->name = std::move(name); 26 timer->name = std::move(name);
32 timer->initial_delay = 0; 27 timer->initial_delay = 0;
33 timer->interval_delay = 0; 28 timer->interval_delay = 0;
34 timer->callback_handle = timer_callback_handle_table.Create(timer).Unwrap(); 29 timer->callback_handle = kernel.CreateTimerCallbackHandle(timer).Unwrap();
35 30
36 return timer; 31 return timer;
37} 32}
@@ -58,13 +53,13 @@ void Timer::Set(s64 initial, s64 interval) {
58 // Immediately invoke the callback 53 // Immediately invoke the callback
59 Signal(0); 54 Signal(0);
60 } else { 55 } else {
61 CoreTiming::ScheduleEvent(CoreTiming::nsToCycles(initial), timer_callback_event_type, 56 CoreTiming::ScheduleEvent(CoreTiming::nsToCycles(initial), kernel.TimerCallbackEventType(),
62 callback_handle); 57 callback_handle);
63 } 58 }
64} 59}
65 60
66void Timer::Cancel() { 61void Timer::Cancel() {
67 CoreTiming::UnscheduleEvent(timer_callback_event_type, callback_handle); 62 CoreTiming::UnscheduleEvent(kernel.TimerCallbackEventType(), callback_handle);
68} 63}
69 64
70void Timer::Clear() { 65void Timer::Clear() {
@@ -89,28 +84,8 @@ void Timer::Signal(int cycles_late) {
89 if (interval_delay != 0) { 84 if (interval_delay != 0) {
90 // Reschedule the timer with the interval delay 85 // Reschedule the timer with the interval delay
91 CoreTiming::ScheduleEvent(CoreTiming::nsToCycles(interval_delay) - cycles_late, 86 CoreTiming::ScheduleEvent(CoreTiming::nsToCycles(interval_delay) - cycles_late,
92 timer_callback_event_type, callback_handle); 87 kernel.TimerCallbackEventType(), callback_handle);
93 } 88 }
94} 89}
95 90
96/// The timer callback event, called when a timer is fired
97static void TimerCallback(u64 timer_handle, int cycles_late) {
98 SharedPtr<Timer> timer =
99 timer_callback_handle_table.Get<Timer>(static_cast<Handle>(timer_handle));
100
101 if (timer == nullptr) {
102 LOG_CRITICAL(Kernel, "Callback fired for invalid timer {:016X}", timer_handle);
103 return;
104 }
105
106 timer->Signal(cycles_late);
107}
108
109void TimersInit() {
110 timer_callback_handle_table.Clear();
111 timer_callback_event_type = CoreTiming::RegisterEvent("TimerCallback", TimerCallback);
112}
113
114void TimersShutdown() {}
115
116} // namespace Kernel 91} // namespace Kernel
diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h
index 4dddc67e0..12915c1b1 100644
--- a/src/core/hle/kernel/timer.h
+++ b/src/core/hle/kernel/timer.h
@@ -10,15 +10,19 @@
10 10
11namespace Kernel { 11namespace Kernel {
12 12
13class KernelCore;
14
13class Timer final : public WaitObject { 15class Timer final : public WaitObject {
14public: 16public:
15 /** 17 /**
16 * Creates a timer 18 * Creates a timer
19 * @param kernel The kernel instance to create the timer callback handle for.
17 * @param reset_type ResetType describing how to create the timer 20 * @param reset_type ResetType describing how to create the timer
18 * @param name Optional name of timer 21 * @param name Optional name of timer
19 * @return The created Timer 22 * @return The created Timer
20 */ 23 */
21 static SharedPtr<Timer> Create(ResetType reset_type, std::string name = "Unknown"); 24 static SharedPtr<Timer> Create(KernelCore& kernel, ResetType reset_type,
25 std::string name = "Unknown");
22 26
23 std::string GetTypeName() const override { 27 std::string GetTypeName() const override {
24 return "Timer"; 28 return "Timer";
@@ -68,7 +72,7 @@ public:
68 void Signal(int cycles_late); 72 void Signal(int cycles_late);
69 73
70private: 74private:
71 Timer(); 75 explicit Timer(KernelCore& kernel);
72 ~Timer() override; 76 ~Timer() override;
73 77
74 ResetType reset_type; ///< The ResetType of this timer 78 ResetType reset_type; ///< The ResetType of this timer
@@ -83,9 +87,4 @@ private:
83 Handle callback_handle; 87 Handle callback_handle;
84}; 88};
85 89
86/// Initializes the required variables for timers
87void TimersInit();
88/// Tears down the timer variables
89void TimersShutdown();
90
91} // namespace Kernel 90} // namespace Kernel
diff --git a/src/core/hle/kernel/wait_object.cpp b/src/core/hle/kernel/wait_object.cpp
index 7681cdee7..eef00b729 100644
--- a/src/core/hle/kernel/wait_object.cpp
+++ b/src/core/hle/kernel/wait_object.cpp
@@ -12,6 +12,9 @@
12 12
13namespace Kernel { 13namespace Kernel {
14 14
15WaitObject::WaitObject(KernelCore& kernel) : Object{kernel} {}
16WaitObject::~WaitObject() = default;
17
15void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) { 18void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) {
16 auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread); 19 auto itr = std::find(waiting_threads.begin(), waiting_threads.end(), thread);
17 if (itr == waiting_threads.end()) 20 if (itr == waiting_threads.end())
diff --git a/src/core/hle/kernel/wait_object.h b/src/core/hle/kernel/wait_object.h
index b5fbc647b..0bd97133c 100644
--- a/src/core/hle/kernel/wait_object.h
+++ b/src/core/hle/kernel/wait_object.h
@@ -11,11 +11,15 @@
11 11
12namespace Kernel { 12namespace Kernel {
13 13
14class KernelCore;
14class Thread; 15class Thread;
15 16
16/// Class that represents a Kernel object that a thread can be waiting on 17/// Class that represents a Kernel object that a thread can be waiting on
17class WaitObject : public Object { 18class WaitObject : public Object {
18public: 19public:
20 explicit WaitObject(KernelCore& kernel);
21 ~WaitObject() override;
22
19 /** 23 /**
20 * Check if the specified thread should wait until the object is available 24 * Check if the specified thread should wait until the object is available
21 * @param thread The thread about which we're deciding. 25 * @param thread The thread about which we're deciding.
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 7e3cf6d58..818c03e0f 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -160,8 +160,9 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger
160 }; 160 };
161 RegisterHandlers(functions); 161 RegisterHandlers(functions);
162 162
163 auto& kernel = Core::System::GetInstance().Kernel();
163 launchable_event = 164 launchable_event =
164 Kernel::Event::Create(Kernel::ResetType::Sticky, "ISelfController:LaunchableEvent"); 165 Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, "ISelfController:LaunchableEvent");
165} 166}
166 167
167void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) { 168void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) {
@@ -332,7 +333,8 @@ ICommonStateGetter::ICommonStateGetter() : ServiceFramework("ICommonStateGetter"
332 }; 333 };
333 RegisterHandlers(functions); 334 RegisterHandlers(functions);
334 335
335 event = Kernel::Event::Create(Kernel::ResetType::OneShot, "ICommonStateGetter:Event"); 336 auto& kernel = Core::System::GetInstance().Kernel();
337 event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "ICommonStateGetter:Event");
336} 338}
337 339
338void ICommonStateGetter::GetBootMode(Kernel::HLERequestContext& ctx) { 340void ICommonStateGetter::GetBootMode(Kernel::HLERequestContext& ctx) {
@@ -505,7 +507,8 @@ public:
505 }; 507 };
506 RegisterHandlers(functions); 508 RegisterHandlers(functions);
507 509
508 state_changed_event = Kernel::Event::Create(Kernel::ResetType::OneShot, 510 auto& kernel = Core::System::GetInstance().Kernel();
511 state_changed_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
509 "ILibraryAppletAccessor:StateChangedEvent"); 512 "ILibraryAppletAccessor:StateChangedEvent");
510 } 513 }
511 514
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index ce709ccf4..5f370bbdf 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -47,7 +47,9 @@ public:
47 RegisterHandlers(functions); 47 RegisterHandlers(functions);
48 48
49 // This is the event handle used to check if the audio buffer was released 49 // This is the event handle used to check if the audio buffer was released
50 buffer_event = Kernel::Event::Create(Kernel::ResetType::Sticky, "IAudioOutBufferReleased"); 50 auto& kernel = Core::System::GetInstance().Kernel();
51 buffer_event =
52 Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, "IAudioOutBufferReleased");
51 53
52 stream = audio_core.OpenStream(audio_params.sample_rate, audio_params.channel_count, 54 stream = audio_core.OpenStream(audio_params.sample_rate, audio_params.channel_count,
53 "IAudioOut", [=]() { buffer_event->Signal(); }); 55 "IAudioOut", [=]() { buffer_event->Signal(); });
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 9e75eb3a6..016db7c82 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -35,8 +35,9 @@ public:
35 }; 35 };
36 RegisterHandlers(functions); 36 RegisterHandlers(functions);
37 37
38 auto& kernel = Core::System::GetInstance().Kernel();
38 system_event = 39 system_event =
39 Kernel::Event::Create(Kernel::ResetType::Sticky, "IAudioRenderer:SystemEvent"); 40 Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, "IAudioRenderer:SystemEvent");
40 renderer = std::make_unique<AudioCore::AudioRenderer>(audren_params, system_event); 41 renderer = std::make_unique<AudioCore::AudioRenderer>(audren_params, system_event);
41 } 42 }
42 43
@@ -121,8 +122,9 @@ public:
121 }; 122 };
122 RegisterHandlers(functions); 123 RegisterHandlers(functions);
123 124
124 buffer_event = 125 auto& kernel = Core::System::GetInstance().Kernel();
125 Kernel::Event::Create(Kernel::ResetType::OneShot, "IAudioOutBufferReleasedEvent"); 126 buffer_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
127 "IAudioOutBufferReleasedEvent");
126 } 128 }
127 129
128private: 130private:
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index c0ba330dc..0d31abe8b 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -4,6 +4,7 @@
4 4
5#include <atomic> 5#include <atomic>
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/core.h"
7#include "core/core_timing.h" 8#include "core/core_timing.h"
8#include "core/core_timing_util.h" 9#include "core/core_timing_util.h"
9#include "core/frontend/emu_window.h" 10#include "core/frontend/emu_window.h"
@@ -35,9 +36,10 @@ public:
35 }; 36 };
36 RegisterHandlers(functions); 37 RegisterHandlers(functions);
37 38
39 auto& kernel = Core::System::GetInstance().Kernel();
38 shared_mem = Kernel::SharedMemory::Create( 40 shared_mem = Kernel::SharedMemory::Create(
39 nullptr, 0x40000, Kernel::MemoryPermission::ReadWrite, Kernel::MemoryPermission::Read, 41 kernel, nullptr, 0x40000, Kernel::MemoryPermission::ReadWrite,
40 0, Kernel::MemoryRegion::BASE, "HID:SharedMemory"); 42 Kernel::MemoryPermission::Read, 0, Kernel::MemoryRegion::BASE, "HID:SharedMemory");
41 43
42 // Register update callbacks 44 // Register update callbacks
43 pad_update_event = CoreTiming::RegisterEvent( 45 pad_update_event = CoreTiming::RegisterEvent(
@@ -402,7 +404,8 @@ public:
402 404
403 RegisterHandlers(functions); 405 RegisterHandlers(functions);
404 406
405 event = Kernel::Event::Create(Kernel::ResetType::OneShot, "hid:EventHandle"); 407 auto& kernel = Core::System::GetInstance().Kernel();
408 event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "hid:EventHandle");
406 } 409 }
407 ~Hid() = default; 410 ~Hid() = default;
408 411
diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp
index 56b05e9e8..4f7543af5 100644
--- a/src/core/hle/service/nfp/nfp.cpp
+++ b/src/core/hle/service/nfp/nfp.cpp
@@ -46,11 +46,13 @@ public:
46 }; 46 };
47 RegisterHandlers(functions); 47 RegisterHandlers(functions);
48 48
49 activate_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "IUser:ActivateEvent"); 49 auto& kernel = Core::System::GetInstance().Kernel();
50 activate_event =
51 Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "IUser:ActivateEvent");
50 deactivate_event = 52 deactivate_event =
51 Kernel::Event::Create(Kernel::ResetType::OneShot, "IUser:DeactivateEvent"); 53 Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "IUser:DeactivateEvent");
52 availability_change_event = 54 availability_change_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot,
53 Kernel::Event::Create(Kernel::ResetType::OneShot, "IUser:AvailabilityChangeEvent"); 55 "IUser:AvailabilityChangeEvent");
54 } 56 }
55 57
56private: 58private:
diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp
index cfe8d9178..ed4f5f539 100644
--- a/src/core/hle/service/nifm/nifm.cpp
+++ b/src/core/hle/service/nifm/nifm.cpp
@@ -2,6 +2,7 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "core/core.h"
5#include "core/hle/ipc_helpers.h" 6#include "core/hle/ipc_helpers.h"
6#include "core/hle/kernel/event.h" 7#include "core/hle/kernel/event.h"
7#include "core/hle/service/nifm/nifm.h" 8#include "core/hle/service/nifm/nifm.h"
@@ -54,8 +55,9 @@ public:
54 }; 55 };
55 RegisterHandlers(functions); 56 RegisterHandlers(functions);
56 57
57 event1 = Kernel::Event::Create(Kernel::ResetType::OneShot, "IRequest:Event1"); 58 auto& kernel = Core::System::GetInstance().Kernel();
58 event2 = Kernel::Event::Create(Kernel::ResetType::OneShot, "IRequest:Event2"); 59 event1 = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "IRequest:Event1");
60 event2 = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "IRequest:Event2");
59 } 61 }
60 62
61private: 63private:
diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp
index 923a52cc5..51638793d 100644
--- a/src/core/hle/service/ns/pl_u.cpp
+++ b/src/core/hle/service/ns/pl_u.cpp
@@ -266,8 +266,9 @@ void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) {
266 SHARED_FONT_MEM_VADDR, shared_font, 0, SHARED_FONT_MEM_SIZE, Kernel::MemoryState::Shared); 266 SHARED_FONT_MEM_VADDR, shared_font, 0, SHARED_FONT_MEM_SIZE, Kernel::MemoryState::Shared);
267 267
268 // Create shared font memory object 268 // Create shared font memory object
269 auto& kernel = Core::System::GetInstance().Kernel();
269 shared_font_mem = Kernel::SharedMemory::Create( 270 shared_font_mem = Kernel::SharedMemory::Create(
270 Core::CurrentProcess(), SHARED_FONT_MEM_SIZE, Kernel::MemoryPermission::ReadWrite, 271 kernel, Core::CurrentProcess(), SHARED_FONT_MEM_SIZE, Kernel::MemoryPermission::ReadWrite,
271 Kernel::MemoryPermission::Read, SHARED_FONT_MEM_VADDR, Kernel::MemoryRegion::BASE, 272 Kernel::MemoryPermission::Read, SHARED_FONT_MEM_VADDR, Kernel::MemoryRegion::BASE,
272 "PL_U:shared_font_mem"); 273 "PL_U:shared_font_mem");
273 274
diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp
index 1b497b814..634ab9196 100644
--- a/src/core/hle/service/nvdrv/interface.cpp
+++ b/src/core/hle/service/nvdrv/interface.cpp
@@ -4,6 +4,7 @@
4 4
5#include <cinttypes> 5#include <cinttypes>
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/core.h"
7#include "core/hle/ipc_helpers.h" 8#include "core/hle/ipc_helpers.h"
8#include "core/hle/kernel/event.h" 9#include "core/hle/kernel/event.h"
9#include "core/hle/service/nvdrv/interface.h" 10#include "core/hle/service/nvdrv/interface.h"
@@ -107,7 +108,8 @@ NVDRV::NVDRV(std::shared_ptr<Module> nvdrv, const char* name)
107 }; 108 };
108 RegisterHandlers(functions); 109 RegisterHandlers(functions);
109 110
110 query_event = Kernel::Event::Create(Kernel::ResetType::OneShot, "NVDRV::query_event"); 111 auto& kernel = Core::System::GetInstance().Kernel();
112 query_event = Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "NVDRV::query_event");
111} 113}
112 114
113} // namespace Service::Nvidia 115} // namespace Service::Nvidia
diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp
index ef5713a71..8d8962276 100644
--- a/src/core/hle/service/nvflinger/buffer_queue.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue.cpp
@@ -6,14 +6,16 @@
6 6
7#include "common/assert.h" 7#include "common/assert.h"
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "core/core.h"
9#include "core/hle/service/nvflinger/buffer_queue.h" 10#include "core/hle/service/nvflinger/buffer_queue.h"
10 11
11namespace Service { 12namespace Service {
12namespace NVFlinger { 13namespace NVFlinger {
13 14
14BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) { 15BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) {
16 auto& kernel = Core::System::GetInstance().Kernel();
15 buffer_wait_event = 17 buffer_wait_event =
16 Kernel::Event::Create(Kernel::ResetType::Sticky, "BufferQueue NativeHandle"); 18 Kernel::Event::Create(kernel, Kernel::ResetType::Sticky, "BufferQueue NativeHandle");
17} 19}
18 20
19void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) { 21void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) {
diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp
index a26a5f812..3996c24fe 100644
--- a/src/core/hle/service/nvflinger/nvflinger.cpp
+++ b/src/core/hle/service/nvflinger/nvflinger.cpp
@@ -161,7 +161,8 @@ void NVFlinger::Compose() {
161Layer::Layer(u64 id, std::shared_ptr<BufferQueue> queue) : id(id), buffer_queue(std::move(queue)) {} 161Layer::Layer(u64 id, std::shared_ptr<BufferQueue> queue) : id(id), buffer_queue(std::move(queue)) {}
162 162
163Display::Display(u64 id, std::string name) : id(id), name(std::move(name)) { 163Display::Display(u64 id, std::string name) : id(id), name(std::move(name)) {
164 vsync_event = Kernel::Event::Create(Kernel::ResetType::Pulse, "Display VSync Event"); 164 auto& kernel = Core::System::GetInstance().Kernel();
165 vsync_event = Kernel::Event::Create(kernel, Kernel::ResetType::Pulse, "Display VSync Event");
165} 166}
166 167
167} // namespace Service::NVFlinger 168} // namespace Service::NVFlinger
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 11951adaf..8fb907072 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -107,19 +107,24 @@ void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager)
107 107
108void ServiceFrameworkBase::InstallAsNamedPort() { 108void ServiceFrameworkBase::InstallAsNamedPort() {
109 ASSERT(port == nullptr); 109 ASSERT(port == nullptr);
110
111 auto& kernel = Core::System::GetInstance().Kernel();
110 SharedPtr<ServerPort> server_port; 112 SharedPtr<ServerPort> server_port;
111 SharedPtr<ClientPort> client_port; 113 SharedPtr<ClientPort> client_port;
112 std::tie(server_port, client_port) = ServerPort::CreatePortPair(max_sessions, service_name); 114 std::tie(server_port, client_port) =
115 ServerPort::CreatePortPair(kernel, max_sessions, service_name);
113 server_port->SetHleHandler(shared_from_this()); 116 server_port->SetHleHandler(shared_from_this());
114 AddNamedPort(service_name, std::move(client_port)); 117 AddNamedPort(service_name, std::move(client_port));
115} 118}
116 119
117Kernel::SharedPtr<Kernel::ClientPort> ServiceFrameworkBase::CreatePort() { 120Kernel::SharedPtr<Kernel::ClientPort> ServiceFrameworkBase::CreatePort() {
118 ASSERT(port == nullptr); 121 ASSERT(port == nullptr);
122
123 auto& kernel = Core::System::GetInstance().Kernel();
119 Kernel::SharedPtr<Kernel::ServerPort> server_port; 124 Kernel::SharedPtr<Kernel::ServerPort> server_port;
120 Kernel::SharedPtr<Kernel::ClientPort> client_port; 125 Kernel::SharedPtr<Kernel::ClientPort> client_port;
121 std::tie(server_port, client_port) = 126 std::tie(server_port, client_port) =
122 Kernel::ServerPort::CreatePortPair(max_sessions, service_name); 127 Kernel::ServerPort::CreatePortPair(kernel, max_sessions, service_name);
123 port = MakeResult<Kernel::SharedPtr<Kernel::ServerPort>>(std::move(server_port)).Unwrap(); 128 port = MakeResult<Kernel::SharedPtr<Kernel::ServerPort>>(std::move(server_port)).Unwrap();
124 port->SetHleHandler(shared_from_this()); 129 port->SetHleHandler(shared_from_this());
125 return client_port; 130 return client_port;
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index f22a2a79f..b240d7eed 100644
--- a/src/core/hle/service/sm/sm.cpp
+++ b/src/core/hle/service/sm/sm.cpp
@@ -4,6 +4,7 @@
4 4
5#include <tuple> 5#include <tuple>
6#include "common/assert.h" 6#include "common/assert.h"
7#include "core/core.h"
7#include "core/hle/ipc_helpers.h" 8#include "core/hle/ipc_helpers.h"
8#include "core/hle/kernel/client_port.h" 9#include "core/hle/kernel/client_port.h"
9#include "core/hle/kernel/client_session.h" 10#include "core/hle/kernel/client_session.h"
@@ -47,9 +48,11 @@ ResultVal<Kernel::SharedPtr<Kernel::ServerPort>> ServiceManager::RegisterService
47 if (registered_services.find(name) != registered_services.end()) 48 if (registered_services.find(name) != registered_services.end())
48 return ERR_ALREADY_REGISTERED; 49 return ERR_ALREADY_REGISTERED;
49 50
51 auto& kernel = Core::System::GetInstance().Kernel();
50 Kernel::SharedPtr<Kernel::ServerPort> server_port; 52 Kernel::SharedPtr<Kernel::ServerPort> server_port;
51 Kernel::SharedPtr<Kernel::ClientPort> client_port; 53 Kernel::SharedPtr<Kernel::ClientPort> client_port;
52 std::tie(server_port, client_port) = Kernel::ServerPort::CreatePortPair(max_sessions, name); 54 std::tie(server_port, client_port) =
55 Kernel::ServerPort::CreatePortPair(kernel, max_sessions, name);
53 56
54 registered_services.emplace(std::move(name), std::move(client_port)); 57 registered_services.emplace(std::move(name), std::move(client_port));
55 return MakeResult<Kernel::SharedPtr<Kernel::ServerPort>>(std::move(server_port)); 58 return MakeResult<Kernel::SharedPtr<Kernel::ServerPort>>(std::move(server_port));
diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp
index 4c79d7902..a53fa6e00 100644
--- a/src/core/loader/deconstructed_rom_directory.cpp
+++ b/src/core/loader/deconstructed_rom_directory.cpp
@@ -6,6 +6,7 @@
6#include "common/common_funcs.h" 6#include "common/common_funcs.h"
7#include "common/file_util.h" 7#include "common/file_util.h"
8#include "common/logging/log.h" 8#include "common/logging/log.h"
9#include "core/core.h"
9#include "core/file_sys/content_archive.h" 10#include "core/file_sys/content_archive.h"
10#include "core/file_sys/control_metadata.h" 11#include "core/file_sys/control_metadata.h"
11#include "core/file_sys/romfs_factory.h" 12#include "core/file_sys/romfs_factory.h"
@@ -117,10 +118,11 @@ ResultStatus AppLoader_DeconstructedRomDirectory::Load(
117 } 118 }
118 } 119 }
119 120
121 auto& kernel = Core::System::GetInstance().Kernel();
120 process->program_id = metadata.GetTitleID(); 122 process->program_id = metadata.GetTitleID();
121 process->svc_access_mask.set(); 123 process->svc_access_mask.set();
122 process->resource_limit = 124 process->resource_limit =
123 Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); 125 kernel.ResourceLimitForCategory(Kernel::ResourceLimitCategory::APPLICATION);
124 process->Run(Memory::PROCESS_IMAGE_VADDR, metadata.GetMainThreadPriority(), 126 process->Run(Memory::PROCESS_IMAGE_VADDR, metadata.GetMainThreadPriority(),
125 metadata.GetMainThreadStackSize()); 127 metadata.GetMainThreadStackSize());
126 128
diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp
index 6420a7f11..3702a8478 100644
--- a/src/core/loader/elf.cpp
+++ b/src/core/loader/elf.cpp
@@ -9,6 +9,7 @@
9#include "common/common_types.h" 9#include "common/common_types.h"
10#include "common/file_util.h" 10#include "common/file_util.h"
11#include "common/logging/log.h" 11#include "common/logging/log.h"
12#include "core/core.h"
12#include "core/hle/kernel/process.h" 13#include "core/hle/kernel/process.h"
13#include "core/hle/kernel/resource_limit.h" 14#include "core/hle/kernel/resource_limit.h"
14#include "core/loader/elf.h" 15#include "core/loader/elf.h"
@@ -300,7 +301,8 @@ SharedPtr<CodeSet> ElfReader::LoadInto(u32 vaddr) {
300 std::vector<u8> program_image(total_image_size); 301 std::vector<u8> program_image(total_image_size);
301 size_t current_image_position = 0; 302 size_t current_image_position = 0;
302 303
303 SharedPtr<CodeSet> codeset = CodeSet::Create(""); 304 auto& kernel = Core::System::GetInstance().Kernel();
305 SharedPtr<CodeSet> codeset = CodeSet::Create(kernel, "");
304 306
305 for (unsigned int i = 0; i < header->e_phnum; ++i) { 307 for (unsigned int i = 0; i < header->e_phnum; ++i) {
306 Elf32_Phdr* p = &segments[i]; 308 Elf32_Phdr* p = &segments[i];
@@ -400,8 +402,9 @@ ResultStatus AppLoader_ELF::Load(Kernel::SharedPtr<Kernel::Process>& process) {
400 process->svc_access_mask.set(); 402 process->svc_access_mask.set();
401 403
402 // Attach the default resource limit (APPLICATION) to the process 404 // Attach the default resource limit (APPLICATION) to the process
405 auto& kernel = Core::System::GetInstance().Kernel();
403 process->resource_limit = 406 process->resource_limit =
404 Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); 407 kernel.ResourceLimitForCategory(Kernel::ResourceLimitCategory::APPLICATION);
405 408
406 process->Run(codeset->entrypoint, 48, Memory::DEFAULT_STACK_SIZE); 409 process->Run(codeset->entrypoint, 48, Memory::DEFAULT_STACK_SIZE);
407 410
diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp
index 2179cf2ea..00205d1d2 100644
--- a/src/core/loader/nro.cpp
+++ b/src/core/loader/nro.cpp
@@ -136,7 +136,8 @@ bool AppLoader_NRO::LoadNro(FileSys::VirtualFile file, VAddr load_base) {
136 } 136 }
137 137
138 // Build program image 138 // Build program image
139 Kernel::SharedPtr<Kernel::CodeSet> codeset = Kernel::CodeSet::Create(""); 139 auto& kernel = Core::System::GetInstance().Kernel();
140 Kernel::SharedPtr<Kernel::CodeSet> codeset = Kernel::CodeSet::Create(kernel, "");
140 std::vector<u8> program_image = file->ReadBytes(PageAlignSize(nro_header.file_size)); 141 std::vector<u8> program_image = file->ReadBytes(PageAlignSize(nro_header.file_size));
141 if (program_image.size() != PageAlignSize(nro_header.file_size)) { 142 if (program_image.size() != PageAlignSize(nro_header.file_size)) {
142 return {}; 143 return {};
@@ -185,9 +186,10 @@ ResultStatus AppLoader_NRO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
185 return ResultStatus::ErrorLoadingNRO; 186 return ResultStatus::ErrorLoadingNRO;
186 } 187 }
187 188
189 auto& kernel = Core::System::GetInstance().Kernel();
188 process->svc_access_mask.set(); 190 process->svc_access_mask.set();
189 process->resource_limit = 191 process->resource_limit =
190 Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); 192 kernel.ResourceLimitForCategory(Kernel::ResourceLimitCategory::APPLICATION);
191 process->Run(base_addr, THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE); 193 process->Run(base_addr, THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE);
192 194
193 is_loaded = true; 195 is_loaded = true;
diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp
index a94558ac5..0c992d662 100644
--- a/src/core/loader/nso.cpp
+++ b/src/core/loader/nso.cpp
@@ -100,7 +100,8 @@ VAddr AppLoader_NSO::LoadModule(FileSys::VirtualFile file, VAddr load_base) {
100 return {}; 100 return {};
101 101
102 // Build program image 102 // Build program image
103 Kernel::SharedPtr<Kernel::CodeSet> codeset = Kernel::CodeSet::Create(""); 103 auto& kernel = Core::System::GetInstance().Kernel();
104 Kernel::SharedPtr<Kernel::CodeSet> codeset = Kernel::CodeSet::Create(kernel, "");
104 std::vector<u8> program_image; 105 std::vector<u8> program_image;
105 for (std::size_t i = 0; i < nso_header.segments.size(); ++i) { 106 for (std::size_t i = 0; i < nso_header.segments.size(); ++i) {
106 const std::vector<u8> compressed_data = 107 const std::vector<u8> compressed_data =
@@ -151,9 +152,10 @@ ResultStatus AppLoader_NSO::Load(Kernel::SharedPtr<Kernel::Process>& process) {
151 LoadModule(file, Memory::PROCESS_IMAGE_VADDR); 152 LoadModule(file, Memory::PROCESS_IMAGE_VADDR);
152 LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", file->GetName(), Memory::PROCESS_IMAGE_VADDR); 153 LOG_DEBUG(Loader, "loaded module {} @ 0x{:X}", file->GetName(), Memory::PROCESS_IMAGE_VADDR);
153 154
155 auto& kernel = Core::System::GetInstance().Kernel();
154 process->svc_access_mask.set(); 156 process->svc_access_mask.set();
155 process->resource_limit = 157 process->resource_limit =
156 Kernel::ResourceLimit::GetForCategory(Kernel::ResourceLimitCategory::APPLICATION); 158 kernel.ResourceLimitForCategory(Kernel::ResourceLimitCategory::APPLICATION);
157 process->Run(Memory::PROCESS_IMAGE_VADDR, THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE); 159 process->Run(Memory::PROCESS_IMAGE_VADDR, THREADPRIO_DEFAULT, Memory::DEFAULT_STACK_SIZE);
158 160
159 is_loaded = true; 161 is_loaded = true;
diff --git a/src/tests/core/arm/arm_test_common.cpp b/src/tests/core/arm/arm_test_common.cpp
index 539746246..038d57b3a 100644
--- a/src/tests/core/arm/arm_test_common.cpp
+++ b/src/tests/core/arm/arm_test_common.cpp
@@ -13,7 +13,7 @@ namespace ArmTests {
13TestEnvironment::TestEnvironment(bool mutable_memory_) 13TestEnvironment::TestEnvironment(bool mutable_memory_)
14 : mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) { 14 : mutable_memory(mutable_memory_), test_memory(std::make_shared<TestMemory>(this)) {
15 15
16 Core::CurrentProcess() = Kernel::Process::Create(""); 16 Core::CurrentProcess() = Kernel::Process::Create(kernel, "");
17 page_table = &Core::CurrentProcess()->vm_manager.page_table; 17 page_table = &Core::CurrentProcess()->vm_manager.page_table;
18 18
19 page_table->pointers.fill(nullptr); 19 page_table->pointers.fill(nullptr);
diff --git a/src/tests/core/arm/arm_test_common.h b/src/tests/core/arm/arm_test_common.h
index 7fdbda494..e4b6df194 100644
--- a/src/tests/core/arm/arm_test_common.h
+++ b/src/tests/core/arm/arm_test_common.h
@@ -9,6 +9,7 @@
9#include <vector> 9#include <vector>
10 10
11#include "common/common_types.h" 11#include "common/common_types.h"
12#include "core/hle/kernel/kernel.h"
12#include "core/memory_hook.h" 13#include "core/memory_hook.h"
13 14
14namespace Memory { 15namespace Memory {
@@ -86,6 +87,7 @@ private:
86 std::shared_ptr<TestMemory> test_memory; 87 std::shared_ptr<TestMemory> test_memory;
87 std::vector<WriteRecord> write_records; 88 std::vector<WriteRecord> write_records;
88 Memory::PageTable* page_table = nullptr; 89 Memory::PageTable* page_table = nullptr;
90 Kernel::KernelCore kernel;
89}; 91};
90 92
91} // namespace ArmTests 93} // namespace ArmTests
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp
index d0926d723..eac0c05f2 100644
--- a/src/yuzu/debugger/wait_tree.cpp
+++ b/src/yuzu/debugger/wait_tree.cpp
@@ -77,9 +77,11 @@ QString WaitTreeText::GetText() const {
77} 77}
78 78
79WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address) : mutex_address(mutex_address) { 79WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address) : mutex_address(mutex_address) {
80 auto& handle_table = Core::System::GetInstance().Kernel().HandleTable();
81
80 mutex_value = Memory::Read32(mutex_address); 82 mutex_value = Memory::Read32(mutex_address);
81 owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Mutex::MutexOwnerMask); 83 owner_handle = static_cast<Kernel::Handle>(mutex_value & Kernel::Mutex::MutexOwnerMask);
82 owner = Kernel::g_handle_table.Get<Kernel::Thread>(owner_handle); 84 owner = handle_table.Get<Kernel::Thread>(owner_handle);
83} 85}
84 86
85QString WaitTreeMutexInfo::GetText() const { 87QString WaitTreeMutexInfo::GetText() const {