summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar Lioncash2018-08-28 12:30:33 -0400
committerGravatar Lioncash2018-08-28 22:31:51 -0400
commit0cbcd6ec9aeeafc298fe2e6e4ac10d68bb7267c5 (patch)
tree2d7bb143d490c3984bff6deda426b818bf27d552 /src
parentMerge pull request #1193 from lioncash/priv (diff)
downloadyuzu-0cbcd6ec9aeeafc298fe2e6e4ac10d68bb7267c5.tar.gz
yuzu-0cbcd6ec9aeeafc298fe2e6e4ac10d68bb7267c5.tar.xz
yuzu-0cbcd6ec9aeeafc298fe2e6e4ac10d68bb7267c5.zip
kernel: Eliminate kernel global state
As means to pave the way for getting rid of global state within core, This eliminates kernel global state by removing all globals. Instead this introduces a KernelCore class which acts as a kernel instance. This instance lives in the System class, which keeps its lifetime contained to the lifetime of the System class. This also forces the kernel types to actually interact with the main kernel instance itself instead of having transient kernel state placed all over several translation units, keeping everything together. It also has a nice consequence of making dependencies much more explicit. This also makes our initialization a tad bit more correct. Previously we were creating a kernel process before the actual kernel was initialized, which doesn't really make much sense. The KernelCore class itself follows the PImpl idiom, which allows keeping all the implementation details sealed away from everything else, which forces the use of the exposed API and allows us to avoid any unnecessary inclusions within the main kernel header.
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 {