diff --git a/README.md b/README.md index 6b0ce81e0..7fd7c6679 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 1658. +This is the source code for early-access 1659. ## Legal Notice diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h index 17d1ee86b..4ace2cd33 100755 --- a/src/common/common_funcs.h +++ b/src/common/common_funcs.h @@ -108,14 +108,6 @@ __declspec(dllimport) void __stdcall DebugBreak(void); } \ } -#define YUZU_NON_COPYABLE(cls) \ - cls(const cls&) = delete; \ - cls& operator=(const cls&) = delete - -#define YUZU_NON_MOVEABLE(cls) \ - cls(cls&&) = delete; \ - cls& operator=(cls&&) = delete - #define R_SUCCEEDED(res) (res.IsSuccess()) /// Evaluates an expression that returns a result, and returns the result if it would fail. @@ -136,19 +128,4 @@ namespace Common { return u32(a) | u32(b) << 8 | u32(c) << 16 | u32(d) << 24; } -// std::size() does not support zero-size C arrays. We're fixing that. -template -constexpr auto Size(const C& c) -> decltype(c.size()) { - return std::size(c); -} - -template -constexpr std::size_t Size(const C& c) { - if constexpr (sizeof(C) == 0) { - return 0; - } else { - return std::size(c); - } -} - } // namespace Common diff --git a/src/common/intrusive_red_black_tree.h b/src/common/intrusive_red_black_tree.h index 1f696fe80..c0bbcd457 100755 --- a/src/common/intrusive_red_black_tree.h +++ b/src/common/intrusive_red_black_tree.h @@ -509,6 +509,7 @@ private: private: static constexpr TypedStorage DerivedStorage = {}; + static_assert(GetParent(GetNode(GetPointer(DerivedStorage))) == GetPointer(DerivedStorage)); }; template > diff --git a/src/common/parent_of_member.h b/src/common/parent_of_member.h index e0f8ab5c8..d9a14529d 100755 --- a/src/common/parent_of_member.h +++ b/src/common/parent_of_member.h @@ -133,27 +133,27 @@ template using GetMemberType = typename GetMemberPointerTraits::Member; template > -constexpr std::ptrdiff_t OffsetOf() { +static inline std::ptrdiff_t OffsetOf = [] { using DeducedParentType = GetParentType; using MemberType = GetMemberType; static_assert(std::is_base_of::value || std::is_same::value); return OffsetOfCalculator::OffsetOf(MemberPtr); -}; +}(); } // namespace impl template > constexpr RealParentType& GetParentReference(impl::GetMemberType* member) { - std::ptrdiff_t Offset = impl::OffsetOf(); + std::ptrdiff_t Offset = impl::OffsetOf; return *static_cast( static_cast(static_cast(static_cast(member)) - Offset)); } template > constexpr RealParentType const& GetParentReference(impl::GetMemberType const* member) { - std::ptrdiff_t Offset = impl::OffsetOf(); + std::ptrdiff_t Offset = impl::OffsetOf; return *static_cast(static_cast( static_cast(static_cast(member)) - Offset)); } diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 83da30418..c28abc24c 100755 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -144,40 +144,31 @@ add_library(core STATIC hle/kernel/board/nintendo/nx/k_system_control.cpp hle/kernel/board/nintendo/nx/k_system_control.h hle/kernel/board/nintendo/nx/secure_monitor.h + hle/kernel/client_port.cpp + hle/kernel/client_port.h + hle/kernel/client_session.cpp + hle/kernel/client_session.h hle/kernel/code_set.cpp hle/kernel/code_set.h hle/kernel/svc_results.h hle/kernel/global_scheduler_context.cpp hle/kernel/global_scheduler_context.h + hle/kernel/handle_table.cpp + hle/kernel/handle_table.h hle/kernel/hle_ipc.cpp hle/kernel/hle_ipc.h - hle/kernel/init/init_slab_setup.cpp - hle/kernel/init/init_slab_setup.h hle/kernel/k_address_arbiter.cpp hle/kernel/k_address_arbiter.h hle/kernel/k_address_space_info.cpp hle/kernel/k_address_space_info.h - hle/kernel/k_auto_object.cpp - hle/kernel/k_auto_object.h - hle/kernel/k_auto_object_container.cpp - hle/kernel/k_auto_object_container.h hle/kernel/k_affinity_mask.h - hle/kernel/k_class_token.cpp - hle/kernel/k_class_token.h - hle/kernel/k_client_port.cpp - hle/kernel/k_client_port.h - hle/kernel/k_client_session.cpp - hle/kernel/k_client_session.h hle/kernel/k_condition_variable.cpp hle/kernel/k_condition_variable.h hle/kernel/k_event.cpp hle/kernel/k_event.h - hle/kernel/k_handle_table.cpp - hle/kernel/k_handle_table.h hle/kernel/k_light_condition_variable.h hle/kernel/k_light_lock.cpp hle/kernel/k_light_lock.h - hle/kernel/k_linked_list.h hle/kernel/k_memory_block.h hle/kernel/k_memory_block_manager.cpp hle/kernel/k_memory_block_manager.h @@ -194,11 +185,7 @@ add_library(core STATIC hle/kernel/k_page_linked_list.h hle/kernel/k_page_table.cpp hle/kernel/k_page_table.h - hle/kernel/k_port.cpp - hle/kernel/k_port.h hle/kernel/k_priority_queue.h - hle/kernel/k_process.cpp - hle/kernel/k_process.h hle/kernel/k_readable_event.cpp hle/kernel/k_readable_event.h hle/kernel/k_resource_limit.cpp @@ -209,12 +196,6 @@ add_library(core STATIC hle/kernel/k_scoped_lock.h hle/kernel/k_scoped_resource_reservation.h hle/kernel/k_scoped_scheduler_lock_and_sleep.h - hle/kernel/k_server_port.cpp - hle/kernel/k_server_port.h - hle/kernel/k_server_session.cpp - hle/kernel/k_server_session.h - hle/kernel/k_session.cpp - hle/kernel/k_session.h hle/kernel/k_shared_memory.cpp hle/kernel/k_shared_memory.h hle/kernel/k_slab_heap.h @@ -227,21 +208,28 @@ add_library(core STATIC hle/kernel/k_thread.h hle/kernel/k_thread_queue.h hle/kernel/k_trace.h - hle/kernel/k_transfer_memory.cpp - hle/kernel/k_transfer_memory.h hle/kernel/k_writable_event.cpp hle/kernel/k_writable_event.h hle/kernel/kernel.cpp hle/kernel/kernel.h hle/kernel/memory_types.h + hle/kernel/object.cpp + hle/kernel/object.h hle/kernel/physical_core.cpp hle/kernel/physical_core.h hle/kernel/physical_memory.h + hle/kernel/process.cpp + hle/kernel/process.h hle/kernel/process_capability.cpp hle/kernel/process_capability.h + hle/kernel/server_port.cpp + hle/kernel/server_port.h + hle/kernel/server_session.cpp + hle/kernel/server_session.h hle/kernel/service_thread.cpp hle/kernel/service_thread.h - hle/kernel/slab_helpers.h + hle/kernel/session.cpp + hle/kernel/session.h hle/kernel/svc.cpp hle/kernel/svc.h hle/kernel/svc_common.h @@ -249,6 +237,8 @@ add_library(core STATIC hle/kernel/svc_wrap.h hle/kernel/time_manager.cpp hle/kernel/time_manager.h + hle/kernel/transfer_memory.cpp + hle/kernel/transfer_memory.h hle/lock.cpp hle/lock.h hle/result.h diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp index 653bb7a77..4ff72abd8 100755 --- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp +++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp @@ -16,8 +16,8 @@ #include "core/core.h" #include "core/core_timing.h" #include "core/hardware_properties.h" -#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_scheduler.h" +#include "core/hle/kernel/process.h" #include "core/hle/kernel/svc.h" #include "core/memory.h" diff --git a/src/core/core.cpp b/src/core/core.cpp index 434bf3262..d459d6c34 100755 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -27,12 +27,12 @@ #include "core/file_sys/vfs_concat.h" #include "core/file_sys/vfs_real.h" #include "core/hardware_interrupt_manager.h" -#include "core/hle/kernel/k_client_port.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/client_port.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/physical_core.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/am/applets/applets.h" #include "core/hle/service/apm/controller.h" #include "core/hle/service/filesystem/filesystem.h" @@ -166,9 +166,9 @@ struct System::Impl { cpu_manager.SetAsyncGpu(is_async_gpu); core_timing.SetMulticore(is_multicore); + core_timing.Initialize([&system]() { system.RegisterHostThread(); }); kernel.Initialize(); cpu_manager.Initialize(); - core_timing.Initialize([&system]() { system.RegisterHostThread(); }); const auto current_time = std::chrono::duration_cast( std::chrono::system_clock::now().time_since_epoch()); @@ -233,11 +233,8 @@ struct System::Impl { } telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider); - auto main_process = Kernel::KProcess::Create(system.Kernel()); - ASSERT(Kernel::KProcess::Initialize(main_process, system, "main", - Kernel::KProcess::ProcessType::Userland) - .IsSuccess()); - main_process->Open(); + auto main_process = + Kernel::Process::Create(system, "main", Kernel::Process::ProcessType::Userland); const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); if (load_result != Loader::ResultStatus::Success) { LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); @@ -247,7 +244,7 @@ struct System::Impl { static_cast(load_result)); } AddGlueRegistrationForProcess(*app_loader, *main_process); - kernel.MakeCurrentProcess(main_process); + kernel.MakeCurrentProcess(main_process.get()); kernel.InitializeCores(); // Initialize cheat engine @@ -314,7 +311,6 @@ struct System::Impl { gpu_core.reset(); perf_stats.reset(); kernel.Shutdown(); - memory.Reset(); applet_manager.ClearAll(); LOG_DEBUG(Core, "Shutdown OK"); @@ -326,7 +322,7 @@ struct System::Impl { return app_loader->ReadTitle(out); } - void AddGlueRegistrationForProcess(Loader::AppLoader& loader, Kernel::KProcess& process) { + void AddGlueRegistrationForProcess(Loader::AppLoader& loader, Kernel::Process& process) { std::vector nacp_data; FileSys::NACP nacp; if (loader.ReadControlData(nacp) == Loader::ResultStatus::Success) { @@ -517,7 +513,7 @@ const Kernel::GlobalSchedulerContext& System::GlobalSchedulerContext() const { return impl->kernel.GlobalSchedulerContext(); } -Kernel::KProcess* System::CurrentProcess() { +Kernel::Process* System::CurrentProcess() { return impl->kernel.CurrentProcess(); } @@ -529,7 +525,7 @@ const Core::DeviceMemory& System::DeviceMemory() const { return *impl->device_memory; } -const Kernel::KProcess* System::CurrentProcess() const { +const Kernel::Process* System::CurrentProcess() const { return impl->kernel.CurrentProcess(); } diff --git a/src/core/core.h b/src/core/core.h index 8b93ba998..f1068d23f 100755 --- a/src/core/core.h +++ b/src/core/core.h @@ -12,6 +12,7 @@ #include "common/common_types.h" #include "core/file_sys/vfs_types.h" +#include "core/hle/kernel/object.h" namespace Core::Frontend { class EmuWindow; @@ -28,7 +29,7 @@ namespace Kernel { class GlobalSchedulerContext; class KernelCore; class PhysicalCore; -class KProcess; +class Process; class KScheduler; } // namespace Kernel @@ -263,10 +264,10 @@ public: [[nodiscard]] const Core::DeviceMemory& DeviceMemory() const; /// Provides a pointer to the current process - [[nodiscard]] Kernel::KProcess* CurrentProcess(); + [[nodiscard]] Kernel::Process* CurrentProcess(); /// Provides a constant pointer to the current process. - [[nodiscard]] const Kernel::KProcess* CurrentProcess() const; + [[nodiscard]] const Kernel::Process* CurrentProcess() const; /// Provides a reference to the core timing instance. [[nodiscard]] Timing::CoreTiming& CoreTiming(); diff --git a/src/core/file_sys/romfs_factory.cpp b/src/core/file_sys/romfs_factory.cpp index aa7f3072f..de6ab721d 100755 --- a/src/core/file_sys/romfs_factory.cpp +++ b/src/core/file_sys/romfs_factory.cpp @@ -13,7 +13,7 @@ #include "core/file_sys/patch_manager.h" #include "core/file_sys/registered_cache.h" #include "core/file_sys/romfs_factory.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/loader/loader.h" diff --git a/src/core/file_sys/savedata_factory.cpp b/src/core/file_sys/savedata_factory.cpp index f973d1d21..fa68af3a8 100755 --- a/src/core/file_sys/savedata_factory.cpp +++ b/src/core/file_sys/savedata_factory.cpp @@ -9,7 +9,7 @@ #include "core/core.h" #include "core/file_sys/savedata_factory.h" #include "core/file_sys/vfs.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" namespace FileSys { diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h index 0906b8cfb..56cc911d1 100755 --- a/src/core/hle/ipc_helpers.h +++ b/src/core/hle/ipc_helpers.h @@ -13,9 +13,12 @@ #include "common/assert.h" #include "common/common_types.h" #include "core/hle/ipc.h" +#include "core/hle/kernel/client_port.h" +#include "core/hle/kernel/client_session.h" #include "core/hle/kernel/hle_ipc.h" -#include "core/hle/kernel/k_client_port.h" -#include "core/hle/kernel/k_session.h" +#include "core/hle/kernel/object.h" +#include "core/hle/kernel/server_session.h" +#include "core/hle/kernel/session.h" #include "core/hle/result.h" namespace IPC { @@ -134,11 +137,9 @@ public: if (context->Session()->IsDomain()) { context->AddDomainObject(std::move(iface)); } else { - auto* session = Kernel::KSession::Create(kernel); - session->Initialize(nullptr, iface->GetServiceName()); - - context->AddMoveObject(&session->GetClientSession()); - iface->ClientConnected(&session->GetServerSession()); + auto [client, server] = Kernel::Session::Create(kernel, iface->GetServiceName()); + context->AddMoveObject(std::move(client)); + iface->ClientConnected(std::move(server)); } } @@ -214,16 +215,10 @@ public: void PushRaw(const T& value); template - void PushMoveObjects(O*... pointers); + void PushMoveObjects(std::shared_ptr... pointers); template - void PushMoveObjects(O&... pointers); - - template - void PushCopyObjects(O*... pointers); - - template - void PushCopyObjects(O&... pointers); + void PushCopyObjects(std::shared_ptr... pointers); private: u32 normal_params_size{}; @@ -306,34 +301,18 @@ void ResponseBuilder::Push(const First& first_value, const Other&... other_value } template -inline void ResponseBuilder::PushCopyObjects(O*... pointers) { +inline void ResponseBuilder::PushCopyObjects(std::shared_ptr... pointers) { auto objects = {pointers...}; for (auto& object : objects) { - context->AddCopyObject(object); + context->AddCopyObject(std::move(object)); } } template -inline void ResponseBuilder::PushCopyObjects(O&... pointers) { - auto objects = {&pointers...}; - for (auto& object : objects) { - context->AddCopyObject(object); - } -} - -template -inline void ResponseBuilder::PushMoveObjects(O*... pointers) { +inline void ResponseBuilder::PushMoveObjects(std::shared_ptr... pointers) { auto objects = {pointers...}; for (auto& object : objects) { - context->AddMoveObject(object); - } -} - -template -inline void ResponseBuilder::PushMoveObjects(O&... pointers) { - auto objects = {&pointers...}; - for (auto& object : objects) { - context->AddMoveObject(object); + context->AddMoveObject(std::move(object)); } } @@ -380,6 +359,12 @@ public: template T PopRaw(); + template + std::shared_ptr GetMoveObject(std::size_t index); + + template + std::shared_ptr GetCopyObject(std::size_t index); + template std::shared_ptr PopIpcInterface() { ASSERT(context->Session()->IsDomain()); @@ -484,4 +469,14 @@ void RequestParser::Pop(First& first_value, Other&... other_values) { Pop(other_values...); } +template +std::shared_ptr RequestParser::GetMoveObject(std::size_t index) { + return context->GetMoveObject(index); +} + +template +std::shared_ptr RequestParser::GetCopyObject(std::size_t index) { + return context->GetCopyObject(index); +} + } // namespace IPC diff --git a/src/core/hle/kernel/global_scheduler_context.cpp b/src/core/hle/kernel/global_scheduler_context.cpp index 7c87cbada..c6838649f 100755 --- a/src/core/hle/kernel/global_scheduler_context.cpp +++ b/src/core/hle/kernel/global_scheduler_context.cpp @@ -17,12 +17,12 @@ GlobalSchedulerContext::GlobalSchedulerContext(KernelCore& kernel) GlobalSchedulerContext::~GlobalSchedulerContext() = default; -void GlobalSchedulerContext::AddThread(KThread* thread) { +void GlobalSchedulerContext::AddThread(std::shared_ptr thread) { std::scoped_lock lock{global_list_guard}; - thread_list.push_back(thread); + thread_list.push_back(std::move(thread)); } -void GlobalSchedulerContext::RemoveThread(KThread* thread) { +void GlobalSchedulerContext::RemoveThread(std::shared_ptr thread) { std::scoped_lock lock{global_list_guard}; thread_list.erase(std::remove(thread_list.begin(), thread_list.end(), thread), thread_list.end()); diff --git a/src/core/hle/kernel/global_scheduler_context.h b/src/core/hle/kernel/global_scheduler_context.h index ba8b67fd1..11592843e 100755 --- a/src/core/hle/kernel/global_scheduler_context.h +++ b/src/core/hle/kernel/global_scheduler_context.h @@ -38,13 +38,13 @@ public: ~GlobalSchedulerContext(); /// Adds a new thread to the scheduler - void AddThread(KThread* thread); + void AddThread(std::shared_ptr thread); /// Removes a thread from the scheduler - void RemoveThread(KThread* thread); + void RemoveThread(std::shared_ptr thread); /// Returns a list of all threads managed by the scheduler - [[nodiscard]] const std::vector& GetThreadList() const { + [[nodiscard]] const std::vector>& GetThreadList() const { return thread_list; } @@ -79,7 +79,7 @@ private: LockType scheduler_lock; /// Lists all thread ids that aren't deleted/etc. - std::vector thread_list; + std::vector> thread_list; Common::SpinLock global_list_guard{}; }; diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index b505d20a6..2b363b1d9 100755 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -14,16 +14,17 @@ #include "common/common_types.h" #include "common/logging/log.h" #include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/hle_ipc.h" -#include "core/hle/kernel/k_handle_table.h" -#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" -#include "core/hle/kernel/k_server_session.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_writable_event.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/object.h" +#include "core/hle/kernel/process.h" +#include "core/hle/kernel/server_session.h" #include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/time_manager.h" #include "core/memory.h" @@ -34,23 +35,28 @@ SessionRequestHandler::SessionRequestHandler() = default; SessionRequestHandler::~SessionRequestHandler() = default; -void SessionRequestHandler::ClientConnected(KServerSession* session) { - session->SetHleHandler(shared_from_this()); +void SessionRequestHandler::ClientConnected(std::shared_ptr server_session) { + server_session->SetHleHandler(shared_from_this()); + connected_sessions.push_back(std::move(server_session)); } -void SessionRequestHandler::ClientDisconnected(KServerSession* session) { - session->SetHleHandler(nullptr); +void SessionRequestHandler::ClientDisconnected( + const std::shared_ptr& server_session) { + server_session->SetHleHandler(nullptr); + boost::range::remove_erase(connected_sessions, server_session); } -HLERequestContext::HLERequestContext(KernelCore& kernel_, Core::Memory::Memory& memory_, - KServerSession* server_session_, KThread* thread_) - : server_session(server_session_), thread(thread_), kernel{kernel_}, memory{memory_} { +HLERequestContext::HLERequestContext(KernelCore& kernel, Core::Memory::Memory& memory, + std::shared_ptr server_session, + std::shared_ptr thread) + : server_session(std::move(server_session)), + thread(std::move(thread)), kernel{kernel}, memory{memory} { cmd_buf[0] = 0; } HLERequestContext::~HLERequestContext() = default; -void HLERequestContext::ParseCommandBuffer(const KHandleTable& handle_table, u32_le* src_cmdbuf, +void HLERequestContext::ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf, bool incoming) { IPC::RequestParser rp(src_cmdbuf); command_header = rp.PopRaw(); @@ -71,12 +77,12 @@ void HLERequestContext::ParseCommandBuffer(const KHandleTable& handle_table, u32 for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_copy; ++handle) { const u32 copy_handle{rp.Pop()}; copy_handles.push_back(copy_handle); - copy_objects.push_back(handle_table.GetObject(copy_handle).GetPointerUnsafe()); + copy_objects.push_back(handle_table.GetGeneric(copy_handle)); } for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_move; ++handle) { const u32 move_handle{rp.Pop()}; move_handles.push_back(move_handle); - move_objects.push_back(handle_table.GetObject(move_handle).GetPointerUnsafe()); + move_objects.push_back(handle_table.GetGeneric(move_handle)); } } else { // For responses we just ignore the handles, they're empty and will be populated when @@ -163,7 +169,7 @@ void HLERequestContext::ParseCommandBuffer(const KHandleTable& handle_table, u32 rp.Skip(1, false); // The command is actually an u64, but we don't use the high part. } -ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const KHandleTable& handle_table, +ResultCode HLERequestContext::PopulateFromIncomingCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf) { ParseCommandBuffer(handle_table, src_cmdbuf, true); if (command_header->type == IPC::CommandType::Close) { @@ -217,12 +223,12 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(KThread& thread) { // for specific values in each of these descriptors. for (auto& object : copy_objects) { ASSERT(object != nullptr); - R_TRY(handle_table.Add(&dst_cmdbuf[current_offset++], object)); + dst_cmdbuf[current_offset++] = handle_table.Create(object).Unwrap(); } for (auto& object : move_objects) { ASSERT(object != nullptr); - R_TRY(handle_table.Add(&dst_cmdbuf[current_offset++], object)); + dst_cmdbuf[current_offset++] = handle_table.Create(object).Unwrap(); } } diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index fa031c121..6fba42615 100755 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -16,8 +16,7 @@ #include "common/concepts.h" #include "common/swap.h" #include "core/hle/ipc.h" -#include "core/hle/kernel/k_auto_object.h" -#include "core/hle/kernel/svc_common.h" +#include "core/hle/kernel/object.h" union ResultCode; @@ -36,14 +35,13 @@ class ServiceFrameworkBase; namespace Kernel { class Domain; +class HandleTable; class HLERequestContext; class KernelCore; -class KHandleTable; -class KProcess; -class KServerSession; +class Process; +class ServerSession; class KThread; class KReadableEvent; -class KSession; class KWritableEvent; enum class ThreadWakeupReason; @@ -73,14 +71,20 @@ public: * associated ServerSession alive for the duration of the connection. * @param server_session Owning pointer to the ServerSession associated with the connection. */ - void ClientConnected(KServerSession* session); + void ClientConnected(std::shared_ptr server_session); /** * Signals that a client has just disconnected from this HLE handler and releases the * associated ServerSession. * @param server_session ServerSession associated with the connection. */ - void ClientDisconnected(KServerSession* session); + void ClientDisconnected(const std::shared_ptr& server_session); + +protected: + /// List of sessions that are connected to this handler. + /// A ServerSession whose server endpoint is an HLE implementation is kept alive by this list + /// for the duration of the connection. + std::vector> connected_sessions; }; /** @@ -105,7 +109,8 @@ public: class HLERequestContext { public: explicit HLERequestContext(KernelCore& kernel, Core::Memory::Memory& memory, - KServerSession* session, KThread* thread); + std::shared_ptr session, + std::shared_ptr thread); ~HLERequestContext(); /// Returns a pointer to the IPC command buffer for this request. @@ -117,12 +122,12 @@ public: * Returns the session through which this request was made. This can be used as a map key to * access per-client data on services. */ - Kernel::KServerSession* Session() { + const std::shared_ptr& Session() const { return server_session; } /// Populates this context with data from the requesting process/thread. - ResultCode PopulateFromIncomingCommandBuffer(const KHandleTable& handle_table, + ResultCode PopulateFromIncomingCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf); /// Writes data from this context back to the requesting process/thread. @@ -213,12 +218,22 @@ public: return move_handles.at(index); } - void AddMoveObject(KAutoObject* object) { - move_objects.emplace_back(object); + template + std::shared_ptr GetCopyObject(std::size_t index) { + return DynamicObjectCast(copy_objects.at(index)); } - void AddCopyObject(KAutoObject* object) { - copy_objects.emplace_back(object); + template + std::shared_ptr GetMoveObject(std::size_t index) { + return DynamicObjectCast(move_objects.at(index)); + } + + void AddMoveObject(std::shared_ptr object) { + move_objects.emplace_back(std::move(object)); + } + + void AddCopyObject(std::shared_ptr object) { + copy_objects.emplace_back(std::move(object)); } void AddDomainObject(std::shared_ptr object) { @@ -261,6 +276,10 @@ public: return *thread; } + const KThread& GetThread() const { + return *thread; + } + bool IsThreadWaiting() const { return is_thread_waiting; } @@ -268,17 +287,16 @@ public: private: friend class IPC::ResponseBuilder; - void ParseCommandBuffer(const KHandleTable& handle_table, u32_le* src_cmdbuf, bool incoming); + void ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf, bool incoming); std::array cmd_buf; - Kernel::KServerSession* server_session{}; - KThread* thread; - + std::shared_ptr server_session; + std::shared_ptr thread; // TODO(yuriks): Check common usage of this and optimize size accordingly boost::container::small_vector move_handles; boost::container::small_vector copy_handles; - boost::container::small_vector move_objects; - boost::container::small_vector copy_objects; + boost::container::small_vector, 8> move_objects; + boost::container::small_vector, 8> copy_objects; boost::container::small_vector, 8> domain_objects; std::optional command_header; diff --git a/src/core/hle/kernel/k_condition_variable.cpp b/src/core/hle/kernel/k_condition_variable.cpp index f51cf3e7b..170d8fa0d 100755 --- a/src/core/hle/kernel/k_condition_variable.cpp +++ b/src/core/hle/kernel/k_condition_variable.cpp @@ -7,13 +7,12 @@ #include "core/arm/exclusive_monitor.h" #include "core/core.h" #include "core/hle/kernel/k_condition_variable.h" -#include "core/hle/kernel/k_linked_list.h" -#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" #include "core/hle/kernel/k_synchronization_object.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/process.h" #include "core/hle/kernel/svc_common.h" #include "core/hle/kernel/svc_results.h" #include "core/memory.h" @@ -108,8 +107,8 @@ ResultCode KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 val // Wait for the address. { - KScopedAutoObject owner_thread; - ASSERT(owner_thread.IsNull()); + std::shared_ptr owner_thread; + ASSERT(!owner_thread); { KScopedSchedulerLock sl(kernel); cur_thread->SetSyncedObject(nullptr, RESULT_SUCCESS); @@ -127,10 +126,8 @@ ResultCode KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 val R_UNLESS(test_tag == (handle | Svc::HandleWaitMask), RESULT_SUCCESS); // Get the lock owner thread. - owner_thread = - kernel.CurrentProcess()->GetHandleTable().GetObjectWithoutPseudoHandle( - handle); - R_UNLESS(owner_thread.IsNotNull(), ResultInvalidHandle); + owner_thread = kernel.CurrentProcess()->GetHandleTable().Get(handle); + R_UNLESS(owner_thread, ResultInvalidHandle); // Update the lock. cur_thread->SetAddressKey(addr, value); @@ -140,7 +137,7 @@ ResultCode KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 val cur_thread->SetMutexWaitAddressForDebugging(addr); } } - ASSERT(owner_thread.IsNotNull()); + ASSERT(owner_thread); } // Remove the thread as a waiter from the lock owner. @@ -179,22 +176,19 @@ KThread* KConditionVariable::SignalImpl(KThread* thread) { KThread* thread_to_close = nullptr; if (can_access) { - if (prev_tag == Svc::InvalidHandle) { + if (prev_tag == InvalidHandle) { // If nobody held the lock previously, we're all good. thread->SetSyncedObject(nullptr, RESULT_SUCCESS); thread->Wakeup(); } else { // Get the previous owner. - KThread* owner_thread = kernel.CurrentProcess() - ->GetHandleTable() - .GetObjectWithoutPseudoHandle( - static_cast(prev_tag & ~Svc::HandleWaitMask)) - .ReleasePointerUnsafe(); + auto owner_thread = kernel.CurrentProcess()->GetHandleTable().Get( + prev_tag & ~Svc::HandleWaitMask); if (owner_thread) { // Add the thread as a waiter on the owner. owner_thread->AddWaiter(thread); - thread_to_close = owner_thread; + thread_to_close = owner_thread.get(); } else { // The lock was tagged with a thread that doesn't exist. thread->SetSyncedObject(nullptr, ResultInvalidState); @@ -214,7 +208,9 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) { // Prepare for signaling. constexpr int MaxThreads = 16; - KLinkedList thread_list{kernel}; + // TODO(bunnei): This should just be Thread once we implement KAutoObject instead of using + // std::shared_ptr. + std::vector> thread_list; std::array thread_array; s32 num_to_close{}; @@ -232,7 +228,7 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) { if (num_to_close < MaxThreads) { thread_array[num_to_close++] = thread; } else { - thread_list.push_back(*thread); + thread_list.push_back(SharedFrom(thread)); } } @@ -254,9 +250,8 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) { } // Close threads in the list. - for (auto it = thread_list.begin(); it != thread_list.end(); - it = thread_list.erase(kernel, it)) { - (*it).Close(); + for (auto it = thread_list.begin(); it != thread_list.end(); it = thread_list.erase(it)) { + (*it)->Close(); } } diff --git a/src/core/hle/kernel/k_event.cpp b/src/core/hle/kernel/k_event.cpp index 986355b78..bb2fa4ad5 100755 --- a/src/core/hle/kernel/k_event.cpp +++ b/src/core/hle/kernel/k_event.cpp @@ -3,53 +3,30 @@ // Refer to the license.txt file included. #include "core/hle/kernel/k_event.h" -#include "core/hle/kernel/k_process.h" -#include "core/hle/kernel/k_resource_limit.h" +#include "core/hle/kernel/k_readable_event.h" +#include "core/hle/kernel/k_writable_event.h" namespace Kernel { -KEvent::KEvent(KernelCore& kernel) - : KAutoObjectWithSlabHeapAndContainer{kernel}, readable_event{kernel}, writable_event{kernel} {} +KEvent::KEvent(KernelCore& kernel, std::string&& name) : Object{kernel, std::move(name)} {} KEvent::~KEvent() = default; -void KEvent::Initialize(std::string&& name_) { - // Increment reference count. - // Because reference count is one on creation, this will result - // in a reference count of two. Thus, when both readable and - // writable events are closed this object will be destroyed. - Open(); +std::shared_ptr KEvent::Create(KernelCore& kernel, std::string&& name) { + return std::make_shared(kernel, std::move(name)); +} +void KEvent::Initialize() { // Create our sub events. - KAutoObject::Create(std::addressof(readable_event)); - KAutoObject::Create(std::addressof(writable_event)); + readable_event = std::make_shared(kernel, GetName() + ":Readable"); + writable_event = std::make_shared(kernel, GetName() + ":Writable"); // Initialize our sub sessions. - readable_event.Initialize(this, name_ + ":Readable"); - writable_event.Initialize(this, name_ + ":Writable"); - - // Set our owner process. - owner = kernel.CurrentProcess(); - if (owner) { - owner->Open(); - } + readable_event->Initialize(this); + writable_event->Initialize(this); // Mark initialized. - name = std::move(name_); initialized = true; } -void KEvent::Finalize() { - KAutoObjectWithSlabHeapAndContainer::Finalize(); -} - -void KEvent::PostDestroy(uintptr_t arg) { - // Release the event count resource the owner process holds. - KProcess* owner = reinterpret_cast(arg); - if (owner) { - owner->GetResourceLimit()->Release(LimitableResource::Events, 1); - owner->Close(); - } -} - } // namespace Kernel diff --git a/src/core/hle/kernel/k_event.h b/src/core/hle/kernel/k_event.h index 4ca869930..2fb887129 100755 --- a/src/core/hle/kernel/k_event.h +++ b/src/core/hle/kernel/k_event.h @@ -4,54 +4,53 @@ #pragma once -#include "core/hle/kernel/k_readable_event.h" -#include "core/hle/kernel/k_writable_event.h" -#include "core/hle/kernel/slab_helpers.h" +#include "core/hle/kernel/object.h" namespace Kernel { class KernelCore; class KReadableEvent; class KWritableEvent; -class KProcess; - -class KEvent final : public KAutoObjectWithSlabHeapAndContainer { - KERNEL_AUTOOBJECT_TRAITS(KEvent, KAutoObject); +class KEvent final : public Object { public: - explicit KEvent(KernelCore& kernel); - virtual ~KEvent(); + explicit KEvent(KernelCore& kernel, std::string&& name); + ~KEvent() override; - void Initialize(std::string&& name); + static std::shared_ptr Create(KernelCore& kernel, std::string&& name); - virtual void Finalize() override; + void Initialize(); - virtual bool IsInitialized() const override { - return initialized; + void Finalize() override {} + + std::string GetTypeName() const override { + return "KEvent"; } - virtual uintptr_t GetPostDestroyArgument() const override { - return reinterpret_cast(owner); + static constexpr HandleType HANDLE_TYPE = HandleType::Event; + HandleType GetHandleType() const override { + return HANDLE_TYPE; } - static void PostDestroy(uintptr_t arg); - - virtual KProcess* GetOwner() const override { - return owner; - } - - KReadableEvent& GetReadableEvent() { + std::shared_ptr& GetReadableEvent() { return readable_event; } - KWritableEvent& GetWritableEvent() { + std::shared_ptr& GetWritableEvent() { + return writable_event; + } + + const std::shared_ptr& GetReadableEvent() const { + return readable_event; + } + + const std::shared_ptr& GetWritableEvent() const { return writable_event; } private: - KReadableEvent readable_event; - KWritableEvent writable_event; - KProcess* owner{}; + std::shared_ptr readable_event; + std::shared_ptr writable_event; bool initialized{}; }; diff --git a/src/core/hle/kernel/k_memory_block.h b/src/core/hle/kernel/k_memory_block.h index a7fdb5fb8..c5b9c5e85 100755 --- a/src/core/hle/kernel/k_memory_block.h +++ b/src/core/hle/kernel/k_memory_block.h @@ -134,10 +134,6 @@ enum class KMemoryPermission : u8 { }; DECLARE_ENUM_FLAG_OPERATORS(KMemoryPermission); -constexpr KMemoryPermission ConvertToKMemoryPermission(Svc::MemoryPermission perm) { - return static_cast(perm); -} - enum class KMemoryAttribute : u8 { None = 0x00, Mask = 0x7F, diff --git a/src/core/hle/kernel/k_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp index d4ce98ee3..d09d5ce48 100755 --- a/src/core/hle/kernel/k_page_table.cpp +++ b/src/core/hle/kernel/k_page_table.cpp @@ -11,11 +11,11 @@ #include "core/hle/kernel/k_memory_block_manager.h" #include "core/hle/kernel/k_page_linked_list.h" #include "core/hle/kernel/k_page_table.h" -#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_scoped_resource_reservation.h" #include "core/hle/kernel/k_system_control.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/process.h" #include "core/hle/kernel/svc_results.h" #include "core/memory.h" @@ -420,7 +420,7 @@ ResultCode KPageTable::MapPhysicalMemory(VAddr addr, std::size_t size) { remaining_size); if (!memory_reservation.Succeeded()) { LOG_ERROR(Kernel, "Could not reserve remaining {:X} bytes", remaining_size); - return ResultLimitReached; + return ResultResourceLimitedExceeded; } KPageLinkedList page_linked_list; @@ -578,7 +578,7 @@ ResultCode KPageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) { AddRegionToPages(dst_addr, num_pages, dst_pages); if (!dst_pages.IsEqual(src_pages)) { - return ResultInvalidMemoryRegion; + return ResultInvalidMemoryRange; } { @@ -641,45 +641,6 @@ ResultCode KPageTable::MapPages(VAddr addr, KPageLinkedList& page_linked_list, K return RESULT_SUCCESS; } -ResultCode KPageTable::UnmapPages(VAddr addr, const KPageLinkedList& page_linked_list) { - VAddr cur_addr{addr}; - - for (const auto& node : page_linked_list.Nodes()) { - const std::size_t num_pages{(addr - cur_addr) / PageSize}; - if (const auto result{ - Operate(addr, num_pages, KMemoryPermission::None, OperationType::Unmap)}; - result.IsError()) { - return result; - } - - cur_addr += node.GetNumPages() * PageSize; - } - - return RESULT_SUCCESS; -} - -ResultCode KPageTable::UnmapPages(VAddr addr, KPageLinkedList& page_linked_list, - KMemoryState state) { - std::lock_guard lock{page_table_lock}; - - const std::size_t num_pages{page_linked_list.GetNumPages()}; - const std::size_t size{num_pages * PageSize}; - - if (!CanContain(addr, size, state)) { - return ResultInvalidCurrentMemory; - } - - if (IsRegionMapped(addr, num_pages * PageSize)) { - return ResultInvalidCurrentMemory; - } - - CASCADE_CODE(UnmapPages(addr, page_linked_list)); - - block_manager->Update(addr, num_pages, state, KMemoryPermission::None); - - return RESULT_SUCCESS; -} - ResultCode KPageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, KMemoryPermission perm) { @@ -829,7 +790,7 @@ ResultVal KPageTable::SetHeapSize(std::size_t size) { if (!memory_reservation.Succeeded()) { LOG_ERROR(Kernel, "Could not reserve heap extension of size {:X} bytes", delta); - return ResultLimitReached; + return ResultResourceLimitedExceeded; } KPageLinkedList page_linked_list; @@ -1106,7 +1067,7 @@ constexpr std::size_t KPageTable::GetRegionSize(KMemoryState state) const { } } -bool KPageTable::CanContain(VAddr addr, std::size_t size, KMemoryState state) const { +constexpr bool KPageTable::CanContain(VAddr addr, std::size_t size, KMemoryState state) const { const VAddr end{addr + size}; const VAddr last{end - 1}; const VAddr region_start{GetRegionAddress(state)}; diff --git a/src/core/hle/kernel/k_page_table.h b/src/core/hle/kernel/k_page_table.h index 8c2cc03eb..49b824379 100755 --- a/src/core/hle/kernel/k_page_table.h +++ b/src/core/hle/kernel/k_page_table.h @@ -40,7 +40,6 @@ public: ResultCode Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size); ResultCode MapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state, KMemoryPermission perm); - ResultCode UnmapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state); ResultCode SetCodeMemoryPermission(VAddr addr, std::size_t size, KMemoryPermission perm); KMemoryInfo QueryInfo(VAddr addr); ResultCode ReserveTransferMemory(VAddr addr, std::size_t size, KMemoryPermission perm); @@ -64,8 +63,6 @@ public: return page_table_impl; } - bool CanContain(VAddr addr, std::size_t size, KMemoryState state) const; - private: enum class OperationType : u32 { Map, @@ -82,7 +79,6 @@ private: ResultCode InitializeMemoryLayout(VAddr start, VAddr end); ResultCode MapPages(VAddr addr, const KPageLinkedList& page_linked_list, KMemoryPermission perm); - ResultCode UnmapPages(VAddr addr, const KPageLinkedList& page_linked_list); void MapPhysicalMemory(KPageLinkedList& page_linked_list, VAddr start, VAddr end); bool IsRegionMapped(VAddr address, u64 size); bool IsRegionContiguous(VAddr addr, u64 size) const; @@ -96,6 +92,7 @@ private: OperationType operation, PAddr map_addr = 0); constexpr VAddr GetRegionAddress(KMemoryState state) const; constexpr std::size_t GetRegionSize(KMemoryState state) const; + constexpr bool CanContain(VAddr addr, std::size_t size, KMemoryState state) const; constexpr ResultCode CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask, KMemoryState state, KMemoryPermission perm_mask, @@ -219,6 +216,8 @@ public: constexpr PAddr GetPhysicalAddr(VAddr addr) { return page_table_impl.backing_addr[addr >> PageBits] + addr; } + +private: constexpr bool Contains(VAddr addr) const { return address_space_start <= addr && addr <= address_space_end - 1; } @@ -226,8 +225,6 @@ public: return address_space_start <= addr && addr < addr + size && addr + size - 1 <= address_space_end - 1; } - -private: constexpr bool IsKernel() const { return is_kernel; } diff --git a/src/core/hle/kernel/k_readable_event.cpp b/src/core/hle/kernel/k_readable_event.cpp index 8fef4bb00..4b4d34857 100755 --- a/src/core/hle/kernel/k_readable_event.cpp +++ b/src/core/hle/kernel/k_readable_event.cpp @@ -2,18 +2,21 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include #include "common/assert.h" -#include "core/hle/kernel/k_event.h" +#include "common/common_funcs.h" +#include "common/logging/log.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/object.h" #include "core/hle/kernel/svc_results.h" namespace Kernel { -KReadableEvent::KReadableEvent(KernelCore& kernel) : KSynchronizationObject{kernel} {} - +KReadableEvent::KReadableEvent(KernelCore& kernel, std::string&& name) + : KSynchronizationObject{kernel, std::move(name)} {} KReadableEvent::~KReadableEvent() = default; bool KReadableEvent::IsSignaled() const { @@ -22,12 +25,6 @@ bool KReadableEvent::IsSignaled() const { return is_signaled; } -void KReadableEvent::Destroy() { - if (parent) { - parent->Close(); - } -} - ResultCode KReadableEvent::Signal() { KScopedSchedulerLock lk{kernel}; diff --git a/src/core/hle/kernel/k_readable_event.h b/src/core/hle/kernel/k_readable_event.h index 1783ef0b8..e6f0fd900 100755 --- a/src/core/hle/kernel/k_readable_event.h +++ b/src/core/hle/kernel/k_readable_event.h @@ -4,9 +4,8 @@ #pragma once -#include "core/hle/kernel/k_auto_object.h" #include "core/hle/kernel/k_synchronization_object.h" -#include "core/hle/kernel/slab_helpers.h" +#include "core/hle/kernel/object.h" #include "core/hle/result.h" namespace Kernel { @@ -14,25 +13,31 @@ namespace Kernel { class KernelCore; class KEvent; -class KReadableEvent : public KSynchronizationObject { - KERNEL_AUTOOBJECT_TRAITS(KReadableEvent, KSynchronizationObject); - +class KReadableEvent final : public KSynchronizationObject { public: - explicit KReadableEvent(KernelCore& kernel); + explicit KReadableEvent(KernelCore& kernel, std::string&& name); ~KReadableEvent() override; - void Initialize(KEvent* parent_, std::string&& name_) { - is_signaled = false; - parent = parent_; - name = std::move(name_); + std::string GetTypeName() const override { + return "KReadableEvent"; + } + + static constexpr HandleType HANDLE_TYPE = HandleType::ReadableEvent; + HandleType GetHandleType() const override { + return HANDLE_TYPE; } KEvent* GetParent() const { return parent; } - virtual bool IsSignaled() const override; - virtual void Destroy() override; + void Initialize(KEvent* parent_) { + is_signaled = false; + parent = parent_; + } + + bool IsSignaled() const override; + void Finalize() override {} ResultCode Signal(); ResultCode Clear(); diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp index ad5095bfd..d05b34ea3 100755 --- a/src/core/hle/kernel/k_resource_limit.cpp +++ b/src/core/hle/kernel/k_resource_limit.cpp @@ -10,16 +10,10 @@ namespace Kernel { constexpr s64 DefaultTimeout = 10000000000; // 10 seconds -KResourceLimit::KResourceLimit(KernelCore& kernel) - : KAutoObjectWithSlabHeapAndContainer{kernel}, lock{kernel}, cond_var{kernel} {} +KResourceLimit::KResourceLimit(KernelCore& kernel, const Core::Timing::CoreTiming& core_timing_) + : Object{kernel}, lock{kernel}, cond_var{kernel}, core_timing(core_timing_) {} KResourceLimit::~KResourceLimit() = default; -void KResourceLimit::Initialize(const Core::Timing::CoreTiming* core_timing_) { - core_timing = core_timing_; -} - -void KResourceLimit::Finalize() {} - s64 KResourceLimit::GetLimitValue(LimitableResource which) const { const auto index = static_cast(which); s64 value{}; @@ -84,7 +78,7 @@ ResultCode KResourceLimit::SetLimitValue(LimitableResource which, s64 value) { } bool KResourceLimit::Reserve(LimitableResource which, s64 value) { - return Reserve(which, value, core_timing->GetGlobalTimeNs().count() + DefaultTimeout); + return Reserve(which, value, core_timing.GetGlobalTimeNs().count() + DefaultTimeout); } bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) { @@ -115,7 +109,7 @@ bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) { } if (current_hints[index] + value <= limit_values[index] && - (timeout < 0 || core_timing->GetGlobalTimeNs().count() < timeout)) { + (timeout < 0 || core_timing.GetGlobalTimeNs().count() < timeout)) { waiter_count++; cond_var.Wait(&lock, timeout); waiter_count--; diff --git a/src/core/hle/kernel/k_resource_limit.h b/src/core/hle/kernel/k_resource_limit.h index 66ebf32df..4542317d0 100755 --- a/src/core/hle/kernel/k_resource_limit.h +++ b/src/core/hle/kernel/k_resource_limit.h @@ -8,6 +8,7 @@ #include "common/common_types.h" #include "core/hle/kernel/k_light_condition_variable.h" #include "core/hle/kernel/k_light_lock.h" +#include "core/hle/kernel/object.h" union ResultCode; @@ -31,16 +32,10 @@ constexpr bool IsValidResourceType(LimitableResource type) { return type < LimitableResource::Count; } -class KResourceLimit final - : public KAutoObjectWithSlabHeapAndContainer { - KERNEL_AUTOOBJECT_TRAITS(KResourceLimit, KAutoObject); - +class KResourceLimit final : public Object { public: - explicit KResourceLimit(KernelCore& kernel); - virtual ~KResourceLimit(); - - void Initialize(const Core::Timing::CoreTiming* core_timing_); - virtual void Finalize() override; + explicit KResourceLimit(KernelCore& kernel, const Core::Timing::CoreTiming& core_timing_); + ~KResourceLimit(); s64 GetLimitValue(LimitableResource which) const; s64 GetCurrentValue(LimitableResource which) const; @@ -54,7 +49,19 @@ public: void Release(LimitableResource which, s64 value); void Release(LimitableResource which, s64 value, s64 hint); - static void PostDestroy([[maybe_unused]] uintptr_t arg) {} + std::string GetTypeName() const override { + return "KResourceLimit"; + } + std::string GetName() const override { + return GetTypeName(); + } + + static constexpr HandleType HANDLE_TYPE = HandleType::ResourceLimit; + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } + + virtual void Finalize() override {} private: using ResourceArray = std::array(LimitableResource::Count)>; @@ -65,6 +72,6 @@ private: mutable KLightLock lock; s32 waiter_count{}; KLightConditionVariable cond_var; - const Core::Timing::CoreTiming* core_timing{}; + const Core::Timing::CoreTiming& core_timing; }; } // namespace Kernel diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index 0115fe6d1..d1df97305 100755 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp @@ -15,12 +15,12 @@ #include "core/core.h" #include "core/core_timing.h" #include "core/cpu_manager.h" -#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/physical_core.h" +#include "core/hle/kernel/process.h" #include "core/hle/kernel/time_manager.h" namespace Kernel { @@ -71,7 +71,7 @@ u64 KScheduler::UpdateHighestPriorityThread(KThread* highest_thread) { } if (state.should_count_idle) { if (highest_thread != nullptr) { - if (KProcess* process = highest_thread->GetOwnerProcess(); process != nullptr) { + if (Process* process = highest_thread->GetOwnerProcess(); process != nullptr) { process->SetRunningThread(core_id, highest_thread, state.idle_count); } } else { @@ -104,7 +104,7 @@ u64 KScheduler::UpdateHighestPriorityThreadsImpl(KernelCore& kernel) { if (top_thread != nullptr) { // If the thread has no waiters, we need to check if the process has a thread pinned. if (top_thread->GetNumKernelWaiters() == 0) { - if (KProcess* parent = top_thread->GetOwnerProcess(); parent != nullptr) { + if (Process* parent = top_thread->GetOwnerProcess(); parent != nullptr) { if (KThread* pinned = parent->GetPinnedThread(static_cast(core_id)); pinned != nullptr && pinned != top_thread) { // We prefer our parent's pinned thread if possible. However, we also don't @@ -411,7 +411,7 @@ void KScheduler::YieldWithoutCoreMigration(KernelCore& kernel) { // Get the current thread and process. KThread& cur_thread = Kernel::GetCurrentThread(kernel); - KProcess& cur_process = *kernel.CurrentProcess(); + Process& cur_process = *kernel.CurrentProcess(); // If the thread's yield count matches, there's nothing for us to do. if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) { @@ -450,7 +450,7 @@ void KScheduler::YieldWithCoreMigration(KernelCore& kernel) { // Get the current thread and process. KThread& cur_thread = Kernel::GetCurrentThread(kernel); - KProcess& cur_process = *kernel.CurrentProcess(); + Process& cur_process = *kernel.CurrentProcess(); // If the thread's yield count matches, there's nothing for us to do. if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) { @@ -538,7 +538,7 @@ void KScheduler::YieldToAnyThread(KernelCore& kernel) { // Get the current thread and process. KThread& cur_thread = Kernel::GetCurrentThread(kernel); - KProcess& cur_process = *kernel.CurrentProcess(); + Process& cur_process = *kernel.CurrentProcess(); // If the thread's yield count matches, there's nothing for us to do. if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) { @@ -617,12 +617,7 @@ KScheduler::KScheduler(Core::System& system, s32 core_id) : system(system), core state.highest_priority_thread = nullptr; } -KScheduler::~KScheduler() { - if (idle_thread) { - idle_thread->Close(); - idle_thread = nullptr; - } -} +KScheduler::~KScheduler() = default; KThread* KScheduler::GetCurrentThread() const { if (auto result = current_thread.load(); result) { @@ -724,7 +719,7 @@ void KScheduler::ScheduleImpl() { current_thread.store(next_thread); - KProcess* const previous_process = system.Kernel().CurrentProcess(); + Process* const previous_process = system.Kernel().CurrentProcess(); UpdateLastContextSwitchTime(previous_thread, previous_process); @@ -780,7 +775,7 @@ void KScheduler::SwitchToCurrent() { } } -void KScheduler::UpdateLastContextSwitchTime(KThread* thread, KProcess* process) { +void KScheduler::UpdateLastContextSwitchTime(KThread* thread, Process* process) { const u64 prev_switch_ticks = last_context_switch_time; const u64 most_recent_switch_ticks = system.CoreTiming().GetCPUTicks(); const u64 update_ticks = most_recent_switch_ticks - prev_switch_ticks; @@ -797,9 +792,13 @@ void KScheduler::UpdateLastContextSwitchTime(KThread* thread, KProcess* process) } void KScheduler::Initialize() { - idle_thread = KThread::Create(system.Kernel()); - ASSERT(KThread::InitializeIdleThread(system, idle_thread, core_id).IsSuccess()); - idle_thread->SetName(fmt::format("IdleThread:{}", core_id)); + std::string name = "Idle Thread Id:" + std::to_string(core_id); + std::function init_func = Core::CpuManager::GetIdleThreadStartFunc(); + void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); + auto thread_res = KThread::CreateThread( + system, ThreadType::Main, name, 0, KThread::IdleThreadPriority, 0, + static_cast(core_id), 0, nullptr, std::move(init_func), init_func_parameter); + idle_thread = thread_res.Unwrap().get(); } KScopedSchedulerLock::KScopedSchedulerLock(KernelCore& kernel) diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h index b789a64a4..8e32865aa 100755 --- a/src/core/hle/kernel/k_scheduler.h +++ b/src/core/hle/kernel/k_scheduler.h @@ -24,7 +24,7 @@ class System; namespace Kernel { class KernelCore; -class KProcess; +class Process; class SchedulerLock; class KThread; @@ -165,7 +165,7 @@ private: * most recent tick count retrieved. No special arithmetic is * applied to it. */ - void UpdateLastContextSwitchTime(KThread* thread, KProcess* process); + void UpdateLastContextSwitchTime(KThread* thread, Process* process); static void OnSwitch(void* this_scheduler); void SwitchToCurrent(); @@ -173,12 +173,12 @@ private: KThread* prev_thread{}; std::atomic current_thread{}; - KThread* idle_thread{}; + KThread* idle_thread; std::shared_ptr switch_fiber{}; struct SchedulingState { - std::atomic needs_scheduling{}; + std::atomic needs_scheduling; bool interrupt_task_thread_runnable{}; bool should_count_idle{}; u64 idle_count{}; diff --git a/src/core/hle/kernel/k_scoped_resource_reservation.h b/src/core/hle/kernel/k_scoped_resource_reservation.h index 07272075d..c5deca00b 100755 --- a/src/core/hle/kernel/k_scoped_resource_reservation.h +++ b/src/core/hle/kernel/k_scoped_resource_reservation.h @@ -8,14 +8,15 @@ #pragma once #include "common/common_types.h" -#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_resource_limit.h" +#include "core/hle/kernel/process.h" namespace Kernel { class KScopedResourceReservation { public: - explicit KScopedResourceReservation(KResourceLimit* l, LimitableResource r, s64 v, s64 timeout) + explicit KScopedResourceReservation(std::shared_ptr l, LimitableResource r, + s64 v, s64 timeout) : resource_limit(std::move(l)), value(v), resource(r) { if (resource_limit && value) { success = resource_limit->Reserve(resource, value, timeout); @@ -24,7 +25,8 @@ public: } } - explicit KScopedResourceReservation(KResourceLimit* l, LimitableResource r, s64 v = 1) + explicit KScopedResourceReservation(std::shared_ptr l, LimitableResource r, + s64 v = 1) : resource_limit(std::move(l)), value(v), resource(r) { if (resource_limit && value) { success = resource_limit->Reserve(resource, value); @@ -33,10 +35,10 @@ public: } } - explicit KScopedResourceReservation(const KProcess* p, LimitableResource r, s64 v, s64 t) + explicit KScopedResourceReservation(const Process* p, LimitableResource r, s64 v, s64 t) : KScopedResourceReservation(p->GetResourceLimit(), r, v, t) {} - explicit KScopedResourceReservation(const KProcess* p, LimitableResource r, s64 v = 1) + explicit KScopedResourceReservation(const Process* p, LimitableResource r, s64 v = 1) : KScopedResourceReservation(p->GetResourceLimit(), r, v) {} ~KScopedResourceReservation() noexcept { @@ -56,7 +58,7 @@ public: } private: - KResourceLimit* resource_limit{}; + std::shared_ptr resource_limit; s64 value; LimitableResource resource; bool success; diff --git a/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h b/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h index b5d405744..ebecf0c77 100755 --- a/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h +++ b/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h @@ -8,7 +8,7 @@ #pragma once #include "common/common_types.h" -#include "core/hle/kernel/k_handle_table.h" +#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/time_manager.h" diff --git a/src/core/hle/kernel/k_shared_memory.cpp b/src/core/hle/kernel/k_shared_memory.cpp index 1da57a4c3..9b14f42b5 100755 --- a/src/core/hle/kernel/k_shared_memory.cpp +++ b/src/core/hle/kernel/k_shared_memory.cpp @@ -8,74 +8,50 @@ #include "core/hle/kernel/k_scoped_resource_reservation.h" #include "core/hle/kernel/k_shared_memory.h" #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/svc_results.h" namespace Kernel { -KSharedMemory::KSharedMemory(KernelCore& kernel) : KAutoObjectWithSlabHeapAndContainer{kernel} {} +KSharedMemory::KSharedMemory(KernelCore& kernel, Core::DeviceMemory& device_memory) + : Object{kernel}, device_memory{device_memory} {} KSharedMemory::~KSharedMemory() { kernel.GetSystemResourceLimit()->Release(LimitableResource::PhysicalMemory, size); } -ResultCode KSharedMemory::Initialize(KernelCore& kernel_, Core::DeviceMemory& device_memory_, - KProcess* owner_process_, KPageLinkedList&& page_list_, - Svc::MemoryPermission owner_permission_, - Svc::MemoryPermission user_permission_, - PAddr physical_address_, std::size_t size_, - std::string name_) { - // Set members. - owner_process = owner_process_; - device_memory = &device_memory_; - page_list = std::move(page_list_); - owner_permission = owner_permission_; - user_permission = user_permission_; - physical_address = physical_address_; - size = size_; - name = name_; +std::shared_ptr KSharedMemory::Create( + KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process, + KPageLinkedList&& page_list, KMemoryPermission owner_permission, + KMemoryPermission user_permission, PAddr physical_address, std::size_t size, std::string name) { - // Get the resource limit. - KResourceLimit* reslimit = kernel.GetSystemResourceLimit(); + const auto resource_limit = kernel.GetSystemResourceLimit(); + KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory, + size); + ASSERT(memory_reservation.Succeeded()); - // Reserve memory for ourselves. - KScopedResourceReservation memory_reservation(reslimit, LimitableResource::PhysicalMemory, - size_); - R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); + std::shared_ptr shared_memory{ + std::make_shared(kernel, device_memory)}; + + shared_memory->owner_process = owner_process; + shared_memory->page_list = std::move(page_list); + shared_memory->owner_permission = owner_permission; + shared_memory->user_permission = user_permission; + shared_memory->physical_address = physical_address; + shared_memory->size = size; + shared_memory->name = name; - // Commit our reservation. memory_reservation.Commit(); - - // Set our resource limit. - resource_limit = reslimit; - resource_limit->Open(); - - // Mark initialized. - is_initialized = true; - - // Clear all pages in the memory. - std::memset(device_memory_.GetPointer(physical_address_), 0, size_); - - return RESULT_SUCCESS; + return shared_memory; } -void KSharedMemory::Finalize() { - // Release the memory reservation. - resource_limit->Release(LimitableResource::PhysicalMemory, size); - resource_limit->Close(); - - // Perform inherited finalization. - KAutoObjectWithSlabHeapAndContainer::Finalize(); -} - -ResultCode KSharedMemory::Map(KProcess& target_process, VAddr address, std::size_t size, - Svc::MemoryPermission permissions) { +ResultCode KSharedMemory::Map(Process& target_process, VAddr address, std::size_t size, + KMemoryPermission permissions) { const u64 page_count{(size + PageSize - 1) / PageSize}; if (page_list.GetNumPages() != page_count) { UNIMPLEMENTED_MSG("Page count does not match"); } - const Svc::MemoryPermission expected = + const KMemoryPermission expected = &target_process == owner_process ? owner_permission : user_permission; if (permissions != expected) { @@ -83,17 +59,7 @@ ResultCode KSharedMemory::Map(KProcess& target_process, VAddr address, std::size } return target_process.PageTable().MapPages(address, page_list, KMemoryState::Shared, - ConvertToKMemoryPermission(permissions)); -} - -ResultCode KSharedMemory::Unmap(KProcess& target_process, VAddr address, std::size_t size) { - const u64 page_count{(size + PageSize - 1) / PageSize}; - - if (page_list.GetNumPages() != page_count) { - UNIMPLEMENTED_MSG("Page count does not match"); - } - - return target_process.PageTable().UnmapPages(address, page_list, KMemoryState::Shared); + permissions); } } // namespace Kernel diff --git a/src/core/hle/kernel/k_shared_memory.h b/src/core/hle/kernel/k_shared_memory.h index 28939c93c..016e34be5 100755 --- a/src/core/hle/kernel/k_shared_memory.h +++ b/src/core/hle/kernel/k_shared_memory.h @@ -11,27 +11,37 @@ #include "core/device_memory.h" #include "core/hle/kernel/k_memory_block.h" #include "core/hle/kernel/k_page_linked_list.h" -#include "core/hle/kernel/k_process.h" -#include "core/hle/kernel/slab_helpers.h" +#include "core/hle/kernel/object.h" +#include "core/hle/kernel/process.h" #include "core/hle/result.h" namespace Kernel { class KernelCore; -class KSharedMemory final - : public KAutoObjectWithSlabHeapAndContainer { - KERNEL_AUTOOBJECT_TRAITS(KSharedMemory, KAutoObject); - +class KSharedMemory final : public Object { public: - explicit KSharedMemory(KernelCore& kernel); + explicit KSharedMemory(KernelCore& kernel, Core::DeviceMemory& device_memory); ~KSharedMemory() override; - ResultCode Initialize(KernelCore& kernel_, Core::DeviceMemory& device_memory_, - KProcess* owner_process_, KPageLinkedList&& page_list_, - Svc::MemoryPermission owner_permission_, - Svc::MemoryPermission user_permission_, PAddr physical_address_, - std::size_t size_, std::string name_); + static std::shared_ptr Create( + KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process, + KPageLinkedList&& page_list, KMemoryPermission owner_permission, + KMemoryPermission user_permission, PAddr physical_address, std::size_t size, + std::string name); + + std::string GetTypeName() const override { + return "SharedMemory"; + } + + std::string GetName() const override { + return name; + } + + static constexpr HandleType HANDLE_TYPE = HandleType::SharedMemory; + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } /** * Maps a shared memory block to an address in the target process' address space @@ -40,16 +50,8 @@ public: * @param size Size of the shared memory block to map * @param permissions Memory block map permissions (specified by SVC field) */ - ResultCode Map(KProcess& target_process, VAddr address, std::size_t size, - Svc::MemoryPermission permissions); - - /** - * Unmaps a shared memory block from an address in the target process' address space - * @param target_process Process on which to unmap the memory block - * @param address Address in system memory to unmap shared memory block - * @param size Size of the shared memory block to unmap - */ - ResultCode Unmap(KProcess& target_process, VAddr address, std::size_t size); + ResultCode Map(Process& target_process, VAddr address, std::size_t size, + KMemoryPermission permissions); /** * Gets a pointer to the shared memory block @@ -57,7 +59,7 @@ public: * @return A pointer to the shared memory block from the specified offset */ u8* GetPointer(std::size_t offset = 0) { - return device_memory->GetPointer(physical_address + offset); + return device_memory.GetPointer(physical_address + offset); } /** @@ -66,26 +68,20 @@ public: * @return A pointer to the shared memory block from the specified offset */ const u8* GetPointer(std::size_t offset = 0) const { - return device_memory->GetPointer(physical_address + offset); + return device_memory.GetPointer(physical_address + offset); } - virtual void Finalize() override; - - virtual bool IsInitialized() const override { - return is_initialized; - } - static void PostDestroy([[maybe_unused]] uintptr_t arg) {} + void Finalize() override {} private: - Core::DeviceMemory* device_memory; - KProcess* owner_process{}; + Core::DeviceMemory& device_memory; + Process* owner_process{}; KPageLinkedList page_list; - Svc::MemoryPermission owner_permission{}; - Svc::MemoryPermission user_permission{}; + KMemoryPermission owner_permission{}; + KMemoryPermission user_permission{}; PAddr physical_address{}; std::size_t size{}; - KResourceLimit* resource_limit{}; - bool is_initialized{}; + std::string name; }; } // namespace Kernel diff --git a/src/core/hle/kernel/k_slab_heap.h b/src/core/hle/kernel/k_slab_heap.h index 5ce9a1d7c..aa4471d2f 100755 --- a/src/core/hle/kernel/k_slab_heap.h +++ b/src/core/hle/kernel/k_slab_heap.h @@ -97,7 +97,6 @@ public: void FreeImpl(void* obj) { // Don't allow freeing an object that wasn't allocated from this heap ASSERT(Contains(reinterpret_cast(obj))); - impl.Free(obj); } @@ -149,14 +148,6 @@ public: return obj; } - T* AllocateWithKernel(KernelCore& kernel) { - T* obj = static_cast(AllocateImpl()); - if (obj != nullptr) { - new (obj) T(kernel); - } - return obj; - } - void Free(T* obj) { FreeImpl(obj); } diff --git a/src/core/hle/kernel/k_synchronization_object.cpp b/src/core/hle/kernel/k_synchronization_object.cpp index 460b8a714..82f72a0fe 100755 --- a/src/core/hle/kernel/k_synchronization_object.cpp +++ b/src/core/hle/kernel/k_synchronization_object.cpp @@ -13,11 +13,6 @@ namespace Kernel { -void KSynchronizationObject::Finalize() { - this->OnFinalizeSynchronizationObject(); - KAutoObject::Finalize(); -} - ResultCode KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index, KSynchronizationObject** objects, const s32 num_objects, s64 timeout) { @@ -135,7 +130,10 @@ ResultCode KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index, return wait_result; } -KSynchronizationObject::KSynchronizationObject(KernelCore& kernel) : KAutoObjectWithList{kernel} {} +KSynchronizationObject::KSynchronizationObject(KernelCore& kernel) : Object{kernel} {} + +KSynchronizationObject::KSynchronizationObject(KernelCore& kernel, std::string&& name) + : Object{kernel, std::move(name)} {} KSynchronizationObject::~KSynchronizationObject() = default; diff --git a/src/core/hle/kernel/k_synchronization_object.h b/src/core/hle/kernel/k_synchronization_object.h index a41dd1220..5803718fd 100755 --- a/src/core/hle/kernel/k_synchronization_object.h +++ b/src/core/hle/kernel/k_synchronization_object.h @@ -6,7 +6,7 @@ #include -#include "core/hle/kernel/k_auto_object.h" +#include "core/hle/kernel/object.h" #include "core/hle/result.h" namespace Kernel { @@ -16,9 +16,7 @@ class Synchronization; class KThread; /// Class that represents a Kernel object that a thread can be waiting on -class KSynchronizationObject : public KAutoObjectWithList { - KERNEL_AUTOOBJECT_TRAITS(KSynchronizationObject, KAutoObject); - +class KSynchronizationObject : public Object { public: struct ThreadListNode { ThreadListNode* next{}; @@ -29,18 +27,15 @@ public: KSynchronizationObject** objects, const s32 num_objects, s64 timeout); - virtual void Finalize() override; - [[nodiscard]] virtual bool IsSignaled() const = 0; [[nodiscard]] std::vector GetWaitingThreadsForDebugging() const; protected: explicit KSynchronizationObject(KernelCore& kernel); + explicit KSynchronizationObject(KernelCore& kernel, std::string&& name); virtual ~KSynchronizationObject(); - virtual void OnFinalizeSynchronizationObject() {} - void NotifyAvailable(ResultCode result); void NotifyAvailable() { return this->NotifyAvailable(RESULT_SUCCESS); @@ -51,4 +46,14 @@ private: ThreadListNode* thread_list_tail{}; }; +// Specialization of DynamicObjectCast for KSynchronizationObjects +template <> +inline std::shared_ptr DynamicObjectCast( + std::shared_ptr object) { + if (object != nullptr && object->IsWaitable()) { + return std::static_pointer_cast(object); + } + return nullptr; +} + } // namespace Kernel diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index ef6dfeeca..e0f53287c 100755 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -18,16 +18,17 @@ #include "core/core.h" #include "core/cpu_manager.h" #include "core/hardware_properties.h" +#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/k_condition_variable.h" -#include "core/hle/kernel/k_handle_table.h" #include "core/hle/kernel/k_memory_layout.h" -#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_thread_queue.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/object.h" +#include "core/hle/kernel/process.h" #include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/time_manager.h" #include "core/hle/result.h" @@ -61,11 +62,11 @@ static void ResetThreadContext64(Core::ARM_Interface::ThreadContext64& context, namespace Kernel { KThread::KThread(KernelCore& kernel) - : KAutoObjectWithSlabHeapAndContainer{kernel}, activity_pause_lock{kernel} {} + : KSynchronizationObject{kernel}, activity_pause_lock{kernel} {} KThread::~KThread() = default; ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, s32 prio, - s32 virt_core, KProcess* owner, ThreadType type) { + s32 virt_core, Process* owner, ThreadType type) { // Assert parameters are valid. ASSERT((type == ThreadType::Main) || (Svc::HighestThreadPriority <= prio && prio <= Svc::LowestThreadPriority)); @@ -176,7 +177,6 @@ ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_s // Set parent, if relevant. if (owner != nullptr) { parent = owner; - parent->Open(); parent->IncrementThreadCount(); } @@ -209,56 +209,14 @@ ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_s } ResultCode KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg, - VAddr user_stack_top, s32 prio, s32 core, KProcess* owner, - ThreadType type, std::function&& init_func, - void* init_func_parameter) { + VAddr user_stack_top, s32 prio, s32 core, Process* owner, + ThreadType type) { // Initialize the thread. R_TRY(thread->Initialize(func, arg, user_stack_top, prio, core, owner, type)); - // Initialize host context. - thread->host_context = - std::make_shared(std::move(init_func), init_func_parameter); - return RESULT_SUCCESS; } -ResultCode KThread::InitializeDummyThread(KThread* thread) { - return thread->Initialize({}, {}, {}, DefaultThreadPriority, 3, {}, ThreadType::Main); -} - -ResultCode KThread::InitializeIdleThread(Core::System& system, KThread* thread, s32 virt_core) { - return InitializeThread(thread, {}, {}, {}, IdleThreadPriority, virt_core, {}, ThreadType::Main, - Core::CpuManager::GetIdleThreadStartFunc(), - system.GetCpuManager().GetStartFuncParamater()); -} - -ResultCode KThread::InitializeHighPriorityThread(Core::System& system, KThread* thread, - KThreadFunction func, uintptr_t arg, - s32 virt_core) { - return InitializeThread(thread, func, arg, {}, {}, virt_core, nullptr, ThreadType::HighPriority, - Core::CpuManager::GetSuspendThreadStartFunc(), - system.GetCpuManager().GetStartFuncParamater()); -} - -ResultCode KThread::InitializeUserThread(Core::System& system, KThread* thread, - KThreadFunction func, uintptr_t arg, VAddr user_stack_top, - s32 prio, s32 virt_core, KProcess* owner) { - system.Kernel().GlobalSchedulerContext().AddThread(thread); - return InitializeThread(thread, func, arg, user_stack_top, prio, virt_core, owner, - ThreadType::User, Core::CpuManager::GetGuestThreadStartFunc(), - system.GetCpuManager().GetStartFuncParamater()); -} - -void KThread::PostDestroy(uintptr_t arg) { - KProcess* owner = reinterpret_cast(arg & ~1ULL); - const bool resource_limit_release_hint = (arg & 1); - const s64 hint_value = (resource_limit_release_hint ? 0 : 1); - if (owner != nullptr) { - owner->GetResourceLimit()->Release(LimitableResource::Threads, 1, hint_value); - owner->Close(); - } -} - void KThread::Finalize() { // If the thread has an owner process, unregister it. if (parent != nullptr) { @@ -288,10 +246,8 @@ void KThread::Finalize() { // Decrement the parent process's thread count. if (parent != nullptr) { parent->DecrementThreadCount(); + parent->GetResourceLimit()->Release(LimitableResource::Threads, 1); } - - // Perform inherited finalization. - KAutoObjectWithSlabHeapAndContainer::Finalize(); } bool KThread::IsSignaled() const { @@ -338,9 +294,6 @@ void KThread::StartTermination() { // Register terminated dpc flag. RegisterDpc(DpcFlag::Terminated); - - // Close the thread. - this->Close(); } void KThread::Pin() { @@ -979,7 +932,7 @@ void KThread::Exit() { // Release the thread resource hint from parent. if (parent != nullptr) { - parent->GetResourceLimit()->Release(Kernel::LimitableResource::Threads, 0, 1); + // TODO(bunnei): Hint that the resource is about to be released. resource_limit_release_hint = true; } @@ -1042,6 +995,56 @@ std::shared_ptr& KThread::GetHostContext() { return host_context; } +ResultVal> KThread::CreateThread(Core::System& system, + ThreadType type_flags, std::string name, + VAddr entry_point, u32 priority, u64 arg, + s32 processor_id, VAddr stack_top, + Process* owner_process) { + auto& kernel = system.Kernel(); + + std::shared_ptr thread = std::make_shared(kernel); + + if (const auto result = + thread->InitializeThread(thread.get(), entry_point, arg, stack_top, priority, + processor_id, owner_process, type_flags); + result.IsError()) { + return result; + } + + thread->name = name; + + auto& scheduler = kernel.GlobalSchedulerContext(); + scheduler.AddThread(thread); + + return MakeResult>(std::move(thread)); +} + +ResultVal> KThread::CreateThread( + Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point, u32 priority, + u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process, + std::function&& thread_start_func, void* thread_start_parameter) { + auto thread_result = CreateThread(system, type_flags, name, entry_point, priority, arg, + processor_id, stack_top, owner_process); + + if (thread_result.Succeeded()) { + (*thread_result)->host_context = + std::make_shared(std::move(thread_start_func), thread_start_parameter); + } + + return thread_result; +} + +ResultVal> KThread::CreateUserThread( + Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point, u32 priority, + u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process) { + std::function init_func = Core::CpuManager::GetGuestThreadStartFunc(); + + void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); + + return CreateThread(system, type_flags, name, entry_point, priority, arg, processor_id, + stack_top, owner_process, std::move(init_func), init_func_parameter); +} + KThread* GetCurrentThreadPointer(KernelCore& kernel) { return kernel.GetCurrentEmuThread(); } diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index 4145ef56c..b442dfe57 100755 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h @@ -19,7 +19,7 @@ #include "core/hle/kernel/k_light_lock.h" #include "core/hle/kernel/k_spin_lock.h" #include "core/hle/kernel/k_synchronization_object.h" -#include "core/hle/kernel/slab_helpers.h" +#include "core/hle/kernel/object.h" #include "core/hle/kernel/svc_common.h" #include "core/hle/kernel/svc_types.h" #include "core/hle/result.h" @@ -37,7 +37,7 @@ namespace Kernel { class GlobalSchedulerContext; class KernelCore; -class KProcess; +class Process; class KScheduler; class KThreadQueue; @@ -99,13 +99,9 @@ enum class ThreadWaitReasonForDebugging : u32 { [[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel); [[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel); -class KThread final : public KAutoObjectWithSlabHeapAndContainer, - public boost::intrusive::list_base_hook<> { - KERNEL_AUTOOBJECT_TRAITS(KThread, KSynchronizationObject); - -private: +class KThread final : public KSynchronizationObject, public boost::intrusive::list_base_hook<> { friend class KScheduler; - friend class KProcess; + friend class Process; public: static constexpr s32 DefaultThreadPriority = 44; @@ -119,10 +115,74 @@ public: using ThreadContext64 = Core::ARM_Interface::ThreadContext64; using WaiterList = boost::intrusive::list; + /** + * Creates and returns a new thread. + * @param system The instance of the whole system + * @param name The friendly name desired for the thread + * @param entry_point The address at which the thread should start execution + * @param priority The thread's priority + * @param arg User data to pass to the thread + * @param processor_id The ID(s) of the processors on which the thread is desired to be run + * @param stack_top The address of the thread's stack top + * @param owner_process The parent process for the thread, if null, it's a kernel thread + * @return A shared pointer to the newly created thread + */ + [[nodiscard]] static ResultVal> CreateThread( + Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point, + u32 priority, u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process); + + /** + * Creates and returns a new thread, with a specified entry point. + * @param system The instance of the whole system + * @param name The friendly name desired for the thread + * @param entry_point The address at which the thread should start execution + * @param priority The thread's priority + * @param arg User data to pass to the thread + * @param processor_id The ID(s) of the processors on which the thread is desired to be run + * @param stack_top The address of the thread's stack top + * @param owner_process The parent process for the thread, if null, it's a kernel thread + * @param thread_start_func The function where the host context will start. + * @param thread_start_parameter The parameter which will passed to host context on init + * @return A shared pointer to the newly created thread + */ + [[nodiscard]] static ResultVal> CreateThread( + Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point, + u32 priority, u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process, + std::function&& thread_start_func, void* thread_start_parameter); + + /** + * Creates and returns a new thread for the emulated "user" process. + * @param system The instance of the whole system + * @param name The friendly name desired for the thread + * @param entry_point The address at which the thread should start execution + * @param priority The thread's priority + * @param arg User data to pass to the thread + * @param processor_id The ID(s) of the processors on which the thread is desired to be run + * @param stack_top The address of the thread's stack top + * @param owner_process The parent process for the thread, if null, it's a kernel thread + * @return A shared pointer to the newly created thread + */ + [[nodiscard]] static ResultVal> CreateUserThread( + Core::System& system, ThreadType type_flags, std::string name, VAddr entry_point, + u32 priority, u64 arg, s32 processor_id, VAddr stack_top, Process* owner_process); + + [[nodiscard]] std::string GetName() const override { + return name; + } + void SetName(std::string new_name) { name = std::move(new_name); } + [[nodiscard]] std::string GetTypeName() const override { + return "Thread"; + } + + static constexpr HandleType HANDLE_TYPE = HandleType::Thread; + [[nodiscard]] HandleType GetHandleType() const override { + return HANDLE_TYPE; + } + /** * Gets the thread's current priority * @return The current thread's priority @@ -197,6 +257,10 @@ public: void Suspend(); + void Finalize() override; + + bool IsSignaled() const override; + void SetSyncedObject(KSynchronizationObject* obj, ResultCode wait_res) { synced_object = obj; wait_result = wait_res; @@ -290,11 +354,11 @@ public: current_core_id = core; } - [[nodiscard]] KProcess* GetOwnerProcess() { + [[nodiscard]] Process* GetOwnerProcess() { return parent; } - [[nodiscard]] const KProcess* GetOwnerProcess() const { + [[nodiscard]] const Process* GetOwnerProcess() const { return parent; } @@ -358,40 +422,6 @@ public: return termination_requested || GetRawState() == ThreadState::Terminated; } - [[nodiscard]] virtual u64 GetId() const override final { - return this->GetThreadID(); - } - - [[nodiscard]] virtual bool IsInitialized() const override { - return initialized; - } - - [[nodiscard]] virtual uintptr_t GetPostDestroyArgument() const override { - return reinterpret_cast(parent) | (resource_limit_release_hint ? 1 : 0); - } - - virtual void Finalize() override; - - [[nodiscard]] virtual bool IsSignaled() const override; - - static void PostDestroy(uintptr_t arg); - - [[nodiscard]] static ResultCode InitializeDummyThread(KThread* thread); - - [[nodiscard]] static ResultCode InitializeIdleThread(Core::System& system, KThread* thread, - s32 virt_core); - - [[nodiscard]] static ResultCode InitializeHighPriorityThread(Core::System& system, - KThread* thread, - KThreadFunction func, - uintptr_t arg, s32 virt_core); - - [[nodiscard]] static ResultCode InitializeUserThread(Core::System& system, KThread* thread, - KThreadFunction func, uintptr_t arg, - VAddr user_stack_top, s32 prio, - s32 virt_core, KProcess* owner); - -public: struct StackParameters { u8 svc_permission[0x10]; std::atomic dpc_flags; @@ -641,13 +671,11 @@ private: void StartTermination(); [[nodiscard]] ResultCode Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, - s32 prio, s32 virt_core, KProcess* owner, ThreadType type); + s32 prio, s32 virt_core, Process* owner, ThreadType type); [[nodiscard]] static ResultCode InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg, VAddr user_stack_top, s32 prio, - s32 core, KProcess* owner, ThreadType type, - std::function&& init_func, - void* init_func_parameter); + s32 core, Process* owner, ThreadType type); static void RestorePriority(KernelCore& kernel, KThread* thread); @@ -669,7 +697,7 @@ private: std::atomic cpu_time{}; KSynchronizationObject* synced_object{}; VAddr address_key{}; - KProcess* parent{}; + Process* parent{}; VAddr kernel_stack_top{}; u32* light_ipc_data{}; VAddr tls_address{}; @@ -714,6 +742,7 @@ private: VAddr mutex_wait_address_for_debugging{}; ThreadWaitReasonForDebugging wait_reason_for_debugging{}; ThreadType thread_type_for_debugging{}; + std::string name; public: using ConditionVariableThreadTreeType = ConditionVariableThreadTree; diff --git a/src/core/hle/kernel/k_writable_event.cpp b/src/core/hle/kernel/k_writable_event.cpp index a430e0661..25c52edb2 100755 --- a/src/core/hle/kernel/k_writable_event.cpp +++ b/src/core/hle/kernel/k_writable_event.cpp @@ -8,28 +8,20 @@ namespace Kernel { -KWritableEvent::KWritableEvent(KernelCore& kernel) : KAutoObjectWithSlabHeapAndContainer{kernel} {} - +KWritableEvent::KWritableEvent(KernelCore& kernel, std::string&& name) + : Object{kernel, std::move(name)} {} KWritableEvent::~KWritableEvent() = default; -void KWritableEvent::Initialize(KEvent* parent_, std::string&& name_) { +void KWritableEvent::Initialize(KEvent* parent_) { parent = parent_; - name = std::move(name_); - parent->GetReadableEvent().Open(); } ResultCode KWritableEvent::Signal() { - return parent->GetReadableEvent().Signal(); + return parent->GetReadableEvent()->Signal(); } ResultCode KWritableEvent::Clear() { - return parent->GetReadableEvent().Clear(); -} - -void KWritableEvent::Destroy() { - // Close our references. - parent->GetReadableEvent().Close(); - parent->Close(); + return parent->GetReadableEvent()->Clear(); } } // namespace Kernel diff --git a/src/core/hle/kernel/k_writable_event.h b/src/core/hle/kernel/k_writable_event.h index 154d2382c..518f5448d 100755 --- a/src/core/hle/kernel/k_writable_event.h +++ b/src/core/hle/kernel/k_writable_event.h @@ -4,8 +4,7 @@ #pragma once -#include "core/hle/kernel/k_auto_object.h" -#include "core/hle/kernel/slab_helpers.h" +#include "core/hle/kernel/object.h" #include "core/hle/result.h" namespace Kernel { @@ -13,19 +12,24 @@ namespace Kernel { class KernelCore; class KEvent; -class KWritableEvent final - : public KAutoObjectWithSlabHeapAndContainer { - KERNEL_AUTOOBJECT_TRAITS(KWritableEvent, KAutoObject); - +class KWritableEvent final : public Object { public: - explicit KWritableEvent(KernelCore& kernel); + explicit KWritableEvent(KernelCore& kernel, std::string&& name); ~KWritableEvent() override; - virtual void Destroy() override; + std::string GetTypeName() const override { + return "KWritableEvent"; + } - static void PostDestroy([[maybe_unused]] uintptr_t arg) {} + static constexpr HandleType HANDLE_TYPE = HandleType::WritableEvent; + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } + + void Initialize(KEvent* parent_); + + void Finalize() override {} - void Initialize(KEvent* parent_, std::string&& name_); ResultCode Signal(); ResultCode Clear(); diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index d917077fa..5c4f45ab4 100755 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -26,12 +26,10 @@ #include "core/cpu_manager.h" #include "core/device_memory.h" #include "core/hardware_properties.h" -#include "core/hle/kernel/init/init_slab_setup.h" -#include "core/hle/kernel/k_client_port.h" -#include "core/hle/kernel/k_handle_table.h" +#include "core/hle/kernel/client_port.h" +#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/k_memory_layout.h" #include "core/hle/kernel/k_memory_manager.h" -#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_shared_memory.h" @@ -39,6 +37,7 @@ #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/physical_core.h" +#include "core/hle/kernel/process.h" #include "core/hle/kernel/service_thread.h" #include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/time_manager.h" @@ -52,7 +51,7 @@ namespace Kernel { struct KernelCore::Impl { explicit Impl(Core::System& system, KernelCore& kernel) - : time_manager{system}, object_list_container{kernel}, system{system} {} + : time_manager{system}, global_handle_table{kernel}, system{system} {} void SetMulticore(bool is_multicore) { this->is_multicore = is_multicore; @@ -60,7 +59,8 @@ struct KernelCore::Impl { void Initialize(KernelCore& kernel) { global_scheduler_context = std::make_unique(kernel); - global_handle_table = std::make_unique(kernel); + + RegisterHostThread(); service_thread_manager = std::make_unique(1, "yuzu:ServiceThreadManager"); @@ -69,20 +69,14 @@ struct KernelCore::Impl { InitializePhysicalCores(); // Derive the initial memory layout from the emulated board - Init::InitializeSlabResourceCounts(kernel); KMemoryLayout memory_layout; DeriveInitialMemoryLayout(memory_layout); - Init::InitializeSlabHeaps(system, memory_layout); - - // Initialize kernel memory and resources. - InitializeSystemResourceLimit(kernel, system.CoreTiming(), memory_layout); InitializeMemoryLayout(memory_layout); - InitializePageSlab(); + InitializeSystemResourceLimit(kernel, system.CoreTiming(), memory_layout); + InitializeSlabHeaps(); InitializeSchedulers(); InitializeSuspendThreads(); InitializePreemption(kernel); - - RegisterHostThread(); } void InitializeCores() { @@ -99,49 +93,34 @@ struct KernelCore::Impl { service_threads.clear(); next_object_id = 0; - next_kernel_process_id = KProcess::InitialKIPIDMin; - next_user_process_id = KProcess::ProcessIDMin; + next_kernel_process_id = Process::InitialKIPIDMin; + next_user_process_id = Process::ProcessIDMin; next_thread_id = 1; - for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { - if (suspend_threads[core_id]) { - suspend_threads[core_id]->Close(); - suspend_threads[core_id] = nullptr; + for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { + if (suspend_threads[i]) { + suspend_threads[i].reset(); } - - schedulers[core_id].reset(); } cores.clear(); - if (current_process) { - current_process->Close(); - current_process = nullptr; - } + current_process = nullptr; - global_handle_table.reset(); + global_handle_table.Clear(); preemption_event = nullptr; - for (auto& iter : named_ports) { - iter.second->Close(); - } named_ports.clear(); exclusive_monitor.reset(); - // Cleanup persistent kernel objects - auto CleanupObject = [](KAutoObject* obj) { - if (obj) { - obj->Close(); - obj = nullptr; - } - }; - CleanupObject(hid_shared_mem); - CleanupObject(font_shared_mem); - CleanupObject(irs_shared_mem); - CleanupObject(time_shared_mem); - CleanupObject(system_resource_limit); + hid_shared_mem = nullptr; + font_shared_mem = nullptr; + irs_shared_mem = nullptr; + time_shared_mem = nullptr; + + system_resource_limit = nullptr; // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others next_host_thread_id = Core::Hardware::NUM_CPU_CORES; @@ -166,9 +145,7 @@ struct KernelCore::Impl { void InitializeSystemResourceLimit(KernelCore& kernel, const Core::Timing::CoreTiming& core_timing, const KMemoryLayout& memory_layout) { - system_resource_limit = KResourceLimit::Create(system.Kernel()); - system_resource_limit->Initialize(&core_timing); - + system_resource_limit = std::make_shared(kernel, core_timing); const auto [total_size, kernel_size] = memory_layout.GetTotalAndKernelMemorySizes(); // If setting the default system values fails, then something seriously wrong has occurred. @@ -212,16 +189,19 @@ struct KernelCore::Impl { } void InitializeSuspendThreads() { - for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { - suspend_threads[core_id] = KThread::Create(system.Kernel()); - ASSERT(KThread::InitializeHighPriorityThread(system, suspend_threads[core_id], {}, {}, - core_id) - .IsSuccess()); - suspend_threads[core_id]->SetName(fmt::format("SuspendThread:{}", core_id)); + for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { + std::string name = "Suspend Thread Id:" + std::to_string(i); + std::function init_func = Core::CpuManager::GetSuspendThreadStartFunc(); + void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater(); + auto thread_res = KThread::CreateThread( + system, ThreadType::HighPriority, std::move(name), 0, 0, 0, static_cast(i), 0, + nullptr, std::move(init_func), init_func_parameter); + + suspend_threads[i] = std::move(thread_res).Unwrap(); } } - void MakeCurrentProcess(KProcess* process) { + void MakeCurrentProcess(Process* process) { current_process = process; if (process == nullptr) { return; @@ -252,15 +232,11 @@ struct KernelCore::Impl { // Gets the dummy KThread for the caller, allocating a new one if this is the first time KThread* GetHostDummyThread() { - auto make_thread = [this]() { - std::unique_ptr thread = std::make_unique(system.Kernel()); - KAutoObject::Create(thread.get()); - ASSERT(KThread::InitializeDummyThread(thread.get()).IsSuccess()); - thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId())); - return std::move(thread); - }; - - thread_local auto thread = make_thread(); + const thread_local auto thread = + KThread::CreateThread( + system, ThreadType::Main, fmt::format("DummyThread:{}", GetHostThreadId()), 0, + KThread::DefaultThreadPriority, 0, static_cast(3), 0, nullptr) + .Unwrap(); return thread.get(); } @@ -395,8 +371,7 @@ struct KernelCore::Impl { const size_t resource_region_size = memory_layout.GetResourceRegionSizeForInit(); // Determine the size of the slab region. - const size_t slab_region_size = - Common::AlignUp(Init::CalculateTotalSlabHeapSize(system.Kernel()), PageSize); + const size_t slab_region_size = Common::AlignUp(KernelSlabHeapSize, PageSize); ASSERT(slab_region_size <= resource_region_size); // Setup the slab region. @@ -594,30 +569,25 @@ struct KernelCore::Impl { const PAddr irs_phys_addr{system_pool.GetAddress() + hid_size + font_size}; const PAddr time_phys_addr{system_pool.GetAddress() + hid_size + font_size + irs_size}; - hid_shared_mem = KSharedMemory::Create(system.Kernel()); - font_shared_mem = KSharedMemory::Create(system.Kernel()); - irs_shared_mem = KSharedMemory::Create(system.Kernel()); - time_shared_mem = KSharedMemory::Create(system.Kernel()); - - hid_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, - {hid_phys_addr, hid_size / PageSize}, - Svc::MemoryPermission::None, Svc::MemoryPermission::Read, - hid_phys_addr, hid_size, "HID:SharedMemory"); - font_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, - {font_phys_addr, font_size / PageSize}, - Svc::MemoryPermission::None, Svc::MemoryPermission::Read, - font_phys_addr, font_size, "Font:SharedMemory"); - irs_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, - {irs_phys_addr, irs_size / PageSize}, - Svc::MemoryPermission::None, Svc::MemoryPermission::Read, - irs_phys_addr, irs_size, "IRS:SharedMemory"); - time_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, - {time_phys_addr, time_size / PageSize}, - Svc::MemoryPermission::None, Svc::MemoryPermission::Read, - time_phys_addr, time_size, "Time:SharedMemory"); + hid_shared_mem = Kernel::KSharedMemory::Create( + system.Kernel(), system.DeviceMemory(), nullptr, {hid_phys_addr, hid_size / PageSize}, + KMemoryPermission::None, KMemoryPermission::Read, hid_phys_addr, hid_size, + "HID:SharedMemory"); + font_shared_mem = Kernel::KSharedMemory::Create( + system.Kernel(), system.DeviceMemory(), nullptr, {font_phys_addr, font_size / PageSize}, + KMemoryPermission::None, KMemoryPermission::Read, font_phys_addr, font_size, + "Font:SharedMemory"); + irs_shared_mem = Kernel::KSharedMemory::Create( + system.Kernel(), system.DeviceMemory(), nullptr, {irs_phys_addr, irs_size / PageSize}, + KMemoryPermission::None, KMemoryPermission::Read, irs_phys_addr, irs_size, + "IRS:SharedMemory"); + time_shared_mem = Kernel::KSharedMemory::Create( + system.Kernel(), system.DeviceMemory(), nullptr, {time_phys_addr, time_size / PageSize}, + KMemoryPermission::None, KMemoryPermission::Read, time_phys_addr, time_size, + "Time:SharedMemory"); } - void InitializePageSlab() { + void InitializeSlabHeaps() { // Allocate slab heaps user_slab_heap_pages = std::make_unique>(); @@ -626,33 +596,30 @@ struct KernelCore::Impl { // Reserve slab heaps ASSERT( system_resource_limit->Reserve(LimitableResource::PhysicalMemory, user_slab_heap_size)); - // Initialize slab heap + // Initialize slab heaps user_slab_heap_pages->Initialize( system.DeviceMemory().GetPointer(Core::DramMemoryMap::SlabHeapBase), user_slab_heap_size); } std::atomic next_object_id{0}; - std::atomic next_kernel_process_id{KProcess::InitialKIPIDMin}; - std::atomic next_user_process_id{KProcess::ProcessIDMin}; + std::atomic next_kernel_process_id{Process::InitialKIPIDMin}; + std::atomic next_user_process_id{Process::ProcessIDMin}; std::atomic next_thread_id{1}; // Lists all processes that exist in the current session. - std::vector process_list; - KProcess* current_process{}; + std::vector> process_list; + Process* current_process = nullptr; std::unique_ptr global_scheduler_context; Kernel::TimeManager time_manager; - Init::KSlabResourceCounts slab_resource_counts{}; - KResourceLimit* system_resource_limit{}; + std::shared_ptr system_resource_limit; std::shared_ptr preemption_event; // This is the kernel's handle table or supervisor handle table which // stores all the objects in place. - std::unique_ptr global_handle_table; - - KAutoObjectWithListContainer object_list_container; + HandleTable global_handle_table; /// Map of named ports managed by the kernel, which can be retrieved using /// the ConnectToPort SVC. @@ -669,10 +636,10 @@ struct KernelCore::Impl { std::unique_ptr> user_slab_heap_pages; // Shared memory for services - Kernel::KSharedMemory* hid_shared_mem{}; - Kernel::KSharedMemory* font_shared_mem{}; - Kernel::KSharedMemory* irs_shared_mem{}; - Kernel::KSharedMemory* time_shared_mem{}; + std::shared_ptr hid_shared_mem; + std::shared_ptr font_shared_mem; + std::shared_ptr irs_shared_mem; + std::shared_ptr time_shared_mem; // Threads used for services std::unordered_set> service_threads; @@ -681,7 +648,7 @@ struct KernelCore::Impl { // the release of itself std::unique_ptr service_thread_manager; - std::array suspend_threads; + std::array, Core::Hardware::NUM_CPU_CORES> suspend_threads{}; std::array interrupts{}; std::array, Core::Hardware::NUM_CPU_CORES> schedulers{}; @@ -696,14 +663,15 @@ struct KernelCore::Impl { }; KernelCore::KernelCore(Core::System& system) : impl{std::make_unique(system, *this)} {} -KernelCore::~KernelCore() = default; +KernelCore::~KernelCore() { + Shutdown(); +} void KernelCore::SetMulticore(bool is_multicore) { impl->SetMulticore(is_multicore); } void KernelCore::Initialize() { - slab_heap_container = std::make_unique(); impl->Initialize(*this); } @@ -715,35 +683,31 @@ void KernelCore::Shutdown() { impl->Shutdown(); } -const KResourceLimit* KernelCore::GetSystemResourceLimit() const { +std::shared_ptr KernelCore::GetSystemResourceLimit() const { return impl->system_resource_limit; } -KResourceLimit* KernelCore::GetSystemResourceLimit() { - return impl->system_resource_limit; +std::shared_ptr KernelCore::RetrieveThreadFromGlobalHandleTable(Handle handle) const { + return impl->global_handle_table.Get(handle); } -KScopedAutoObject KernelCore::RetrieveThreadFromGlobalHandleTable(Handle handle) const { - return impl->global_handle_table->GetObject(handle); +void KernelCore::AppendNewProcess(std::shared_ptr process) { + impl->process_list.push_back(std::move(process)); } -void KernelCore::AppendNewProcess(KProcess* process) { - impl->process_list.push_back(process); -} - -void KernelCore::MakeCurrentProcess(KProcess* process) { +void KernelCore::MakeCurrentProcess(Process* process) { impl->MakeCurrentProcess(process); } -KProcess* KernelCore::CurrentProcess() { +Process* KernelCore::CurrentProcess() { return impl->current_process; } -const KProcess* KernelCore::CurrentProcess() const { +const Process* KernelCore::CurrentProcess() const { return impl->current_process; } -const std::vector& KernelCore::GetProcessList() const { +const std::vector>& KernelCore::GetProcessList() const { return impl->process_list; } @@ -817,14 +781,6 @@ const Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() const { return *impl->exclusive_monitor; } -KAutoObjectWithListContainer& KernelCore::ObjectListContainer() { - return impl->object_list_container; -} - -const KAutoObjectWithListContainer& KernelCore::ObjectListContainer() const { - return impl->object_list_container; -} - void KernelCore::InvalidateAllInstructionCaches() { for (auto& physical_core : impl->cores) { physical_core.ArmInterface().ClearInstructionCache(); @@ -844,9 +800,8 @@ void KernelCore::PrepareReschedule(std::size_t id) { // TODO: Reimplement, this } -void KernelCore::AddNamedPort(std::string name, KClientPort* port) { - port->Open(); - impl->named_ports.emplace(std::move(name), port); +void KernelCore::AddNamedPort(std::string name, std::shared_ptr port) { + impl->named_ports.emplace(std::move(name), std::move(port)); } KernelCore::NamedPortTable::iterator KernelCore::FindNamedPort(const std::string& name) { @@ -878,12 +833,12 @@ u64 KernelCore::CreateNewUserProcessID() { return impl->next_user_process_id++; } -KHandleTable& KernelCore::GlobalHandleTable() { - return *impl->global_handle_table; +Kernel::HandleTable& KernelCore::GlobalHandleTable() { + return impl->global_handle_table; } -const KHandleTable& KernelCore::GlobalHandleTable() const { - return *impl->global_handle_table; +const Kernel::HandleTable& KernelCore::GlobalHandleTable() const { + return impl->global_handle_table; } void KernelCore::RegisterCoreThread(std::size_t core_id) { @@ -955,9 +910,9 @@ void KernelCore::Suspend(bool in_suspention) { { KScopedSchedulerLock lock(*this); const auto state = should_suspend ? ThreadState::Runnable : ThreadState::Waiting; - for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { - impl->suspend_threads[core_id]->SetState(state); - impl->suspend_threads[core_id]->SetWaitReasonForDebugging( + for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { + impl->suspend_threads[i]->SetState(state); + impl->suspend_threads[i]->SetWaitReasonForDebugging( ThreadWaitReasonForDebugging::Suspended); } } @@ -997,14 +952,6 @@ void KernelCore::ReleaseServiceThread(std::weak_ptr servi }); } -Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() { - return impl->slab_resource_counts; -} - -const Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() const { - return impl->slab_resource_counts; -} - bool KernelCore::IsPhantomModeForSingleCore() const { return impl->IsPhantomModeForSingleCore(); } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 5d1b62abe..a500e63bc 100755 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -11,10 +11,8 @@ #include #include "core/arm/cpu_interrupt_handler.h" #include "core/hardware_properties.h" -#include "core/hle/kernel/k_auto_object.h" -#include "core/hle/kernel/k_slab_heap.h" #include "core/hle/kernel/memory_types.h" -#include "core/hle/kernel/svc_common.h" +#include "core/hle/kernel/object.h" namespace Core { class CPUInterruptHandler; @@ -29,32 +27,20 @@ struct EventType; namespace Kernel { -class KClientPort; +class ClientPort; class GlobalSchedulerContext; -class KAutoObjectWithListContainer; -class KClientSession; -class KEvent; -class KHandleTable; -class KLinkedListNode; +class HandleTable; class KMemoryManager; -class KPort; -class KProcess; class KResourceLimit; class KScheduler; -class KSession; class KSharedMemory; class KThread; -class KTransferMemory; -class KWritableEvent; class PhysicalCore; +class Process; class ServiceThread; class Synchronization; class TimeManager; -namespace Init { -struct KSlabResourceCounts; -} - template class KSlabHeap; @@ -65,7 +51,7 @@ constexpr EmuThreadHandle EmuThreadHandleReserved{1ULL << 63}; /// Represents a single instance of the kernel. class KernelCore { private: - using NamedPortTable = std::unordered_map; + using NamedPortTable = std::unordered_map>; public: /// Constructs an instance of the kernel using the given System @@ -97,28 +83,25 @@ public: void Shutdown(); /// Retrieves a shared pointer to the system resource limit instance. - const KResourceLimit* GetSystemResourceLimit() const; - - /// Retrieves a shared pointer to the system resource limit instance. - KResourceLimit* GetSystemResourceLimit(); + std::shared_ptr GetSystemResourceLimit() const; /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table. - KScopedAutoObject RetrieveThreadFromGlobalHandleTable(Handle handle) const; + std::shared_ptr RetrieveThreadFromGlobalHandleTable(Handle handle) const; /// Adds the given shared pointer to an internal list of active processes. - void AppendNewProcess(KProcess* process); + void AppendNewProcess(std::shared_ptr process); /// Makes the given process the new current process. - void MakeCurrentProcess(KProcess* process); + void MakeCurrentProcess(Process* process); /// Retrieves a pointer to the current process. - KProcess* CurrentProcess(); + Process* CurrentProcess(); /// Retrieves a const pointer to the current process. - const KProcess* CurrentProcess() const; + const Process* CurrentProcess() const; /// Retrieves the list of processes. - const std::vector& GetProcessList() const; + const std::vector>& GetProcessList() const; /// Gets the sole instance of the global scheduler Kernel::GlobalSchedulerContext& GlobalSchedulerContext(); @@ -160,10 +143,6 @@ public: const Core::ExclusiveMonitor& GetExclusiveMonitor() const; - KAutoObjectWithListContainer& ObjectListContainer(); - - const KAutoObjectWithListContainer& ObjectListContainer() const; - std::array& Interrupts(); const std::array& Interrupts() const; @@ -173,7 +152,7 @@ public: void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); /// Adds a port to the named port table - void AddNamedPort(std::string name, KClientPort* port); + void AddNamedPort(std::string name, std::shared_ptr port); /// Finds a port within the named port table with the given name. NamedPortTable::iterator FindNamedPort(const std::string& name); @@ -246,10 +225,9 @@ public: /** * Creates an HLE service thread, which are used to execute service routines asynchronously. - * While these are allocated per ServerSession, these need to be owned and managed outside - * of ServerSession to avoid a circular dependency. - * @param name String name for the ServerSession creating this thread, used for debug - * purposes. + * While these are allocated per ServerSession, these need to be owned and managed outside of + * ServerSession to avoid a circular dependency. + * @param name String name for the ServerSession creating this thread, used for debug purposes. * @returns The a weak pointer newly created service thread. */ std::weak_ptr CreateServiceThread(const std::string& name); @@ -265,42 +243,9 @@ public: bool IsPhantomModeForSingleCore() const; void SetIsPhantomModeForSingleCore(bool value); - /// Gets the slab heap for the specified kernel object type. - template - KSlabHeap& SlabHeap() { - if constexpr (std::is_same_v) { - return slab_heap_container->client_session; - } else if constexpr (std::is_same_v) { - return slab_heap_container->event; - } else if constexpr (std::is_same_v) { - return slab_heap_container->linked_list_node; - } else if constexpr (std::is_same_v) { - return slab_heap_container->port; - } else if constexpr (std::is_same_v) { - return slab_heap_container->process; - } else if constexpr (std::is_same_v) { - return slab_heap_container->resource_limit; - } else if constexpr (std::is_same_v) { - return slab_heap_container->session; - } else if constexpr (std::is_same_v) { - return slab_heap_container->shared_memory; - } else if constexpr (std::is_same_v) { - return slab_heap_container->thread; - } else if constexpr (std::is_same_v) { - return slab_heap_container->transfer_memory; - } else if constexpr (std::is_same_v) { - return slab_heap_container->writeable_event; - } - } - - /// Gets the current slab resource counts. - Init::KSlabResourceCounts& SlabResourceCounts(); - - /// Gets the current slab resource counts. - const Init::KSlabResourceCounts& SlabResourceCounts() const; - private: - friend class KProcess; + friend class Object; + friend class Process; friend class KThread; /// Creates a new object ID, incrementing the internal object ID counter. @@ -316,33 +261,14 @@ private: u64 CreateNewThreadID(); /// Provides a reference to the global handle table. - KHandleTable& GlobalHandleTable(); + Kernel::HandleTable& GlobalHandleTable(); /// Provides a const reference to the global handle table. - const KHandleTable& GlobalHandleTable() const; + const Kernel::HandleTable& GlobalHandleTable() const; struct Impl; std::unique_ptr impl; - bool exception_exited{}; - -private: - /// Helper to encapsulate all slab heaps in a single heap allocated container - struct SlabHeapContainer { - KSlabHeap client_session; - KSlabHeap event; - KSlabHeap linked_list_node; - KSlabHeap port; - KSlabHeap process; - KSlabHeap resource_limit; - KSlabHeap session; - KSlabHeap shared_memory; - KSlabHeap thread; - KSlabHeap transfer_memory; - KSlabHeap writeable_event; - }; - - std::unique_ptr slab_heap_container; }; } // namespace Kernel diff --git a/src/core/hle/kernel/process_capability.cpp b/src/core/hle/kernel/process_capability.cpp index fcb8b1ea5..1006ee50c 100755 --- a/src/core/hle/kernel/process_capability.cpp +++ b/src/core/hle/kernel/process_capability.cpp @@ -6,7 +6,7 @@ #include "common/bit_util.h" #include "common/logging/log.h" -#include "core/hle/kernel/k_handle_table.h" +#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/k_page_table.h" #include "core/hle/kernel/process_capability.h" #include "core/hle/kernel/svc_results.h" @@ -99,7 +99,7 @@ void ProcessCapabilities::InitializeForMetadatalessProcess() { interrupt_capabilities.set(); // Allow using the maximum possible amount of handles - handle_table_size = static_cast(KHandleTable::MaxTableSize); + handle_table_size = static_cast(HandleTable::MAX_COUNT); // Allow all debugging capabilities. is_debuggable = true; @@ -159,7 +159,7 @@ ResultCode ProcessCapabilities::ParseSingleFlagCapability(u32& set_flags, u32& s const auto type = GetCapabilityType(flag); if (type == CapabilityType::Unset) { - return ResultInvalidArgument; + return ResultInvalidCapabilityDescriptor; } // Bail early on ignorable entries, as one would expect, @@ -202,7 +202,7 @@ ResultCode ProcessCapabilities::ParseSingleFlagCapability(u32& set_flags, u32& s } LOG_ERROR(Kernel, "Invalid capability type! type={}", type); - return ResultInvalidArgument; + return ResultInvalidCapabilityDescriptor; } void ProcessCapabilities::Clear() { @@ -225,7 +225,7 @@ ResultCode ProcessCapabilities::HandlePriorityCoreNumFlags(u32 flags) { if (priority_mask != 0 || core_mask != 0) { LOG_ERROR(Kernel, "Core or priority mask are not zero! priority_mask={}, core_mask={}", priority_mask, core_mask); - return ResultInvalidArgument; + return ResultInvalidCapabilityDescriptor; } const u32 core_num_min = (flags >> 16) & 0xFF; @@ -329,7 +329,7 @@ ResultCode ProcessCapabilities::HandleProgramTypeFlags(u32 flags) { const u32 reserved = flags >> 17; if (reserved != 0) { LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved); - return ResultReservedUsed; + return ResultReservedValue; } program_type = static_cast((flags >> 14) & 0b111); @@ -349,7 +349,7 @@ ResultCode ProcessCapabilities::HandleKernelVersionFlags(u32 flags) { LOG_ERROR(Kernel, "Kernel version is non zero or flags are too small! major_version={}, flags={}", major_version, flags); - return ResultInvalidArgument; + return ResultInvalidCapabilityDescriptor; } kernel_version = flags; @@ -360,7 +360,7 @@ ResultCode ProcessCapabilities::HandleHandleTableFlags(u32 flags) { const u32 reserved = flags >> 26; if (reserved != 0) { LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved); - return ResultReservedUsed; + return ResultReservedValue; } handle_table_size = static_cast((flags >> 16) & 0x3FF); @@ -371,7 +371,7 @@ ResultCode ProcessCapabilities::HandleDebugFlags(u32 flags) { const u32 reserved = flags >> 19; if (reserved != 0) { LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved); - return ResultReservedUsed; + return ResultReservedValue; } is_debuggable = (flags & 0x20000) != 0; diff --git a/src/core/hle/kernel/service_thread.cpp b/src/core/hle/kernel/service_thread.cpp index 04be8a502..ee46f3e21 100755 --- a/src/core/hle/kernel/service_thread.cpp +++ b/src/core/hle/kernel/service_thread.cpp @@ -13,8 +13,8 @@ #include "common/scope_exit.h" #include "common/thread.h" #include "core/core.h" -#include "core/hle/kernel/k_session.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/server_session.h" #include "core/hle/kernel/service_thread.h" #include "core/hle/lock.h" #include "video_core/renderer_base.h" @@ -26,7 +26,7 @@ public: explicit Impl(KernelCore& kernel, std::size_t num_threads, const std::string& name); ~Impl(); - void QueueSyncRequest(KSession& session, std::shared_ptr&& context); + void QueueSyncRequest(ServerSession& session, std::shared_ptr&& context); private: std::vector threads; @@ -69,27 +69,18 @@ ServiceThread::Impl::Impl(KernelCore& kernel, std::size_t num_threads, const std }); } -void ServiceThread::Impl::QueueSyncRequest(KSession& session, +void ServiceThread::Impl::QueueSyncRequest(ServerSession& session, std::shared_ptr&& context) { { std::unique_lock lock{queue_mutex}; - // Open a reference to the session to ensure it is not closes while the service request - // completes asynchronously. - session.Open(); - - requests.emplace([session_ptr{&session}, context{std::move(context)}]() { - // Close the reference. - SCOPE_EXIT({ session_ptr->Close(); }); - - // If the session has been closed, we are done. - if (session_ptr->IsServerClosed()) { - return; + // ServerSession owns the service thread, so we cannot caption a strong pointer here in the + // event that the ServerSession is terminated. + std::weak_ptr weak_ptr{SharedFrom(&session)}; + requests.emplace([weak_ptr, context{std::move(context)}]() { + if (auto strong_ptr = weak_ptr.lock()) { + strong_ptr->CompleteSyncRequest(*context); } - - // Complete the service request. - KScopedAutoObject server_session{&session_ptr->GetServerSession()}; - server_session->CompleteSyncRequest(*context); }); } condition.notify_one(); @@ -111,7 +102,7 @@ ServiceThread::ServiceThread(KernelCore& kernel, std::size_t num_threads, const ServiceThread::~ServiceThread() = default; -void ServiceThread::QueueSyncRequest(KSession& session, +void ServiceThread::QueueSyncRequest(ServerSession& session, std::shared_ptr&& context) { impl->QueueSyncRequest(session, std::move(context)); } diff --git a/src/core/hle/kernel/service_thread.h b/src/core/hle/kernel/service_thread.h index 6a7fd7c56..025ab8fb5 100755 --- a/src/core/hle/kernel/service_thread.h +++ b/src/core/hle/kernel/service_thread.h @@ -11,14 +11,14 @@ namespace Kernel { class HLERequestContext; class KernelCore; -class KSession; +class ServerSession; class ServiceThread final { public: explicit ServiceThread(KernelCore& kernel, std::size_t num_threads, const std::string& name); ~ServiceThread(); - void QueueSyncRequest(KSession& session, std::shared_ptr&& context); + void QueueSyncRequest(ServerSession& session, std::shared_ptr&& context); private: class Impl; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 52011be9c..bebb86154 100755 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -21,16 +21,15 @@ #include "core/core_timing.h" #include "core/core_timing_util.h" #include "core/cpu_manager.h" +#include "core/hle/kernel/client_port.h" +#include "core/hle/kernel/client_session.h" +#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/k_address_arbiter.h" -#include "core/hle/kernel/k_client_port.h" -#include "core/hle/kernel/k_client_session.h" #include "core/hle/kernel/k_condition_variable.h" #include "core/hle/kernel/k_event.h" -#include "core/hle/kernel/k_handle_table.h" #include "core/hle/kernel/k_memory_block.h" #include "core/hle/kernel/k_memory_layout.h" #include "core/hle/kernel/k_page_table.h" -#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_scheduler.h" @@ -39,15 +38,16 @@ #include "core/hle/kernel/k_shared_memory.h" #include "core/hle/kernel/k_synchronization_object.h" #include "core/hle/kernel/k_thread.h" -#include "core/hle/kernel/k_transfer_memory.h" #include "core/hle/kernel/k_writable_event.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/physical_core.h" +#include "core/hle/kernel/process.h" #include "core/hle/kernel/svc.h" #include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/svc_types.h" #include "core/hle/kernel/svc_wrap.h" #include "core/hle/kernel/time_manager.h" +#include "core/hle/kernel/transfer_memory.h" #include "core/hle/lock.h" #include "core/hle/result.h" #include "core/hle/service/service.h" @@ -113,7 +113,7 @@ ResultCode MapUnmapMemorySanityChecks(const KPageTable& manager, VAddr dst_addr, LOG_ERROR(Kernel_SVC, "Destination is not within the stack region, addr=0x{:016X}, size=0x{:016X}", dst_addr, size); - return ResultInvalidMemoryRegion; + return ResultInvalidMemoryRange; } if (manager.IsInsideHeapRegion(dst_addr, size)) { @@ -121,7 +121,7 @@ ResultCode MapUnmapMemorySanityChecks(const KPageTable& manager, VAddr dst_addr, "Destination does not fit within the heap region, addr=0x{:016X}, " "size=0x{:016X}", dst_addr, size); - return ResultInvalidMemoryRegion; + return ResultInvalidMemoryRange; } if (manager.IsInsideAliasRegion(dst_addr, size)) { @@ -129,7 +129,7 @@ ResultCode MapUnmapMemorySanityChecks(const KPageTable& manager, VAddr dst_addr, "Destination does not fit within the map region, addr=0x{:016X}, " "size=0x{:016X}", dst_addr, size); - return ResultInvalidMemoryRegion; + return ResultInvalidMemoryRange; } return RESULT_SUCCESS; @@ -141,6 +141,38 @@ enum class ResourceLimitValueType { PeakValue, }; +ResultVal RetrieveResourceLimitValue(Core::System& system, Handle resource_limit, + u32 resource_type, ResourceLimitValueType value_type) { + std::lock_guard lock{HLE::g_hle_lock}; + const auto type = static_cast(resource_type); + if (!IsValidResourceType(type)) { + LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); + return ResultInvalidEnumValue; + } + + const auto* const current_process = system.Kernel().CurrentProcess(); + ASSERT(current_process != nullptr); + + const auto resource_limit_object = + current_process->GetHandleTable().Get(resource_limit); + if (!resource_limit_object) { + LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", + resource_limit); + return ResultInvalidHandle; + } + + switch (value_type) { + case ResourceLimitValueType::CurrentValue: + return MakeResult(resource_limit_object->GetCurrentValue(type)); + case ResourceLimitValueType::LimitValue: + return MakeResult(resource_limit_object->GetLimitValue(type)); + case ResourceLimitValueType::PeakValue: + return MakeResult(resource_limit_object->GetPeakValue(type)); + default: + LOG_ERROR(Kernel_SVC, "Invalid resource value_type: '{}'", value_type); + return ResultInvalidEnumValue; + } +} } // Anonymous namespace /// Set the process heap to a given Size. It can both extend and shrink the heap. @@ -259,8 +291,11 @@ static ResultCode UnmapMemory32(Core::System& system, u32 dst_addr, u32 src_addr } /// Connect to an OS service given the port name, returns the handle to the port to out -static ResultCode ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_address) { +static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, + VAddr port_name_address) { + std::lock_guard lock{HLE::g_hle_lock}; auto& memory = system.Memory(); + if (!memory.IsValidVirtualAddress(port_name_address)) { LOG_ERROR(Kernel_SVC, "Port Name Address is not a valid virtual address, port_name_address=0x{:016X}", @@ -279,33 +314,21 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out, VAddr po LOG_TRACE(Kernel_SVC, "called port_name={}", port_name); - // Get the current handle table. auto& kernel = system.Kernel(); - auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); - - // Find the client port. const auto it = kernel.FindNamedPort(port_name); if (!kernel.IsValidNamedPort(it)) { LOG_WARNING(Kernel_SVC, "tried to connect to unknown port: {}", port_name); return ResultNotFound; } - auto port = it->second; - // Reserve a handle for the port. - // NOTE: Nintendo really does write directly to the output handle here. - R_TRY(handle_table.Reserve(out)); - auto handle_guard = SCOPE_GUARD({ handle_table.Unreserve(*out); }); + auto client_port = it->second; - // Create a session. - KClientSession* session{}; - R_TRY(port->CreateSession(std::addressof(session))); + std::shared_ptr client_session; + CASCADE_RESULT(client_session, client_port->Connect()); - // Register the session in the table, close the extra reference. - handle_table.Register(*out, session); - session->Close(); - - // We succeeded. - handle_guard.Cancel(); + // Return the client session + auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); + CASCADE_RESULT(*out_handle, handle_table.Create(client_session)); return RESULT_SUCCESS; } @@ -317,12 +340,14 @@ static ResultCode ConnectToNamedPort32(Core::System& system, Handle* out_handle, /// Makes a blocking IPC call to an OS service. static ResultCode SendSyncRequest(Core::System& system, Handle handle) { - auto& kernel = system.Kernel(); + const auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); + std::shared_ptr session = handle_table.Get(handle); + if (!session) { + LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle); + return ResultInvalidHandle; + } - KScopedAutoObject session = - kernel.CurrentProcess()->GetHandleTable().GetObject(handle); - R_UNLESS(session.IsNotNull(), ResultInvalidHandle); LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); auto thread = kernel.CurrentScheduler()->GetCurrentThread(); @@ -330,7 +355,7 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) { KScopedSchedulerLock lock(kernel); thread->SetState(ThreadState::Waiting); thread->SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC); - session->SendSyncRequest(thread, system.Memory(), system.CoreTiming()); + session->SendSyncRequest(SharedFrom(thread), system.Memory(), system.CoreTiming()); } KSynchronizationObject* dummy{}; @@ -343,13 +368,18 @@ static ResultCode SendSyncRequest32(Core::System& system, Handle handle) { /// Get the ID for the specified thread. static ResultCode GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle) { + LOG_TRACE(Kernel_SVC, "called thread=0x{:08X}", thread_handle); + // Get the thread from its handle. - KScopedAutoObject thread = - system.Kernel().CurrentProcess()->GetHandleTable().GetObject(thread_handle); - R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); + const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); + const std::shared_ptr thread = handle_table.Get(thread_handle); + if (!thread) { + LOG_ERROR(Kernel_SVC, "Invalid thread handle provided (handle={:08X})", thread_handle); + return ResultInvalidHandle; + } // Get the thread's id. - *out_thread_id = thread->GetId(); + *out_thread_id = thread->GetThreadID(); return RESULT_SUCCESS; } @@ -365,101 +395,110 @@ static ResultCode GetThreadId32(Core::System& system, u32* out_thread_id_low, } /// Gets the ID of the specified process or a specified thread's owning process. -static ResultCode GetProcessId(Core::System& system, u64* out_process_id, Handle handle) { +static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle handle) { LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle); - // Get the object from the handle table. - KScopedAutoObject obj = - system.Kernel().CurrentProcess()->GetHandleTable().GetObject( - static_cast(handle)); - R_UNLESS(obj.IsNotNull(), ResultInvalidHandle); - - // Get the process from the object. - KProcess* process = nullptr; - if (KProcess* p = obj->DynamicCast(); p != nullptr) { - // The object is a process, so we can use it directly. - process = p; - } else if (KThread* t = obj->DynamicCast(); t != nullptr) { - // The object is a thread, so we want to use its parent. - process = reinterpret_cast(obj.GetPointerUnsafe())->GetOwnerProcess(); - } else { - // TODO(bunnei): This should also handle debug objects before returning. - UNIMPLEMENTED_MSG("Debug objects not implemented"); + const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); + const std::shared_ptr process = handle_table.Get(handle); + if (process) { + *process_id = process->GetProcessID(); + return RESULT_SUCCESS; } - // Make sure the target process exists. - R_UNLESS(process != nullptr, ResultInvalidHandle); + const std::shared_ptr thread = handle_table.Get(handle); + if (thread) { + const Process* const owner_process = thread->GetOwnerProcess(); + if (!owner_process) { + LOG_ERROR(Kernel_SVC, "Non-existent owning process encountered."); + return ResultInvalidHandle; + } - // Get the process id. - *out_process_id = process->GetId(); + *process_id = owner_process->GetProcessID(); + return RESULT_SUCCESS; + } + // NOTE: This should also handle debug objects before returning. + + LOG_ERROR(Kernel_SVC, "Handle does not exist, handle=0x{:08X}", handle); return ResultInvalidHandle; } -static ResultCode GetProcessId32(Core::System& system, u32* out_process_id_low, - u32* out_process_id_high, Handle handle) { - u64 out_process_id{}; - const auto result = GetProcessId(system, &out_process_id, handle); - *out_process_id_low = static_cast(out_process_id); - *out_process_id_high = static_cast(out_process_id >> 32); +static ResultCode GetProcessId32(Core::System& system, u32* process_id_low, u32* process_id_high, + Handle handle) { + u64 process_id{}; + const auto result = GetProcessId(system, &process_id, handle); + *process_id_low = static_cast(process_id); + *process_id_high = static_cast(process_id >> 32); return result; } /// Wait for the given handles to synchronize, timeout after the specified nanoseconds static ResultCode WaitSynchronization(Core::System& system, s32* index, VAddr handles_address, - u64 num_handles, s64 nano_seconds) { - LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, num_handles={}, nano_seconds={}", - handles_address, num_handles, nano_seconds); + u64 handle_count, s64 nano_seconds) { + LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}", + handles_address, handle_count, nano_seconds); - // Ensure number of handles is valid. - R_UNLESS(0 <= num_handles && num_handles <= ArgumentHandleCountMax, ResultOutOfRange); - - auto& kernel = system.Kernel(); - std::vector objs(num_handles); - const auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); - Handle* handles = system.Memory().GetPointer(handles_address); - - // Copy user handles. - if (num_handles > 0) { - // Convert the handles to objects. - R_UNLESS(handle_table.GetMultipleObjects(objs.data(), handles, - num_handles), - ResultInvalidHandle); + auto& memory = system.Memory(); + if (!memory.IsValidVirtualAddress(handles_address)) { + LOG_ERROR(Kernel_SVC, + "Handle address is not a valid virtual address, handle_address=0x{:016X}", + handles_address); + return ResultInvalidPointer; } - // Ensure handles are closed when we're done. - SCOPE_EXIT({ - for (u64 i = 0; i < num_handles; ++i) { - objs[i]->Close(); - } - }); + static constexpr u64 MaxHandles = 0x40; - return KSynchronizationObject::Wait(kernel, index, objs.data(), static_cast(objs.size()), - nano_seconds); + if (handle_count > MaxHandles) { + LOG_ERROR(Kernel_SVC, "Handle count specified is too large, expected {} but got {}", + MaxHandles, handle_count); + return ResultOutOfRange; + } + + auto& kernel = system.Kernel(); + std::vector objects(handle_count); + const auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); + + for (u64 i = 0; i < handle_count; ++i) { + const Handle handle = memory.Read32(handles_address + i * sizeof(Handle)); + const auto object = handle_table.Get(handle); + + if (object == nullptr) { + LOG_ERROR(Kernel_SVC, "Object is a nullptr"); + return ResultInvalidHandle; + } + + objects[i] = object.get(); + } + return KSynchronizationObject::Wait(kernel, index, objects.data(), + static_cast(objects.size()), nano_seconds); } static ResultCode WaitSynchronization32(Core::System& system, u32 timeout_low, u32 handles_address, - s32 num_handles, u32 timeout_high, s32* index) { + s32 handle_count, u32 timeout_high, s32* index) { const s64 nano_seconds{(static_cast(timeout_high) << 32) | static_cast(timeout_low)}; - return WaitSynchronization(system, index, handles_address, num_handles, nano_seconds); + return WaitSynchronization(system, index, handles_address, handle_count, nano_seconds); } /// Resumes a thread waiting on WaitSynchronization -static ResultCode CancelSynchronization(Core::System& system, Handle handle) { - LOG_TRACE(Kernel_SVC, "called handle=0x{:X}", handle); +static ResultCode CancelSynchronization(Core::System& system, Handle thread_handle) { + LOG_TRACE(Kernel_SVC, "called thread=0x{:X}", thread_handle); // Get the thread from its handle. - KScopedAutoObject thread = - system.Kernel().CurrentProcess()->GetHandleTable().GetObject( - static_cast(handle)); + const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); + std::shared_ptr thread = handle_table.Get(thread_handle); + + if (!thread) { + LOG_ERROR(Kernel_SVC, "Invalid thread handle provided (handle={:08X})", thread_handle); + return ResultInvalidHandle; + } // Cancel the thread's wait. thread->WaitCancel(); return RESULT_SUCCESS; } -static ResultCode CancelSynchronization32(Core::System& system, Handle handle) { - return CancelSynchronization(system, handle); +static ResultCode CancelSynchronization32(Core::System& system, Handle thread_handle) { + return CancelSynchronization(system, thread_handle); } /// Attempts to locks a mutex @@ -639,7 +678,7 @@ static void OutputDebugString(Core::System& system, VAddr address, u64 len) { } /// Gets system/memory information for the current process -static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle handle, +static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, u64 handle, u64 info_sub_id) { std::lock_guard lock{HLE::g_hle_lock}; LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, @@ -705,9 +744,10 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle return ResultInvalidEnumValue; } - const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); - KScopedAutoObject process = handle_table.GetObject(handle); - if (process.IsNull()) { + const auto& current_process_handle_table = + system.Kernel().CurrentProcess()->GetHandleTable(); + const auto process = current_process_handle_table.Get(static_cast(handle)); + if (!process) { LOG_ERROR(Kernel_SVC, "Process is not valid! info_id={}, info_sub_id={}, handle={:08X}", info_id, info_sub_id, handle); return ResultInvalidHandle; @@ -811,19 +851,21 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle return ResultInvalidCombination; } - KProcess* const current_process = system.Kernel().CurrentProcess(); - KHandleTable& handle_table = current_process->GetHandleTable(); + Process* const current_process = system.Kernel().CurrentProcess(); + HandleTable& handle_table = current_process->GetHandleTable(); const auto resource_limit = current_process->GetResourceLimit(); if (!resource_limit) { - *result = Svc::InvalidHandle; + *result = KernelHandle::InvalidHandle; // Yes, the kernel considers this a successful operation. return RESULT_SUCCESS; } - Handle handle{}; - R_TRY(handle_table.Add(&handle, resource_limit)); + const auto table_result = handle_table.Create(resource_limit); + if (table_result.Failed()) { + return table_result.Code(); + } - *result = handle; + *result = *table_result; return RESULT_SUCCESS; } @@ -834,9 +876,9 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle return ResultInvalidHandle; } - if (info_sub_id >= KProcess::RANDOM_ENTROPY_SIZE) { + if (info_sub_id >= Process::RANDOM_ENTROPY_SIZE) { LOG_ERROR(Kernel_SVC, "Entropy size is out of range, expected {} but got {}", - KProcess::RANDOM_ENTROPY_SIZE, info_sub_id); + Process::RANDOM_ENTROPY_SIZE, info_sub_id); return ResultInvalidCombination; } @@ -857,10 +899,9 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle return ResultInvalidCombination; } - KScopedAutoObject thread = - system.Kernel().CurrentProcess()->GetHandleTable().GetObject( - static_cast(handle)); - if (thread.IsNull()) { + const auto thread = system.Kernel().CurrentProcess()->GetHandleTable().Get( + static_cast(handle)); + if (!thread) { LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}", static_cast(handle)); return ResultInvalidHandle; @@ -869,7 +910,7 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle const auto& core_timing = system.CoreTiming(); const auto& scheduler = *system.Kernel().CurrentScheduler(); const auto* const current_thread = scheduler.GetCurrentThread(); - const bool same_thread = current_thread == thread.GetPointerUnsafe(); + const bool same_thread = current_thread == thread.get(); const u64 prev_ctx_ticks = scheduler.GetLastContextSwitchTicks(); u64 out_ticks = 0; @@ -925,10 +966,10 @@ static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) if (!(addr < addr + size)) { LOG_ERROR(Kernel_SVC, "Size causes 64-bit overflow of address"); - return ResultInvalidMemoryRegion; + return ResultInvalidMemoryRange; } - KProcess* const current_process{system.Kernel().CurrentProcess()}; + Process* const current_process{system.Kernel().CurrentProcess()}; auto& page_table{current_process->PageTable()}; if (current_process->GetSystemResourceSize() == 0) { @@ -940,14 +981,14 @@ static ResultCode MapPhysicalMemory(Core::System& system, VAddr addr, u64 size) LOG_ERROR(Kernel_SVC, "Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr, size); - return ResultInvalidMemoryRegion; + return ResultInvalidMemoryRange; } if (page_table.IsOutsideAliasRegion(addr, size)) { LOG_ERROR(Kernel_SVC, "Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr, size); - return ResultInvalidMemoryRegion; + return ResultInvalidMemoryRange; } return page_table.MapPhysicalMemory(addr, size); @@ -979,10 +1020,10 @@ static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size if (!(addr < addr + size)) { LOG_ERROR(Kernel_SVC, "Size causes 64-bit overflow of address"); - return ResultInvalidMemoryRegion; + return ResultInvalidMemoryRange; } - KProcess* const current_process{system.Kernel().CurrentProcess()}; + Process* const current_process{system.Kernel().CurrentProcess()}; auto& page_table{current_process->PageTable()}; if (current_process->GetSystemResourceSize() == 0) { @@ -994,14 +1035,14 @@ static ResultCode UnmapPhysicalMemory(Core::System& system, VAddr addr, u64 size LOG_ERROR(Kernel_SVC, "Address is not within the address space, addr=0x{:016X}, size=0x{:016X}", addr, size); - return ResultInvalidMemoryRegion; + return ResultInvalidMemoryRange; } if (page_table.IsOutsideAliasRegion(addr, size)) { LOG_ERROR(Kernel_SVC, "Address is not within the alias region, addr=0x{:016X}, size=0x{:016X}", addr, size); - return ResultInvalidMemoryRegion; + return ResultInvalidMemoryRange; } return page_table.UnmapPhysicalMemory(addr, size); @@ -1021,19 +1062,37 @@ static ResultCode SetThreadActivity(Core::System& system, Handle thread_handle, constexpr auto IsValidThreadActivity = [](ThreadActivity activity) { return activity == ThreadActivity::Runnable || activity == ThreadActivity::Paused; }; - R_UNLESS(IsValidThreadActivity(thread_activity), ResultInvalidEnumValue); + if (!IsValidThreadActivity(thread_activity)) { + LOG_ERROR(Kernel_SVC, "Invalid thread activity value provided (activity={})", + thread_activity); + return ResultInvalidEnumValue; + } // Get the thread from its handle. - KScopedAutoObject thread = - system.Kernel().CurrentProcess()->GetHandleTable().GetObject(thread_handle); - R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); + auto& kernel = system.Kernel(); + const auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); + const std::shared_ptr thread = handle_table.Get(thread_handle); + if (!thread) { + LOG_ERROR(Kernel_SVC, "Invalid thread handle provided (handle={:08X})", thread_handle); + return ResultInvalidHandle; + } // Check that the activity is being set on a non-current thread for the current process. - R_UNLESS(thread->GetOwnerProcess() == system.Kernel().CurrentProcess(), ResultInvalidHandle); - R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(system.Kernel()), ResultBusy); + if (thread->GetOwnerProcess() != kernel.CurrentProcess()) { + LOG_ERROR(Kernel_SVC, "Invalid owning process for the created thread."); + return ResultInvalidHandle; + } + if (thread.get() == GetCurrentThreadPointer(kernel)) { + LOG_ERROR(Kernel_SVC, "Thread is busy"); + return ResultBusy; + } // Set the activity. - R_TRY(thread->SetActivity(thread_activity)); + const auto set_result = thread->SetActivity(thread_activity); + if (set_result.IsError()) { + LOG_ERROR(Kernel_SVC, "Failed to set thread activity."); + return set_result; + } return RESULT_SUCCESS; } @@ -1048,55 +1107,36 @@ static ResultCode GetThreadContext(Core::System& system, VAddr out_context, Hand LOG_DEBUG(Kernel_SVC, "called, out_context=0x{:08X}, thread_handle=0x{:X}", out_context, thread_handle); - auto& kernel = system.Kernel(); - // Get the thread from its handle. - KScopedAutoObject thread = - kernel.CurrentProcess()->GetHandleTable().GetObject(thread_handle); - R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); + const auto* current_process = system.Kernel().CurrentProcess(); + const std::shared_ptr thread = + current_process->GetHandleTable().Get(thread_handle); + if (!thread) { + LOG_ERROR(Kernel_SVC, "Invalid thread handle provided (handle={})", thread_handle); + return ResultInvalidHandle; + } // Require the handle be to a non-current thread in the current process. - const auto* current_process = kernel.CurrentProcess(); - R_UNLESS(current_process == thread->GetOwnerProcess(), ResultInvalidId); - - // Verify that the thread isn't terminated. - R_UNLESS(thread->GetState() != ThreadState::Terminated, ResultTerminationRequested); - - /// Check that the thread is not the current one. - /// NOTE: Nintendo does not check this, and thus the following loop will deadlock. - R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(kernel), ResultInvalidId); - - // Try to get the thread context until the thread isn't current on any core. - while (true) { - KScopedSchedulerLock sl{kernel}; - - // TODO(bunnei): Enforce that thread is suspended for debug here. - - // If the thread's raw state isn't runnable, check if it's current on some core. - if (thread->GetRawState() != ThreadState::Runnable) { - bool current = false; - for (auto i = 0; i < static_cast(Core::Hardware::NUM_CPU_CORES); ++i) { - if (thread.GetPointerUnsafe() == kernel.Scheduler(i).GetCurrentThread()) { - current = true; - } - break; - } - - // If the thread is current, retry until it isn't. - if (current) { - continue; - } - } - - // Get the thread context. - std::vector context; - R_TRY(thread->GetThreadContext3(context)); - - // Copy the thread context to user space. - system.Memory().WriteBlock(out_context, context.data(), context.size()); - - return RESULT_SUCCESS; + if (thread->GetOwnerProcess() != current_process) { + LOG_ERROR(Kernel_SVC, "Thread owning process is not the current process."); + return ResultInvalidHandle; } + if (thread.get() == system.Kernel().CurrentScheduler()->GetCurrentThread()) { + LOG_ERROR(Kernel_SVC, "Current thread is busy."); + return ResultBusy; + } + + // Get the thread context. + std::vector context; + const auto context_result = thread->GetThreadContext3(context); + if (context_result.IsError()) { + LOG_ERROR(Kernel_SVC, "Unable to successfully retrieve thread context (result: {})", + context_result.raw); + return context_result; + } + + // Copy the thread context to user space. + system.Memory().WriteBlock(out_context, context.data(), context.size()); return RESULT_SUCCESS; } @@ -1110,9 +1150,12 @@ static ResultCode GetThreadPriority(Core::System& system, u32* out_priority, Han LOG_TRACE(Kernel_SVC, "called"); // Get the thread from its handle. - KScopedAutoObject thread = - system.Kernel().CurrentProcess()->GetHandleTable().GetObject(handle); - R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); + const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); + const std::shared_ptr thread = handle_table.Get(handle); + if (!thread) { + LOG_ERROR(Kernel_SVC, "Invalid thread handle provided (handle={:08X})", handle); + return ResultInvalidHandle; + } // Get the thread's priority. *out_priority = thread->GetPriority(); @@ -1124,26 +1167,30 @@ static ResultCode GetThreadPriority32(Core::System& system, u32* out_priority, H } /// Sets the priority for the specified thread -static ResultCode SetThreadPriority(Core::System& system, Handle thread_handle, u32 priority) { - // Get the current process. - KProcess& process = *system.Kernel().CurrentProcess(); +static ResultCode SetThreadPriority(Core::System& system, Handle handle, u32 priority) { + LOG_TRACE(Kernel_SVC, "called"); // Validate the priority. - R_UNLESS(HighestThreadPriority <= priority && priority <= LowestThreadPriority, - ResultInvalidPriority); - R_UNLESS(process.CheckThreadPriority(priority), ResultInvalidPriority); + if (HighestThreadPriority > priority || priority > LowestThreadPriority) { + LOG_ERROR(Kernel_SVC, "Invalid thread priority specified (priority={})", priority); + return ResultInvalidPriority; + } // Get the thread from its handle. - KScopedAutoObject thread = process.GetHandleTable().GetObject(thread_handle); - R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); + const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); + const std::shared_ptr thread = handle_table.Get(handle); + if (!thread) { + LOG_ERROR(Kernel_SVC, "Invalid handle provided (handle={:08X})", handle); + return ResultInvalidHandle; + } // Set the thread priority. thread->SetBasePriority(priority); return RESULT_SUCCESS; } -static ResultCode SetThreadPriority32(Core::System& system, Handle thread_handle, u32 priority) { - return SetThreadPriority(system, thread_handle, priority); +static ResultCode SetThreadPriority32(Core::System& system, Handle handle, u32 priority) { + return SetThreadPriority(system, handle, priority); } /// Get which CPU core is executing the current thread @@ -1156,97 +1203,82 @@ static u32 GetCurrentProcessorNumber32(Core::System& system) { return GetCurrentProcessorNumber(system); } -constexpr bool IsValidSharedMemoryPermission(Svc::MemoryPermission perm) { - switch (perm) { - case Svc::MemoryPermission::Read: - case Svc::MemoryPermission::ReadWrite: - return true; - default: - return false; - } -} - -constexpr bool IsValidRemoteSharedMemoryPermission(Svc::MemoryPermission perm) { - return IsValidSharedMemoryPermission(perm) || perm == Svc::MemoryPermission::DontCare; -} - -static ResultCode MapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, - u64 size, Svc::MemoryPermission map_perm) { +static ResultCode MapSharedMemory(Core::System& system, Handle shared_memory_handle, VAddr addr, + u64 size, u32 permissions) { + std::lock_guard lock{HLE::g_hle_lock}; LOG_TRACE(Kernel_SVC, "called, shared_memory_handle=0x{:X}, addr=0x{:X}, size=0x{:X}, permissions=0x{:08X}", - shmem_handle, address, size, map_perm); + shared_memory_handle, addr, size, permissions); - // Validate the address/size. - R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress); - R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); - R_UNLESS(size > 0, ResultInvalidSize); - R_UNLESS((address < address + size), ResultInvalidCurrentMemory); + if (!Common::Is4KBAligned(addr)) { + LOG_ERROR(Kernel_SVC, "Address is not aligned to 4KB, addr=0x{:016X}", addr); + return ResultInvalidAddress; + } - // Validate the permission. - R_UNLESS(IsValidSharedMemoryPermission(map_perm), ResultInvalidNewMemoryPermission); + if (size == 0) { + LOG_ERROR(Kernel_SVC, "Size is 0"); + return ResultInvalidSize; + } - // Get the current process. - auto& process = *system.Kernel().CurrentProcess(); - auto& page_table = process.PageTable(); + if (!Common::Is4KBAligned(size)) { + LOG_ERROR(Kernel_SVC, "Size is not aligned to 4KB, size=0x{:016X}", size); + return ResultInvalidSize; + } - // Get the shared memory. - KScopedAutoObject shmem = process.GetHandleTable().GetObject(shmem_handle); - R_UNLESS(shmem.IsNotNull(), ResultInvalidHandle); + if (!IsValidAddressRange(addr, size)) { + LOG_ERROR(Kernel_SVC, "Region is not a valid address range, addr=0x{:016X}, size=0x{:016X}", + addr, size); + return ResultInvalidCurrentMemory; + } - // Verify that the mapping is in range. - R_UNLESS(page_table.CanContain(address, size, KMemoryState::Shared), ResultInvalidMemoryRegion); + const auto permission_type = static_cast(permissions); + if ((permission_type | MemoryPermission::Write) != MemoryPermission::ReadWrite) { + LOG_ERROR(Kernel_SVC, "Expected Read or ReadWrite permission but got permissions=0x{:08X}", + permissions); + return ResultInvalidMemoryPermissions; + } - // Add the shared memory to the process. - R_TRY(process.AddSharedMemory(shmem.GetPointerUnsafe(), address, size)); + auto* const current_process{system.Kernel().CurrentProcess()}; + auto& page_table{current_process->PageTable()}; - // Ensure that we clean up the shared memory if we fail to map it. - auto guard = - SCOPE_GUARD({ process.RemoveSharedMemory(shmem.GetPointerUnsafe(), address, size); }); + if (page_table.IsInvalidRegion(addr, size)) { + LOG_ERROR(Kernel_SVC, + "Addr does not fit within the valid region, addr=0x{:016X}, " + "size=0x{:016X}", + addr, size); + return ResultInvalidMemoryRange; + } - // Map the shared memory. - R_TRY(shmem->Map(process, address, size, map_perm)); + if (page_table.IsInsideHeapRegion(addr, size)) { + LOG_ERROR(Kernel_SVC, + "Addr does not fit within the heap region, addr=0x{:016X}, " + "size=0x{:016X}", + addr, size); + return ResultInvalidMemoryRange; + } - // We succeeded. - guard.Cancel(); - return RESULT_SUCCESS; + if (page_table.IsInsideAliasRegion(addr, size)) { + LOG_ERROR(Kernel_SVC, + "Address does not fit within the map region, addr=0x{:016X}, " + "size=0x{:016X}", + addr, size); + return ResultInvalidMemoryRange; + } + + auto shared_memory{current_process->GetHandleTable().Get(shared_memory_handle)}; + if (!shared_memory) { + LOG_ERROR(Kernel_SVC, "Shared memory does not exist, shared_memory_handle=0x{:08X}", + shared_memory_handle); + return ResultInvalidHandle; + } + + return shared_memory->Map(*current_process, addr, size, + static_cast(permission_type)); } -static ResultCode MapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, - u32 size, Svc::MemoryPermission map_perm) { - return MapSharedMemory(system, shmem_handle, address, size, map_perm); -} - -static ResultCode UnmapSharedMemory(Core::System& system, Handle shmem_handle, VAddr address, - u64 size) { - // Validate the address/size. - R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress); - R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); - R_UNLESS(size > 0, ResultInvalidSize); - R_UNLESS((address < address + size), ResultInvalidCurrentMemory); - - // Get the current process. - auto& process = *system.Kernel().CurrentProcess(); - auto& page_table = process.PageTable(); - - // Get the shared memory. - KScopedAutoObject shmem = process.GetHandleTable().GetObject(shmem_handle); - R_UNLESS(shmem.IsNotNull(), ResultInvalidHandle); - - // Verify that the mapping is in range. - R_UNLESS(page_table.CanContain(address, size, KMemoryState::Shared), ResultInvalidMemoryRegion); - - // Unmap the shared memory. - R_TRY(shmem->Unmap(process, address, size)); - - // Remove the shared memory from the process. - process.RemoveSharedMemory(shmem.GetPointerUnsafe(), address, size); - - return RESULT_SUCCESS; -} - -static ResultCode UnmapSharedMemory32(Core::System& system, Handle shmem_handle, u32 address, - u32 size) { - return UnmapSharedMemory(system, shmem_handle, address, size); +static ResultCode MapSharedMemory32(Core::System& system, Handle shared_memory_handle, u32 addr, + u32 size, u32 permissions) { + return MapSharedMemory(system, shared_memory_handle, addr, size, permissions); } static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_address, @@ -1255,8 +1287,8 @@ static ResultCode QueryProcessMemory(Core::System& system, VAddr memory_info_add std::lock_guard lock{HLE::g_hle_lock}; LOG_TRACE(Kernel_SVC, "called process=0x{:08X} address={:X}", process_handle, address); const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); - KScopedAutoObject process = handle_table.GetObject(process_handle); - if (process.IsNull()) { + std::shared_ptr process = handle_table.Get(process_handle); + if (!process) { LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}", process_handle); return ResultInvalidHandle; @@ -1337,8 +1369,8 @@ static ResultCode MapProcessCodeMemory(Core::System& system, Handle process_hand } const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); - KScopedAutoObject process = handle_table.GetObject(process_handle); - if (process.IsNull()) { + auto process = handle_table.Get(process_handle); + if (!process) { LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).", process_handle); return ResultInvalidHandle; @@ -1358,7 +1390,7 @@ static ResultCode MapProcessCodeMemory(Core::System& system, Handle process_hand "Destination address range is not within the ASLR region (dst_address=0x{:016X}, " "size=0x{:016X}).", dst_address, size); - return ResultInvalidMemoryRegion; + return ResultInvalidMemoryRange; } return page_table.MapProcessCodeMemory(dst_address, src_address, size); @@ -1405,8 +1437,8 @@ static ResultCode UnmapProcessCodeMemory(Core::System& system, Handle process_ha } const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); - KScopedAutoObject process = handle_table.GetObject(process_handle); - if (process.IsNull()) { + auto process = handle_table.Get(process_handle); + if (!process) { LOG_ERROR(Kernel_SVC, "Invalid process handle specified (handle=0x{:08X}).", process_handle); return ResultInvalidHandle; @@ -1426,7 +1458,7 @@ static ResultCode UnmapProcessCodeMemory(Core::System& system, Handle process_ha "Destination address range is not within the ASLR region (dst_address=0x{:016X}, " "size=0x{:016X}).", dst_address, size); - return ResultInvalidMemoryRegion; + return ResultInvalidMemoryRange; } return page_table.UnmapProcessCodeMemory(dst_address, src_address, size); @@ -1451,7 +1483,7 @@ static void ExitProcess32(Core::System& system) { ExitProcess(system); } -static constexpr bool IsValidVirtualCoreId(int32_t core_id) { +static constexpr bool IsValidCoreId(int32_t core_id) { return (0 <= core_id && core_id < static_cast(Core::Hardware::NUM_CPU_CORES)); } @@ -1471,7 +1503,7 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e } // Validate arguments. - if (!IsValidVirtualCoreId(core_id)) { + if (!IsValidCoreId(core_id)) { LOG_ERROR(Kernel_SVC, "Invalid Core ID specified (id={})", core_id); return ResultInvalidCoreId; } @@ -1489,42 +1521,35 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e return ResultInvalidPriority; } - // Reserve a new thread from the process resource limit (waiting up to 100ms). KScopedResourceReservation thread_reservation( kernel.CurrentProcess(), LimitableResource::Threads, 1, system.CoreTiming().GetGlobalTimeNs().count() + 100000000); if (!thread_reservation.Succeeded()) { LOG_ERROR(Kernel_SVC, "Could not reserve a new thread"); - return ResultLimitReached; + return ResultResourceLimitedExceeded; } - // Create the thread. - KThread* thread = KThread::Create(kernel); - if (!thread) { - LOG_ERROR(Kernel_SVC, "Unable to create new threads. Thread creation limit reached."); - return ResultOutOfResource; - } - SCOPE_EXIT({ thread->Close(); }); - - // Initialize the thread. + std::shared_ptr thread; { KScopedLightLock lk{process.GetStateLock()}; - R_TRY(KThread::InitializeUserThread(system, thread, entry_point, arg, stack_bottom, - priority, core_id, &process)); + CASCADE_RESULT(thread, + KThread::CreateUserThread(system, ThreadType::User, "", entry_point, + priority, arg, core_id, stack_bottom, &process)); } + const auto new_thread_handle = process.GetHandleTable().Create(thread); + if (new_thread_handle.Failed()) { + LOG_ERROR(Kernel_SVC, "Failed to create handle with error=0x{:X}", + new_thread_handle.Code().raw); + return new_thread_handle.Code(); + } + *out_handle = *new_thread_handle; + // Set the thread name for debugging purposes. - thread->SetName(fmt::format("thread[entry_point={:X}, handle={:X}]", entry_point, *out_handle)); - - // Commit the thread reservation. + thread->SetName( + fmt::format("thread[entry_point={:X}, handle={:X}]", entry_point, *new_thread_handle)); thread_reservation.Commit(); - // Register the new thread. - KThread::Register(kernel, thread); - - // Add the thread to the handle table. - R_TRY(process.GetHandleTable().Add(out_handle, thread)); - return RESULT_SUCCESS; } @@ -1538,15 +1563,21 @@ static ResultCode StartThread(Core::System& system, Handle thread_handle) { LOG_DEBUG(Kernel_SVC, "called thread=0x{:08X}", thread_handle); // Get the thread from its handle. - KScopedAutoObject thread = - system.Kernel().CurrentProcess()->GetHandleTable().GetObject(thread_handle); - R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); + const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); + const std::shared_ptr thread = handle_table.Get(thread_handle); + if (!thread) { + LOG_ERROR(Kernel_SVC, "Invalid thread handle provided (handle={:08X})", thread_handle); + return ResultInvalidHandle; + } // Try to start the thread. - R_TRY(thread->Run()); - - // If we succeeded, persist a reference to the thread. - thread->Open(); + const auto run_result = thread->Run(); + if (run_result.IsError()) { + LOG_ERROR(Kernel_SVC, + "Unable to successfuly start thread (thread handle={:08X}, result={})", + thread_handle, run_result.raw); + return run_result; + } return RESULT_SUCCESS; } @@ -1560,7 +1591,7 @@ static void ExitThread(Core::System& system) { LOG_DEBUG(Kernel_SVC, "called, pc=0x{:08X}", system.CurrentArmInterface().GetPC()); auto* const current_thread = system.Kernel().CurrentScheduler()->GetCurrentThread(); - system.GlobalSchedulerContext().RemoveThread(current_thread); + system.GlobalSchedulerContext().RemoveThread(SharedFrom(current_thread)); current_thread->Exit(); } @@ -1793,11 +1824,8 @@ static void GetSystemTick32(Core::System& system, u32* time_low, u32* time_high) static ResultCode CloseHandle(Core::System& system, Handle handle) { LOG_TRACE(Kernel_SVC, "Closing handle 0x{:08X}", handle); - // Remove the handle. - R_UNLESS(system.Kernel().CurrentProcess()->GetHandleTable().Remove(handle), - ResultInvalidHandle); - - return RESULT_SUCCESS; + auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); + return handle_table.Close(handle); } static ResultCode CloseHandle32(Core::System& system, Handle handle) { @@ -1813,16 +1841,16 @@ static ResultCode ResetSignal(Core::System& system, Handle handle) { // Try to reset as readable event. { - KScopedAutoObject readable_event = handle_table.GetObject(handle); - if (readable_event.IsNotNull()) { + auto readable_event = handle_table.Get(handle); + if (readable_event) { return readable_event->Reset(); } } // Try to reset as process. { - KScopedAutoObject process = handle_table.GetObject(handle); - if (process.IsNotNull()) { + auto process = handle_table.Get(handle); + if (process) { return process->Reset(); } } @@ -1836,68 +1864,65 @@ static ResultCode ResetSignal32(Core::System& system, Handle handle) { return ResetSignal(system, handle); } -static constexpr bool IsValidTransferMemoryPermission(MemoryPermission perm) { - switch (perm) { - case MemoryPermission::None: - case MemoryPermission::Read: - case MemoryPermission::ReadWrite: - return true; - default: - return false; - } -} - /// Creates a TransferMemory object -static ResultCode CreateTransferMemory(Core::System& system, Handle* out, VAddr address, u64 size, - MemoryPermission map_perm) { +static ResultCode CreateTransferMemory(Core::System& system, Handle* handle, VAddr addr, u64 size, + u32 permissions) { + std::lock_guard lock{HLE::g_hle_lock}; + LOG_DEBUG(Kernel_SVC, "called addr=0x{:X}, size=0x{:X}, perms=0x{:08X}", addr, size, + permissions); + + if (!Common::Is4KBAligned(addr)) { + LOG_ERROR(Kernel_SVC, "Address ({:016X}) is not page aligned!", addr); + return ResultInvalidAddress; + } + + if (!Common::Is4KBAligned(size) || size == 0) { + LOG_ERROR(Kernel_SVC, "Size ({:016X}) is not page aligned or equal to zero!", size); + return ResultInvalidAddress; + } + + if (!IsValidAddressRange(addr, size)) { + LOG_ERROR(Kernel_SVC, "Address and size cause overflow! (address={:016X}, size={:016X})", + addr, size); + return ResultInvalidCurrentMemory; + } + + const auto perms{static_cast(permissions)}; + if (perms > MemoryPermission::ReadWrite || perms == MemoryPermission::Write) { + LOG_ERROR(Kernel_SVC, "Invalid memory permissions for transfer memory! (perms={:08X})", + permissions); + return ResultInvalidMemoryPermissions; + } + auto& kernel = system.Kernel(); - - // Validate the size. - R_UNLESS(Common::IsAligned(address, PageSize), ResultInvalidAddress); - R_UNLESS(Common::IsAligned(size, PageSize), ResultInvalidSize); - R_UNLESS(size > 0, ResultInvalidSize); - R_UNLESS((address < address + size), ResultInvalidCurrentMemory); - - // Validate the permissions. - R_UNLESS(IsValidTransferMemoryPermission(map_perm), ResultInvalidNewMemoryPermission); - - // Get the current process and handle table. - auto& process = *kernel.CurrentProcess(); - auto& handle_table = process.GetHandleTable(); - // Reserve a new transfer memory from the process resource limit. KScopedResourceReservation trmem_reservation(kernel.CurrentProcess(), LimitableResource::TransferMemory); - R_UNLESS(trmem_reservation.Succeeded(), ResultLimitReached); + if (!trmem_reservation.Succeeded()) { + LOG_ERROR(Kernel_SVC, "Could not reserve a new transfer memory"); + return ResultResourceLimitedExceeded; + } + auto transfer_mem_handle = TransferMemory::Create(kernel, system.Memory(), addr, size, + static_cast(perms)); - // Create the transfer memory. - KTransferMemory* trmem = KTransferMemory::Create(kernel); - R_UNLESS(trmem != nullptr, ResultOutOfResource); + if (const auto reserve_result{transfer_mem_handle->Reserve()}; reserve_result.IsError()) { + return reserve_result; + } - // Ensure the only reference is in the handle table when we're done. - SCOPE_EXIT({ trmem->Close(); }); - - // Ensure that the region is in range. - R_UNLESS(process.PageTable().Contains(address, size), ResultInvalidCurrentMemory); - - // Initialize the transfer memory. - R_TRY(trmem->Initialize(address, size, map_perm)); - - // Commit the reservation. + auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); + const auto result{handle_table.Create(std::move(transfer_mem_handle))}; + if (result.Failed()) { + return result.Code(); + } trmem_reservation.Commit(); - // Register the transfer memory. - KTransferMemory::Register(kernel, trmem); - - // Add the transfer memory to the handle table. - R_TRY(handle_table.Add(out, trmem)); - + *handle = *result; return RESULT_SUCCESS; } -static ResultCode CreateTransferMemory32(Core::System& system, Handle* out, u32 address, u32 size, - MemoryPermission map_perm) { - return CreateTransferMemory(system, out, address, size, map_perm); +static ResultCode CreateTransferMemory32(Core::System& system, Handle* handle, u32 addr, u32 size, + u32 permissions) { + return CreateTransferMemory(system, handle, addr, size, permissions); } static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, s32* out_core_id, @@ -1905,12 +1930,19 @@ static ResultCode GetThreadCoreMask(Core::System& system, Handle thread_handle, LOG_TRACE(Kernel_SVC, "called, handle=0x{:08X}", thread_handle); // Get the thread from its handle. - KScopedAutoObject thread = - system.Kernel().CurrentProcess()->GetHandleTable().GetObject(thread_handle); - R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); + const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); + const std::shared_ptr thread = handle_table.Get(thread_handle); + if (!thread) { + LOG_ERROR(Kernel_SVC, "Invalid thread handle specified (handle={:08X})", thread_handle); + return ResultInvalidHandle; + } // Get the core mask. - R_TRY(thread->GetCoreMask(out_core_id, out_affinity_mask)); + const auto result = thread->GetCoreMask(out_core_id, out_affinity_mask); + if (result.IsError()) { + LOG_ERROR(Kernel_SVC, "Unable to successfully retrieve core mask (result={})", result.raw); + return result; + } return RESULT_SUCCESS; } @@ -1926,33 +1958,58 @@ static ResultCode GetThreadCoreMask32(Core::System& system, Handle thread_handle static ResultCode SetThreadCoreMask(Core::System& system, Handle thread_handle, s32 core_id, u64 affinity_mask) { + LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, core_id=0x{:X}, affinity_mask=0x{:016X}", + thread_handle, core_id, affinity_mask); + + const auto& current_process = *system.Kernel().CurrentProcess(); + // Determine the core id/affinity mask. - if (core_id == IdealCoreUseProcessValue) { - core_id = system.Kernel().CurrentProcess()->GetIdealCoreId(); + if (core_id == Svc::IdealCoreUseProcessValue) { + core_id = current_process.GetIdealCoreId(); affinity_mask = (1ULL << core_id); } else { // Validate the affinity mask. - const u64 process_core_mask = system.Kernel().CurrentProcess()->GetCoreMask(); - R_UNLESS((affinity_mask | process_core_mask) == process_core_mask, ResultInvalidCoreId); - R_UNLESS(affinity_mask != 0, ResultInvalidCombination); + const u64 process_core_mask = current_process.GetCoreMask(); + if ((affinity_mask | process_core_mask) != process_core_mask) { + LOG_ERROR(Kernel_SVC, + "Affinity mask does match the process core mask (affinity mask={:016X}, core " + "mask={:016X})", + affinity_mask, process_core_mask); + return ResultInvalidCoreId; + } + if (affinity_mask == 0) { + LOG_ERROR(Kernel_SVC, "Affinity mask is zero."); + return ResultInvalidCombination; + } // Validate the core id. - if (IsValidVirtualCoreId(core_id)) { - R_UNLESS(((1ULL << core_id) & affinity_mask) != 0, ResultInvalidCombination); + if (IsValidCoreId(core_id)) { + if (((1ULL << core_id) & affinity_mask) == 0) { + LOG_ERROR(Kernel_SVC, "Invalid core ID (ID={})", core_id); + return ResultInvalidCombination; + } } else { - R_UNLESS(core_id == IdealCoreNoUpdate || core_id == IdealCoreDontCare, - ResultInvalidCoreId); + if (core_id != IdealCoreNoUpdate && core_id != IdealCoreDontCare) { + LOG_ERROR(Kernel_SVC, "Invalid core ID (ID={})", core_id); + return ResultInvalidCoreId; + } } } // Get the thread from its handle. - KScopedAutoObject thread = - system.Kernel().CurrentProcess()->GetHandleTable().GetObject(thread_handle); - R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); + const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); + const std::shared_ptr thread = handle_table.Get(thread_handle); + if (!thread) { + LOG_ERROR(Kernel_SVC, "Invalid thread handle (handle={:08X})", thread_handle); + return ResultInvalidHandle; + } // Set the core mask. - R_TRY(thread->SetCoreMask(core_id, affinity_mask)); - + const auto set_result = thread->SetCoreMask(core_id, affinity_mask); + if (set_result.IsError()) { + LOG_ERROR(Kernel_SVC, "Unable to successfully set core mask (result={})", set_result.raw); + return set_result; + } return RESULT_SUCCESS; } @@ -1965,12 +2022,27 @@ static ResultCode SetThreadCoreMask32(Core::System& system, Handle thread_handle static ResultCode SignalEvent(Core::System& system, Handle event_handle) { LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); + auto& kernel = system.Kernel(); // Get the current handle table. - const KHandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); + const HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); + + // Reserve a new event from the process resource limit. + KScopedResourceReservation event_reservation(kernel.CurrentProcess(), + LimitableResource::Events); + if (!event_reservation.Succeeded()) { + LOG_ERROR(Kernel, "Could not reserve a new event"); + return ResultResourceLimitedExceeded; + } // Get the writable event. - KScopedAutoObject writable_event = handle_table.GetObject(event_handle); - R_UNLESS(writable_event.IsNotNull(), ResultInvalidHandle); + auto writable_event = handle_table.Get(event_handle); + if (!writable_event) { + LOG_ERROR(Kernel_SVC, "Invalid event handle provided (handle={:08X})", event_handle); + return ResultInvalidHandle; + } + + // Commit the successfuly reservation. + event_reservation.Commit(); return writable_event->Signal(); } @@ -1987,16 +2059,16 @@ static ResultCode ClearEvent(Core::System& system, Handle event_handle) { // Try to clear the writable event. { - KScopedAutoObject writable_event = handle_table.GetObject(event_handle); - if (writable_event.IsNotNull()) { + auto writable_event = handle_table.Get(event_handle); + if (writable_event) { return writable_event->Clear(); } } // Try to clear the readable event. { - KScopedAutoObject readable_event = handle_table.GetObject(event_handle); - if (readable_event.IsNotNull()) { + auto readable_event = handle_table.Get(event_handle); + if (readable_event) { return readable_event->Clear(); } } @@ -2015,40 +2087,34 @@ static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* o // Get the kernel reference and handle table. auto& kernel = system.Kernel(); - auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); - - // Reserve a new event from the process resource limit - KScopedResourceReservation event_reservation(kernel.CurrentProcess(), - LimitableResource::Events); - R_UNLESS(event_reservation.Succeeded(), ResultLimitReached); + HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); // Create a new event. - KEvent* event = KEvent::Create(kernel); - R_UNLESS(event != nullptr, ResultOutOfResource); + const auto event = KEvent::Create(kernel, "CreateEvent"); + if (!event) { + LOG_ERROR(Kernel_SVC, "Unable to create new events. Event creation limit reached."); + return ResultOutOfResource; + } // Initialize the event. - event->Initialize("CreateEvent"); - - // Commit the thread reservation. - event_reservation.Commit(); - - // Ensure that we clean up the event (and its only references are handle table) on function end. - SCOPE_EXIT({ - event->GetWritableEvent().Close(); - event->GetReadableEvent().Close(); - }); - - // Register the event. - KEvent::Register(kernel, event); + event->Initialize(); // Add the writable event to the handle table. - R_TRY(handle_table.Add(out_write, std::addressof(event->GetWritableEvent()))); + const auto write_create_result = handle_table.Create(event->GetWritableEvent()); + if (write_create_result.Failed()) { + return write_create_result.Code(); + } + *out_write = *write_create_result; // Add the writable event to the handle table. - auto handle_guard = SCOPE_GUARD({ handle_table.Remove(*out_write); }); + auto handle_guard = SCOPE_GUARD({ handle_table.Close(*write_create_result); }); // Add the readable event to the handle table. - R_TRY(handle_table.Add(out_read, std::addressof(event->GetReadableEvent()))); + const auto read_create_result = handle_table.Create(event->GetReadableEvent()); + if (read_create_result.Failed()) { + return read_create_result.Code(); + } + *out_read = *read_create_result; // We succeeded. handle_guard.Cancel(); @@ -2068,8 +2134,8 @@ static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_ }; const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); - KScopedAutoObject process = handle_table.GetObject(process_handle); - if (process.IsNull()) { + const auto process = handle_table.Get(process_handle); + if (!process) { LOG_ERROR(Kernel_SVC, "Process handle does not exist, process_handle=0x{:08X}", process_handle); return ResultInvalidHandle; @@ -2086,86 +2152,83 @@ static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_ } static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle) { + std::lock_guard lock{HLE::g_hle_lock}; LOG_DEBUG(Kernel_SVC, "called"); - // Create a new resource limit. auto& kernel = system.Kernel(); - KResourceLimit* resource_limit = KResourceLimit::Create(kernel); - R_UNLESS(resource_limit != nullptr, ResultOutOfResource); + auto resource_limit = std::make_shared(kernel, system.CoreTiming()); - // Ensure we don't leak a reference to the limit. - SCOPE_EXIT({ resource_limit->Close(); }); + auto* const current_process = kernel.CurrentProcess(); + ASSERT(current_process != nullptr); - // Initialize the resource limit. - resource_limit->Initialize(&system.CoreTiming()); - - // Register the limit. - KResourceLimit::Register(kernel, resource_limit); - - // Add the limit to the handle table. - R_TRY(kernel.CurrentProcess()->GetHandleTable().Add(out_handle, resource_limit)); + const auto handle = current_process->GetHandleTable().Create(std::move(resource_limit)); + if (handle.Failed()) { + return handle.Code(); + } + *out_handle = *handle; return RESULT_SUCCESS; } -static ResultCode GetResourceLimitLimitValue(Core::System& system, u64* out_limit_value, - Handle resource_limit_handle, - LimitableResource which) { - LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}", resource_limit_handle, - which); +static ResultCode GetResourceLimitLimitValue(Core::System& system, u64* out_value, + Handle resource_limit, u32 resource_type) { + LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type); - // Validate the resource. - R_UNLESS(IsValidResourceType(which), ResultInvalidEnumValue); - - // Get the resource limit. - auto& kernel = system.Kernel(); - KScopedAutoObject resource_limit = - kernel.CurrentProcess()->GetHandleTable().GetObject(resource_limit_handle); - R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle); - - // Get the limit value. - *out_limit_value = resource_limit->GetLimitValue(which); + const auto limit_value = RetrieveResourceLimitValue(system, resource_limit, resource_type, + ResourceLimitValueType::LimitValue); + if (limit_value.Failed()) { + return limit_value.Code(); + } + *out_value = static_cast(*limit_value); return RESULT_SUCCESS; } -static ResultCode GetResourceLimitCurrentValue(Core::System& system, u64* out_current_value, - Handle resource_limit_handle, - LimitableResource which) { - LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}", resource_limit_handle, - which); +static ResultCode GetResourceLimitCurrentValue(Core::System& system, u64* out_value, + Handle resource_limit, u32 resource_type) { + LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}", resource_limit, resource_type); - // Validate the resource. - R_UNLESS(IsValidResourceType(which), ResultInvalidEnumValue); - - // Get the resource limit. - auto& kernel = system.Kernel(); - KScopedAutoObject resource_limit = - kernel.CurrentProcess()->GetHandleTable().GetObject(resource_limit_handle); - R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle); - - // Get the current value. - *out_current_value = resource_limit->GetCurrentValue(which); + const auto current_value = RetrieveResourceLimitValue(system, resource_limit, resource_type, + ResourceLimitValueType::CurrentValue); + if (current_value.Failed()) { + return current_value.Code(); + } + *out_value = static_cast(*current_value); return RESULT_SUCCESS; } -static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resource_limit_handle, - LimitableResource which, u64 limit_value) { - LOG_DEBUG(Kernel_SVC, "called, resource_limit_handle={:08X}, which={}, limit_value={}", - resource_limit_handle, which, limit_value); +static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resource_limit, + u32 resource_type, u64 value) { + LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}, Value={}", resource_limit, + resource_type, value); - // Validate the resource. - R_UNLESS(IsValidResourceType(which), ResultInvalidEnumValue); + const auto type = static_cast(resource_type); + if (!IsValidResourceType(type)) { + LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); + return ResultInvalidEnumValue; + } - // Get the resource limit. - auto& kernel = system.Kernel(); - KScopedAutoObject resource_limit = - kernel.CurrentProcess()->GetHandleTable().GetObject(resource_limit_handle); - R_UNLESS(resource_limit.IsNotNull(), ResultInvalidHandle); + auto* const current_process = system.Kernel().CurrentProcess(); + ASSERT(current_process != nullptr); - // Set the limit value. - R_TRY(resource_limit->SetLimitValue(which, limit_value)); + auto resource_limit_object = + current_process->GetHandleTable().Get(resource_limit); + if (!resource_limit_object) { + LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", + resource_limit); + return ResultInvalidHandle; + } + + const auto set_result = resource_limit_object->SetLimitValue(type, static_cast(value)); + if (set_result.IsError()) { + LOG_ERROR(Kernel_SVC, + "Attempted to lower resource limit ({}) for category '{}' below its current " + "value ({})", + resource_limit_object->GetLimitValue(type), resource_type, + resource_limit_object->GetCurrentValue(type)); + return set_result; + } return RESULT_SUCCESS; } @@ -2288,7 +2351,7 @@ static const FunctionDef SVC_Table_32[] = { {0x11, SvcWrap32, "SignalEvent32"}, {0x12, SvcWrap32, "ClearEvent32"}, {0x13, SvcWrap32, "MapSharedMemory32"}, - {0x14, SvcWrap32, "UnmapSharedMemory32"}, + {0x14, nullptr, "UnmapSharedMemory32"}, {0x15, SvcWrap32, "CreateTransferMemory32"}, {0x16, SvcWrap32, "CloseHandle32"}, {0x17, SvcWrap32, "ResetSignal32"}, @@ -2483,7 +2546,7 @@ static const FunctionDef SVC_Table_64[] = { {0x11, SvcWrap64, "SignalEvent"}, {0x12, SvcWrap64, "ClearEvent"}, {0x13, SvcWrap64, "MapSharedMemory"}, - {0x14, SvcWrap64, "UnmapSharedMemory"}, + {0x14, nullptr, "UnmapSharedMemory"}, {0x15, SvcWrap64, "CreateTransferMemory"}, {0x16, SvcWrap64, "CloseHandle"}, {0x17, SvcWrap64, "ResetSignal"}, diff --git a/src/core/hle/kernel/svc_common.h b/src/core/hle/kernel/svc_common.h index 60ea2c405..4af049551 100755 --- a/src/core/hle/kernel/svc_common.h +++ b/src/core/hle/kernel/svc_common.h @@ -6,24 +6,9 @@ #include "common/common_types.h" -namespace Kernel { -using Handle = u32; -} - namespace Kernel::Svc { constexpr s32 ArgumentHandleCountMax = 0x40; constexpr u32 HandleWaitMask{1u << 30}; -constexpr inline Handle InvalidHandle = Handle(0); - -enum PseudoHandle : Handle { - CurrentThread = 0xFFFF8000, - CurrentProcess = 0xFFFF8001, -}; - -constexpr bool IsPseudoHandle(Handle handle) { - return handle == PseudoHandle::CurrentProcess || handle == PseudoHandle::CurrentThread; -} - } // namespace Kernel::Svc diff --git a/src/core/hle/kernel/svc_results.h b/src/core/hle/kernel/svc_results.h index 53a940723..a26d9f2c9 100755 --- a/src/core/hle/kernel/svc_results.h +++ b/src/core/hle/kernel/svc_results.h @@ -10,18 +10,18 @@ namespace Kernel { // Confirmed Switch kernel error codes -constexpr ResultCode ResultOutOfSessions{ErrorModule::Kernel, 7}; -constexpr ResultCode ResultInvalidArgument{ErrorModule::Kernel, 14}; +constexpr ResultCode ResultMaxConnectionsReached{ErrorModule::Kernel, 7}; +constexpr ResultCode ResultInvalidCapabilityDescriptor{ErrorModule::Kernel, 14}; constexpr ResultCode ResultNoSynchronizationObject{ErrorModule::Kernel, 57}; constexpr ResultCode ResultTerminationRequested{ErrorModule::Kernel, 59}; constexpr ResultCode ResultInvalidSize{ErrorModule::Kernel, 101}; constexpr ResultCode ResultInvalidAddress{ErrorModule::Kernel, 102}; constexpr ResultCode ResultOutOfResource{ErrorModule::Kernel, 103}; constexpr ResultCode ResultOutOfMemory{ErrorModule::Kernel, 104}; -constexpr ResultCode ResultOutOfHandles{ErrorModule::Kernel, 105}; +constexpr ResultCode ResultHandleTableFull{ErrorModule::Kernel, 105}; constexpr ResultCode ResultInvalidCurrentMemory{ErrorModule::Kernel, 106}; -constexpr ResultCode ResultInvalidNewMemoryPermission{ErrorModule::Kernel, 108}; -constexpr ResultCode ResultInvalidMemoryRegion{ErrorModule::Kernel, 110}; +constexpr ResultCode ResultInvalidMemoryPermissions{ErrorModule::Kernel, 108}; +constexpr ResultCode ResultInvalidMemoryRange{ErrorModule::Kernel, 110}; constexpr ResultCode ResultInvalidPriority{ErrorModule::Kernel, 112}; constexpr ResultCode ResultInvalidCoreId{ErrorModule::Kernel, 113}; constexpr ResultCode ResultInvalidHandle{ErrorModule::Kernel, 114}; @@ -33,11 +33,9 @@ constexpr ResultCode ResultOutOfRange{ErrorModule::Kernel, 119}; constexpr ResultCode ResultInvalidEnumValue{ErrorModule::Kernel, 120}; constexpr ResultCode ResultNotFound{ErrorModule::Kernel, 121}; constexpr ResultCode ResultBusy{ErrorModule::Kernel, 122}; -constexpr ResultCode ResultSessionClosed{ErrorModule::Kernel, 123}; +constexpr ResultCode ResultSessionClosedByRemote{ErrorModule::Kernel, 123}; constexpr ResultCode ResultInvalidState{ErrorModule::Kernel, 125}; -constexpr ResultCode ResultReservedUsed{ErrorModule::Kernel, 126}; -constexpr ResultCode ResultPortClosed{ErrorModule::Kernel, 131}; -constexpr ResultCode ResultLimitReached{ErrorModule::Kernel, 132}; -constexpr ResultCode ResultInvalidId{ErrorModule::Kernel, 519}; +constexpr ResultCode ResultReservedValue{ErrorModule::Kernel, 126}; +constexpr ResultCode ResultResourceLimitedExceeded{ErrorModule::Kernel, 132}; } // namespace Kernel diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h index 913b16494..96afd544b 100755 --- a/src/core/hle/kernel/svc_wrap.h +++ b/src/core/hle/kernel/svc_wrap.h @@ -154,28 +154,15 @@ void SvcWrap64(Core::System& system) { FuncReturn(system, retval); } -// Used by GetResourceLimitLimitValue. -template -void SvcWrap64(Core::System& system) { - u64 param_1 = 0; - const u32 retval = func(system, ¶m_1, static_cast(Param(system, 1)), - static_cast(Param(system, 2))) - .raw; - - system.CurrentArmInterface().SetReg(1, param_1); - FuncReturn(system, retval); -} - template void SvcWrap64(Core::System& system) { FuncReturn(system, func(system, static_cast(Param(system, 0)), Param(system, 1)).raw); } -// Used by SetResourceLimitLimitValue -template +template void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, static_cast(Param(system, 0)), - static_cast(Param(system, 1)), Param(system, 2)) + FuncReturn(system, func(system, static_cast(Param(system, 0)), + static_cast(Param(system, 1)), Param(system, 2)) .raw); } @@ -232,11 +219,10 @@ void SvcWrap64(Core::System& system) { func(system, Param(system, 0), Param(system, 1), static_cast(Param(system, 2))).raw); } -// Used by MapSharedMemory -template +template void SvcWrap64(Core::System& system) { - FuncReturn(system, func(system, static_cast(Param(system, 0)), Param(system, 1), - Param(system, 2), static_cast(Param(system, 3))) + FuncReturn(system, func(system, static_cast(Param(system, 0)), Param(system, 1), + Param(system, 2), static_cast(Param(system, 3))) .raw); } @@ -266,13 +252,11 @@ void SvcWrap64(Core::System& system) { .raw); } -// Used by GetInfo -template +template void SvcWrap64(Core::System& system) { u64 param_1 = 0; - const u32 retval = func(system, ¶m_1, Param(system, 1), - static_cast(Param(system, 2)), Param(system, 3)) - .raw; + const u32 retval = + func(system, ¶m_1, Param(system, 1), Param(system, 2), Param(system, 3)).raw; system.CurrentArmInterface().SetReg(1, param_1); FuncReturn(system, retval); @@ -289,12 +273,11 @@ void SvcWrap64(Core::System& system) { FuncReturn(system, retval); } -// Used by CreateTransferMemory -template +template void SvcWrap64(Core::System& system) { u32 param_1 = 0; const u32 retval = func(system, ¶m_1, Param(system, 1), Param(system, 2), - static_cast(Param(system, 3))) + static_cast(Param(system, 3))) .raw; system.CurrentArmInterface().SetReg(1, param_1); @@ -554,16 +537,6 @@ void SvcWrap32(Core::System& system) { FuncReturn(system, retval); } -// Used by MapSharedMemory32 -template -void SvcWrap32(Core::System& system) { - const u32 retval = func(system, static_cast(Param(system, 0)), - static_cast(Param(system, 1)), static_cast(Param(system, 2)), - static_cast(Param(system, 3))) - .raw; - FuncReturn(system, retval); -} - // Used by SetThreadCoreMask32 template void SvcWrap32(Core::System& system) { @@ -613,12 +586,11 @@ void SvcWrap32(Core::System& system) { } // Used by CreateTransferMemory32 -template +template void SvcWrap32(Core::System& system) { Handle handle = 0; - const u32 retval = func(system, &handle, Param32(system, 1), Param32(system, 2), - static_cast(Param32(system, 3))) - .raw; + const u32 retval = + func(system, &handle, Param32(system, 1), Param32(system, 2), Param32(system, 3)).raw; system.CurrentArmInterface().SetReg(1, handle); FuncReturn(system, retval); } diff --git a/src/core/hle/kernel/time_manager.cpp b/src/core/hle/kernel/time_manager.cpp index ae9b4be2f..fd0630019 100755 --- a/src/core/hle/kernel/time_manager.cpp +++ b/src/core/hle/kernel/time_manager.cpp @@ -6,6 +6,7 @@ #include "core/core.h" #include "core/core_timing.h" #include "core/core_timing_util.h" +#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" @@ -14,12 +15,16 @@ namespace Kernel { TimeManager::TimeManager(Core::System& system_) : system{system_} { - time_manager_event_type = - Core::Timing::CreateEvent("Kernel::TimeManagerCallback", - [this](std::uintptr_t thread_handle, std::chrono::nanoseconds) { - KThread* thread = reinterpret_cast(thread_handle); - thread->Wakeup(); - }); + time_manager_event_type = Core::Timing::CreateEvent( + "Kernel::TimeManagerCallback", + [this](std::uintptr_t thread_handle, std::chrono::nanoseconds) { + std::shared_ptr thread; + { + std::lock_guard lock{mutex}; + thread = SharedFrom(reinterpret_cast(thread_handle)); + } + thread->Wakeup(); + }); } void TimeManager::ScheduleTimeEvent(KThread* thread, s64 nanoseconds) { diff --git a/src/core/hle/kernel/time_manager.h b/src/core/hle/kernel/time_manager.h index 2d175a9c4..0d7f05f30 100755 --- a/src/core/hle/kernel/time_manager.h +++ b/src/core/hle/kernel/time_manager.h @@ -8,6 +8,8 @@ #include #include +#include "core/hle/kernel/object.h" + namespace Core { class System; } // namespace Core diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 49c09a570..5450dcf0f 100755 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -16,8 +16,8 @@ #include "core/file_sys/control_metadata.h" #include "core/file_sys/patch_manager.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/acc/acc.h" #include "core/hle/service/acc/acc_aa.h" #include "core/hle/service/acc/acc_su.h" diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 408e441dc..58c7f2930 100755 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -15,11 +15,11 @@ #include "core/file_sys/savedata_factory.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/k_event.h" -#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_readable_event.h" -#include "core/hle/kernel/k_transfer_memory.h" #include "core/hle/kernel/k_writable_event.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/process.h" +#include "core/hle/kernel/transfer_memory.h" #include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applet_ae.h" @@ -42,7 +42,6 @@ #include "core/hle/service/set/set.h" #include "core/hle/service/sm/sm.h" #include "core/hle/service/vi/vi.h" -#include "core/memory.h" namespace Service::AM { @@ -254,8 +253,7 @@ IDebugFunctions::IDebugFunctions(Core::System& system_) IDebugFunctions::~IDebugFunctions() = default; ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nvflinger_) - : ServiceFramework{system_, "ISelfController"}, nvflinger{nvflinger_}, - launchable_event{system.Kernel()}, accumulated_suspended_tick_changed_event{system.Kernel()} { + : ServiceFramework{system_, "ISelfController"}, nvflinger{nvflinger_} { // clang-format off static const FunctionInfo functions[] = { {0, &ISelfController::Exit, "Exit"}, @@ -308,20 +306,19 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv RegisterHandlers(functions); - Kernel::KAutoObject::Create(std::addressof(launchable_event)); - - launchable_event.Initialize("ISelfController:LaunchableEvent"); + auto& kernel = system.Kernel(); + launchable_event = Kernel::KEvent::Create(kernel, "ISelfController:LaunchableEvent"); + launchable_event->Initialize(); // This event is created by AM on the first time GetAccumulatedSuspendedTickChangedEvent() is // called. Yuzu can just create it unconditionally, since it doesn't need to support multiple // ISelfControllers. The event is signaled on creation, and on transition from suspended -> not // suspended if the event has previously been created by a call to // GetAccumulatedSuspendedTickChangedEvent. - - Kernel::KAutoObject::Create(std::addressof(accumulated_suspended_tick_changed_event)); - accumulated_suspended_tick_changed_event.Initialize( - "ISelfController:AccumulatedSuspendedTickChangedEvent"); - accumulated_suspended_tick_changed_event.GetWritableEvent().Signal(); + accumulated_suspended_tick_changed_event = + Kernel::KEvent::Create(kernel, "ISelfController:AccumulatedSuspendedTickChangedEvent"); + accumulated_suspended_tick_changed_event->Initialize(); + accumulated_suspended_tick_changed_event->GetWritableEvent()->Signal(); } ISelfController::~ISelfController() = default; @@ -380,11 +377,11 @@ void ISelfController::LeaveFatalSection(Kernel::HLERequestContext& ctx) { void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_AM, "(STUBBED) called"); - launchable_event.GetWritableEvent().Signal(); + launchable_event->GetWritableEvent()->Signal(); IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(launchable_event.GetReadableEvent()); + rb.PushCopyObjects(launchable_event->GetReadableEvent()); } void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) { @@ -563,7 +560,7 @@ void ISelfController::GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequest IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(accumulated_suspended_tick_changed_event.GetReadableEvent()); + rb.PushCopyObjects(accumulated_suspended_tick_changed_event->GetReadableEvent()); } void ISelfController::SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestContext& ctx) { @@ -581,40 +578,39 @@ void ISelfController::SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestCo rb.Push(RESULT_SUCCESS); } -AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel) - : on_new_message{kernel}, on_operation_mode_changed{kernel} { - - Kernel::KAutoObject::Create(std::addressof(on_new_message)); - Kernel::KAutoObject::Create(std::addressof(on_operation_mode_changed)); - - on_new_message.Initialize("AMMessageQueue:OnMessageReceived"); - on_operation_mode_changed.Initialize("AMMessageQueue:OperationModeChanged"); +AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel) { + on_new_message = Kernel::KEvent::Create(kernel, "AMMessageQueue:OnMessageReceived"); + on_new_message->Initialize(); + on_operation_mode_changed = + Kernel::KEvent::Create(kernel, "AMMessageQueue:OperationModeChanged"); + on_operation_mode_changed->Initialize(); } AppletMessageQueue::~AppletMessageQueue() = default; -Kernel::KReadableEvent& AppletMessageQueue::GetMessageReceiveEvent() { - return on_new_message.GetReadableEvent(); +const std::shared_ptr& AppletMessageQueue::GetMessageReceiveEvent() const { + return on_new_message->GetReadableEvent(); } -Kernel::KReadableEvent& AppletMessageQueue::GetOperationModeChangedEvent() { - return on_operation_mode_changed.GetReadableEvent(); +const std::shared_ptr& AppletMessageQueue::GetOperationModeChangedEvent() + const { + return on_operation_mode_changed->GetReadableEvent(); } void AppletMessageQueue::PushMessage(AppletMessage msg) { messages.push(msg); - on_new_message.GetWritableEvent().Signal(); + on_new_message->GetWritableEvent()->Signal(); } AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() { if (messages.empty()) { - on_new_message.GetWritableEvent().Clear(); + on_new_message->GetWritableEvent()->Clear(); return AppletMessage::NoMessage; } auto msg = messages.front(); messages.pop(); if (messages.empty()) { - on_new_message.GetWritableEvent().Clear(); + on_new_message->GetWritableEvent()->Clear(); } return msg; } @@ -634,7 +630,7 @@ void AppletMessageQueue::FocusStateChanged() { void AppletMessageQueue::OperationModeChanged() { PushMessage(AppletMessage::OperationModeChanged); PushMessage(AppletMessage::PerformanceModeChanged); - on_operation_mode_changed.GetWritableEvent().Signal(); + on_operation_mode_changed->GetWritableEvent()->Signal(); } ICommonStateGetter::ICommonStateGetter(Core::System& system_, @@ -931,9 +927,11 @@ private: void GetAppletStateChangedEvent(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_AM, "called"); + const auto event = applet->GetBroker().GetStateChangedEvent(); + IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(applet->GetBroker().GetStateChangedEvent()); + rb.PushCopyObjects(event); } void IsCompleted(Kernel::HLERequestContext& ctx) { @@ -1215,16 +1213,16 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContex } auto transfer_mem = - system.CurrentProcess()->GetHandleTable().GetObject(handle); + system.CurrentProcess()->GetHandleTable().Get(handle); - if (transfer_mem.IsNull()) { + if (transfer_mem == nullptr) { LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_UNKNOWN); return; } - const u8* const mem_begin = system.Memory().GetPointer(transfer_mem->GetSourceAddress()); + const u8* const mem_begin = transfer_mem->GetPointer(); const u8* const mem_end = mem_begin + transfer_mem->GetSize(); std::vector memory{mem_begin, mem_end}; @@ -1249,16 +1247,16 @@ void ILibraryAppletCreator::CreateHandleStorage(Kernel::HLERequestContext& ctx) } auto transfer_mem = - system.CurrentProcess()->GetHandleTable().GetObject(handle); + system.CurrentProcess()->GetHandleTable().Get(handle); - if (transfer_mem.IsNull()) { + if (transfer_mem == nullptr) { LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_UNKNOWN); return; } - const u8* const mem_begin = system.Memory().GetPointer(transfer_mem->GetSourceAddress()); + const u8* const mem_begin = transfer_mem->GetPointer(); const u8* const mem_end = mem_begin + transfer_mem->GetSize(); std::vector memory{mem_begin, mem_end}; @@ -1268,9 +1266,7 @@ void ILibraryAppletCreator::CreateHandleStorage(Kernel::HLERequestContext& ctx) } IApplicationFunctions::IApplicationFunctions(Core::System& system_) - : ServiceFramework{system_, "IApplicationFunctions"}, gpu_error_detected_event{system.Kernel()}, - friend_invitation_storage_channel_event{system.Kernel()}, - health_warning_disappeared_system_event{system.Kernel()} { + : ServiceFramework{system_, "IApplicationFunctions"} { // clang-format off static const FunctionInfo functions[] = { {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"}, @@ -1338,15 +1334,16 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_) RegisterHandlers(functions); - Kernel::KAutoObject::Create(std::addressof(gpu_error_detected_event)); - Kernel::KAutoObject::Create(std::addressof(friend_invitation_storage_channel_event)); - Kernel::KAutoObject::Create(std::addressof(health_warning_disappeared_system_event)); - - gpu_error_detected_event.Initialize("IApplicationFunctions:GpuErrorDetectedSystemEvent"); - friend_invitation_storage_channel_event.Initialize( - "IApplicationFunctions:FriendInvitationStorageChannelEvent"); - health_warning_disappeared_system_event.Initialize( - "IApplicationFunctions:HealthWarningDisappearedSystemEvent"); + auto& kernel = system.Kernel(); + gpu_error_detected_event = + Kernel::KEvent::Create(kernel, "IApplicationFunctions:GpuErrorDetectedSystemEvent"); + gpu_error_detected_event->Initialize(); + friend_invitation_storage_channel_event = + Kernel::KEvent::Create(kernel, "IApplicationFunctions:FriendInvitationStorageChannelEvent"); + friend_invitation_storage_channel_event->Initialize(); + health_warning_disappeared_system_event = + Kernel::KEvent::Create(kernel, "IApplicationFunctions:HealthWarningDisappearedSystemEvent"); + health_warning_disappeared_system_event->Initialize(); } IApplicationFunctions::~IApplicationFunctions() = default; @@ -1743,7 +1740,7 @@ void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(Kernel::HLERequestCon IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(gpu_error_detected_event.GetReadableEvent()); + rb.PushCopyObjects(gpu_error_detected_event->GetReadableEvent()); } void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx) { @@ -1751,7 +1748,7 @@ void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERe IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(friend_invitation_storage_channel_event.GetReadableEvent()); + rb.PushCopyObjects(friend_invitation_storage_channel_event->GetReadableEvent()); } void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel( @@ -1767,7 +1764,7 @@ void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(Kernel::HLERe IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(health_warning_disappeared_system_event.GetReadableEvent()); + rb.PushCopyObjects(health_warning_disappeared_system_event->GetReadableEvent()); } void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger, @@ -1785,8 +1782,7 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger } IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_) - : ServiceFramework{system_, "IHomeMenuFunctions"}, pop_from_general_channel_event{ - system.Kernel()} { + : ServiceFramework{system_, "IHomeMenuFunctions"} { // clang-format off static const FunctionInfo functions[] = { {10, &IHomeMenuFunctions::RequestToGetForeground, "RequestToGetForeground"}, @@ -1807,8 +1803,9 @@ IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_) RegisterHandlers(functions); - Kernel::KAutoObject::Create(std::addressof(pop_from_general_channel_event)); - pop_from_general_channel_event.Initialize("IHomeMenuFunctions:PopFromGeneralChannelEvent"); + pop_from_general_channel_event = + Kernel::KEvent::Create(system.Kernel(), "IHomeMenuFunctions:PopFromGeneralChannelEvent"); + pop_from_general_channel_event->Initialize(); } IHomeMenuFunctions::~IHomeMenuFunctions() = default; @@ -1825,7 +1822,7 @@ void IHomeMenuFunctions::GetPopFromGeneralChannelEvent(Kernel::HLERequestContext IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(pop_from_general_channel_event.GetReadableEvent()); + rb.PushCopyObjects(pop_from_general_channel_event->GetReadableEvent()); } IGlobalStateController::IGlobalStateController(Core::System& system_) diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index 184030a8e..5d302e155 100755 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -8,12 +8,12 @@ #include #include -#include "core/hle/kernel/k_event.h" #include "core/hle/service/service.h" namespace Kernel { class KernelCore; -class KTransferMemory; +class KEvent; +class TransferMemory; } // namespace Kernel namespace Service::NVFlinger { @@ -56,8 +56,8 @@ public: explicit AppletMessageQueue(Kernel::KernelCore& kernel); ~AppletMessageQueue(); - Kernel::KReadableEvent& GetMessageReceiveEvent(); - Kernel::KReadableEvent& GetOperationModeChangedEvent(); + const std::shared_ptr& GetMessageReceiveEvent() const; + const std::shared_ptr& GetOperationModeChangedEvent() const; void PushMessage(AppletMessage msg); AppletMessage PopMessage(); std::size_t GetMessageCount() const; @@ -67,8 +67,8 @@ public: private: std::queue messages; - Kernel::KEvent on_new_message; - Kernel::KEvent on_operation_mode_changed; + std::shared_ptr on_new_message; + std::shared_ptr on_operation_mode_changed; }; class IWindowController final : public ServiceFramework { @@ -156,8 +156,8 @@ private: }; NVFlinger::NVFlinger& nvflinger; - Kernel::KEvent launchable_event; - Kernel::KEvent accumulated_suspended_tick_changed_event; + std::shared_ptr launchable_event; + std::shared_ptr accumulated_suspended_tick_changed_event; u32 idle_time_detection_extension = 0; u64 num_fatal_sections_entered = 0; @@ -300,9 +300,9 @@ private: bool launch_popped_application_specific = false; bool launch_popped_account_preselect = false; s32 previous_program_index{-1}; - Kernel::KEvent gpu_error_detected_event; - Kernel::KEvent friend_invitation_storage_channel_event; - Kernel::KEvent health_warning_disappeared_system_event; + std::shared_ptr gpu_error_detected_event; + std::shared_ptr friend_invitation_storage_channel_event; + std::shared_ptr health_warning_disappeared_system_event; }; class IHomeMenuFunctions final : public ServiceFramework { @@ -314,7 +314,7 @@ private: void RequestToGetForeground(Kernel::HLERequestContext& ctx); void GetPopFromGeneralChannelEvent(Kernel::HLERequestContext& ctx); - Kernel::KEvent pop_from_general_channel_event; + std::shared_ptr pop_from_general_channel_event; }; class IGlobalStateController final : public ServiceFramework { diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp index ae995df6b..a56df6a7e 100755 --- a/src/core/hle/service/am/applets/applets.cpp +++ b/src/core/hle/service/am/applets/applets.cpp @@ -12,8 +12,10 @@ #include "core/frontend/applets/profile_select.h" #include "core/frontend/applets/software_keyboard.h" #include "core/frontend/applets/web_browser.h" +#include "core/hle/kernel/k_event.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_writable_event.h" +#include "core/hle/kernel/server_session.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applet_ae.h" #include "core/hle/service/am/applet_oe.h" @@ -29,16 +31,16 @@ namespace Service::AM::Applets { AppletDataBroker::AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_) - : system{system_}, applet_mode{applet_mode_}, state_changed_event{system.Kernel()}, - pop_out_data_event{system.Kernel()}, pop_interactive_out_data_event{system.Kernel()} { - - Kernel::KAutoObject::Create(std::addressof(state_changed_event)); - Kernel::KAutoObject::Create(std::addressof(pop_out_data_event)); - Kernel::KAutoObject::Create(std::addressof(pop_interactive_out_data_event)); - - state_changed_event.Initialize("ILibraryAppletAccessor:StateChangedEvent"); - pop_out_data_event.Initialize("ILibraryAppletAccessor:PopDataOutEvent"); - pop_interactive_out_data_event.Initialize("ILibraryAppletAccessor:PopInteractiveDataOutEvent"); + : system{system_}, applet_mode{applet_mode_} { + state_changed_event = + Kernel::KEvent::Create(system.Kernel(), "ILibraryAppletAccessor:StateChangedEvent"); + state_changed_event->Initialize(); + pop_out_data_event = + Kernel::KEvent::Create(system.Kernel(), "ILibraryAppletAccessor:PopDataOutEvent"); + pop_out_data_event->Initialize(); + pop_interactive_out_data_event = Kernel::KEvent::Create( + system.Kernel(), "ILibraryAppletAccessor:PopInteractiveDataOutEvent"); + pop_interactive_out_data_event->Initialize(); } AppletDataBroker::~AppletDataBroker() = default; @@ -65,7 +67,7 @@ std::shared_ptr AppletDataBroker::PopNormalDataToGame() { auto out = std::move(out_channel.front()); out_channel.pop_front(); - pop_out_data_event.GetWritableEvent().Clear(); + pop_out_data_event->GetWritableEvent()->Clear(); return out; } @@ -84,7 +86,7 @@ std::shared_ptr AppletDataBroker::PopInteractiveDataToGame() { auto out = std::move(out_interactive_channel.front()); out_interactive_channel.pop_front(); - pop_interactive_out_data_event.GetWritableEvent().Clear(); + pop_interactive_out_data_event->GetWritableEvent()->Clear(); return out; } @@ -103,7 +105,7 @@ void AppletDataBroker::PushNormalDataFromGame(std::shared_ptr&& storag void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr&& storage) { out_channel.emplace_back(std::move(storage)); - pop_out_data_event.GetWritableEvent().Signal(); + pop_out_data_event->GetWritableEvent()->Signal(); } void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr&& storage) { @@ -112,11 +114,11 @@ void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr&& s void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr&& storage) { out_interactive_channel.emplace_back(std::move(storage)); - pop_interactive_out_data_event.GetWritableEvent().Signal(); + pop_interactive_out_data_event->GetWritableEvent()->Signal(); } -void AppletDataBroker::SignalStateChanged() { - state_changed_event.GetWritableEvent().Signal(); +void AppletDataBroker::SignalStateChanged() const { + state_changed_event->GetWritableEvent()->Signal(); switch (applet_mode) { case LibraryAppletMode::AllForeground: @@ -140,16 +142,16 @@ void AppletDataBroker::SignalStateChanged() { } } -Kernel::KReadableEvent& AppletDataBroker::GetNormalDataEvent() { - return pop_out_data_event.GetReadableEvent(); +std::shared_ptr AppletDataBroker::GetNormalDataEvent() const { + return pop_out_data_event->GetReadableEvent(); } -Kernel::KReadableEvent& AppletDataBroker::GetInteractiveDataEvent() { - return pop_interactive_out_data_event.GetReadableEvent(); +std::shared_ptr AppletDataBroker::GetInteractiveDataEvent() const { + return pop_interactive_out_data_event->GetReadableEvent(); } -Kernel::KReadableEvent& AppletDataBroker::GetStateChangedEvent() { - return state_changed_event.GetReadableEvent(); +std::shared_ptr AppletDataBroker::GetStateChangedEvent() const { + return state_changed_event->GetReadableEvent(); } Applet::Applet(Core::System& system_, LibraryAppletMode applet_mode_) diff --git a/src/core/hle/service/am/applets/applets.h b/src/core/hle/service/am/applets/applets.h index 5c0b4b459..4215d2232 100755 --- a/src/core/hle/service/am/applets/applets.h +++ b/src/core/hle/service/am/applets/applets.h @@ -8,7 +8,7 @@ #include #include "common/swap.h" -#include "core/hle/kernel/k_event.h" +#include "core/hle/kernel/object.h" union ResultCode; @@ -95,11 +95,11 @@ public: void PushInteractiveDataFromGame(std::shared_ptr&& storage); void PushInteractiveDataFromApplet(std::shared_ptr&& storage); - void SignalStateChanged(); + void SignalStateChanged() const; - Kernel::KReadableEvent& GetNormalDataEvent(); - Kernel::KReadableEvent& GetInteractiveDataEvent(); - Kernel::KReadableEvent& GetStateChangedEvent(); + std::shared_ptr GetNormalDataEvent() const; + std::shared_ptr GetInteractiveDataEvent() const; + std::shared_ptr GetStateChangedEvent() const; private: Core::System& system; @@ -119,13 +119,13 @@ private: // PopInteractiveDataToGame and PushInteractiveDataFromApplet std::deque> out_interactive_channel; - Kernel::KEvent state_changed_event; + std::shared_ptr state_changed_event; // Signaled on PushNormalDataFromApplet - Kernel::KEvent pop_out_data_event; + std::shared_ptr pop_out_data_event; // Signaled on PushInteractiveDataFromApplet - Kernel::KEvent pop_interactive_out_data_event; + std::shared_ptr pop_interactive_out_data_event; }; class Applet { diff --git a/src/core/hle/service/am/applets/error.cpp b/src/core/hle/service/am/applets/error.cpp index 08348b180..0dd6ec68e 100755 --- a/src/core/hle/service/am/applets/error.cpp +++ b/src/core/hle/service/am/applets/error.cpp @@ -9,7 +9,7 @@ #include "common/string_util.h" #include "core/core.h" #include "core/frontend/applets/error.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applets/error.h" #include "core/reporter.h" diff --git a/src/core/hle/service/am/applets/general_backend.cpp b/src/core/hle/service/am/applets/general_backend.cpp index e95499edd..b7483261e 100755 --- a/src/core/hle/service/am/applets/general_backend.cpp +++ b/src/core/hle/service/am/applets/general_backend.cpp @@ -9,7 +9,7 @@ #include "common/logging/log.h" #include "core/core.h" #include "core/frontend/applets/general_frontend.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/hle/result.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applets/general_backend.h" diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp index e5f4a4485..2404921fd 100755 --- a/src/core/hle/service/am/applets/web_browser.cpp +++ b/src/core/hle/service/am/applets/web_browser.cpp @@ -17,7 +17,7 @@ #include "core/file_sys/system_archive/system_archive.h" #include "core/file_sys/vfs_vector.h" #include "core/frontend/applets/web_browser.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/hle/result.h" #include "core/hle/service/am/am.h" #include "core/hle/service/am/applets/web_browser.h" diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp index 1863260f1..75867e349 100755 --- a/src/core/hle/service/aoc/aoc_u.cpp +++ b/src/core/hle/service/aoc/aoc_u.cpp @@ -16,9 +16,10 @@ #include "core/file_sys/patch_manager.h" #include "core/file_sys/registered_cache.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/k_event.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/aoc/aoc_u.h" #include "core/loader/loader.h" @@ -49,7 +50,7 @@ static std::vector AccumulateAOCTitleIDs(Core::System& system) { class IPurchaseEventManager final : public ServiceFramework { public: explicit IPurchaseEventManager(Core::System& system_) - : ServiceFramework{system_, "IPurchaseEventManager"}, purchased_event{system.Kernel()} { + : ServiceFramework{system_, "IPurchaseEventManager"} { // clang-format off static const FunctionInfo functions[] = { {0, &IPurchaseEventManager::SetDefaultDeliveryTarget, "SetDefaultDeliveryTarget"}, @@ -62,8 +63,9 @@ public: RegisterHandlers(functions); - Kernel::KAutoObject::Create(std::addressof(purchased_event)); - purchased_event.Initialize("IPurchaseEventManager:PurchasedEvent"); + purchased_event = + Kernel::KEvent::Create(system.Kernel(), "IPurchaseEventManager:PurchasedEvent"); + purchased_event->Initialize(); } private: @@ -96,15 +98,14 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(purchased_event.GetReadableEvent()); + rb.PushCopyObjects(purchased_event->GetReadableEvent()); } - Kernel::KEvent purchased_event; + std::shared_ptr purchased_event; }; AOC_U::AOC_U(Core::System& system_) - : ServiceFramework{system_, "aoc:u"}, add_on_content{AccumulateAOCTitleIDs(system)}, - aoc_change_event{system.Kernel()} { + : ServiceFramework{system_, "aoc:u"}, add_on_content{AccumulateAOCTitleIDs(system)} { // clang-format off static const FunctionInfo functions[] = { {0, nullptr, "CountAddOnContentByApplicationId"}, @@ -126,8 +127,9 @@ AOC_U::AOC_U(Core::System& system_) RegisterHandlers(functions); - Kernel::KAutoObject::Create(std::addressof(aoc_change_event)); - aoc_change_event.Initialize("GetAddOnContentListChanged:Event"); + auto& kernel = system.Kernel(); + aoc_change_event = Kernel::KEvent::Create(kernel, "GetAddOnContentListChanged:Event"); + aoc_change_event->Initialize(); } AOC_U::~AOC_U() = default; @@ -254,7 +256,7 @@ void AOC_U::GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(aoc_change_event.GetReadableEvent()); + rb.PushCopyObjects(aoc_change_event->GetReadableEvent()); } void AOC_U::CreateEcPurchasedEventManager(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/aoc/aoc_u.h b/src/core/hle/service/aoc/aoc_u.h index 65095baa2..1aa23529e 100755 --- a/src/core/hle/service/aoc/aoc_u.h +++ b/src/core/hle/service/aoc/aoc_u.h @@ -4,7 +4,6 @@ #pragma once -#include "core/hle/kernel/k_event.h" #include "core/hle/service/service.h" namespace Core { @@ -32,7 +31,7 @@ private: void CreatePermanentEcPurchasedEventManager(Kernel::HLERequestContext& ctx); std::vector add_on_content; - Kernel::KEvent aoc_change_event; + std::shared_ptr aoc_change_event; }; /// Registers all AOC services with the specified service manager. diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index e1ae726f5..5f51fca9a 100755 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -43,9 +43,9 @@ class IAudioOut final : public ServiceFramework { public: IAudioOut(Core::System& system_, AudoutParams audio_params_, AudioCore::AudioOut& audio_core_, std::string&& device_name_, std::string&& unique_name) - : ServiceFramework{system_, "IAudioOut"}, audio_core{audio_core_}, device_name{std::move( - device_name_)}, - audio_params{audio_params_}, buffer_event{system.Kernel()}, main_memory{system.Memory()} { + : ServiceFramework{system_, "IAudioOut"}, audio_core{audio_core_}, + device_name{std::move(device_name_)}, audio_params{audio_params_}, main_memory{ + system.Memory()} { // clang-format off static const FunctionInfo functions[] = { {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"}, @@ -67,13 +67,13 @@ public: RegisterHandlers(functions); // This is the event handle used to check if the audio buffer was released - Kernel::KAutoObject::Create(std::addressof(buffer_event)); - buffer_event.Initialize("IAudioOutBufferReleased"); + buffer_event = Kernel::KEvent::Create(system.Kernel(), "IAudioOutBufferReleased"); + buffer_event->Initialize(); stream = audio_core.OpenStream(system.CoreTiming(), audio_params.sample_rate, audio_params.channel_count, std::move(unique_name), [this] { const auto guard = LockService(); - buffer_event.GetWritableEvent().Signal(); + buffer_event->GetWritableEvent()->Signal(); }); } @@ -126,7 +126,7 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(buffer_event.GetReadableEvent()); + rb.PushCopyObjects(buffer_event->GetReadableEvent()); } void AppendAudioOutBufferImpl(Kernel::HLERequestContext& ctx) { @@ -220,7 +220,7 @@ private: [[maybe_unused]] AudoutParams audio_params{}; /// This is the event handle used to check if the audio buffer was released - Kernel::KEvent buffer_event; + std::shared_ptr buffer_event; Core::Memory::Memory& main_memory; }; diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 513bd3730..3a48342fd 100755 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -30,7 +30,7 @@ public: explicit IAudioRenderer(Core::System& system_, const AudioCommon::AudioRendererParameter& audren_params, const std::size_t instance_number) - : ServiceFramework{system_, "IAudioRenderer"}, system_event{system.Kernel()} { + : ServiceFramework{system_, "IAudioRenderer"} { // clang-format off static const FunctionInfo functions[] = { {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"}, @@ -49,13 +49,13 @@ public: // clang-format on RegisterHandlers(functions); - Kernel::KAutoObject::Create(std::addressof(system_event)); - system_event.Initialize("IAudioRenderer:SystemEvent"); + system_event = Kernel::KEvent::Create(system.Kernel(), "IAudioRenderer:SystemEvent"); + system_event->Initialize(); renderer = std::make_unique( system.CoreTiming(), system.Memory(), audren_params, [this]() { const auto guard = LockService(); - system_event.GetWritableEvent().Signal(); + system_event->GetWritableEvent()->Signal(); }, instance_number); } @@ -128,7 +128,7 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(system_event.GetReadableEvent()); + rb.PushCopyObjects(system_event->GetReadableEvent()); } void SetRenderingTimeLimit(Kernel::HLERequestContext& ctx) { @@ -162,7 +162,7 @@ private: rb.Push(ERR_NOT_SUPPORTED); } - Kernel::KEvent system_event; + std::shared_ptr system_event; std::unique_ptr renderer; u32 rendering_time_limit_percent = 100; }; @@ -170,9 +170,7 @@ private: class IAudioDevice final : public ServiceFramework { public: explicit IAudioDevice(Core::System& system_, u32_le revision_num) - : ServiceFramework{system_, "IAudioDevice"}, revision{revision_num}, - buffer_event{system.Kernel()}, audio_input_device_switch_event{system.Kernel()}, - audio_output_device_switch_event{system.Kernel()} { + : ServiceFramework{system_, "IAudioDevice"}, revision{revision_num} { static const FunctionInfo functions[] = { {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"}, {1, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolume"}, @@ -190,17 +188,20 @@ public: }; RegisterHandlers(functions); - Kernel::KAutoObject::Create(std::addressof(buffer_event)); - buffer_event.Initialize("IAudioOutBufferReleasedEvent"); + auto& kernel = system.Kernel(); + buffer_event = Kernel::KEvent::Create(kernel, "IAudioOutBufferReleasedEvent"); + buffer_event->Initialize(); // Should be similar to audio_output_device_switch_event - Kernel::KAutoObject::Create(std::addressof(audio_input_device_switch_event)); - audio_input_device_switch_event.Initialize("IAudioDevice:AudioInputDeviceSwitchedEvent"); + audio_input_device_switch_event = + Kernel::KEvent::Create(kernel, "IAudioDevice:AudioInputDeviceSwitchedEvent"); + audio_input_device_switch_event->Initialize(); // Should only be signalled when an audio output device has been changed, example: speaker // to headset - Kernel::KAutoObject::Create(std::addressof(audio_output_device_switch_event)); - audio_output_device_switch_event.Initialize("IAudioDevice:AudioOutputDeviceSwitchedEvent"); + audio_output_device_switch_event = + Kernel::KEvent::Create(kernel, "IAudioDevice:AudioOutputDeviceSwitchedEvent"); + audio_output_device_switch_event->Initialize(); } private: @@ -289,11 +290,11 @@ private: void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) { LOG_WARNING(Service_Audio, "(STUBBED) called"); - buffer_event.GetWritableEvent().Signal(); + buffer_event->GetWritableEvent()->Signal(); IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(buffer_event.GetReadableEvent()); + rb.PushCopyObjects(buffer_event->GetReadableEvent()); } void GetActiveChannelCount(Kernel::HLERequestContext& ctx) { @@ -310,7 +311,7 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(audio_input_device_switch_event.GetReadableEvent()); + rb.PushCopyObjects(audio_input_device_switch_event->GetReadableEvent()); } void QueryAudioDeviceOutputEvent(Kernel::HLERequestContext& ctx) { @@ -318,13 +319,13 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(audio_output_device_switch_event.GetReadableEvent()); + rb.PushCopyObjects(audio_output_device_switch_event->GetReadableEvent()); } u32_le revision = 0; - Kernel::KEvent buffer_event; - Kernel::KEvent audio_input_device_switch_event; - Kernel::KEvent audio_output_device_switch_event; + std::shared_ptr buffer_event; + std::shared_ptr audio_input_device_switch_event; + std::shared_ptr audio_output_device_switch_event; }; // namespace Audio diff --git a/src/core/hle/service/bcat/backend/backend.cpp b/src/core/hle/service/bcat/backend/backend.cpp index 0e935bfa6..92d25dbe4 100755 --- a/src/core/hle/service/bcat/backend/backend.cpp +++ b/src/core/hle/service/bcat/backend/backend.cpp @@ -5,6 +5,7 @@ #include "common/hex_util.h" #include "common/logging/log.h" #include "core/core.h" +#include "core/hle/kernel/k_event.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_writable_event.h" #include "core/hle/lock.h" @@ -13,14 +14,14 @@ namespace Service::BCAT { ProgressServiceBackend::ProgressServiceBackend(Kernel::KernelCore& kernel, - std::string_view event_name) - : update_event{kernel} { - Kernel::KAutoObject::Create(std::addressof(update_event)); - update_event.Initialize("ProgressServiceBackend:UpdateEvent:" + std::string(event_name)); + std::string_view event_name) { + event = Kernel::KEvent::Create(kernel, + "ProgressServiceBackend:UpdateEvent:" + std::string(event_name)); + event->Initialize(); } -Kernel::KReadableEvent& ProgressServiceBackend::GetEvent() { - return update_event.GetReadableEvent(); +std::shared_ptr ProgressServiceBackend::GetEvent() const { + return event->GetReadableEvent(); } DeliveryCacheProgressImpl& ProgressServiceBackend::GetImpl() { @@ -85,12 +86,12 @@ void ProgressServiceBackend::FinishDownload(ResultCode result) { SignalUpdate(); } -void ProgressServiceBackend::SignalUpdate() { +void ProgressServiceBackend::SignalUpdate() const { if (need_hle_lock) { std::lock_guard lock(HLE::g_hle_lock); - update_event.GetWritableEvent().Signal(); + event->GetWritableEvent()->Signal(); } else { - update_event.GetWritableEvent().Signal(); + event->GetWritableEvent()->Signal(); } } diff --git a/src/core/hle/service/bcat/backend/backend.h b/src/core/hle/service/bcat/backend/backend.h index f591a362a..db585b069 100755 --- a/src/core/hle/service/bcat/backend/backend.h +++ b/src/core/hle/service/bcat/backend/backend.h @@ -11,7 +11,6 @@ #include "common/common_types.h" #include "core/file_sys/vfs_types.h" -#include "core/hle/kernel/k_event.h" #include "core/hle/result.h" namespace Core { @@ -99,13 +98,13 @@ public: private: explicit ProgressServiceBackend(Kernel::KernelCore& kernel, std::string_view event_name); - Kernel::KReadableEvent& GetEvent(); + std::shared_ptr GetEvent() const; DeliveryCacheProgressImpl& GetImpl(); - void SignalUpdate(); + void SignalUpdate() const; DeliveryCacheProgressImpl impl{}; - Kernel::KEvent update_event; + std::shared_ptr event; bool need_hle_lock = false; }; diff --git a/src/core/hle/service/bcat/module.cpp b/src/core/hle/service/bcat/module.cpp index 0206cbb6a..285085f2a 100755 --- a/src/core/hle/service/bcat/module.cpp +++ b/src/core/hle/service/bcat/module.cpp @@ -12,9 +12,9 @@ #include "core/core.h" #include "core/file_sys/vfs.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_writable_event.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/bcat/backend/backend.h" #include "core/hle/service/bcat/bcat.h" #include "core/hle/service/bcat/module.h" @@ -88,9 +88,11 @@ struct DeliveryCacheDirectoryEntry { class IDeliveryCacheProgressService final : public ServiceFramework { public: - explicit IDeliveryCacheProgressService(Core::System& system_, Kernel::KReadableEvent& event_, + explicit IDeliveryCacheProgressService(Core::System& system_, + std::shared_ptr event_, const DeliveryCacheProgressImpl& impl_) - : ServiceFramework{system_, "IDeliveryCacheProgressService"}, event{event_}, impl{impl_} { + : ServiceFramework{system_, "IDeliveryCacheProgressService"}, event{std::move(event_)}, + impl{impl_} { // clang-format off static const FunctionInfo functions[] = { {0, &IDeliveryCacheProgressService::GetEvent, "GetEvent"}, @@ -119,7 +121,7 @@ private: rb.Push(RESULT_SUCCESS); } - Kernel::KReadableEvent& event; + std::shared_ptr event; const DeliveryCacheProgressImpl& impl; }; diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp index fd97a822c..af3a5842d 100755 --- a/src/core/hle/service/btdrv/btdrv.cpp +++ b/src/core/hle/service/btdrv/btdrv.cpp @@ -17,8 +17,7 @@ namespace Service::BtDrv { class Bt final : public ServiceFramework { public: - explicit Bt(Core::System& system_) - : ServiceFramework{system_, "bt"}, register_event{system.Kernel()} { + explicit Bt(Core::System& system_) : ServiceFramework{system_, "bt"} { // clang-format off static const FunctionInfo functions[] = { {0, nullptr, "LeClientReadCharacteristic"}, @@ -35,8 +34,9 @@ public: // clang-format on RegisterHandlers(functions); - Kernel::KAutoObject::Create(std::addressof(register_event)); - register_event.Initialize("BT:RegisterEvent"); + auto& kernel = system.Kernel(); + register_event = Kernel::KEvent::Create(kernel, "BT:RegisterEvent"); + register_event->Initialize(); } private: @@ -45,10 +45,10 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(register_event.GetReadableEvent()); + rb.PushCopyObjects(register_event->GetReadableEvent()); } - Kernel::KEvent register_event; + std::shared_ptr register_event; }; class BtDrv final : public ServiceFramework { diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp index 3b5ef69e1..d1ebc2388 100755 --- a/src/core/hle/service/btm/btm.cpp +++ b/src/core/hle/service/btm/btm.cpp @@ -18,10 +18,7 @@ namespace Service::BTM { class IBtmUserCore final : public ServiceFramework { public: - explicit IBtmUserCore(Core::System& system_) - : ServiceFramework{system_, "IBtmUserCore"}, scan_event{system.Kernel()}, - connection_event{system.Kernel()}, service_discovery{system.Kernel()}, - config_event{system.Kernel()} { + explicit IBtmUserCore(Core::System& system_) : ServiceFramework{system_, "IBtmUserCore"} { // clang-format off static const FunctionInfo functions[] = { {0, &IBtmUserCore::AcquireBleScanEvent, "AcquireBleScanEvent"}, @@ -60,15 +57,15 @@ public: // clang-format on RegisterHandlers(functions); - Kernel::KAutoObject::Create(std::addressof(scan_event)); - Kernel::KAutoObject::Create(std::addressof(connection_event)); - Kernel::KAutoObject::Create(std::addressof(service_discovery)); - Kernel::KAutoObject::Create(std::addressof(config_event)); - - scan_event.Initialize("IBtmUserCore:ScanEvent"); - connection_event.Initialize("IBtmUserCore:ConnectionEvent"); - service_discovery.Initialize("IBtmUserCore:Discovery"); - config_event.Initialize("IBtmUserCore:ConfigEvent"); + auto& kernel = system.Kernel(); + scan_event = Kernel::KEvent::Create(kernel, "IBtmUserCore:ScanEvent"); + scan_event->Initialize(); + connection_event = Kernel::KEvent::Create(kernel, "IBtmUserCore:ConnectionEvent"); + connection_event->Initialize(); + service_discovery = Kernel::KEvent::Create(kernel, "IBtmUserCore:Discovery"); + service_discovery->Initialize(); + config_event = Kernel::KEvent::Create(kernel, "IBtmUserCore:ConfigEvent"); + config_event->Initialize(); } private: @@ -77,7 +74,7 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(scan_event.GetReadableEvent()); + rb.PushCopyObjects(scan_event->GetReadableEvent()); } void AcquireBleConnectionEvent(Kernel::HLERequestContext& ctx) { @@ -85,7 +82,7 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(connection_event.GetReadableEvent()); + rb.PushCopyObjects(connection_event->GetReadableEvent()); } void AcquireBleServiceDiscoveryEvent(Kernel::HLERequestContext& ctx) { @@ -93,7 +90,7 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(service_discovery.GetReadableEvent()); + rb.PushCopyObjects(service_discovery->GetReadableEvent()); } void AcquireBleMtuConfigEvent(Kernel::HLERequestContext& ctx) { @@ -101,13 +98,13 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(config_event.GetReadableEvent()); + rb.PushCopyObjects(config_event->GetReadableEvent()); } - Kernel::KEvent scan_event; - Kernel::KEvent connection_event; - Kernel::KEvent service_discovery; - Kernel::KEvent config_event; + std::shared_ptr scan_event; + std::shared_ptr connection_event; + std::shared_ptr service_discovery; + std::shared_ptr config_event; }; class BTM_USR final : public ServiceFramework { diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp index 432abde76..13147472e 100755 --- a/src/core/hle/service/fatal/fatal.cpp +++ b/src/core/hle/service/fatal/fatal.cpp @@ -12,7 +12,7 @@ #include "common/swap.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/fatal/fatal.h" #include "core/hle/service/fatal/fatal_p.h" #include "core/hle/service/fatal/fatal_u.h" diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 67baaee9b..67b2b3102 100755 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -21,7 +21,7 @@ #include "core/file_sys/sdmc_factory.h" #include "core/file_sys/vfs.h" #include "core/file_sys/vfs_offset.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/filesystem/fsp_ldr.h" #include "core/hle/service/filesystem/fsp_pr.h" diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index 92ea27074..7dc487e48 100755 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -25,7 +25,7 @@ #include "core/file_sys/system_archive/system_archive.h" #include "core/file_sys/vfs.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/filesystem/fsp_srv.h" #include "core/reporter.h" diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index 91c202952..a35979053 100755 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp @@ -185,8 +185,7 @@ private: class INotificationService final : public ServiceFramework { public: explicit INotificationService(Common::UUID uuid_, Core::System& system_) - : ServiceFramework{system_, "INotificationService"}, uuid{uuid_}, notification_event{ - system.Kernel()} { + : ServiceFramework{system_, "INotificationService"}, uuid{uuid_} { // clang-format off static const FunctionInfo functions[] = { {0, &INotificationService::GetEvent, "GetEvent"}, @@ -197,8 +196,9 @@ public: RegisterHandlers(functions); - Kernel::KAutoObject::Create(std::addressof(notification_event)); - notification_event.Initialize("INotificationService:NotifyEvent"); + notification_event = + Kernel::KEvent::Create(system.Kernel(), "INotificationService:NotifyEvent"); + notification_event->Initialize(); } private: @@ -207,7 +207,7 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(notification_event.GetReadableEvent()); + rb.PushCopyObjects(notification_event->GetReadableEvent()); } void Clear(Kernel::HLERequestContext& ctx) { @@ -273,7 +273,7 @@ private: }; Common::UUID uuid{Common::INVALID_UUID}; - Kernel::KEvent notification_event; + std::shared_ptr notification_event; std::queue notifications; States states{}; }; diff --git a/src/core/hle/service/glue/arp.cpp b/src/core/hle/service/glue/arp.cpp index 6ad62ee5a..7b1c6677c 100755 --- a/src/core/hle/service/glue/arp.cpp +++ b/src/core/hle/service/glue/arp.cpp @@ -9,8 +9,8 @@ #include "core/file_sys/control_metadata.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/hle_ipc.h" -#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/glue/arp.h" #include "core/hle/service/glue/errors.h" #include "core/hle/service/glue/manager.h" diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp index 7acad3798..d4678ef49 100755 --- a/src/core/hle/service/hid/controllers/npad.cpp +++ b/src/core/hle/service/hid/controllers/npad.cpp @@ -159,7 +159,7 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { const auto controller_type = connected_controllers[controller_idx].type; auto& controller = shared_memory_entries[controller_idx]; if (controller_type == NPadControllerType::None) { - styleset_changed_events[controller_idx]->GetWritableEvent().Signal(); + styleset_changed_events[controller_idx]->GetWritableEvent()->Signal(); return; } controller.style_set.raw = 0; // Zero out @@ -253,8 +253,9 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) { void Controller_NPad::OnInit() { auto& kernel = system.Kernel(); for (std::size_t i = 0; i < styleset_changed_events.size(); ++i) { - styleset_changed_events[i] = Kernel::KEvent::Create(kernel); - styleset_changed_events[i]->Initialize(fmt::format("npad:NpadStyleSetChanged_{}", i)); + styleset_changed_events[i] = + Kernel::KEvent::Create(kernel, fmt::format("npad:NpadStyleSetChanged_{}", i)); + styleset_changed_events[i]->Initialize(); } if (!IsControllerActivated()) { @@ -340,11 +341,6 @@ void Controller_NPad::OnRelease() { VibrateControllerAtIndex(npad_idx, device_idx, {}); } } - - for (std::size_t i = 0; i < styleset_changed_events.size(); ++i) { - styleset_changed_events[i]->Close(); - styleset_changed_events[i] = nullptr; - } } void Controller_NPad::RequestPadStateUpdate(u32 npad_id) { @@ -959,12 +955,14 @@ bool Controller_NPad::IsVibrationDeviceMounted(const DeviceHandle& vibration_dev return vibration_devices_mounted[npad_index][device_index]; } -Kernel::KReadableEvent& Controller_NPad::GetStyleSetChangedEvent(u32 npad_id) { - return styleset_changed_events[NPadIdToIndex(npad_id)]->GetReadableEvent(); +std::shared_ptr Controller_NPad::GetStyleSetChangedEvent( + u32 npad_id) const { + const auto& styleset_event = styleset_changed_events[NPadIdToIndex(npad_id)]; + return styleset_event->GetReadableEvent(); } void Controller_NPad::SignalStyleSetChangedEvent(u32 npad_id) const { - styleset_changed_events[NPadIdToIndex(npad_id)]->GetWritableEvent().Signal(); + styleset_changed_events[NPadIdToIndex(npad_id)]->GetWritableEvent()->Signal(); } void Controller_NPad::AddNewControllerAt(NPadControllerType controller, std::size_t npad_index) { diff --git a/src/core/hle/service/hid/controllers/npad.h b/src/core/hle/service/hid/controllers/npad.h index c050c9a44..ea484d4bf 100755 --- a/src/core/hle/service/hid/controllers/npad.h +++ b/src/core/hle/service/hid/controllers/npad.h @@ -11,6 +11,7 @@ #include "common/quaternion.h" #include "common/settings.h" #include "core/frontend/input.h" +#include "core/hle/kernel/object.h" #include "core/hle/service/hid/controllers/controller_base.h" namespace Kernel { @@ -198,7 +199,7 @@ public: bool IsVibrationDeviceMounted(const DeviceHandle& vibration_device_handle) const; - Kernel::KReadableEvent& GetStyleSetChangedEvent(u32 npad_id); + std::shared_ptr GetStyleSetChangedEvent(u32 npad_id) const; void SignalStyleSetChangedEvent(u32 npad_id) const; // Adds a new controller at an index. @@ -572,9 +573,8 @@ private: NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual}; NpadCommunicationMode communication_mode{NpadCommunicationMode::Default}; // Each controller should have their own styleset changed event - std::array styleset_changed_events{}; - std::array, 10> - last_vibration_timepoints{}; + std::array, 10> styleset_changed_events; + std::array, 10> last_vibration_timepoints; std::array, 10> latest_vibration_values{}; bool permit_vibration_session_enabled{false}; std::array, 10> vibration_devices_mounted{}; diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 49c17fd14..9c4bf6d16 100755 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -13,18 +13,18 @@ #include "core/frontend/input.h" #include "core/hardware_properties.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/k_client_port.h" +#include "core/hle/kernel/client_port.h" +#include "core/hle/kernel/client_session.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_shared_memory.h" -#include "core/hle/kernel/k_transfer_memory.h" #include "core/hle/kernel/k_writable_event.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/transfer_memory.h" #include "core/hle/service/hid/errors.h" #include "core/hle/service/hid/hid.h" #include "core/hle/service/hid/irs.h" #include "core/hle/service/hid/xcd.h" #include "core/hle/service/service.h" -#include "core/memory.h" #include "core/hle/service/hid/controllers/console_sixaxis.h" #include "core/hle/service/hid/controllers/controller_base.h" @@ -53,6 +53,9 @@ IAppletResource::IAppletResource(Core::System& system_) }; RegisterHandlers(functions); + auto& kernel = system.Kernel(); + shared_mem = SharedFrom(&kernel.GetHidSharedMem()); + MakeController(HidController::DebugPad); MakeController(HidController::Touchscreen); MakeController(HidController::Mouse); @@ -115,7 +118,7 @@ void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(&system.Kernel().GetHidSharedMem()); + rb.PushCopyObjects(shared_mem); } void IAppletResource::UpdateControllers(std::uintptr_t user_data, @@ -127,8 +130,7 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data, if (should_reload) { controller->OnLoadInputDevices(); } - controller->OnUpdate(core_timing, system.Kernel().GetHidSharedMem().GetPointer(), - SHARED_MEMORY_SIZE); + controller->OnUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE); } // If ns_late is higher than the update rate ignore the delay @@ -143,7 +145,7 @@ void IAppletResource::UpdateMotion(std::uintptr_t user_data, std::chrono::nanose auto& core_timing = system.CoreTiming(); controllers[static_cast(HidController::NPad)]->OnMotionUpdate( - core_timing, system.Kernel().GetHidSharedMem().GetPointer(), SHARED_MEMORY_SIZE); + core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE); // If ns_late is higher than the update rate ignore the delay if (ns_late > motion_update_ns) { @@ -1494,20 +1496,20 @@ void Hid::InitializeSevenSixAxisSensor(Kernel::HLERequestContext& ctx) { ASSERT_MSG(t_mem_1_size == 0x1000, "t_mem_1_size is not 0x1000 bytes"); ASSERT_MSG(t_mem_2_size == 0x7F000, "t_mem_2_size is not 0x7F000 bytes"); - auto t_mem_1 = system.CurrentProcess()->GetHandleTable().GetObject( - t_mem_1_handle); + auto t_mem_1 = + system.CurrentProcess()->GetHandleTable().Get(t_mem_1_handle); - if (t_mem_1.IsNull()) { + if (t_mem_1 == nullptr) { LOG_ERROR(Service_HID, "t_mem_1 is a nullptr for handle=0x{:08X}", t_mem_1_handle); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_UNKNOWN); return; } - auto t_mem_2 = system.CurrentProcess()->GetHandleTable().GetObject( - t_mem_2_handle); + auto t_mem_2 = + system.CurrentProcess()->GetHandleTable().Get(t_mem_2_handle); - if (t_mem_2.IsNull()) { + if (t_mem_2 == nullptr) { LOG_ERROR(Service_HID, "t_mem_2 is a nullptr for handle=0x{:08X}", t_mem_2_handle); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_UNKNOWN); @@ -1522,7 +1524,7 @@ void Hid::InitializeSevenSixAxisSensor(Kernel::HLERequestContext& ctx) { .ActivateController(); applet_resource->GetController(HidController::ConsoleSixAxisSensor) - .SetTransferMemoryPointer(system.Memory().GetPointer(t_mem_1->GetSourceAddress())); + .SetTransferMemoryPointer(t_mem_1->GetPointer()); LOG_WARNING(Service_HID, "called, t_mem_1_handle=0x{:08X}, t_mem_2_handle=0x{:08X}, " diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index aa3307955..c2bdd39a3 100755 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -13,6 +13,10 @@ namespace Core::Timing { struct EventType; } +namespace Kernel { +class KSharedMemory; +} + namespace Service::SM { class ServiceManager; } @@ -65,6 +69,8 @@ private: void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); void UpdateMotion(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); + std::shared_ptr shared_mem; + std::shared_ptr pad_update_event; std::shared_ptr motion_update_event; diff --git a/src/core/hle/service/hid/irs.cpp b/src/core/hle/service/hid/irs.cpp index 3c6085990..2dfa936fb 100755 --- a/src/core/hle/service/hid/irs.cpp +++ b/src/core/hle/service/hid/irs.cpp @@ -37,6 +37,10 @@ IRS::IRS(Core::System& system_) : ServiceFramework{system_, "irs"} { // clang-format on RegisterHandlers(functions); + + auto& kernel = system.Kernel(); + + shared_mem = SharedFrom(&kernel.GetIrsSharedMem()); } void IRS::ActivateIrsensor(Kernel::HLERequestContext& ctx) { @@ -58,7 +62,7 @@ void IRS::GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(&system.Kernel().GetIrsSharedMem()); + rb.PushCopyObjects(shared_mem); } void IRS::StopImageProcessor(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/hid/irs.h b/src/core/hle/service/hid/irs.h index 9bc6462b0..b0c8c7168 100755 --- a/src/core/hle/service/hid/irs.h +++ b/src/core/hle/service/hid/irs.h @@ -4,12 +4,17 @@ #pragma once +#include "core/hle/kernel/object.h" #include "core/hle/service/service.h" namespace Core { class System; } +namespace Kernel { +class KSharedMemory; +} + namespace Service::HID { class IRS final : public ServiceFramework { @@ -37,6 +42,7 @@ private: void StopImageProcessorAsync(Kernel::HLERequestContext& ctx); void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx); + std::shared_ptr shared_mem; const u32 device_handle{0xABCD}; }; diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index 563916f29..c8bc60ad1 100755 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp @@ -12,8 +12,8 @@ #include "core/core.h" #include "core/hle/ipc_helpers.h" #include "core/hle/kernel/k_page_table.h" -#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_system_control.h" +#include "core/hle/kernel/process.h" #include "core/hle/kernel/svc_results.h" #include "core/hle/service/ldr/ldr.h" #include "core/hle/service/service.h" @@ -321,7 +321,7 @@ public: return addr; } - ResultVal MapProcessCodeMemory(Kernel::KProcess* process, VAddr baseAddress, + ResultVal MapProcessCodeMemory(Kernel::Process* process, VAddr baseAddress, u64 size) const { for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) { auto& page_table{process->PageTable()}; @@ -342,7 +342,7 @@ public: return ERROR_INSUFFICIENT_ADDRESS_SPACE; } - ResultVal MapNro(Kernel::KProcess* process, VAddr nro_addr, std::size_t nro_size, + ResultVal MapNro(Kernel::Process* process, VAddr nro_addr, std::size_t nro_size, VAddr bss_addr, std::size_t bss_size, std::size_t size) const { for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) { auto& page_table{process->PageTable()}; @@ -378,7 +378,7 @@ public: return ERROR_INSUFFICIENT_ADDRESS_SPACE; } - ResultCode LoadNro(Kernel::KProcess* process, const NROHeader& nro_header, VAddr nro_addr, + ResultCode LoadNro(Kernel::Process* process, const NROHeader& nro_header, VAddr nro_addr, VAddr start) const { const VAddr text_start{start + nro_header.segment_headers[TEXT_INDEX].memory_offset}; const VAddr ro_start{start + nro_header.segment_headers[RO_INDEX].memory_offset}; diff --git a/src/core/hle/service/mm/mm_u.cpp b/src/core/hle/service/mm/mm_u.cpp index c8519e2db..b0cb07d24 100755 --- a/src/core/hle/service/mm/mm_u.cpp +++ b/src/core/hle/service/mm/mm_u.cpp @@ -4,6 +4,7 @@ #include "common/logging/log.h" #include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/client_session.h" #include "core/hle/service/mm/mm_u.h" #include "core/hle/service/sm/sm.h" diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp index d25b20ab5..2d1d4d67f 100755 --- a/src/core/hle/service/nfp/nfp.cpp +++ b/src/core/hle/service/nfp/nfp.cpp @@ -8,6 +8,7 @@ #include "common/logging/log.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/k_event.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_writable_event.h" @@ -23,9 +24,10 @@ constexpr ResultCode ERR_NO_APPLICATION_AREA(ErrorModule::NFP, 152); Module::Interface::Interface(std::shared_ptr module_, Core::System& system_, const char* name) - : ServiceFramework{system_, name}, nfc_tag_load{system.Kernel()}, module{std::move(module_)} { - Kernel::KAutoObject::Create(std::addressof(nfc_tag_load)); - nfc_tag_load.Initialize("IUser:NFCTagDetected"); + : ServiceFramework{system_, name}, module{std::move(module_)} { + auto& kernel = system.Kernel(); + nfc_tag_load = Kernel::KEvent::Create(kernel, "IUser:NFCTagDetected"); + nfc_tag_load->Initialize(); } Module::Interface::~Interface() = default; @@ -33,8 +35,7 @@ Module::Interface::~Interface() = default; class IUser final : public ServiceFramework { public: explicit IUser(Module::Interface& nfp_interface_, Core::System& system_) - : ServiceFramework{system_, "NFP::IUser"}, nfp_interface{nfp_interface_}, - deactivate_event{system.Kernel()}, availability_change_event{system.Kernel()} { + : ServiceFramework{system_, "NFP::IUser"}, nfp_interface{nfp_interface_} { static const FunctionInfo functions[] = { {0, &IUser::Initialize, "Initialize"}, {1, &IUser::Finalize, "Finalize"}, @@ -64,11 +65,11 @@ public: }; RegisterHandlers(functions); - Kernel::KAutoObject::Create(std::addressof(deactivate_event)); - Kernel::KAutoObject::Create(std::addressof(availability_change_event)); - - deactivate_event.Initialize("IUser:DeactivateEvent"); - availability_change_event.Initialize("IUser:AvailabilityChangeEvent"); + auto& kernel = system.Kernel(); + deactivate_event = Kernel::KEvent::Create(kernel, "IUser:DeactivateEvent"); + deactivate_event->Initialize(); + availability_change_event = Kernel::KEvent::Create(kernel, "IUser:AvailabilityChangeEvent"); + availability_change_event->Initialize(); } private: @@ -166,7 +167,7 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(deactivate_event.GetReadableEvent()); + rb.PushCopyObjects(deactivate_event->GetReadableEvent()); } void StopDetection(Kernel::HLERequestContext& ctx) { @@ -175,7 +176,7 @@ private: switch (device_state) { case DeviceState::TagFound: case DeviceState::TagNearby: - deactivate_event.GetWritableEvent().Signal(); + deactivate_event->GetWritableEvent()->Signal(); device_state = DeviceState::Initialized; break; case DeviceState::SearchingForTag: @@ -264,7 +265,7 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(availability_change_event.GetReadableEvent()); + rb.PushCopyObjects(availability_change_event->GetReadableEvent()); } void GetRegisterInfo(Kernel::HLERequestContext& ctx) { @@ -318,9 +319,9 @@ private: const u32 npad_id{0}; // Player 1 controller State state{State::NonInitialized}; DeviceState device_state{DeviceState::Initialized}; - Module::Interface& nfp_interface; - Kernel::KEvent deactivate_event; - Kernel::KEvent availability_change_event; + std::shared_ptr deactivate_event; + std::shared_ptr availability_change_event; + const Module::Interface& nfp_interface; }; void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) { @@ -338,12 +339,12 @@ bool Module::Interface::LoadAmiibo(const std::vector& buffer) { } std::memcpy(&amiibo, buffer.data(), sizeof(amiibo)); - nfc_tag_load.GetWritableEvent().Signal(); + nfc_tag_load->GetWritableEvent()->Signal(); return true; } -Kernel::KReadableEvent& Module::Interface::GetNFCEvent() { - return nfc_tag_load.GetReadableEvent(); +const std::shared_ptr& Module::Interface::GetNFCEvent() const { + return nfc_tag_load->GetReadableEvent(); } const Module::Interface::AmiiboFile& Module::Interface::GetAmiiboBuffer() const { diff --git a/src/core/hle/service/nfp/nfp.h b/src/core/hle/service/nfp/nfp.h index 5e4e49bc6..c46551760 100755 --- a/src/core/hle/service/nfp/nfp.h +++ b/src/core/hle/service/nfp/nfp.h @@ -7,7 +7,6 @@ #include #include -#include "core/hle/kernel/k_event.h" #include "core/hle/service/service.h" namespace Kernel { @@ -39,11 +38,11 @@ public: void CreateUserInterface(Kernel::HLERequestContext& ctx); bool LoadAmiibo(const std::vector& buffer); - Kernel::KReadableEvent& GetNFCEvent(); + const std::shared_ptr& GetNFCEvent() const; const AmiiboFile& GetAmiiboBuffer() const; private: - Kernel::KEvent nfc_tag_load; + std::shared_ptr nfc_tag_load; AmiiboFile amiibo{}; protected: diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp index 94ef3983a..9f110df8e 100755 --- a/src/core/hle/service/nifm/nifm.cpp +++ b/src/core/hle/service/nifm/nifm.cpp @@ -127,8 +127,7 @@ public: class IRequest final : public ServiceFramework { public: - explicit IRequest(Core::System& system_) - : ServiceFramework{system_, "IRequest"}, event1{system.Kernel()}, event2{system.Kernel()} { + explicit IRequest(Core::System& system_) : ServiceFramework{system_, "IRequest"} { static const FunctionInfo functions[] = { {0, &IRequest::GetRequestState, "GetRequestState"}, {1, &IRequest::GetResult, "GetResult"}, @@ -158,11 +157,12 @@ public: }; RegisterHandlers(functions); - Kernel::KAutoObject::Create(std::addressof(event1)); - Kernel::KAutoObject::Create(std::addressof(event2)); + auto& kernel = system.Kernel(); - event1.Initialize("IRequest:Event1"); - event2.Initialize("IRequest:Event2"); + event1 = Kernel::KEvent::Create(kernel, "IRequest:Event1"); + event1->Initialize(); + event2 = Kernel::KEvent::Create(kernel, "IRequest:Event2"); + event2->Initialize(); } private: @@ -198,7 +198,7 @@ private: IPC::ResponseBuilder rb{ctx, 2, 2}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(event1.GetReadableEvent(), event2.GetReadableEvent()); + rb.PushCopyObjects(event1->GetReadableEvent(), event2->GetReadableEvent()); } void Cancel(Kernel::HLERequestContext& ctx) { @@ -229,7 +229,7 @@ private: rb.Push(0); } - Kernel::KEvent event1, event2; + std::shared_ptr event1, event2; }; class INetworkProfile final : public ServiceFramework { diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp index 420a5a075..fee360ab9 100755 --- a/src/core/hle/service/nim/nim.cpp +++ b/src/core/hle/service/nim/nim.cpp @@ -300,8 +300,7 @@ class IEnsureNetworkClockAvailabilityService final : public ServiceFramework { public: explicit IEnsureNetworkClockAvailabilityService(Core::System& system_) - : ServiceFramework{system_, "IEnsureNetworkClockAvailabilityService"}, - finished_event{system.Kernel()} { + : ServiceFramework{system_, "IEnsureNetworkClockAvailabilityService"} { static const FunctionInfo functions[] = { {0, &IEnsureNetworkClockAvailabilityService::StartTask, "StartTask"}, {1, &IEnsureNetworkClockAvailabilityService::GetFinishNotificationEvent, @@ -313,17 +312,19 @@ public: }; RegisterHandlers(functions); - Kernel::KAutoObject::Create(std::addressof(finished_event)); - finished_event.Initialize("IEnsureNetworkClockAvailabilityService:FinishEvent"); + auto& kernel = system.Kernel(); + finished_event = + Kernel::KEvent::Create(kernel, "IEnsureNetworkClockAvailabilityService:FinishEvent"); + finished_event->Initialize(); } private: - Kernel::KEvent finished_event; + std::shared_ptr finished_event; void StartTask(Kernel::HLERequestContext& ctx) { // No need to connect to the internet, just finish the task straight away. LOG_DEBUG(Service_NIM, "called"); - finished_event.GetWritableEvent().Signal(); + finished_event->GetWritableEvent()->Signal(); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } @@ -333,7 +334,7 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(finished_event.GetReadableEvent()); + rb.PushCopyObjects(finished_event->GetReadableEvent()); } void GetResult(Kernel::HLERequestContext& ctx) { @@ -345,7 +346,7 @@ private: void Cancel(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_NIM, "called"); - finished_event.GetWritableEvent().Clear(); + finished_event->GetWritableEvent()->Clear(); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); } diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index e14acce58..da139fdc4 100755 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp @@ -130,6 +130,9 @@ struct PL_U::Impl { } } + /// Handle to shared memory region designated for a shared font + std::shared_ptr shared_font_mem; + /// Backing memory for the shared font data std::shared_ptr shared_font; @@ -257,13 +260,14 @@ void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) { // Create shared font memory object auto& kernel = system.Kernel(); + impl->shared_font_mem = SharedFrom(&kernel.GetFontSharedMem()); - std::memcpy(kernel.GetFontSharedMem().GetPointer(), impl->shared_font->data(), + std::memcpy(impl->shared_font_mem->GetPointer(), impl->shared_font->data(), impl->shared_font->size()); IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(&kernel.GetFontSharedMem()); + rb.PushCopyObjects(impl->shared_font_mem); } void PL_U::GetSharedFontInOrderOfPriority(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp index 775e76330..6f4007294 100755 --- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp @@ -102,20 +102,20 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector& input, std::vector return NvResult::Success; } - auto& event = events_interface.events[event_id]; + auto event = events_interface.events[event_id]; auto& gpu = system.GPU(); // This is mostly to take into account unimplemented features. As synced // gpu is always synced. if (!gpu.IsAsync()) { - event.event->GetWritableEvent().Signal(); + event.event->GetWritableEvent()->Signal(); return NvResult::Success; } auto lock = gpu.LockSync(); const u32 current_syncpoint_value = event.fence.value; const s32 diff = current_syncpoint_value - params.threshold; if (diff >= 0) { - event.event->GetWritableEvent().Signal(); + event.event->GetWritableEvent()->Signal(); params.value = current_syncpoint_value; std::memcpy(output.data(), ¶ms, sizeof(params)); return NvResult::Success; @@ -142,7 +142,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector& input, std::vector params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000; } params.value |= event_id; - event.event->GetWritableEvent().Clear(); + event.event->GetWritableEvent()->Clear(); gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value); std::memcpy(output.data(), ¶ms, sizeof(params)); return NvResult::Timeout; diff --git a/src/core/hle/service/nvdrv/interface.cpp b/src/core/hle/service/nvdrv/interface.cpp index dc9b9341f..eff9c3cc9 100755 --- a/src/core/hle/service/nvdrv/interface.cpp +++ b/src/core/hle/service/nvdrv/interface.cpp @@ -187,8 +187,8 @@ void NVDRV::QueryEvent(Kernel::HLERequestContext& ctx) { if (event_id < MaxNvEvents) { IPC::ResponseBuilder rb{ctx, 3, 1}; rb.Push(RESULT_SUCCESS); - auto& event = nvdrv->GetEvent(event_id); - event.Clear(); + auto event = nvdrv->GetEvent(event_id); + event->Clear(); rb.PushCopyObjects(event); rb.PushEnum(NvResult::Success); } else { diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index 74796dce1..ede77858a 100755 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp @@ -42,8 +42,9 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger Module::Module(Core::System& system) : syncpoint_manager{system.GPU()} { auto& kernel = system.Kernel(); for (u32 i = 0; i < MaxNvEvents; i++) { - events_interface.events[i].event = Kernel::KEvent::Create(kernel); - events_interface.events[i].event->Initialize(fmt::format("NVDRV::NvEvent_{}", i)); + std::string event_label = fmt::format("NVDRV::NvEvent_{}", i); + events_interface.events[i] = {Kernel::KEvent::Create(kernel, std::move(event_label))}; + events_interface.events[i].event->Initialize(); events_interface.status[i] = EventState::Free; events_interface.registered[i] = false; } @@ -63,12 +64,7 @@ Module::Module(Core::System& system) : syncpoint_manager{system.GPU()} { std::make_shared(system, nvmap_dev, syncpoint_manager); } -Module::~Module() { - for (u32 i = 0; i < MaxNvEvents; i++) { - events_interface.events[i].event->Close(); - events_interface.events[i].event = nullptr; - } -} +Module::~Module() = default; NvResult Module::VerifyFD(DeviceFD fd) const { if (fd < 0) { @@ -176,16 +172,16 @@ void Module::SignalSyncpt(const u32 syncpoint_id, const u32 value) { if (events_interface.assigned_syncpt[i] == syncpoint_id && events_interface.assigned_value[i] == value) { events_interface.LiberateEvent(i); - events_interface.events[i].event->GetWritableEvent().Signal(); + events_interface.events[i].event->GetWritableEvent()->Signal(); } } } -Kernel::KReadableEvent& Module::GetEvent(const u32 event_id) { +std::shared_ptr Module::GetEvent(const u32 event_id) const { return events_interface.events[event_id].event->GetReadableEvent(); } -Kernel::KWritableEvent& Module::GetEventWriteable(const u32 event_id) { +std::shared_ptr Module::GetEventWriteable(const u32 event_id) const { return events_interface.events[event_id].event->GetWritableEvent(); } diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index a43ceb7ae..53719aadd 100755 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h @@ -35,7 +35,7 @@ class nvdevice; /// Represents an Nvidia event struct NvEvent { - Kernel::KEvent* event{}; + std::shared_ptr event; Fence fence{}; }; @@ -136,9 +136,9 @@ public: void SignalSyncpt(const u32 syncpoint_id, const u32 value); - Kernel::KReadableEvent& GetEvent(u32 event_id); + std::shared_ptr GetEvent(u32 event_id) const; - Kernel::KWritableEvent& GetEventWriteable(u32 event_id); + std::shared_ptr GetEventWriteable(u32 event_id) const; private: /// Manages syncpoints on the host diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index 0b6e7430b..7842a82ed 100755 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp @@ -7,6 +7,7 @@ #include "common/assert.h" #include "common/logging/log.h" #include "core/core.h" +#include "core/hle/kernel/k_event.h" #include "core/hle/kernel/k_writable_event.h" #include "core/hle/kernel/kernel.h" #include "core/hle/service/nvflinger/buffer_queue.h" @@ -14,9 +15,9 @@ namespace Service::NVFlinger { BufferQueue::BufferQueue(Kernel::KernelCore& kernel, u32 id, u64 layer_id) - : id(id), layer_id(layer_id), buffer_wait_event{kernel} { - Kernel::KAutoObject::Create(std::addressof(buffer_wait_event)); - buffer_wait_event.Initialize("BufferQueue:WaitEvent"); + : id(id), layer_id(layer_id) { + buffer_wait_event = Kernel::KEvent::Create(kernel, "BufferQueue:WaitEvent"); + buffer_wait_event->Initialize(); } BufferQueue::~BufferQueue() = default; @@ -41,7 +42,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer) .multi_fence = {}, }; - buffer_wait_event.GetWritableEvent().Signal(); + buffer_wait_event->GetWritableEvent()->Signal(); } std::optional> BufferQueue::DequeueBuffer(u32 width, @@ -119,7 +120,7 @@ void BufferQueue::CancelBuffer(u32 slot, const Service::Nvidia::MultiFence& mult } free_buffers_condition.notify_one(); - buffer_wait_event.GetWritableEvent().Signal(); + buffer_wait_event->GetWritableEvent()->Signal(); } std::optional> BufferQueue::AcquireBuffer() { @@ -154,7 +155,7 @@ void BufferQueue::ReleaseBuffer(u32 slot) { } free_buffers_condition.notify_one(); - buffer_wait_event.GetWritableEvent().Signal(); + buffer_wait_event->GetWritableEvent()->Signal(); } void BufferQueue::Connect() { @@ -169,7 +170,7 @@ void BufferQueue::Disconnect() { std::unique_lock lock{queue_sequence_mutex}; queue_sequence.clear(); } - buffer_wait_event.GetWritableEvent().Signal(); + buffer_wait_event->GetWritableEvent()->Signal(); is_connect = false; free_buffers_condition.notify_one(); } @@ -188,12 +189,12 @@ u32 BufferQueue::Query(QueryType type) { return 0; } -Kernel::KWritableEvent& BufferQueue::GetWritableBufferWaitEvent() { - return buffer_wait_event.GetWritableEvent(); +std::shared_ptr BufferQueue::GetWritableBufferWaitEvent() const { + return buffer_wait_event->GetWritableEvent(); } -Kernel::KReadableEvent& BufferQueue::GetBufferWaitEvent() { - return buffer_wait_event.GetReadableEvent(); +std::shared_ptr BufferQueue::GetBufferWaitEvent() const { + return buffer_wait_event->GetReadableEvent(); } } // namespace Service::NVFlinger diff --git a/src/core/hle/service/nvflinger/buffer_queue.h b/src/core/hle/service/nvflinger/buffer_queue.h index 4ec0b1506..163fa4c54 100755 --- a/src/core/hle/service/nvflinger/buffer_queue.h +++ b/src/core/hle/service/nvflinger/buffer_queue.h @@ -13,8 +13,7 @@ #include "common/common_funcs.h" #include "common/math_util.h" #include "common/swap.h" -#include "core/hle/kernel/k_event.h" -#include "core/hle/kernel/k_readable_event.h" +#include "core/hle/kernel/object.h" #include "core/hle/service/nvdrv/nvdata.h" namespace Kernel { @@ -116,9 +115,9 @@ public: return is_connect; } - Kernel::KWritableEvent& GetWritableBufferWaitEvent(); + std::shared_ptr GetWritableBufferWaitEvent() const; - Kernel::KReadableEvent& GetBufferWaitEvent(); + std::shared_ptr GetBufferWaitEvent() const; private: BufferQueue(const BufferQueue&) = delete; @@ -130,7 +129,7 @@ private: std::list free_buffers; std::array buffers; std::list queue_sequence; - Kernel::KEvent buffer_wait_event; + std::shared_ptr buffer_wait_event; std::mutex free_buffers_mutex; std::condition_variable free_buffers_condition; diff --git a/src/core/hle/service/nvflinger/nvflinger.cpp b/src/core/hle/service/nvflinger/nvflinger.cpp index 7fb9133c7..c43593e7f 100755 --- a/src/core/hle/service/nvflinger/nvflinger.cpp +++ b/src/core/hle/service/nvflinger/nvflinger.cpp @@ -165,7 +165,7 @@ std::optional NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) co return layer->GetBufferQueue().GetId(); } -Kernel::KReadableEvent* NVFlinger::FindVsyncEvent(u64 display_id) { +std::shared_ptr NVFlinger::FindVsyncEvent(u64 display_id) const { const auto lock_guard = Lock(); auto* const display = FindDisplay(display_id); @@ -173,7 +173,7 @@ Kernel::KReadableEvent* NVFlinger::FindVsyncEvent(u64 display_id) { return nullptr; } - return &display->GetVSyncEvent(); + return display->GetVSyncEvent(); } BufferQueue* NVFlinger::FindBufferQueue(u32 id) { diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h index b0febdaec..6fe2c7f2a 100755 --- a/src/core/hle/service/nvflinger/nvflinger.h +++ b/src/core/hle/service/nvflinger/nvflinger.h @@ -5,7 +5,6 @@ #pragma once #include -#include #include #include #include @@ -15,6 +14,7 @@ #include #include "common/common_types.h" +#include "core/hle/kernel/object.h" namespace Common { class Event; @@ -72,7 +72,7 @@ public: /// Gets the vsync event for the specified display. /// /// If an invalid display ID is provided, then nullptr is returned. - [[nodiscard]] Kernel::KReadableEvent* FindVsyncEvent(u64 display_id); + [[nodiscard]] std::shared_ptr FindVsyncEvent(u64 display_id) const; /// Obtains a buffer queue identified by the ID. [[nodiscard]] BufferQueue* FindBufferQueue(u32 id); @@ -106,7 +106,7 @@ private: std::shared_ptr nvdrv; - std::list displays; + std::vector displays; std::vector> buffer_queues; /// Id to use for the next layer that is created, this counter is shared among all displays. diff --git a/src/core/hle/service/pctl/module.cpp b/src/core/hle/service/pctl/module.cpp index 1c3d81143..9bebe6088 100755 --- a/src/core/hle/service/pctl/module.cpp +++ b/src/core/hle/service/pctl/module.cpp @@ -7,7 +7,7 @@ #include "core/file_sys/control_metadata.h" #include "core/file_sys/patch_manager.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/pctl/module.h" #include "core/hle/service/pctl/pctl.h" diff --git a/src/core/hle/service/pm/pm.cpp b/src/core/hle/service/pm/pm.cpp index f4715935d..68736c40c 100755 --- a/src/core/hle/service/pm/pm.cpp +++ b/src/core/hle/service/pm/pm.cpp @@ -4,8 +4,8 @@ #include "core/core.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/pm/pm.h" #include "core/hle/service/service.h" @@ -17,9 +17,9 @@ constexpr ResultCode ERROR_PROCESS_NOT_FOUND{ErrorModule::PM, 1}; constexpr u64 NO_PROCESS_FOUND_PID{0}; -std::optional SearchProcessList( - const std::vector& process_list, - std::function predicate) { +std::optional> SearchProcessList( + const std::vector>& process_list, + std::function&)> predicate) { const auto iter = std::find_if(process_list.begin(), process_list.end(), predicate); if (iter == process_list.end()) { @@ -30,9 +30,9 @@ std::optional SearchProcessList( } void GetApplicationPidGeneric(Kernel::HLERequestContext& ctx, - const std::vector& process_list) { + const std::vector>& process_list) { const auto process = SearchProcessList(process_list, [](const auto& process) { - return process->GetProcessID() == Kernel::KProcess::ProcessIDMin; + return process->GetProcessID() == Kernel::Process::ProcessIDMin; }); IPC::ResponseBuilder rb{ctx, 4}; @@ -125,7 +125,8 @@ private: class Info final : public ServiceFramework { public: - explicit Info(Core::System& system_, const std::vector& process_list_) + explicit Info(Core::System& system_, + const std::vector>& process_list_) : ServiceFramework{system_, "pm:info"}, process_list{process_list_} { static const FunctionInfo functions[] = { {0, &Info::GetTitleId, "GetTitleId"}, @@ -155,7 +156,7 @@ private: rb.Push((*process)->GetTitleID()); } - const std::vector& process_list; + const std::vector>& process_list; }; class Shell final : public ServiceFramework { diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp index c914f8145..d5b3b17a5 100755 --- a/src/core/hle/service/prepo/prepo.cpp +++ b/src/core/hle/service/prepo/prepo.cpp @@ -6,7 +6,7 @@ #include "common/logging/log.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/acc/profile_manager.h" #include "core/hle/service/prepo/prepo.h" #include "core/hle/service/service.h" @@ -60,7 +60,7 @@ private: const auto process_id = rp.PopRaw(); const auto data1 = ctx.ReadBuffer(0); - const auto data2 = [&ctx] { + const auto data2 = [ctx] { if (ctx.CanReadBuffer(1)) { return ctx.ReadBuffer(1); } @@ -87,7 +87,7 @@ private: const auto process_id = rp.PopRaw(); const auto data1 = ctx.ReadBuffer(0); - const auto data2 = [&ctx] { + const auto data2 = [ctx] { if (ctx.CanReadBuffer(1)) { return ctx.ReadBuffer(1); } @@ -139,7 +139,7 @@ private: const auto title_id = rp.PopRaw(); const auto data1 = ctx.ReadBuffer(0); - const auto data2 = [&ctx] { + const auto data2 = [ctx] { if (ctx.CanReadBuffer(1)) { return ctx.ReadBuffer(1); } @@ -163,7 +163,7 @@ private: const auto title_id = rp.PopRaw(); const auto data1 = ctx.ReadBuffer(0); - const auto data2 = [&ctx] { + const auto data2 = [ctx] { if (ctx.CanReadBuffer(1)) { return ctx.ReadBuffer(1); } diff --git a/src/core/hle/service/ptm/psm.cpp b/src/core/hle/service/ptm/psm.cpp index bb7af9217..26ed52273 100755 --- a/src/core/hle/service/ptm/psm.cpp +++ b/src/core/hle/service/ptm/psm.cpp @@ -19,8 +19,7 @@ namespace Service::PSM { class IPsmSession final : public ServiceFramework { public: - explicit IPsmSession(Core::System& system_) - : ServiceFramework{system_, "IPsmSession"}, state_change_event{system.Kernel()} { + explicit IPsmSession(Core::System& system_) : ServiceFramework{system_, "IPsmSession"} { // clang-format off static const FunctionInfo functions[] = { {0, &IPsmSession::BindStateChangeEvent, "BindStateChangeEvent"}, @@ -33,27 +32,28 @@ public: RegisterHandlers(functions); - Kernel::KAutoObject::Create(std::addressof(state_change_event)); - state_change_event.Initialize("IPsmSession::state_change_event"); + state_change_event = + Kernel::KEvent::Create(system_.Kernel(), "IPsmSession::state_change_event"); + state_change_event->Initialize(); } ~IPsmSession() override = default; void SignalChargerTypeChanged() { if (should_signal && should_signal_charger_type) { - state_change_event.GetWritableEvent().Signal(); + state_change_event->GetWritableEvent()->Signal(); } } void SignalPowerSupplyChanged() { if (should_signal && should_signal_power_supply) { - state_change_event.GetWritableEvent().Signal(); + state_change_event->GetWritableEvent()->Signal(); } } void SignalBatteryVoltageStateChanged() { if (should_signal && should_signal_battery_voltage) { - state_change_event.GetWritableEvent().Signal(); + state_change_event->GetWritableEvent()->Signal(); } } @@ -65,7 +65,7 @@ private: IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(state_change_event.GetReadableEvent()); + rb.PushCopyObjects(state_change_event->GetReadableEvent()); } void UnbindStateChangeEvent(Kernel::HLERequestContext& ctx) { @@ -114,7 +114,7 @@ private: bool should_signal_power_supply{}; bool should_signal_battery_voltage{}; bool should_signal{}; - Kernel::KEvent state_change_event; + std::shared_ptr state_change_event; }; class PSM final : public ServiceFramework { diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 00e683c2f..41a502d8d 100755 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -11,11 +11,11 @@ #include "core/core.h" #include "core/hle/ipc.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/k_client_port.h" -#include "core/hle/kernel/k_process.h" -#include "core/hle/kernel/k_server_port.h" +#include "core/hle/kernel/client_port.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/process.h" +#include "core/hle/kernel/server_port.h" #include "core/hle/service/acc/acc.h" #include "core/hle/service/am/am.h" #include "core/hle/service/aoc/aoc_u.h" @@ -116,11 +116,10 @@ void ServiceFrameworkBase::InstallAsNamedPort(Kernel::KernelCore& kernel) { ASSERT(!port_installed); - auto* port = Kernel::KPort::Create(kernel); - port->Initialize(max_sessions, false, service_name); - port->GetServerPort().SetHleHandler(shared_from_this()); - kernel.AddNamedPort(service_name, &port->GetClientPort()); - + auto [server_port, client_port] = + Kernel::ServerPort::CreatePortPair(kernel, max_sessions, service_name); + server_port->SetHleHandler(shared_from_this()); + kernel.AddNamedPort(service_name, std::move(client_port)); port_installed = true; } diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 884951428..916445517 100755 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -11,6 +11,7 @@ #include "common/common_types.h" #include "common/spin_lock.h" #include "core/hle/kernel/hle_ipc.h" +#include "core/hle/kernel/object.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // Namespace Service @@ -20,8 +21,11 @@ class System; } namespace Kernel { +class ClientPort; +class ServerPort; +class ServerSession; class HLERequestContext; -} +} // namespace Kernel namespace Service { diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp index 4f1ffe55f..5909fdd85 100755 --- a/src/core/hle/service/set/set_sys.cpp +++ b/src/core/hle/service/set/set_sys.cpp @@ -7,7 +7,7 @@ #include "core/file_sys/errors.h" #include "core/file_sys/system_archive/system_version.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/k_client_port.h" +#include "core/hle/kernel/client_port.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/set/set_sys.h" diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/controller.cpp index ee026e22f..916177efd 100755 --- a/src/core/hle/service/sm/controller.cpp +++ b/src/core/hle/service/sm/controller.cpp @@ -5,16 +5,16 @@ #include "common/assert.h" #include "common/logging/log.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/k_client_session.h" -#include "core/hle/kernel/k_server_session.h" -#include "core/hle/kernel/k_session.h" +#include "core/hle/kernel/client_session.h" +#include "core/hle/kernel/server_session.h" +#include "core/hle/kernel/session.h" #include "core/hle/service/sm/controller.h" namespace Service::SM { void Controller::ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx) { ASSERT_MSG(ctx.Session()->IsSession(), "Session is already a domain"); - LOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetId()); + LOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetObjectId()); ctx.Session()->ConvertToDomain(); IPC::ResponseBuilder rb{ctx, 3}; @@ -30,7 +30,7 @@ void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; rb.Push(RESULT_SUCCESS); - rb.PushMoveObjects(ctx.Session()->GetParent()->GetClientSession()); + rb.PushMoveObjects(ctx.Session()->GetParent()->Client()); } void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 568effbc9..94608d529 100755 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -6,12 +6,9 @@ #include "common/assert.h" #include "core/core.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/k_client_port.h" -#include "core/hle/kernel/k_client_session.h" -#include "core/hle/kernel/k_port.h" -#include "core/hle/kernel/k_server_port.h" -#include "core/hle/kernel/k_server_session.h" -#include "core/hle/kernel/k_session.h" +#include "core/hle/kernel/client_port.h" +#include "core/hle/kernel/client_session.h" +#include "core/hle/kernel/server_port.h" #include "core/hle/result.h" #include "core/hle/service/sm/controller.h" #include "core/hle/service/sm/sm.h" @@ -50,8 +47,8 @@ void ServiceManager::InstallInterfaces(std::shared_ptr self, Cor self->controller_interface = std::make_unique(system); } -ResultVal ServiceManager::RegisterService(std::string name, - u32 max_sessions) { +ResultVal> ServiceManager::RegisterService(std::string name, + u32 max_sessions) { CASCADE_CODE(ValidateServiceName(name)); @@ -60,12 +57,11 @@ ResultVal ServiceManager::RegisterService(std::string name return ERR_ALREADY_REGISTERED; } - auto* port = Kernel::KPort::Create(kernel); - port->Initialize(max_sessions, false, name); + auto [server_port, client_port] = + Kernel::ServerPort::CreatePortPair(kernel, max_sessions, name); - registered_services.emplace(std::move(name), port); - - return MakeResult(&port->GetServerPort()); + registered_services.emplace(std::move(name), std::move(client_port)); + return MakeResult(std::move(server_port)); } ResultCode ServiceManager::UnregisterService(const std::string& name) { @@ -76,14 +72,12 @@ ResultCode ServiceManager::UnregisterService(const std::string& name) { LOG_ERROR(Service_SM, "Server is not registered! service={}", name); return ERR_SERVICE_NOT_REGISTERED; } - - iter->second->Close(); - registered_services.erase(iter); return RESULT_SUCCESS; } -ResultVal ServiceManager::GetServicePort(const std::string& name) { +ResultVal> ServiceManager::GetServicePort( + const std::string& name) { CASCADE_CODE(ValidateServiceName(name)); auto it = registered_services.find(name); @@ -95,6 +89,13 @@ ResultVal ServiceManager::GetServicePort(const std::string& name return MakeResult(it->second); } +ResultVal> ServiceManager::ConnectToService( + const std::string& name) { + + CASCADE_RESULT(auto client_port, GetServicePort(name)); + return client_port->Connect(); +} + SM::~SM() = default; /** @@ -118,32 +119,30 @@ void SM::GetService(Kernel::HLERequestContext& ctx) { std::string name(name_buf.begin(), end); - auto result = service_manager->GetServicePort(name); - if (result.Failed()) { + auto client_port = service_manager->GetServicePort(name); + if (client_port.Failed()) { IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(result.Code()); - LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.Code().raw); + rb.Push(client_port.Code()); + LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, client_port.Code().raw); if (name.length() == 0) return; // LibNX Fix UNIMPLEMENTED(); return; } - auto* port = result.Unwrap(); + auto [client, server] = Kernel::Session::Create(kernel, name); - auto* session = Kernel::KSession::Create(kernel); - session->Initialize(&port->GetClientPort(), std::move(name)); - - if (port->GetServerPort().GetHLEHandler()) { - port->GetServerPort().GetHLEHandler()->ClientConnected(&session->GetServerSession()); + const auto& server_port = client_port.Unwrap()->GetServerPort(); + if (server_port->GetHLEHandler()) { + server_port->GetHLEHandler()->ClientConnected(server); } else { - port->EnqueueSession(&session->GetServerSession()); + server_port->AppendPendingSession(server); } - LOG_DEBUG(Service_SM, "called service={} -> session={}", name, session->GetId()); + LOG_DEBUG(Service_SM, "called service={} -> session={}", name, client->GetObjectId()); IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; rb.Push(RESULT_SUCCESS); - rb.PushMoveObjects(session->GetClientSession()); + rb.PushMoveObjects(std::move(client)); } void SM::RegisterService(Kernel::HLERequestContext& ctx) { @@ -171,9 +170,7 @@ void SM::RegisterService(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; rb.Push(handle.Code()); - - auto server_port = handle.Unwrap(); - rb.PushMoveObjects(server_port); + rb.PushMoveObjects(std::move(handle).Unwrap()); } void SM::UnregisterService(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index af5010c3b..3f46ae44f 100755 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -10,7 +10,9 @@ #include #include "common/concepts.h" -#include "core/hle/kernel/k_port.h" +#include "core/hle/kernel/client_port.h" +#include "core/hle/kernel/object.h" +#include "core/hle/kernel/server_port.h" #include "core/hle/result.h" #include "core/hle/service/service.h" @@ -19,11 +21,10 @@ class System; } namespace Kernel { -class KClientPort; -class KClientSession; +class ClientPort; +class ClientSession; class KernelCore; -class KPort; -class KServerPort; +class ServerPort; class SessionRequestHandler; } // namespace Kernel @@ -54,9 +55,11 @@ public: explicit ServiceManager(Kernel::KernelCore& kernel_); ~ServiceManager(); - ResultVal RegisterService(std::string name, u32 max_sessions); + ResultVal> RegisterService(std::string name, + u32 max_sessions); ResultCode UnregisterService(const std::string& name); - ResultVal GetServicePort(const std::string& name); + ResultVal> GetServicePort(const std::string& name); + ResultVal> ConnectToService(const std::string& name); template T> std::shared_ptr GetService(const std::string& service_name) const { @@ -65,11 +68,11 @@ public: LOG_DEBUG(Service, "Can't find service: {}", service_name); return nullptr; } - auto* port = service->second; + auto port = service->second->GetServerPort(); if (port == nullptr) { return nullptr; } - return std::static_pointer_cast(port->GetServerPort().GetHLEHandler()); + return std::static_pointer_cast(port->GetHLEHandler()); } void InvokeControlRequest(Kernel::HLERequestContext& context); @@ -78,8 +81,8 @@ private: std::weak_ptr sm_interface; std::unique_ptr controller_interface; - /// Map of registered services, retrieved using GetServicePort. - std::unordered_map registered_services; + /// Map of registered services, retrieved using GetServicePort or ConnectToService. + std::unordered_map> registered_services; /// Kernel context Kernel::KernelCore& kernel; diff --git a/src/core/hle/service/time/standard_user_system_clock_core.cpp b/src/core/hle/service/time/standard_user_system_clock_core.cpp index 7f47b12b8..3172acc5a 100755 --- a/src/core/hle/service/time/standard_user_system_clock_core.cpp +++ b/src/core/hle/service/time/standard_user_system_clock_core.cpp @@ -4,6 +4,7 @@ #include "common/assert.h" #include "core/core.h" +#include "core/hle/kernel/k_event.h" #include "core/hle/service/time/standard_local_system_clock_core.h" #include "core/hle/service/time/standard_network_system_clock_core.h" #include "core/hle/service/time/standard_user_system_clock_core.h" @@ -16,10 +17,10 @@ StandardUserSystemClockCore::StandardUserSystemClockCore( : SystemClockCore(local_system_clock_core.GetSteadyClockCore()), local_system_clock_core{local_system_clock_core}, network_system_clock_core{network_system_clock_core}, auto_correction_enabled{}, - auto_correction_time{SteadyClockTimePoint::GetRandom()}, auto_correction_event{ - system.Kernel()} { - Kernel::KAutoObject::Create(std::addressof(auto_correction_event)); - auto_correction_event.Initialize("StandardUserSystemClockCore:AutoCorrectionEvent"); + auto_correction_time{SteadyClockTimePoint::GetRandom()}, + auto_correction_event{Kernel::KEvent::Create( + system.Kernel(), "StandardUserSystemClockCore:AutoCorrectionEvent")} { + auto_correction_event->Initialize(); } ResultCode StandardUserSystemClockCore::SetAutomaticCorrectionEnabled(Core::System& system, diff --git a/src/core/hle/service/time/standard_user_system_clock_core.h b/src/core/hle/service/time/standard_user_system_clock_core.h index 1bff8a5af..5bc8bf5c2 100755 --- a/src/core/hle/service/time/standard_user_system_clock_core.h +++ b/src/core/hle/service/time/standard_user_system_clock_core.h @@ -4,7 +4,6 @@ #pragma once -#include "core/hle/kernel/k_event.h" #include "core/hle/service/time/clock_types.h" #include "core/hle/service/time/system_clock_core.h" @@ -55,7 +54,7 @@ private: StandardNetworkSystemClockCore& network_system_clock_core; bool auto_correction_enabled{}; SteadyClockTimePoint auto_correction_time; - Kernel::KEvent auto_correction_event; + std::shared_ptr auto_correction_event; }; } // namespace Service::Time::Clock diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index e7991012b..32f372d71 100755 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -8,7 +8,8 @@ #include "core/core_timing_util.h" #include "core/hardware_properties.h" #include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/k_client_port.h" +#include "core/hle/kernel/client_port.h" +#include "core/hle/kernel/client_session.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/kernel.h" #include "core/hle/service/time/interface.h" @@ -392,7 +393,7 @@ void Module::Interface::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& c LOG_DEBUG(Service_Time, "called"); IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(&system.Kernel().GetTimeSharedMem()); + rb.PushCopyObjects(SharedFrom(&system.Kernel().GetTimeSharedMem())); } Module::Interface::Interface(std::shared_ptr module_, Core::System& system_, diff --git a/src/core/hle/service/time/time_sharedmemory.cpp b/src/core/hle/service/time/time_sharedmemory.cpp index eb57899f6..018ce94ed 100755 --- a/src/core/hle/service/time/time_sharedmemory.cpp +++ b/src/core/hle/service/time/time_sharedmemory.cpp @@ -16,11 +16,16 @@ namespace Service::Time { static constexpr std::size_t SHARED_MEMORY_SIZE{0x1000}; SharedMemory::SharedMemory(Core::System& system) : system(system) { - std::memset(system.Kernel().GetTimeSharedMem().GetPointer(), 0, SHARED_MEMORY_SIZE); + shared_memory_holder = SharedFrom(&system.Kernel().GetTimeSharedMem()); + std::memset(shared_memory_holder->GetPointer(), 0, SHARED_MEMORY_SIZE); } SharedMemory::~SharedMemory() = default; +std::shared_ptr SharedMemory::GetSharedMemoryHolder() const { + return shared_memory_holder; +} + void SharedMemory::SetupStandardSteadyClock(const Common::UUID& clock_source_id, Clock::TimeSpanType current_time_point) { const Clock::TimeSpanType ticks_time_span{Clock::TimeSpanType::FromTicks( @@ -29,22 +34,22 @@ void SharedMemory::SetupStandardSteadyClock(const Common::UUID& clock_source_id, static_cast(current_time_point.nanoseconds - ticks_time_span.nanoseconds), clock_source_id}; shared_memory_format.standard_steady_clock_timepoint.StoreData( - system.Kernel().GetTimeSharedMem().GetPointer(), context); + shared_memory_holder->GetPointer(), context); } void SharedMemory::UpdateLocalSystemClockContext(const Clock::SystemClockContext& context) { shared_memory_format.standard_local_system_clock_context.StoreData( - system.Kernel().GetTimeSharedMem().GetPointer(), context); + shared_memory_holder->GetPointer(), context); } void SharedMemory::UpdateNetworkSystemClockContext(const Clock::SystemClockContext& context) { shared_memory_format.standard_network_system_clock_context.StoreData( - system.Kernel().GetTimeSharedMem().GetPointer(), context); + shared_memory_holder->GetPointer(), context); } void SharedMemory::SetAutomaticCorrectionEnabled(bool is_enabled) { shared_memory_format.standard_user_system_clock_automatic_correction.StoreData( - system.Kernel().GetTimeSharedMem().GetPointer(), is_enabled); + shared_memory_holder->GetPointer(), is_enabled); } } // namespace Service::Time diff --git a/src/core/hle/service/time/time_sharedmemory.h b/src/core/hle/service/time/time_sharedmemory.h index 1ad9a286d..3bc749114 100755 --- a/src/core/hle/service/time/time_sharedmemory.h +++ b/src/core/hle/service/time/time_sharedmemory.h @@ -17,6 +17,9 @@ public: explicit SharedMemory(Core::System& system); ~SharedMemory(); + // Return the shared memory handle + std::shared_ptr GetSharedMemoryHolder() const; + // TODO(ogniK): We have to properly simulate memory barriers, how are we going to do this? template struct MemoryBarrier { @@ -60,6 +63,7 @@ public: void SetAutomaticCorrectionEnabled(bool is_enabled); private: + std::shared_ptr shared_memory_holder; Core::System& system; Format shared_memory_format{}; }; diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp index becbd36c1..ac9e87338 100755 --- a/src/core/hle/service/vi/display/vi_display.cpp +++ b/src/core/hle/service/vi/display/vi_display.cpp @@ -17,10 +17,10 @@ namespace Service::VI { -Display::Display(u64 id, std::string name, Core::System& system) - : id{id}, name{std::move(name)}, vsync_event{system.Kernel()} { - Kernel::KAutoObject::Create(std::addressof(vsync_event)); - vsync_event.Initialize(fmt::format("Display VSync Event {}", id)); +Display::Display(u64 id, std::string name, Core::System& system) : id{id}, name{std::move(name)} { + auto& kernel = system.Kernel(); + vsync_event = Kernel::KEvent::Create(kernel, fmt::format("Display VSync Event {}", id)); + vsync_event->Initialize(); } Display::~Display() = default; @@ -33,12 +33,12 @@ const Layer& Display::GetLayer(std::size_t index) const { return *layers.at(index); } -Kernel::KReadableEvent& Display::GetVSyncEvent() { - return vsync_event.GetReadableEvent(); +std::shared_ptr Display::GetVSyncEvent() const { + return vsync_event->GetReadableEvent(); } void Display::SignalVSyncEvent() { - vsync_event.GetWritableEvent().Signal(); + vsync_event->GetWritableEvent()->Signal(); } void Display::CreateLayer(u64 layer_id, NVFlinger::BufferQueue& buffer_queue) { diff --git a/src/core/hle/service/vi/display/vi_display.h b/src/core/hle/service/vi/display/vi_display.h index 388ce6083..8340059de 100755 --- a/src/core/hle/service/vi/display/vi_display.h +++ b/src/core/hle/service/vi/display/vi_display.h @@ -8,7 +8,6 @@ #include #include -#include "common/common_funcs.h" #include "common/common_types.h" namespace Kernel { @@ -25,9 +24,6 @@ class Layer; /// Represents a single display type class Display { - YUZU_NON_COPYABLE(Display); - YUZU_NON_MOVEABLE(Display); - public: /// Constructs a display with a given unique ID and name. /// @@ -37,6 +33,12 @@ public: Display(u64 id, std::string name, Core::System& system); ~Display(); + Display(const Display&) = delete; + Display& operator=(const Display&) = delete; + + Display(Display&&) = default; + Display& operator=(Display&&) = default; + /// Gets the unique ID assigned to this display. u64 GetID() const { return id; @@ -59,7 +61,7 @@ public: const Layer& GetLayer(std::size_t index) const; /// Gets the readable vsync event. - Kernel::KReadableEvent& GetVSyncEvent(); + std::shared_ptr GetVSyncEvent() const; /// Signals the internal vsync event. void SignalVSyncEvent(); @@ -100,7 +102,7 @@ private: std::string name; std::vector> layers; - Kernel::KEvent vsync_event; + std::shared_ptr vsync_event; }; } // namespace Service::VI diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 32e47a43e..7ae07d072 100755 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -669,10 +669,12 @@ private: LOG_WARNING(Service_VI, "(STUBBED) called id={}, unknown={:08X}", id, unknown); + const auto& buffer_queue = *nv_flinger.FindBufferQueue(id); + // TODO(Subv): Find out what this actually is. IPC::ResponseBuilder rb{ctx, 2, 1}; rb.Push(RESULT_SUCCESS); - rb.PushCopyObjects(nv_flinger.FindBufferQueue(id)->GetBufferWaitEvent()); + rb.PushCopyObjects(buffer_queue.GetBufferWaitEvent()); } NVFlinger::NVFlinger& nv_flinger; diff --git a/src/core/loader/deconstructed_rom_directory.cpp b/src/core/loader/deconstructed_rom_directory.cpp index 42f023258..fed47ecda 100755 --- a/src/core/loader/deconstructed_rom_directory.cpp +++ b/src/core/loader/deconstructed_rom_directory.cpp @@ -13,8 +13,8 @@ #include "core/file_sys/patch_manager.h" #include "core/file_sys/romfs_factory.h" #include "core/hle/kernel/k_page_table.h" -#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/loader/deconstructed_rom_directory.h" #include "core/loader/nso.h" @@ -88,7 +88,7 @@ FileType AppLoader_DeconstructedRomDirectory::IdentifyType(const FileSys::Virtua } AppLoader_DeconstructedRomDirectory::LoadResult AppLoader_DeconstructedRomDirectory::Load( - Kernel::KProcess& process, Core::System& system) { + Kernel::Process& process, Core::System& system) { if (is_loaded) { return {ResultStatus::ErrorAlreadyLoaded, {}}; } diff --git a/src/core/loader/deconstructed_rom_directory.h b/src/core/loader/deconstructed_rom_directory.h index a49a8b001..22a4ec5a6 100755 --- a/src/core/loader/deconstructed_rom_directory.h +++ b/src/core/loader/deconstructed_rom_directory.h @@ -44,7 +44,7 @@ public: return IdentifyType(file); } - LoadResult Load(Kernel::KProcess& process, Core::System& system) override; + LoadResult Load(Kernel::Process& process, Core::System& system) override; ResultStatus ReadRomFS(FileSys::VirtualFile& out_dir) override; ResultStatus ReadIcon(std::vector& out_buffer) override; diff --git a/src/core/loader/elf.cpp b/src/core/loader/elf.cpp index c062a4259..627c18c7e 100755 --- a/src/core/loader/elf.cpp +++ b/src/core/loader/elf.cpp @@ -11,7 +11,7 @@ #include "common/logging/log.h" #include "core/hle/kernel/code_set.h" #include "core/hle/kernel/k_page_table.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/loader/elf.h" #include "core/memory.h" @@ -386,7 +386,7 @@ FileType AppLoader_ELF::IdentifyType(const FileSys::VirtualFile& elf_file) { return FileType::Error; } -AppLoader_ELF::LoadResult AppLoader_ELF::Load(Kernel::KProcess& process, +AppLoader_ELF::LoadResult AppLoader_ELF::Load(Kernel::Process& process, [[maybe_unused]] Core::System& system) { if (is_loaded) { return {ResultStatus::ErrorAlreadyLoaded, {}}; diff --git a/src/core/loader/elf.h b/src/core/loader/elf.h index 890299a20..2b86c0b49 100755 --- a/src/core/loader/elf.h +++ b/src/core/loader/elf.h @@ -32,7 +32,7 @@ public: return IdentifyType(file); } - LoadResult Load(Kernel::KProcess& process, Core::System& system) override; + LoadResult Load(Kernel::Process& process, Core::System& system) override; }; } // namespace Loader diff --git a/src/core/loader/kip.cpp b/src/core/loader/kip.cpp index 3ae9e6e0e..9b447da2a 100755 --- a/src/core/loader/kip.cpp +++ b/src/core/loader/kip.cpp @@ -7,7 +7,7 @@ #include "core/file_sys/program_metadata.h" #include "core/hle/kernel/code_set.h" #include "core/hle/kernel/k_page_table.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/loader/kip.h" #include "core/memory.h" @@ -42,7 +42,7 @@ FileType AppLoader_KIP::GetFileType() const { : FileType::Error; } -AppLoader::LoadResult AppLoader_KIP::Load(Kernel::KProcess& process, +AppLoader::LoadResult AppLoader_KIP::Load(Kernel::Process& process, [[maybe_unused]] Core::System& system) { if (is_loaded) { return {ResultStatus::ErrorAlreadyLoaded, {}}; diff --git a/src/core/loader/kip.h b/src/core/loader/kip.h index 5f914b4a8..2fe636f01 100755 --- a/src/core/loader/kip.h +++ b/src/core/loader/kip.h @@ -32,7 +32,7 @@ public: FileType GetFileType() const override; - LoadResult Load(Kernel::KProcess& process, Core::System& system) override; + LoadResult Load(Kernel::Process& process, Core::System& system) override; private: std::unique_ptr kip; diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 11b2d0837..e4f5fd40c 100755 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -11,7 +11,7 @@ #include "common/logging/log.h" #include "common/string_util.h" #include "core/core.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/loader/deconstructed_rom_directory.h" #include "core/loader/elf.h" #include "core/loader/kip.h" diff --git a/src/core/loader/loader.h b/src/core/loader/loader.h index 9eac11dec..bf6db1ab1 100755 --- a/src/core/loader/loader.h +++ b/src/core/loader/loader.h @@ -25,7 +25,7 @@ class NACP; namespace Kernel { struct AddressMapping; -class KProcess; +class Process; } // namespace Kernel namespace Loader { @@ -165,7 +165,7 @@ public: * * @return The status result of the operation. */ - virtual LoadResult Load(Kernel::KProcess& process, Core::System& system) = 0; + virtual LoadResult Load(Kernel::Process& process, Core::System& system) = 0; /** * Get the code (typically .code section) of the application diff --git a/src/core/loader/nax.cpp b/src/core/loader/nax.cpp index aceb66414..f53c3a72c 100755 --- a/src/core/loader/nax.cpp +++ b/src/core/loader/nax.cpp @@ -6,7 +6,7 @@ #include "core/file_sys/content_archive.h" #include "core/file_sys/romfs.h" #include "core/file_sys/xts_archive.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/loader/nax.h" #include "core/loader/nca.h" @@ -41,7 +41,7 @@ FileType AppLoader_NAX::GetFileType() const { return IdentifyTypeImpl(*nax); } -AppLoader_NAX::LoadResult AppLoader_NAX::Load(Kernel::KProcess& process, Core::System& system) { +AppLoader_NAX::LoadResult AppLoader_NAX::Load(Kernel::Process& process, Core::System& system) { if (is_loaded) { return {ResultStatus::ErrorAlreadyLoaded, {}}; } diff --git a/src/core/loader/nax.h b/src/core/loader/nax.h index b3a50894f..68427c1cf 100755 --- a/src/core/loader/nax.h +++ b/src/core/loader/nax.h @@ -37,7 +37,7 @@ public: FileType GetFileType() const override; - LoadResult Load(Kernel::KProcess& process, Core::System& system) override; + LoadResult Load(Kernel::Process& process, Core::System& system) override; ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; u64 ReadRomFSIVFCOffset() const override; diff --git a/src/core/loader/nca.cpp b/src/core/loader/nca.cpp index 418cbf61b..47e7a77a9 100755 --- a/src/core/loader/nca.cpp +++ b/src/core/loader/nca.cpp @@ -9,7 +9,7 @@ #include "core/core.h" #include "core/file_sys/content_archive.h" #include "core/file_sys/romfs_factory.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/loader/deconstructed_rom_directory.h" #include "core/loader/nca.h" @@ -32,7 +32,7 @@ FileType AppLoader_NCA::IdentifyType(const FileSys::VirtualFile& nca_file) { return FileType::Error; } -AppLoader_NCA::LoadResult AppLoader_NCA::Load(Kernel::KProcess& process, Core::System& system) { +AppLoader_NCA::LoadResult AppLoader_NCA::Load(Kernel::Process& process, Core::System& system) { if (is_loaded) { return {ResultStatus::ErrorAlreadyLoaded, {}}; } diff --git a/src/core/loader/nca.h b/src/core/loader/nca.h index f2ff080bb..c9792f390 100755 --- a/src/core/loader/nca.h +++ b/src/core/loader/nca.h @@ -39,7 +39,7 @@ public: return IdentifyType(file); } - LoadResult Load(Kernel::KProcess& process, Core::System& system) override; + LoadResult Load(Kernel::Process& process, Core::System& system) override; ResultStatus ReadRomFS(FileSys::VirtualFile& dir) override; u64 ReadRomFSIVFCOffset() const override; diff --git a/src/core/loader/nro.cpp b/src/core/loader/nro.cpp index ef54fa574..0597cfa60 100755 --- a/src/core/loader/nro.cpp +++ b/src/core/loader/nro.cpp @@ -17,8 +17,8 @@ #include "core/file_sys/vfs_offset.h" #include "core/hle/kernel/code_set.h" #include "core/hle/kernel/k_page_table.h" -#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_thread.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/loader/nro.h" #include "core/loader/nso.h" @@ -130,7 +130,7 @@ static constexpr u32 PageAlignSize(u32 size) { return static_cast((size + Core::Memory::PAGE_MASK) & ~Core::Memory::PAGE_MASK); } -static bool LoadNroImpl(Kernel::KProcess& process, const std::vector& data) { +static bool LoadNroImpl(Kernel::Process& process, const std::vector& data) { if (data.size() < sizeof(NroHeader)) { return {}; } @@ -199,11 +199,11 @@ static bool LoadNroImpl(Kernel::KProcess& process, const std::vector& data) return true; } -bool AppLoader_NRO::LoadNro(Kernel::KProcess& process, const FileSys::VfsFile& nro_file) { +bool AppLoader_NRO::LoadNro(Kernel::Process& process, const FileSys::VfsFile& nro_file) { return LoadNroImpl(process, nro_file.ReadAllBytes()); } -AppLoader_NRO::LoadResult AppLoader_NRO::Load(Kernel::KProcess& process, Core::System& system) { +AppLoader_NRO::LoadResult AppLoader_NRO::Load(Kernel::Process& process, Core::System& system) { if (is_loaded) { return {ResultStatus::ErrorAlreadyLoaded, {}}; } diff --git a/src/core/loader/nro.h b/src/core/loader/nro.h index fd453b402..20bbaeb0e 100755 --- a/src/core/loader/nro.h +++ b/src/core/loader/nro.h @@ -19,7 +19,7 @@ class NACP; } namespace Kernel { -class KProcess; +class Process; } namespace Loader { @@ -43,7 +43,7 @@ public: return IdentifyType(file); } - LoadResult Load(Kernel::KProcess& process, Core::System& system) override; + LoadResult Load(Kernel::Process& process, Core::System& system) override; ResultStatus ReadIcon(std::vector& buffer) override; ResultStatus ReadProgramId(u64& out_program_id) override; @@ -53,7 +53,7 @@ public: bool IsRomFSUpdatable() const override; private: - bool LoadNro(Kernel::KProcess& process, const FileSys::VfsFile& nro_file); + bool LoadNro(Kernel::Process& process, const FileSys::VfsFile& nro_file); std::vector icon_data; std::unique_ptr nacp; diff --git a/src/core/loader/nso.cpp b/src/core/loader/nso.cpp index df59412cf..f671afe02 100755 --- a/src/core/loader/nso.cpp +++ b/src/core/loader/nso.cpp @@ -17,8 +17,8 @@ #include "core/file_sys/patch_manager.h" #include "core/hle/kernel/code_set.h" #include "core/hle/kernel/k_page_table.h" -#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_thread.h" +#include "core/hle/kernel/process.h" #include "core/loader/nso.h" #include "core/memory.h" @@ -71,7 +71,7 @@ FileType AppLoader_NSO::IdentifyType(const FileSys::VirtualFile& in_file) { return FileType::NSO; } -std::optional AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core::System& system, +std::optional AppLoader_NSO::LoadModule(Kernel::Process& process, Core::System& system, const FileSys::VfsFile& nso_file, VAddr load_base, bool should_pass_arguments, bool load_into_process, std::optional pm) { @@ -162,7 +162,7 @@ std::optional AppLoader_NSO::LoadModule(Kernel::KProcess& process, Core:: return load_base + image_size; } -AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::KProcess& process, Core::System& system) { +AppLoader_NSO::LoadResult AppLoader_NSO::Load(Kernel::Process& process, Core::System& system) { if (is_loaded) { return {ResultStatus::ErrorAlreadyLoaded, {}}; } diff --git a/src/core/loader/nso.h b/src/core/loader/nso.h index f7b61bc2d..195149b55 100755 --- a/src/core/loader/nso.h +++ b/src/core/loader/nso.h @@ -17,7 +17,7 @@ class System; } namespace Kernel { -class KProcess; +class Process; } namespace Loader { @@ -86,12 +86,12 @@ public: return IdentifyType(file); } - static std::optional LoadModule(Kernel::KProcess& process, Core::System& system, + static std::optional LoadModule(Kernel::Process& process, Core::System& system, const FileSys::VfsFile& nso_file, VAddr load_base, bool should_pass_arguments, bool load_into_process, std::optional pm = {}); - LoadResult Load(Kernel::KProcess& process, Core::System& system) override; + LoadResult Load(Kernel::Process& process, Core::System& system) override; ResultStatus ReadNSOModules(Modules& out_modules) override; diff --git a/src/core/loader/nsp.cpp b/src/core/loader/nsp.cpp index d815a7cd3..d7e590f1c 100755 --- a/src/core/loader/nsp.cpp +++ b/src/core/loader/nsp.cpp @@ -13,7 +13,7 @@ #include "core/file_sys/patch_manager.h" #include "core/file_sys/registered_cache.h" #include "core/file_sys/submission_package.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/loader/deconstructed_rom_directory.h" #include "core/loader/nca.h" @@ -79,7 +79,7 @@ FileType AppLoader_NSP::IdentifyType(const FileSys::VirtualFile& nsp_file) { return FileType::Error; } -AppLoader_NSP::LoadResult AppLoader_NSP::Load(Kernel::KProcess& process, Core::System& system) { +AppLoader_NSP::LoadResult AppLoader_NSP::Load(Kernel::Process& process, Core::System& system) { if (is_loaded) { return {ResultStatus::ErrorAlreadyLoaded, {}}; } diff --git a/src/core/loader/nsp.h b/src/core/loader/nsp.h index 644c0ff58..1660f1b94 100755 --- a/src/core/loader/nsp.h +++ b/src/core/loader/nsp.h @@ -45,7 +45,7 @@ public: return IdentifyType(file); } - LoadResult Load(Kernel::KProcess& process, Core::System& system) override; + LoadResult Load(Kernel::Process& process, Core::System& system) override; ResultStatus ReadRomFS(FileSys::VirtualFile& out_file) override; u64 ReadRomFSIVFCOffset() const override; diff --git a/src/core/loader/xci.cpp b/src/core/loader/xci.cpp index 635d6ae15..0125ddf33 100755 --- a/src/core/loader/xci.cpp +++ b/src/core/loader/xci.cpp @@ -13,7 +13,7 @@ #include "core/file_sys/registered_cache.h" #include "core/file_sys/romfs.h" #include "core/file_sys/submission_package.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/loader/nca.h" #include "core/loader/xci.h" @@ -56,7 +56,7 @@ FileType AppLoader_XCI::IdentifyType(const FileSys::VirtualFile& xci_file) { return FileType::Error; } -AppLoader_XCI::LoadResult AppLoader_XCI::Load(Kernel::KProcess& process, Core::System& system) { +AppLoader_XCI::LoadResult AppLoader_XCI::Load(Kernel::Process& process, Core::System& system) { if (is_loaded) { return {ResultStatus::ErrorAlreadyLoaded, {}}; } diff --git a/src/core/loader/xci.h b/src/core/loader/xci.h index 708155c30..7ea8179af 100755 --- a/src/core/loader/xci.h +++ b/src/core/loader/xci.h @@ -45,7 +45,7 @@ public: return IdentifyType(file); } - LoadResult Load(Kernel::KProcess& process, Core::System& system) override; + LoadResult Load(Kernel::Process& process, Core::System& system) override; ResultStatus ReadRomFS(FileSys::VirtualFile& out_file) override; u64 ReadRomFSIVFCOffset() const override; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index b4c56e1c1..b9dd3e275 100755 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -17,8 +17,8 @@ #include "core/core.h" #include "core/device_memory.h" #include "core/hle/kernel/k_page_table.h" -#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/physical_memory.h" +#include "core/hle/kernel/process.h" #include "core/memory.h" #include "video_core/gpu.h" @@ -30,7 +30,7 @@ namespace Core::Memory { struct Memory::Impl { explicit Impl(Core::System& system_) : system{system_} {} - void SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) { + void SetCurrentPageTable(Kernel::Process& process, u32 core_id) { current_page_table = &process.PageTable().PageTableImpl(); const std::size_t address_space_width = process.PageTable().GetAddressSpaceWidth(); @@ -50,7 +50,7 @@ struct Memory::Impl { MapPages(page_table, base / PAGE_SIZE, size / PAGE_SIZE, 0, Common::PageType::Unmapped); } - bool IsValidVirtualAddress(const Kernel::KProcess& process, const VAddr vaddr) const { + bool IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) const { const auto& page_table = process.PageTable().PageTableImpl(); const auto [pointer, type] = page_table.pointers[vaddr >> PAGE_BITS].PointerType(); return pointer != nullptr || type == Common::PageType::RasterizerCachedMemory; @@ -82,22 +82,6 @@ struct Memory::Impl { return nullptr; } - u8* GetKernelBuffer(VAddr start_vaddr, size_t size) { - // TODO(bunnei): This is just a workaround until we have kernel memory layout mapped & - // managed. Until then, we use this to allocate and access kernel memory regions. - - auto search = kernel_memory_regions.find(start_vaddr); - if (search != kernel_memory_regions.end()) { - return search->second.get(); - } - - std::unique_ptr new_memory_region{new u8[size]}; - u8* raw_ptr = new_memory_region.get(); - kernel_memory_regions[start_vaddr] = std::move(new_memory_region); - - return raw_ptr; - } - u8 Read8(const VAddr addr) { return Read(addr); } @@ -194,7 +178,7 @@ struct Memory::Impl { return string; } - void ReadBlock(const Kernel::KProcess& process, const VAddr src_addr, void* dest_buffer, + void ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer, const std::size_t size) { const auto& page_table = process.PageTable().PageTableImpl(); @@ -239,7 +223,7 @@ struct Memory::Impl { } } - void ReadBlockUnsafe(const Kernel::KProcess& process, const VAddr src_addr, void* dest_buffer, + void ReadBlockUnsafe(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer, const std::size_t size) { const auto& page_table = process.PageTable().PageTableImpl(); @@ -291,7 +275,7 @@ struct Memory::Impl { ReadBlockUnsafe(*system.CurrentProcess(), src_addr, dest_buffer, size); } - void WriteBlock(const Kernel::KProcess& process, const VAddr dest_addr, const void* src_buffer, + void WriteBlock(const Kernel::Process& process, const VAddr dest_addr, const void* src_buffer, const std::size_t size) { const auto& page_table = process.PageTable().PageTableImpl(); std::size_t remaining_size = size; @@ -334,7 +318,7 @@ struct Memory::Impl { } } - void WriteBlockUnsafe(const Kernel::KProcess& process, const VAddr dest_addr, + void WriteBlockUnsafe(const Kernel::Process& process, const VAddr dest_addr, const void* src_buffer, const std::size_t size) { const auto& page_table = process.PageTable().PageTableImpl(); std::size_t remaining_size = size; @@ -384,7 +368,7 @@ struct Memory::Impl { WriteBlockUnsafe(*system.CurrentProcess(), dest_addr, src_buffer, size); } - void ZeroBlock(const Kernel::KProcess& process, const VAddr dest_addr, const std::size_t size) { + void ZeroBlock(const Kernel::Process& process, const VAddr dest_addr, const std::size_t size) { const auto& page_table = process.PageTable().PageTableImpl(); std::size_t remaining_size = size; std::size_t page_index = dest_addr >> PAGE_BITS; @@ -429,7 +413,7 @@ struct Memory::Impl { ZeroBlock(*system.CurrentProcess(), dest_addr, size); } - void CopyBlock(const Kernel::KProcess& process, VAddr dest_addr, VAddr src_addr, + void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr, const std::size_t size) { const auto& page_table = process.PageTable().PageTableImpl(); std::size_t remaining_size = size; @@ -727,21 +711,13 @@ struct Memory::Impl { } Common::PageTable* current_page_table = nullptr; - std::unordered_map> kernel_memory_regions; Core::System& system; }; -Memory::Memory(Core::System& system_) : system{system_} { - Reset(); -} - +Memory::Memory(Core::System& system) : impl{std::make_unique(system)} {} Memory::~Memory() = default; -void Memory::Reset() { - impl = std::make_unique(system); -} - -void Memory::SetCurrentPageTable(Kernel::KProcess& process, u32 core_id) { +void Memory::SetCurrentPageTable(Kernel::Process& process, u32 core_id) { impl->SetCurrentPageTable(process, core_id); } @@ -753,7 +729,7 @@ void Memory::UnmapRegion(Common::PageTable& page_table, VAddr base, u64 size) { impl->UnmapRegion(page_table, base, size); } -bool Memory::IsValidVirtualAddress(const Kernel::KProcess& process, const VAddr vaddr) const { +bool Memory::IsValidVirtualAddress(const Kernel::Process& process, const VAddr vaddr) const { return impl->IsValidVirtualAddress(process, vaddr); } @@ -765,10 +741,6 @@ u8* Memory::GetPointer(VAddr vaddr) { return impl->GetPointer(vaddr); } -u8* Memory::GetKernelBuffer(VAddr start_vaddr, size_t size) { - return impl->GetKernelBuffer(start_vaddr, size); -} - const u8* Memory::GetPointer(VAddr vaddr) const { return impl->GetPointer(vaddr); } @@ -829,7 +801,7 @@ std::string Memory::ReadCString(VAddr vaddr, std::size_t max_length) { return impl->ReadCString(vaddr, max_length); } -void Memory::ReadBlock(const Kernel::KProcess& process, const VAddr src_addr, void* dest_buffer, +void Memory::ReadBlock(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer, const std::size_t size) { impl->ReadBlock(process, src_addr, dest_buffer, size); } @@ -838,7 +810,7 @@ void Memory::ReadBlock(const VAddr src_addr, void* dest_buffer, const std::size_ impl->ReadBlock(src_addr, dest_buffer, size); } -void Memory::ReadBlockUnsafe(const Kernel::KProcess& process, const VAddr src_addr, +void Memory::ReadBlockUnsafe(const Kernel::Process& process, const VAddr src_addr, void* dest_buffer, const std::size_t size) { impl->ReadBlockUnsafe(process, src_addr, dest_buffer, size); } @@ -847,7 +819,7 @@ void Memory::ReadBlockUnsafe(const VAddr src_addr, void* dest_buffer, const std: impl->ReadBlockUnsafe(src_addr, dest_buffer, size); } -void Memory::WriteBlock(const Kernel::KProcess& process, VAddr dest_addr, const void* src_buffer, +void Memory::WriteBlock(const Kernel::Process& process, VAddr dest_addr, const void* src_buffer, std::size_t size) { impl->WriteBlock(process, dest_addr, src_buffer, size); } @@ -856,7 +828,7 @@ void Memory::WriteBlock(const VAddr dest_addr, const void* src_buffer, const std impl->WriteBlock(dest_addr, src_buffer, size); } -void Memory::WriteBlockUnsafe(const Kernel::KProcess& process, VAddr dest_addr, +void Memory::WriteBlockUnsafe(const Kernel::Process& process, VAddr dest_addr, const void* src_buffer, std::size_t size) { impl->WriteBlockUnsafe(process, dest_addr, src_buffer, size); } @@ -866,7 +838,7 @@ void Memory::WriteBlockUnsafe(const VAddr dest_addr, const void* src_buffer, impl->WriteBlockUnsafe(dest_addr, src_buffer, size); } -void Memory::ZeroBlock(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size) { +void Memory::ZeroBlock(const Kernel::Process& process, VAddr dest_addr, std::size_t size) { impl->ZeroBlock(process, dest_addr, size); } @@ -874,7 +846,7 @@ void Memory::ZeroBlock(VAddr dest_addr, std::size_t size) { impl->ZeroBlock(dest_addr, size); } -void Memory::CopyBlock(const Kernel::KProcess& process, VAddr dest_addr, VAddr src_addr, +void Memory::CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr, const std::size_t size) { impl->CopyBlock(process, dest_addr, src_addr, size); } diff --git a/src/core/memory.h b/src/core/memory.h index 345fd870d..6d34fcfe2 100755 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -19,7 +19,7 @@ class System; namespace Kernel { class PhysicalMemory; -class KProcess; +class Process; } // namespace Kernel namespace Core::Memory { @@ -58,17 +58,12 @@ public: Memory(Memory&&) = default; Memory& operator=(Memory&&) = default; - /** - * Resets the state of the Memory system. - */ - void Reset(); - /** * Changes the currently active page table to that of the given process instance. * * @param process The process to use the page table of. */ - void SetCurrentPageTable(Kernel::KProcess& process, u32 core_id); + void SetCurrentPageTable(Kernel::Process& process, u32 core_id); /** * Maps an allocated buffer onto a region of the emulated process address space. @@ -99,7 +94,7 @@ public: * * @returns True if the given virtual address is valid, false otherwise. */ - bool IsValidVirtualAddress(const Kernel::KProcess& process, VAddr vaddr) const; + bool IsValidVirtualAddress(const Kernel::Process& process, VAddr vaddr) const; /** * Checks whether or not the supplied address is a valid virtual @@ -121,15 +116,6 @@ public: */ u8* GetPointer(VAddr vaddr); - /** - * Gets a pointer to the start of a kernel heap allocated memory region. Will allocate one if it - * does not already exist. - * - * @param start_vaddr Start virtual address for the memory region. - * @param size Size of the memory region. - */ - u8* GetKernelBuffer(VAddr start_vaddr, size_t size); - template T* GetPointer(VAddr vaddr) { return reinterpret_cast(GetPointer(vaddr)); @@ -333,7 +319,7 @@ public: * @post The range [dest_buffer, size) contains the read bytes from the * process' address space. */ - void ReadBlock(const Kernel::KProcess& process, VAddr src_addr, void* dest_buffer, + void ReadBlock(const Kernel::Process& process, VAddr src_addr, void* dest_buffer, std::size_t size); /** @@ -354,7 +340,7 @@ public: * @post The range [dest_buffer, size) contains the read bytes from the * process' address space. */ - void ReadBlockUnsafe(const Kernel::KProcess& process, VAddr src_addr, void* dest_buffer, + void ReadBlockUnsafe(const Kernel::Process& process, VAddr src_addr, void* dest_buffer, std::size_t size); /** @@ -414,7 +400,7 @@ public: * and will mark that region as invalidated to caches that the active * graphics backend may be maintaining over the course of execution. */ - void WriteBlock(const Kernel::KProcess& process, VAddr dest_addr, const void* src_buffer, + void WriteBlock(const Kernel::Process& process, VAddr dest_addr, const void* src_buffer, std::size_t size); /** @@ -434,7 +420,7 @@ public: * will be ignored and an error will be logged. * */ - void WriteBlockUnsafe(const Kernel::KProcess& process, VAddr dest_addr, const void* src_buffer, + void WriteBlockUnsafe(const Kernel::Process& process, VAddr dest_addr, const void* src_buffer, std::size_t size); /** @@ -486,7 +472,7 @@ public: * @post The range [dest_addr, size) within the process' address space is * filled with zeroes. */ - void ZeroBlock(const Kernel::KProcess& process, VAddr dest_addr, std::size_t size); + void ZeroBlock(const Kernel::Process& process, VAddr dest_addr, std::size_t size); /** * Fills the specified address range within the current process' address space with zeroes. @@ -511,7 +497,7 @@ public: * @post The range [dest_addr, size) within the process' address space contains the * same data within the range [src_addr, size). */ - void CopyBlock(const Kernel::KProcess& process, VAddr dest_addr, VAddr src_addr, + void CopyBlock(const Kernel::Process& process, VAddr dest_addr, VAddr src_addr, std::size_t size); /** @@ -538,8 +524,6 @@ public: void RasterizerMarkRegionCached(VAddr vaddr, u64 size, bool cached); private: - Core::System& system; - struct Impl; std::unique_ptr impl; }; diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp index 0f5ef7954..7643b7846 100755 --- a/src/core/memory/cheat_engine.cpp +++ b/src/core/memory/cheat_engine.cpp @@ -11,7 +11,7 @@ #include "core/core_timing_util.h" #include "core/hardware_properties.h" #include "core/hle/kernel/k_page_table.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/hid/controllers/npad.h" #include "core/hle/service/hid/hid.h" #include "core/hle/service/sm/sm.h" diff --git a/src/core/reporter.cpp b/src/core/reporter.cpp index 896add892..311d4dda8 100755 --- a/src/core/reporter.cpp +++ b/src/core/reporter.cpp @@ -19,7 +19,7 @@ #include "core/core.h" #include "core/hle/kernel/hle_ipc.h" #include "core/hle/kernel/k_page_table.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/hle/result.h" #include "core/memory.h" #include "core/reporter.h" diff --git a/src/video_core/memory_manager.cpp b/src/video_core/memory_manager.cpp index 76492a103..9529a1256 100755 --- a/src/video_core/memory_manager.cpp +++ b/src/video_core/memory_manager.cpp @@ -7,7 +7,7 @@ #include "common/logging/log.h" #include "core/core.h" #include "core/hle/kernel/k_page_table.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/memory.h" #include "video_core/gpu.h" #include "video_core/memory_manager.h" diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp index b387f2943..2f2784951 100755 --- a/src/video_core/renderer_opengl/gl_rasterizer.cpp +++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp @@ -19,7 +19,7 @@ #include "common/scope_exit.h" #include "common/settings.h" #include "core/core.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/memory.h" #include "video_core/engines/kepler_compute.h" #include "video_core/engines/maxwell_3d.h" diff --git a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp index dbcb751cb..97fb11ac6 100755 --- a/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp +++ b/src/video_core/renderer_opengl/gl_shader_disk_cache.cpp @@ -15,7 +15,7 @@ #include "common/settings.h" #include "common/zstd_compression.h" #include "core/core.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "video_core/engines/shader_type.h" #include "video_core/renderer_opengl/gl_shader_cache.h" #include "video_core/renderer_opengl/gl_shader_disk_cache.h" diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 86495803e..7ff9491f4 100755 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -32,7 +32,7 @@ #include "common/settings.h" #include "core/core.h" #include "core/frontend/framebuffer_layout.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "input_common/keyboard.h" #include "input_common/main.h" #include "input_common/mouse/mouse_input.h" diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp index bdfda6c54..3bca6277b 100755 --- a/src/yuzu/debugger/wait_tree.cpp +++ b/src/yuzu/debugger/wait_tree.cpp @@ -12,13 +12,12 @@ #include "common/assert.h" #include "core/arm/arm_interface.h" #include "core/core.h" -#include "core/hle/kernel/k_class_token.h" -#include "core/hle/kernel/k_handle_table.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_synchronization_object.h" #include "core/hle/kernel/k_thread.h" +#include "core/hle/kernel/process.h" #include "core/hle/kernel/svc_common.h" #include "core/hle/kernel/svc_types.h" #include "core/memory.h" @@ -92,7 +91,7 @@ std::size_t WaitTreeItem::Row() const { std::vector> WaitTreeItem::MakeThreadItemList() { std::vector> item_list; std::size_t row = 0; - auto add_threads = [&](const std::vector& threads) { + auto add_threads = [&](const std::vector>& threads) { for (std::size_t i = 0; i < threads.size(); ++i) { if (threads[i]->GetThreadTypeForDebugging() == Kernel::ThreadType::User) { item_list.push_back(std::make_unique(*threads[i])); @@ -115,11 +114,11 @@ QString WaitTreeText::GetText() const { return text; } -WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address, const Kernel::KHandleTable& handle_table) +WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address, const Kernel::HandleTable& handle_table) : mutex_address(mutex_address) { mutex_value = Core::System::GetInstance().Memory().Read32(mutex_address); owner_handle = static_cast(mutex_value & Kernel::Svc::HandleWaitMask); - owner = handle_table.GetObject(owner_handle).GetPointerUnsafe(); + owner = handle_table.Get(owner_handle); } WaitTreeMutexInfo::~WaitTreeMutexInfo() = default; @@ -184,20 +183,18 @@ bool WaitTreeExpandableItem::IsExpandable() const { } QString WaitTreeSynchronizationObject::GetText() const { - return tr("[%1] %2 %3") - .arg(object.GetId()) - .arg(QString::fromStdString(object.GetTypeObj().GetName()), + return tr("[%1]%2 %3") + .arg(object.GetObjectId()) + .arg(QString::fromStdString(object.GetTypeName()), QString::fromStdString(object.GetName())); } std::unique_ptr WaitTreeSynchronizationObject::make( const Kernel::KSynchronizationObject& object) { - const auto type = - static_cast(object.GetTypeObj().GetClassToken()); - switch (type) { - case Kernel::KClassTokenGenerator::ObjectType::KReadableEvent: + switch (object.GetHandleType()) { + case Kernel::HandleType::ReadableEvent: return std::make_unique(static_cast(object)); - case Kernel::KClassTokenGenerator::ObjectType::KThread: + case Kernel::HandleType::Thread: return std::make_unique(static_cast(object)); default: return std::make_unique(object); @@ -207,13 +204,12 @@ std::unique_ptr WaitTreeSynchronizationObject::ma std::vector> WaitTreeSynchronizationObject::GetChildren() const { std::vector> list; - auto threads = object.GetWaitingThreadsForDebugging(); + const auto& threads = object.GetWaitingThreadsForDebugging(); if (threads.empty()) { list.push_back(std::make_unique(tr("waited by no thread"))); } else { - list.push_back(std::make_unique(std::move(threads))); + list.push_back(std::make_unique(threads)); } - return list; } @@ -381,8 +377,8 @@ WaitTreeEvent::WaitTreeEvent(const Kernel::KReadableEvent& object) : WaitTreeSynchronizationObject(object) {} WaitTreeEvent::~WaitTreeEvent() = default; -WaitTreeThreadList::WaitTreeThreadList(std::vector&& list) - : thread_list(std::move(list)) {} +WaitTreeThreadList::WaitTreeThreadList(const std::vector& list) + : thread_list(list) {} WaitTreeThreadList::~WaitTreeThreadList() = default; QString WaitTreeThreadList::GetText() const { diff --git a/src/yuzu/debugger/wait_tree.h b/src/yuzu/debugger/wait_tree.h index d450345df..3da2fdfd2 100755 --- a/src/yuzu/debugger/wait_tree.h +++ b/src/yuzu/debugger/wait_tree.h @@ -11,15 +11,13 @@ #include #include #include - #include "common/common_types.h" -#include "core/hle/kernel/k_auto_object.h" -#include "core/hle/kernel/svc_common.h" +#include "core/hle/kernel/object.h" class EmuThread; namespace Kernel { -class KHandleTable; +class HandleTable; class KReadableEvent; class KSynchronizationObject; class KThread; @@ -75,17 +73,17 @@ public: class WaitTreeMutexInfo : public WaitTreeExpandableItem { Q_OBJECT public: - explicit WaitTreeMutexInfo(VAddr mutex_address, const Kernel::KHandleTable& handle_table); + explicit WaitTreeMutexInfo(VAddr mutex_address, const Kernel::HandleTable& handle_table); ~WaitTreeMutexInfo() override; QString GetText() const override; std::vector> GetChildren() const override; private: - VAddr mutex_address{}; - u32 mutex_value{}; - Kernel::Handle owner_handle{}; - Kernel::KThread* owner{}; + VAddr mutex_address; + u32 mutex_value; + Kernel::Handle owner_handle; + std::shared_ptr owner; }; class WaitTreeCallstack : public WaitTreeExpandableItem { @@ -151,14 +149,14 @@ public: class WaitTreeThreadList : public WaitTreeExpandableItem { Q_OBJECT public: - explicit WaitTreeThreadList(std::vector&& list); + explicit WaitTreeThreadList(const std::vector& list); ~WaitTreeThreadList() override; QString GetText() const override; std::vector> GetChildren() const override; private: - std::vector thread_list; + const std::vector& thread_list; }; class WaitTreeModel : public QAbstractItemModel { diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 9e72acbf7..00d4cfe67 100755 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -92,7 +92,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual #include "core/file_sys/romfs.h" #include "core/file_sys/savedata_factory.h" #include "core/file_sys/submission_package.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/am/am.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/nfp/nfp.h" diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp index e2812ca61..4871ac3bb 100755 --- a/src/yuzu_cmd/yuzu.cpp +++ b/src/yuzu_cmd/yuzu.cpp @@ -27,7 +27,7 @@ #include "core/crypto/key_manager.h" #include "core/file_sys/registered_cache.h" #include "core/file_sys/vfs_real.h" -#include "core/hle/kernel/k_process.h" +#include "core/hle/kernel/process.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/loader/loader.h" #include "core/telemetry_session.h"