diff options
Diffstat (limited to 'src')
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 | ||
| 174 | Kernel::KernelCore& System::Kernel() { | ||
| 175 | return kernel; | ||
| 176 | } | ||
| 177 | |||
| 178 | const Kernel::KernelCore& System::Kernel() const { | ||
| 179 | return kernel; | ||
| 180 | } | ||
| 181 | |||
| 174 | ARM_Interface& System::ArmInterface(size_t core_index) { | 182 | ARM_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 | ||
| 15 | namespace Kernel { | 15 | namespace Kernel { |
| 16 | 16 | ||
| 17 | ClientPort::ClientPort() = default; | 17 | ClientPort::ClientPort(KernelCore& kernel) : Object{kernel} {} |
| 18 | ClientPort::~ClientPort() = default; | 18 | ClientPort::~ClientPort() = default; |
| 19 | 19 | ||
| 20 | ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { | 20 | ResultVal<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 | ||
| 12 | namespace Kernel { | 12 | namespace Kernel { |
| 13 | 13 | ||
| 14 | class ServerPort; | ||
| 15 | class ClientSession; | 14 | class ClientSession; |
| 15 | class KernelCore; | ||
| 16 | class ServerPort; | ||
| 16 | 17 | ||
| 17 | class ClientPort final : public Object { | 18 | class ClientPort final : public Object { |
| 18 | public: | 19 | public: |
| @@ -44,7 +45,7 @@ public: | |||
| 44 | void ConnectionClosed(); | 45 | void ConnectionClosed(); |
| 45 | 46 | ||
| 46 | private: | 47 | private: |
| 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 | ||
| 12 | namespace Kernel { | 12 | namespace Kernel { |
| 13 | 13 | ||
| 14 | ClientSession::ClientSession() = default; | 14 | ClientSession::ClientSession(KernelCore& kernel) : Object{kernel} {} |
| 15 | ClientSession::~ClientSession() { | 15 | ClientSession::~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 | ||
| 13 | namespace Kernel { | 13 | namespace Kernel { |
| 14 | 14 | ||
| 15 | class ServerSession; | 15 | class KernelCore; |
| 16 | class Session; | 16 | class Session; |
| 17 | class ServerSession; | ||
| 17 | class Thread; | 18 | class Thread; |
| 18 | 19 | ||
| 19 | class ClientSession final : public Object { | 20 | class ClientSession final : public Object { |
| @@ -41,7 +42,7 @@ public: | |||
| 41 | std::shared_ptr<Session> parent; | 42 | std::shared_ptr<Session> parent; |
| 42 | 43 | ||
| 43 | private: | 44 | private: |
| 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 | ||
| 11 | namespace Kernel { | 11 | namespace Kernel { |
| 12 | 12 | ||
| 13 | Event::Event() {} | 13 | Event::Event(KernelCore& kernel) : WaitObject{kernel} {} |
| 14 | Event::~Event() {} | 14 | Event::~Event() = default; |
| 15 | 15 | ||
| 16 | SharedPtr<Event> Event::Create(ResetType reset_type, std::string name) { | 16 | SharedPtr<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 | ||
| 11 | namespace Kernel { | 11 | namespace Kernel { |
| 12 | 12 | ||
| 13 | class KernelCore; | ||
| 14 | |||
| 13 | class Event final : public WaitObject { | 15 | class Event final : public WaitObject { |
| 14 | public: | 16 | public: |
| 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 | ||
| 46 | private: | 50 | private: |
| 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 | ||
| 14 | namespace Kernel { | 14 | namespace Kernel { |
| 15 | 15 | ||
| 16 | HandleTable g_handle_table; | ||
| 17 | |||
| 18 | HandleTable::HandleTable() { | 16 | HandleTable::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 | ||
| 124 | extern 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 | ||
| 12 | namespace Kernel { | 25 | namespace Kernel { |
| 13 | 26 | ||
| 14 | std::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 | */ | ||
| 32 | static 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 | ||
| 90 | static 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 | 103 | struct KernelCore::Impl { |
| 17 | void 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 | |||
| 222 | KernelCore::KernelCore() : impl{std::make_unique<Impl>()} {} | ||
| 223 | KernelCore::~KernelCore() { | ||
| 224 | Shutdown(); | ||
| 225 | } | ||
| 226 | |||
| 227 | void KernelCore::Initialize() { | ||
| 228 | impl->Initialize(*this); | ||
| 229 | } | ||
| 230 | |||
| 231 | void KernelCore::Shutdown() { | ||
| 232 | impl->Shutdown(); | ||
| 233 | } | ||
| 234 | |||
| 235 | Kernel::HandleTable& KernelCore::HandleTable() { | ||
| 236 | return impl->handle_table; | ||
| 237 | } | ||
| 238 | |||
| 239 | const Kernel::HandleTable& KernelCore::HandleTable() const { | ||
| 240 | return impl->handle_table; | ||
| 241 | } | ||
| 242 | |||
| 243 | SharedPtr<ResourceLimit> KernelCore::ResourceLimitForCategory( | ||
| 244 | ResourceLimitCategory category) const { | ||
| 245 | return impl->resource_limits.at(static_cast<std::size_t>(category)); | ||
| 246 | } | ||
| 247 | |||
| 248 | SharedPtr<Thread> KernelCore::RetrieveThreadFromWakeupCallbackHandleTable(Handle handle) const { | ||
| 249 | return impl->thread_wakeup_callback_handle_table.Get<Thread>(handle); | ||
| 250 | } | ||
| 251 | |||
| 252 | SharedPtr<Timer> KernelCore::RetrieveTimerFromCallbackHandleTable(Handle handle) const { | ||
| 253 | return impl->timer_callback_handle_table.Get<Timer>(handle); | ||
| 254 | } | ||
| 255 | |||
| 256 | void KernelCore::AppendNewProcess(SharedPtr<Process> process) { | ||
| 257 | impl->process_list.push_back(std::move(process)); | ||
| 258 | } | ||
| 259 | |||
| 260 | u32 KernelCore::CreateNewObjectID() { | ||
| 261 | return impl->next_object_id++; | ||
| 262 | } | ||
| 263 | |||
| 264 | u32 KernelCore::CreateNewThreadID() { | ||
| 265 | return impl->next_thread_id++; | ||
| 26 | } | 266 | } |
| 27 | 267 | ||
| 28 | /// Shutdown the kernel | 268 | u32 KernelCore::CreateNewProcessID() { |
| 29 | void Shutdown() { | 269 | return impl->next_process_id++; |
| 30 | // Free all kernel objects | 270 | } |
| 31 | g_handle_table.Clear(); | ||
| 32 | 271 | ||
| 33 | Kernel::ThreadingShutdown(); | 272 | ResultVal<Handle> KernelCore::CreateTimerCallbackHandle(const SharedPtr<Timer>& timer) { |
| 273 | return impl->timer_callback_handle_table.Create(timer); | ||
| 274 | } | ||
| 275 | |||
| 276 | CoreTiming::EventType* KernelCore::ThreadWakeupCallbackEventType() const { | ||
| 277 | return impl->thread_wakeup_event_type; | ||
| 278 | } | ||
| 279 | |||
| 280 | CoreTiming::EventType* KernelCore::TimerCallbackEventType() const { | ||
| 281 | return impl->timer_callback_event_type; | ||
| 282 | } | ||
| 283 | |||
| 284 | Kernel::HandleTable& KernelCore::ThreadWakeupCallbackHandleTable() { | ||
| 285 | return impl->thread_wakeup_callback_handle_table; | ||
| 286 | } | ||
| 34 | 287 | ||
| 35 | Kernel::TimersShutdown(); | 288 | const 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 | |||
| 9 | template <typename T> | ||
| 10 | class ResultVal; | ||
| 11 | |||
| 12 | namespace CoreTiming { | ||
| 13 | struct EventType; | ||
| 14 | } | ||
| 8 | 15 | ||
| 9 | namespace Kernel { | 16 | namespace Kernel { |
| 10 | 17 | ||
| 11 | /// Initialize the kernel with the specified system mode. | 18 | class HandleTable; |
| 12 | void Init(); | 19 | class Process; |
| 20 | class ResourceLimit; | ||
| 21 | class Thread; | ||
| 22 | class Timer; | ||
| 23 | |||
| 24 | enum class ResourceLimitCategory : u8; | ||
| 25 | |||
| 26 | /// Represents a single instance of the kernel. | ||
| 27 | class KernelCore { | ||
| 28 | public: | ||
| 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 | |||
| 62 | private: | ||
| 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; |
| 15 | void 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 | ||
| 61 | ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle, | 61 | ResultCode 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 | ||
| 12 | namespace Kernel { | 12 | namespace Kernel { |
| 13 | 13 | ||
| 14 | class HandleTable; | ||
| 14 | class Thread; | 15 | class Thread; |
| 15 | 16 | ||
| 16 | class Mutex final { | 17 | class 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 | ||
| 8 | namespace Kernel { | 9 | namespace Kernel { |
| 9 | 10 | ||
| 11 | Object::Object(KernelCore& kernel) : kernel{kernel}, object_id{kernel.CreateNewObjectID()} {} | ||
| 10 | Object::~Object() = default; | 12 | Object::~Object() = default; |
| 11 | 13 | ||
| 12 | bool Object::IsWaitable() const { | 14 | bool 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 | ||
| 15 | namespace Kernel { | 15 | namespace Kernel { |
| 16 | 16 | ||
| 17 | class KernelCore; | ||
| 18 | |||
| 17 | using Handle = u32; | 19 | using Handle = u32; |
| 18 | 20 | ||
| 19 | enum class HandleType : u32 { | 21 | enum class HandleType : u32 { |
| @@ -40,6 +42,7 @@ enum class ResetType { | |||
| 40 | 42 | ||
| 41 | class Object : NonCopyable { | 43 | class Object : NonCopyable { |
| 42 | public: | 44 | public: |
| 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 | ||
| 64 | public: | 67 | protected: |
| 65 | static std::atomic<u32> next_object_id; | 68 | /// The kernel instance this object was created under. |
| 69 | KernelCore& kernel; | ||
| 66 | 70 | ||
| 67 | private: | 71 | private: |
| 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 | ||
| 17 | namespace Kernel { | 18 | namespace Kernel { |
| 18 | 19 | ||
| 19 | // Lists all processes that exist in the current session. | 20 | SharedPtr<CodeSet> CodeSet::Create(KernelCore& kernel, std::string name) { |
| 20 | static std::vector<SharedPtr<Process>> process_list; | 21 | SharedPtr<CodeSet> codeset(new CodeSet(kernel)); |
| 21 | |||
| 22 | SharedPtr<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 | ||
| 28 | CodeSet::CodeSet() {} | 26 | CodeSet::CodeSet(KernelCore& kernel) : Object{kernel} {} |
| 29 | CodeSet::~CodeSet() {} | 27 | CodeSet::~CodeSet() = default; |
| 30 | |||
| 31 | u32 Process::next_process_id; | ||
| 32 | 28 | ||
| 33 | SharedPtr<Process> Process::Create(std::string&& name) { | 29 | SharedPtr<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 | ||
| 134 | void Process::LoadModule(SharedPtr<CodeSet> module_, VAddr base_addr) { | 131 | void 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 | ||
| 234 | Kernel::Process::Process() {} | 231 | Kernel::Process::Process(KernelCore& kernel) : Object{kernel} {} |
| 235 | Kernel::Process::~Process() {} | 232 | Kernel::Process::~Process() {} |
| 236 | 233 | ||
| 237 | void ClearProcessList() { | ||
| 238 | process_list.clear(); | ||
| 239 | } | ||
| 240 | |||
| 241 | SharedPtr<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 | ||
| 20 | namespace Kernel { | 20 | namespace Kernel { |
| 21 | 21 | ||
| 22 | class KernelCore; | ||
| 23 | |||
| 22 | struct AddressMapping { | 24 | struct 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 | ||
| 111 | private: | 113 | private: |
| 112 | CodeSet(); | 114 | explicit CodeSet(KernelCore& kernel); |
| 113 | ~CodeSet() override; | 115 | ~CodeSet() override; |
| 114 | }; | 116 | }; |
| 115 | 117 | ||
| 116 | class Process final : public Object { | 118 | class Process final : public Object { |
| 117 | public: | 119 | public: |
| 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 | ||
| 208 | private: | 208 | private: |
| 209 | Process(); | 209 | explicit Process(KernelCore& kernel); |
| 210 | ~Process() override; | 210 | ~Process() override; |
| 211 | }; | 211 | }; |
| 212 | 212 | ||
| 213 | void ClearProcessList(); | ||
| 214 | |||
| 215 | /// Retrieves a process from the current list of processes. | ||
| 216 | SharedPtr<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 | ||
| 10 | namespace Kernel { | 10 | namespace Kernel { |
| 11 | 11 | ||
| 12 | static SharedPtr<ResourceLimit> resource_limits[4]; | 12 | ResourceLimit::ResourceLimit(KernelCore& kernel) : Object{kernel} {} |
| 13 | ResourceLimit::~ResourceLimit() = default; | ||
| 13 | 14 | ||
| 14 | ResourceLimit::ResourceLimit() {} | 15 | SharedPtr<ResourceLimit> ResourceLimit::Create(KernelCore& kernel, std::string name) { |
| 15 | ResourceLimit::~ResourceLimit() {} | 16 | SharedPtr<ResourceLimit> resource_limit(new ResourceLimit(kernel)); |
| 16 | |||
| 17 | SharedPtr<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 | ||
| 24 | SharedPtr<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 | |||
| 37 | s32 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const { | 22 | s32 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 | |||
| 93 | void 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 | |||
| 152 | void 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 | ||
| 10 | namespace Kernel { | 10 | namespace Kernel { |
| 11 | 11 | ||
| 12 | class KernelCore; | ||
| 13 | |||
| 12 | enum class ResourceLimitCategory : u8 { | 14 | enum 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 | ||
| 115 | private: | 110 | private: |
| 116 | ResourceLimit(); | 111 | explicit ResourceLimit(KernelCore& kernel); |
| 117 | ~ResourceLimit() override; | 112 | ~ResourceLimit() override; |
| 118 | }; | 113 | }; |
| 119 | 114 | ||
| 120 | /// Initializes the resource limits | ||
| 121 | void ResourceLimitsInit(); | ||
| 122 | |||
| 123 | // Destroys the resource limits | ||
| 124 | void 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 | ||
| 14 | namespace Kernel { | 14 | namespace Kernel { |
| 15 | 15 | ||
| 16 | ServerPort::ServerPort() {} | 16 | ServerPort::ServerPort(KernelCore& kernel) : WaitObject{kernel} {} |
| 17 | ServerPort::~ServerPort() {} | 17 | ServerPort::~ServerPort() = default; |
| 18 | 18 | ||
| 19 | ResultVal<SharedPtr<ServerSession>> ServerPort::Accept() { | 19 | ResultVal<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 | ||
| 38 | std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> ServerPort::CreatePortPair( | 38 | std::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 @@ | |||
| 15 | namespace Kernel { | 15 | namespace Kernel { |
| 16 | 16 | ||
| 17 | class ClientPort; | 17 | class ClientPort; |
| 18 | class KernelCore; | ||
| 18 | class ServerSession; | 19 | class ServerSession; |
| 19 | class SessionRequestHandler; | 20 | class 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 | ||
| 71 | private: | 73 | private: |
| 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 | ||
| 21 | namespace Kernel { | 21 | namespace Kernel { |
| 22 | 22 | ||
| 23 | ServerSession::ServerSession() = default; | 23 | ServerSession::ServerSession(KernelCore& kernel) : WaitObject{kernel} {} |
| 24 | ServerSession::~ServerSession() { | 24 | ServerSession::~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 | ||
| 38 | ResultVal<SharedPtr<ServerSession>> ServerSession::Create(std::string name) { | 38 | ResultVal<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 | ||
| 163 | ServerSession::SessionPair ServerSession::CreateSessionPair(const std::string& name, | 163 | ServerSession::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 | ||
| 16 | namespace Kernel { | 16 | namespace Kernel { |
| 17 | 17 | ||
| 18 | class ClientSession; | ||
| 19 | class ClientPort; | 18 | class ClientPort; |
| 19 | class ClientSession; | ||
| 20 | class HLERequestContext; | ||
| 21 | class KernelCore; | ||
| 20 | class ServerSession; | 22 | class ServerSession; |
| 21 | class Session; | 23 | class Session; |
| 22 | class SessionRequestHandler; | 24 | class SessionRequestHandler; |
| 23 | class Thread; | 25 | class Thread; |
| 24 | class 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 | ||
| 113 | private: | 115 | private: |
| 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 | ||
| 14 | namespace Kernel { | 14 | namespace Kernel { |
| 15 | 15 | ||
| 16 | SharedMemory::SharedMemory() {} | 16 | SharedMemory::SharedMemory(KernelCore& kernel) : Object{kernel} {} |
| 17 | SharedMemory::~SharedMemory() {} | 17 | SharedMemory::~SharedMemory() = default; |
| 18 | 18 | ||
| 19 | SharedPtr<SharedMemory> SharedMemory::Create(SharedPtr<Process> owner_process, u64 size, | 19 | SharedPtr<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 | ||
| 62 | SharedPtr<SharedMemory> SharedMemory::CreateForApplet(std::shared_ptr<std::vector<u8>> heap_block, | 62 | SharedPtr<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 | ||
| 16 | namespace Kernel { | 16 | namespace Kernel { |
| 17 | 17 | ||
| 18 | class KernelCore; | ||
| 19 | |||
| 18 | /// Permissions for mapped shared memory blocks | 20 | /// Permissions for mapped shared memory blocks |
| 19 | enum class MemoryPermission : u32 { | 21 | enum class MemoryPermission : u32 { |
| 20 | None = 0, | 22 | None = 0, |
| @@ -32,6 +34,7 @@ class SharedMemory final : public Object { | |||
| 32 | public: | 34 | public: |
| 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 | ||
| 127 | private: | 132 | private: |
| 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. |
| 95 | static ResultCode SendSyncRequest(Handle handle) { | 96 | static 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) { | |||
| 112 | static ResultCode GetThreadId(u32* thread_id, Handle thread_handle) { | 114 | static 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) { | |||
| 125 | static ResultCode GetProcessId(u32* process_id, Handle process_handle) { | 128 | static 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 | |||
| 219 | static ResultCode CancelSynchronization(Handle thread_handle) { | 224 | static 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 |
| 354 | static ResultCode GetThreadPriority(u32* priority, Handle handle) { | 362 | static 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 |
| 432 | static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_info*/, | 444 | static 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 | |||
| 548 | static ResultCode StartThread(Handle thread_handle) { | 563 | static 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 |
| 784 | static ResultCode CloseHandle(Handle handle) { | 802 | static 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 |
| 790 | static ResultCode ResetSignal(Handle handle) { | 810 | static 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 | |||
| 806 | static ResultCode GetThreadCoreMask(Handle thread_handle, u32* core, u64* mask) { | 830 | static 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 | ||
| 873 | static ResultCode ClearEvent(Handle handle) { | 902 | static 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 | ||
| 30 | namespace Kernel { | 31 | namespace Kernel { |
| 31 | 32 | ||
| 32 | /// Event type for the thread wake up event | ||
| 33 | static CoreTiming::EventType* ThreadWakeupEventType = nullptr; | ||
| 34 | |||
| 35 | bool Thread::ShouldWait(Thread* thread) const { | 33 | bool 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 | 41 | Thread::Thread(KernelCore& kernel) : WaitObject{kernel} {} |
| 44 | // us to simply use a pool index or similar. | 42 | Thread::~Thread() = default; |
| 45 | static Kernel::HandleTable wakeup_callback_handle_table; | ||
| 46 | |||
| 47 | // The first available thread id at startup | ||
| 48 | static u32 next_thread_id; | ||
| 49 | |||
| 50 | /** | ||
| 51 | * Creates a new thread ID | ||
| 52 | * @return The new thread ID | ||
| 53 | */ | ||
| 54 | inline static u32 const NewThreadId() { | ||
| 55 | return next_thread_id++; | ||
| 56 | } | ||
| 57 | |||
| 58 | Thread::Thread() {} | ||
| 59 | Thread::~Thread() {} | ||
| 60 | 43 | ||
| 61 | void Thread::Stop() { | 44 | void 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 | */ | ||
| 106 | static 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 | |||
| 158 | void Thread::WakeAfterDelay(s64 nanoseconds) { | 84 | void 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 | ||
| 169 | void Thread::CancelWakeupTimer() { | 95 | void Thread::CancelWakeupTimer() { |
| 170 | CoreTiming::UnscheduleEventThreadsafe(ThreadWakeupEventType, callback_handle); | 96 | CoreTiming::UnscheduleEventThreadsafe(kernel.ThreadWakeupCallbackEventType(), callback_handle); |
| 171 | } | 97 | } |
| 172 | 98 | ||
| 173 | static boost::optional<s32> GetNextProcessorId(u64 mask) { | 99 | static 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 | ||
| 297 | ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point, u32 priority, | 223 | ResultVal<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 | ||
| 386 | SharedPtr<Thread> SetupMainThread(VAddr entry_point, u32 priority, | 312 | SharedPtr<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 | ||
| 531 | void ThreadingInit() { | ||
| 532 | ThreadWakeupEventType = CoreTiming::RegisterEvent("ThreadWakeupCallback", ThreadWakeupCallback); | ||
| 533 | next_thread_id = 1; | ||
| 534 | } | ||
| 535 | |||
| 536 | void 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 | ||
| 57 | namespace Kernel { | 57 | namespace Kernel { |
| 58 | 58 | ||
| 59 | class KernelCore; | ||
| 59 | class Process; | 60 | class Process; |
| 60 | class Scheduler; | 61 | class Scheduler; |
| 61 | 62 | ||
| @@ -63,6 +64,7 @@ class Thread final : public WaitObject { | |||
| 63 | public: | 64 | public: |
| 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 | ||
| 265 | private: | 268 | private: |
| 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 | */ |
| 279 | SharedPtr<Thread> SetupMainThread(VAddr entry_point, u32 priority, | 283 | SharedPtr<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 | */ |
| 295 | void ExitCurrentThread(); | 299 | void ExitCurrentThread(); |
| 296 | 300 | ||
| 297 | /** | ||
| 298 | * Initialize threading | ||
| 299 | */ | ||
| 300 | void ThreadingInit(); | ||
| 301 | |||
| 302 | /** | ||
| 303 | * Shutdown threading | ||
| 304 | */ | ||
| 305 | void 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 | ||
| 15 | namespace Kernel { | 16 | namespace Kernel { |
| 16 | 17 | ||
| 17 | /// The event type of the generic timer callback event | 18 | Timer::Timer(KernelCore& kernel) : WaitObject{kernel} {} |
| 18 | static CoreTiming::EventType* timer_callback_event_type = nullptr; | 19 | Timer::~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. | ||
| 21 | static Kernel::HandleTable timer_callback_handle_table; | ||
| 22 | 20 | ||
| 23 | Timer::Timer() {} | 21 | SharedPtr<Timer> Timer::Create(KernelCore& kernel, ResetType reset_type, std::string name) { |
| 24 | Timer::~Timer() {} | 22 | SharedPtr<Timer> timer(new Timer(kernel)); |
| 25 | |||
| 26 | SharedPtr<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 | ||
| 66 | void Timer::Cancel() { | 61 | void Timer::Cancel() { |
| 67 | CoreTiming::UnscheduleEvent(timer_callback_event_type, callback_handle); | 62 | CoreTiming::UnscheduleEvent(kernel.TimerCallbackEventType(), callback_handle); |
| 68 | } | 63 | } |
| 69 | 64 | ||
| 70 | void Timer::Clear() { | 65 | void 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 | ||
| 97 | static 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 | |||
| 109 | void TimersInit() { | ||
| 110 | timer_callback_handle_table.Clear(); | ||
| 111 | timer_callback_event_type = CoreTiming::RegisterEvent("TimerCallback", TimerCallback); | ||
| 112 | } | ||
| 113 | |||
| 114 | void 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 | ||
| 11 | namespace Kernel { | 11 | namespace Kernel { |
| 12 | 12 | ||
| 13 | class KernelCore; | ||
| 14 | |||
| 13 | class Timer final : public WaitObject { | 15 | class Timer final : public WaitObject { |
| 14 | public: | 16 | public: |
| 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 | ||
| 70 | private: | 74 | private: |
| 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 | ||
| 87 | void TimersInit(); | ||
| 88 | /// Tears down the timer variables | ||
| 89 | void 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 | ||
| 13 | namespace Kernel { | 13 | namespace Kernel { |
| 14 | 14 | ||
| 15 | WaitObject::WaitObject(KernelCore& kernel) : Object{kernel} {} | ||
| 16 | WaitObject::~WaitObject() = default; | ||
| 17 | |||
| 15 | void WaitObject::AddWaitingThread(SharedPtr<Thread> thread) { | 18 | void 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 | ||
| 12 | namespace Kernel { | 12 | namespace Kernel { |
| 13 | 13 | ||
| 14 | class KernelCore; | ||
| 14 | class Thread; | 15 | class 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 |
| 17 | class WaitObject : public Object { | 18 | class WaitObject : public Object { |
| 18 | public: | 19 | public: |
| 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 | ||
| 167 | void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) { | 168 | void 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 | ||
| 338 | void ICommonStateGetter::GetBootMode(Kernel::HLERequestContext& ctx) { | 340 | void 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 | ||
| 128 | private: | 130 | private: |
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 | ||
| 56 | private: | 58 | private: |
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 | ||
| 61 | private: | 63 | private: |
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 | ||
| 11 | namespace Service { | 12 | namespace Service { |
| 12 | namespace NVFlinger { | 13 | namespace NVFlinger { |
| 13 | 14 | ||
| 14 | BufferQueue::BufferQueue(u32 id, u64 layer_id) : id(id), layer_id(layer_id) { | 15 | BufferQueue::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 | ||
| 19 | void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) { | 21 | void 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() { | |||
| 161 | Layer::Layer(u64 id, std::shared_ptr<BufferQueue> queue) : id(id), buffer_queue(std::move(queue)) {} | 161 | Layer::Layer(u64 id, std::shared_ptr<BufferQueue> queue) : id(id), buffer_queue(std::move(queue)) {} |
| 162 | 162 | ||
| 163 | Display::Display(u64 id, std::string name) : id(id), name(std::move(name)) { | 163 | Display::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 | ||
| 108 | void ServiceFrameworkBase::InstallAsNamedPort() { | 108 | void 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 | ||
| 117 | Kernel::SharedPtr<Kernel::ClientPort> ServiceFrameworkBase::CreatePort() { | 120 | Kernel::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 { | |||
| 13 | TestEnvironment::TestEnvironment(bool mutable_memory_) | 13 | TestEnvironment::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 | ||
| 14 | namespace Memory { | 15 | namespace 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 | ||
| 79 | WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address) : mutex_address(mutex_address) { | 79 | WaitTreeMutexInfo::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 | ||
| 85 | QString WaitTreeMutexInfo::GetText() const { | 87 | QString WaitTreeMutexInfo::GetText() const { |