early-access version 1659

This commit is contained in:
pineappleEA 2021-05-06 03:20:08 +02:00
parent 590872e3be
commit 37b353b187
142 changed files with 1763 additions and 1991 deletions

View file

@ -1,7 +1,7 @@
yuzu emulator early access yuzu emulator early access
============= =============
This is the source code for early-access 1658. This is the source code for early-access 1659.
## Legal Notice ## Legal Notice

View file

@ -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()) #define R_SUCCEEDED(res) (res.IsSuccess())
/// Evaluates an expression that returns a result, and returns the result if it would fail. /// 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; 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 <class C>
constexpr auto Size(const C& c) -> decltype(c.size()) {
return std::size(c);
}
template <class C>
constexpr std::size_t Size(const C& c) {
if constexpr (sizeof(C) == 0) {
return 0;
} else {
return std::size(c);
}
}
} // namespace Common } // namespace Common

View file

@ -509,6 +509,7 @@ private:
private: private:
static constexpr TypedStorage<Derived> DerivedStorage = {}; static constexpr TypedStorage<Derived> DerivedStorage = {};
static_assert(GetParent(GetNode(GetPointer(DerivedStorage))) == GetPointer(DerivedStorage));
}; };
template <auto T, class Derived = impl::GetParentType<T>> template <auto T, class Derived = impl::GetParentType<T>>

View file

@ -133,27 +133,27 @@ template <auto MemberPtr>
using GetMemberType = typename GetMemberPointerTraits<decltype(MemberPtr)>::Member; using GetMemberType = typename GetMemberPointerTraits<decltype(MemberPtr)>::Member;
template <auto MemberPtr, typename RealParentType = GetParentType<MemberPtr>> template <auto MemberPtr, typename RealParentType = GetParentType<MemberPtr>>
constexpr std::ptrdiff_t OffsetOf() { static inline std::ptrdiff_t OffsetOf = [] {
using DeducedParentType = GetParentType<MemberPtr>; using DeducedParentType = GetParentType<MemberPtr>;
using MemberType = GetMemberType<MemberPtr>; using MemberType = GetMemberType<MemberPtr>;
static_assert(std::is_base_of<DeducedParentType, RealParentType>::value || static_assert(std::is_base_of<DeducedParentType, RealParentType>::value ||
std::is_same<RealParentType, DeducedParentType>::value); std::is_same<RealParentType, DeducedParentType>::value);
return OffsetOfCalculator<RealParentType, MemberType>::OffsetOf(MemberPtr); return OffsetOfCalculator<RealParentType, MemberType>::OffsetOf(MemberPtr);
}; }();
} // namespace impl } // namespace impl
template <auto MemberPtr, typename RealParentType = impl::GetParentType<MemberPtr>> template <auto MemberPtr, typename RealParentType = impl::GetParentType<MemberPtr>>
constexpr RealParentType& GetParentReference(impl::GetMemberType<MemberPtr>* member) { constexpr RealParentType& GetParentReference(impl::GetMemberType<MemberPtr>* member) {
std::ptrdiff_t Offset = impl::OffsetOf<MemberPtr, RealParentType>(); std::ptrdiff_t Offset = impl::OffsetOf<MemberPtr, RealParentType>;
return *static_cast<RealParentType*>( return *static_cast<RealParentType*>(
static_cast<void*>(static_cast<uint8_t*>(static_cast<void*>(member)) - Offset)); static_cast<void*>(static_cast<uint8_t*>(static_cast<void*>(member)) - Offset));
} }
template <auto MemberPtr, typename RealParentType = impl::GetParentType<MemberPtr>> template <auto MemberPtr, typename RealParentType = impl::GetParentType<MemberPtr>>
constexpr RealParentType const& GetParentReference(impl::GetMemberType<MemberPtr> const* member) { constexpr RealParentType const& GetParentReference(impl::GetMemberType<MemberPtr> const* member) {
std::ptrdiff_t Offset = impl::OffsetOf<MemberPtr, RealParentType>(); std::ptrdiff_t Offset = impl::OffsetOf<MemberPtr, RealParentType>;
return *static_cast<const RealParentType*>(static_cast<const void*>( return *static_cast<const RealParentType*>(static_cast<const void*>(
static_cast<const uint8_t*>(static_cast<const void*>(member)) - Offset)); static_cast<const uint8_t*>(static_cast<const void*>(member)) - Offset));
} }

View file

@ -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.cpp
hle/kernel/board/nintendo/nx/k_system_control.h hle/kernel/board/nintendo/nx/k_system_control.h
hle/kernel/board/nintendo/nx/secure_monitor.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.cpp
hle/kernel/code_set.h hle/kernel/code_set.h
hle/kernel/svc_results.h hle/kernel/svc_results.h
hle/kernel/global_scheduler_context.cpp hle/kernel/global_scheduler_context.cpp
hle/kernel/global_scheduler_context.h 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.cpp
hle/kernel/hle_ipc.h 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.cpp
hle/kernel/k_address_arbiter.h hle/kernel/k_address_arbiter.h
hle/kernel/k_address_space_info.cpp hle/kernel/k_address_space_info.cpp
hle/kernel/k_address_space_info.h 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_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.cpp
hle/kernel/k_condition_variable.h hle/kernel/k_condition_variable.h
hle/kernel/k_event.cpp hle/kernel/k_event.cpp
hle/kernel/k_event.h 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_condition_variable.h
hle/kernel/k_light_lock.cpp hle/kernel/k_light_lock.cpp
hle/kernel/k_light_lock.h hle/kernel/k_light_lock.h
hle/kernel/k_linked_list.h
hle/kernel/k_memory_block.h hle/kernel/k_memory_block.h
hle/kernel/k_memory_block_manager.cpp hle/kernel/k_memory_block_manager.cpp
hle/kernel/k_memory_block_manager.h 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_linked_list.h
hle/kernel/k_page_table.cpp hle/kernel/k_page_table.cpp
hle/kernel/k_page_table.h 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_priority_queue.h
hle/kernel/k_process.cpp
hle/kernel/k_process.h
hle/kernel/k_readable_event.cpp hle/kernel/k_readable_event.cpp
hle/kernel/k_readable_event.h hle/kernel/k_readable_event.h
hle/kernel/k_resource_limit.cpp hle/kernel/k_resource_limit.cpp
@ -209,12 +196,6 @@ add_library(core STATIC
hle/kernel/k_scoped_lock.h hle/kernel/k_scoped_lock.h
hle/kernel/k_scoped_resource_reservation.h hle/kernel/k_scoped_resource_reservation.h
hle/kernel/k_scoped_scheduler_lock_and_sleep.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.cpp
hle/kernel/k_shared_memory.h hle/kernel/k_shared_memory.h
hle/kernel/k_slab_heap.h hle/kernel/k_slab_heap.h
@ -227,21 +208,28 @@ add_library(core STATIC
hle/kernel/k_thread.h hle/kernel/k_thread.h
hle/kernel/k_thread_queue.h hle/kernel/k_thread_queue.h
hle/kernel/k_trace.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.cpp
hle/kernel/k_writable_event.h hle/kernel/k_writable_event.h
hle/kernel/kernel.cpp hle/kernel/kernel.cpp
hle/kernel/kernel.h hle/kernel/kernel.h
hle/kernel/memory_types.h hle/kernel/memory_types.h
hle/kernel/object.cpp
hle/kernel/object.h
hle/kernel/physical_core.cpp hle/kernel/physical_core.cpp
hle/kernel/physical_core.h hle/kernel/physical_core.h
hle/kernel/physical_memory.h hle/kernel/physical_memory.h
hle/kernel/process.cpp
hle/kernel/process.h
hle/kernel/process_capability.cpp hle/kernel/process_capability.cpp
hle/kernel/process_capability.h 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.cpp
hle/kernel/service_thread.h 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.cpp
hle/kernel/svc.h hle/kernel/svc.h
hle/kernel/svc_common.h hle/kernel/svc_common.h
@ -249,6 +237,8 @@ add_library(core STATIC
hle/kernel/svc_wrap.h hle/kernel/svc_wrap.h
hle/kernel/time_manager.cpp hle/kernel/time_manager.cpp
hle/kernel/time_manager.h hle/kernel/time_manager.h
hle/kernel/transfer_memory.cpp
hle/kernel/transfer_memory.h
hle/lock.cpp hle/lock.cpp
hle/lock.h hle/lock.h
hle/result.h hle/result.h

View file

@ -16,8 +16,8 @@
#include "core/core.h" #include "core/core.h"
#include "core/core_timing.h" #include "core/core_timing.h"
#include "core/hardware_properties.h" #include "core/hardware_properties.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/svc.h" #include "core/hle/kernel/svc.h"
#include "core/memory.h" #include "core/memory.h"

View file

@ -27,12 +27,12 @@
#include "core/file_sys/vfs_concat.h" #include "core/file_sys/vfs_concat.h"
#include "core/file_sys/vfs_real.h" #include "core/file_sys/vfs_real.h"
#include "core/hardware_interrupt_manager.h" #include "core/hardware_interrupt_manager.h"
#include "core/hle/kernel/k_client_port.h" #include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/physical_core.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/am/applets/applets.h"
#include "core/hle/service/apm/controller.h" #include "core/hle/service/apm/controller.h"
#include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/filesystem/filesystem.h"
@ -166,9 +166,9 @@ struct System::Impl {
cpu_manager.SetAsyncGpu(is_async_gpu); cpu_manager.SetAsyncGpu(is_async_gpu);
core_timing.SetMulticore(is_multicore); core_timing.SetMulticore(is_multicore);
core_timing.Initialize([&system]() { system.RegisterHostThread(); });
kernel.Initialize(); kernel.Initialize();
cpu_manager.Initialize(); cpu_manager.Initialize();
core_timing.Initialize([&system]() { system.RegisterHostThread(); });
const auto current_time = std::chrono::duration_cast<std::chrono::seconds>( const auto current_time = std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch()); std::chrono::system_clock::now().time_since_epoch());
@ -233,11 +233,8 @@ struct System::Impl {
} }
telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider); telemetry_session->AddInitialInfo(*app_loader, fs_controller, *content_provider);
auto main_process = Kernel::KProcess::Create(system.Kernel()); auto main_process =
ASSERT(Kernel::KProcess::Initialize(main_process, system, "main", Kernel::Process::Create(system, "main", Kernel::Process::ProcessType::Userland);
Kernel::KProcess::ProcessType::Userland)
.IsSuccess());
main_process->Open();
const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); const auto [load_result, load_parameters] = app_loader->Load(*main_process, system);
if (load_result != Loader::ResultStatus::Success) { if (load_result != Loader::ResultStatus::Success) {
LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result);
@ -247,7 +244,7 @@ struct System::Impl {
static_cast<u32>(load_result)); static_cast<u32>(load_result));
} }
AddGlueRegistrationForProcess(*app_loader, *main_process); AddGlueRegistrationForProcess(*app_loader, *main_process);
kernel.MakeCurrentProcess(main_process); kernel.MakeCurrentProcess(main_process.get());
kernel.InitializeCores(); kernel.InitializeCores();
// Initialize cheat engine // Initialize cheat engine
@ -314,7 +311,6 @@ struct System::Impl {
gpu_core.reset(); gpu_core.reset();
perf_stats.reset(); perf_stats.reset();
kernel.Shutdown(); kernel.Shutdown();
memory.Reset();
applet_manager.ClearAll(); applet_manager.ClearAll();
LOG_DEBUG(Core, "Shutdown OK"); LOG_DEBUG(Core, "Shutdown OK");
@ -326,7 +322,7 @@ struct System::Impl {
return app_loader->ReadTitle(out); return app_loader->ReadTitle(out);
} }
void AddGlueRegistrationForProcess(Loader::AppLoader& loader, Kernel::KProcess& process) { void AddGlueRegistrationForProcess(Loader::AppLoader& loader, Kernel::Process& process) {
std::vector<u8> nacp_data; std::vector<u8> nacp_data;
FileSys::NACP nacp; FileSys::NACP nacp;
if (loader.ReadControlData(nacp) == Loader::ResultStatus::Success) { if (loader.ReadControlData(nacp) == Loader::ResultStatus::Success) {
@ -517,7 +513,7 @@ const Kernel::GlobalSchedulerContext& System::GlobalSchedulerContext() const {
return impl->kernel.GlobalSchedulerContext(); return impl->kernel.GlobalSchedulerContext();
} }
Kernel::KProcess* System::CurrentProcess() { Kernel::Process* System::CurrentProcess() {
return impl->kernel.CurrentProcess(); return impl->kernel.CurrentProcess();
} }
@ -529,7 +525,7 @@ const Core::DeviceMemory& System::DeviceMemory() const {
return *impl->device_memory; return *impl->device_memory;
} }
const Kernel::KProcess* System::CurrentProcess() const { const Kernel::Process* System::CurrentProcess() const {
return impl->kernel.CurrentProcess(); return impl->kernel.CurrentProcess();
} }

View file

@ -12,6 +12,7 @@
#include "common/common_types.h" #include "common/common_types.h"
#include "core/file_sys/vfs_types.h" #include "core/file_sys/vfs_types.h"
#include "core/hle/kernel/object.h"
namespace Core::Frontend { namespace Core::Frontend {
class EmuWindow; class EmuWindow;
@ -28,7 +29,7 @@ namespace Kernel {
class GlobalSchedulerContext; class GlobalSchedulerContext;
class KernelCore; class KernelCore;
class PhysicalCore; class PhysicalCore;
class KProcess; class Process;
class KScheduler; class KScheduler;
} // namespace Kernel } // namespace Kernel
@ -263,10 +264,10 @@ public:
[[nodiscard]] const Core::DeviceMemory& DeviceMemory() const; [[nodiscard]] const Core::DeviceMemory& DeviceMemory() const;
/// Provides a pointer to the current process /// Provides a pointer to the current process
[[nodiscard]] Kernel::KProcess* CurrentProcess(); [[nodiscard]] Kernel::Process* CurrentProcess();
/// Provides a constant pointer to the current process. /// 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. /// Provides a reference to the core timing instance.
[[nodiscard]] Timing::CoreTiming& CoreTiming(); [[nodiscard]] Timing::CoreTiming& CoreTiming();

View file

@ -13,7 +13,7 @@
#include "core/file_sys/patch_manager.h" #include "core/file_sys/patch_manager.h"
#include "core/file_sys/registered_cache.h" #include "core/file_sys/registered_cache.h"
#include "core/file_sys/romfs_factory.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/hle/service/filesystem/filesystem.h"
#include "core/loader/loader.h" #include "core/loader/loader.h"

View file

@ -9,7 +9,7 @@
#include "core/core.h" #include "core/core.h"
#include "core/file_sys/savedata_factory.h" #include "core/file_sys/savedata_factory.h"
#include "core/file_sys/vfs.h" #include "core/file_sys/vfs.h"
#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/process.h"
namespace FileSys { namespace FileSys {

View file

@ -13,9 +13,12 @@
#include "common/assert.h" #include "common/assert.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/ipc.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/hle_ipc.h"
#include "core/hle/kernel/k_client_port.h" #include "core/hle/kernel/object.h"
#include "core/hle/kernel/k_session.h" #include "core/hle/kernel/server_session.h"
#include "core/hle/kernel/session.h"
#include "core/hle/result.h" #include "core/hle/result.h"
namespace IPC { namespace IPC {
@ -134,11 +137,9 @@ public:
if (context->Session()->IsDomain()) { if (context->Session()->IsDomain()) {
context->AddDomainObject(std::move(iface)); context->AddDomainObject(std::move(iface));
} else { } else {
auto* session = Kernel::KSession::Create(kernel); auto [client, server] = Kernel::Session::Create(kernel, iface->GetServiceName());
session->Initialize(nullptr, iface->GetServiceName()); context->AddMoveObject(std::move(client));
iface->ClientConnected(std::move(server));
context->AddMoveObject(&session->GetClientSession());
iface->ClientConnected(&session->GetServerSession());
} }
} }
@ -214,16 +215,10 @@ public:
void PushRaw(const T& value); void PushRaw(const T& value);
template <typename... O> template <typename... O>
void PushMoveObjects(O*... pointers); void PushMoveObjects(std::shared_ptr<O>... pointers);
template <typename... O> template <typename... O>
void PushMoveObjects(O&... pointers); void PushCopyObjects(std::shared_ptr<O>... pointers);
template <typename... O>
void PushCopyObjects(O*... pointers);
template <typename... O>
void PushCopyObjects(O&... pointers);
private: private:
u32 normal_params_size{}; u32 normal_params_size{};
@ -306,34 +301,18 @@ void ResponseBuilder::Push(const First& first_value, const Other&... other_value
} }
template <typename... O> template <typename... O>
inline void ResponseBuilder::PushCopyObjects(O*... pointers) { inline void ResponseBuilder::PushCopyObjects(std::shared_ptr<O>... pointers) {
auto objects = {pointers...}; auto objects = {pointers...};
for (auto& object : objects) { for (auto& object : objects) {
context->AddCopyObject(object); context->AddCopyObject(std::move(object));
} }
} }
template <typename... O> template <typename... O>
inline void ResponseBuilder::PushCopyObjects(O&... pointers) { inline void ResponseBuilder::PushMoveObjects(std::shared_ptr<O>... pointers) {
auto objects = {&pointers...};
for (auto& object : objects) {
context->AddCopyObject(object);
}
}
template <typename... O>
inline void ResponseBuilder::PushMoveObjects(O*... pointers) {
auto objects = {pointers...}; auto objects = {pointers...};
for (auto& object : objects) { for (auto& object : objects) {
context->AddMoveObject(object); context->AddMoveObject(std::move(object));
}
}
template <typename... O>
inline void ResponseBuilder::PushMoveObjects(O&... pointers) {
auto objects = {&pointers...};
for (auto& object : objects) {
context->AddMoveObject(object);
} }
} }
@ -380,6 +359,12 @@ public:
template <typename T> template <typename T>
T PopRaw(); T PopRaw();
template <typename T>
std::shared_ptr<T> GetMoveObject(std::size_t index);
template <typename T>
std::shared_ptr<T> GetCopyObject(std::size_t index);
template <class T> template <class T>
std::shared_ptr<T> PopIpcInterface() { std::shared_ptr<T> PopIpcInterface() {
ASSERT(context->Session()->IsDomain()); ASSERT(context->Session()->IsDomain());
@ -484,4 +469,14 @@ void RequestParser::Pop(First& first_value, Other&... other_values) {
Pop(other_values...); Pop(other_values...);
} }
template <typename T>
std::shared_ptr<T> RequestParser::GetMoveObject(std::size_t index) {
return context->GetMoveObject<T>(index);
}
template <typename T>
std::shared_ptr<T> RequestParser::GetCopyObject(std::size_t index) {
return context->GetCopyObject<T>(index);
}
} // namespace IPC } // namespace IPC

View file

@ -17,12 +17,12 @@ GlobalSchedulerContext::GlobalSchedulerContext(KernelCore& kernel)
GlobalSchedulerContext::~GlobalSchedulerContext() = default; GlobalSchedulerContext::~GlobalSchedulerContext() = default;
void GlobalSchedulerContext::AddThread(KThread* thread) { void GlobalSchedulerContext::AddThread(std::shared_ptr<KThread> thread) {
std::scoped_lock lock{global_list_guard}; 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<KThread> thread) {
std::scoped_lock lock{global_list_guard}; std::scoped_lock lock{global_list_guard};
thread_list.erase(std::remove(thread_list.begin(), thread_list.end(), thread), thread_list.erase(std::remove(thread_list.begin(), thread_list.end(), thread),
thread_list.end()); thread_list.end());

View file

@ -38,13 +38,13 @@ public:
~GlobalSchedulerContext(); ~GlobalSchedulerContext();
/// Adds a new thread to the scheduler /// Adds a new thread to the scheduler
void AddThread(KThread* thread); void AddThread(std::shared_ptr<KThread> thread);
/// Removes a thread from the scheduler /// Removes a thread from the scheduler
void RemoveThread(KThread* thread); void RemoveThread(std::shared_ptr<KThread> thread);
/// Returns a list of all threads managed by the scheduler /// Returns a list of all threads managed by the scheduler
[[nodiscard]] const std::vector<KThread*>& GetThreadList() const { [[nodiscard]] const std::vector<std::shared_ptr<KThread>>& GetThreadList() const {
return thread_list; return thread_list;
} }
@ -79,7 +79,7 @@ private:
LockType scheduler_lock; LockType scheduler_lock;
/// Lists all thread ids that aren't deleted/etc. /// Lists all thread ids that aren't deleted/etc.
std::vector<KThread*> thread_list; std::vector<std::shared_ptr<KThread>> thread_list;
Common::SpinLock global_list_guard{}; Common::SpinLock global_list_guard{};
}; };

View file

@ -14,16 +14,17 @@
#include "common/common_types.h" #include "common/common_types.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/hle/ipc_helpers.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/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_readable_event.h"
#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.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_thread.h"
#include "core/hle/kernel/k_writable_event.h" #include "core/hle/kernel/k_writable_event.h"
#include "core/hle/kernel/kernel.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/svc_results.h"
#include "core/hle/kernel/time_manager.h" #include "core/hle/kernel/time_manager.h"
#include "core/memory.h" #include "core/memory.h"
@ -34,23 +35,28 @@ SessionRequestHandler::SessionRequestHandler() = default;
SessionRequestHandler::~SessionRequestHandler() = default; SessionRequestHandler::~SessionRequestHandler() = default;
void SessionRequestHandler::ClientConnected(KServerSession* session) { void SessionRequestHandler::ClientConnected(std::shared_ptr<ServerSession> server_session) {
session->SetHleHandler(shared_from_this()); server_session->SetHleHandler(shared_from_this());
connected_sessions.push_back(std::move(server_session));
} }
void SessionRequestHandler::ClientDisconnected(KServerSession* session) { void SessionRequestHandler::ClientDisconnected(
session->SetHleHandler(nullptr); const std::shared_ptr<ServerSession>& server_session) {
server_session->SetHleHandler(nullptr);
boost::range::remove_erase(connected_sessions, server_session);
} }
HLERequestContext::HLERequestContext(KernelCore& kernel_, Core::Memory::Memory& memory_, HLERequestContext::HLERequestContext(KernelCore& kernel, Core::Memory::Memory& memory,
KServerSession* server_session_, KThread* thread_) std::shared_ptr<ServerSession> server_session,
: server_session(server_session_), thread(thread_), kernel{kernel_}, memory{memory_} { std::shared_ptr<KThread> thread)
: server_session(std::move(server_session)),
thread(std::move(thread)), kernel{kernel}, memory{memory} {
cmd_buf[0] = 0; cmd_buf[0] = 0;
} }
HLERequestContext::~HLERequestContext() = default; 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) { bool incoming) {
IPC::RequestParser rp(src_cmdbuf); IPC::RequestParser rp(src_cmdbuf);
command_header = rp.PopRaw<IPC::CommandHeader>(); command_header = rp.PopRaw<IPC::CommandHeader>();
@ -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) { for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_copy; ++handle) {
const u32 copy_handle{rp.Pop<Handle>()}; const u32 copy_handle{rp.Pop<Handle>()};
copy_handles.push_back(copy_handle); 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) { for (u32 handle = 0; handle < handle_descriptor_header->num_handles_to_move; ++handle) {
const u32 move_handle{rp.Pop<Handle>()}; const u32 move_handle{rp.Pop<Handle>()};
move_handles.push_back(move_handle); 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 { } else {
// For responses we just ignore the handles, they're empty and will be populated when // 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. 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) { u32_le* src_cmdbuf) {
ParseCommandBuffer(handle_table, src_cmdbuf, true); ParseCommandBuffer(handle_table, src_cmdbuf, true);
if (command_header->type == IPC::CommandType::Close) { 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 specific values in each of these descriptors.
for (auto& object : copy_objects) { for (auto& object : copy_objects) {
ASSERT(object != nullptr); 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) { for (auto& object : move_objects) {
ASSERT(object != nullptr); ASSERT(object != nullptr);
R_TRY(handle_table.Add(&dst_cmdbuf[current_offset++], object)); dst_cmdbuf[current_offset++] = handle_table.Create(object).Unwrap();
} }
} }

View file

@ -16,8 +16,7 @@
#include "common/concepts.h" #include "common/concepts.h"
#include "common/swap.h" #include "common/swap.h"
#include "core/hle/ipc.h" #include "core/hle/ipc.h"
#include "core/hle/kernel/k_auto_object.h" #include "core/hle/kernel/object.h"
#include "core/hle/kernel/svc_common.h"
union ResultCode; union ResultCode;
@ -36,14 +35,13 @@ class ServiceFrameworkBase;
namespace Kernel { namespace Kernel {
class Domain; class Domain;
class HandleTable;
class HLERequestContext; class HLERequestContext;
class KernelCore; class KernelCore;
class KHandleTable; class Process;
class KProcess; class ServerSession;
class KServerSession;
class KThread; class KThread;
class KReadableEvent; class KReadableEvent;
class KSession;
class KWritableEvent; class KWritableEvent;
enum class ThreadWakeupReason; enum class ThreadWakeupReason;
@ -73,14 +71,20 @@ public:
* associated ServerSession alive for the duration of the connection. * associated ServerSession alive for the duration of the connection.
* @param server_session Owning pointer to the ServerSession associated with the connection. * @param server_session Owning pointer to the ServerSession associated with the connection.
*/ */
void ClientConnected(KServerSession* session); void ClientConnected(std::shared_ptr<ServerSession> server_session);
/** /**
* Signals that a client has just disconnected from this HLE handler and releases the * Signals that a client has just disconnected from this HLE handler and releases the
* associated ServerSession. * associated ServerSession.
* @param server_session ServerSession associated with the connection. * @param server_session ServerSession associated with the connection.
*/ */
void ClientDisconnected(KServerSession* session); void ClientDisconnected(const std::shared_ptr<ServerSession>& 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<std::shared_ptr<ServerSession>> connected_sessions;
}; };
/** /**
@ -105,7 +109,8 @@ public:
class HLERequestContext { class HLERequestContext {
public: public:
explicit HLERequestContext(KernelCore& kernel, Core::Memory::Memory& memory, explicit HLERequestContext(KernelCore& kernel, Core::Memory::Memory& memory,
KServerSession* session, KThread* thread); std::shared_ptr<ServerSession> session,
std::shared_ptr<KThread> thread);
~HLERequestContext(); ~HLERequestContext();
/// Returns a pointer to the IPC command buffer for this request. /// 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 * Returns the session through which this request was made. This can be used as a map key to
* access per-client data on services. * access per-client data on services.
*/ */
Kernel::KServerSession* Session() { const std::shared_ptr<Kernel::ServerSession>& Session() const {
return server_session; return server_session;
} }
/// Populates this context with data from the requesting process/thread. /// 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); u32_le* src_cmdbuf);
/// Writes data from this context back to the requesting process/thread. /// Writes data from this context back to the requesting process/thread.
@ -213,12 +218,22 @@ public:
return move_handles.at(index); return move_handles.at(index);
} }
void AddMoveObject(KAutoObject* object) { template <typename T>
move_objects.emplace_back(object); std::shared_ptr<T> GetCopyObject(std::size_t index) {
return DynamicObjectCast<T>(copy_objects.at(index));
} }
void AddCopyObject(KAutoObject* object) { template <typename T>
copy_objects.emplace_back(object); std::shared_ptr<T> GetMoveObject(std::size_t index) {
return DynamicObjectCast<T>(move_objects.at(index));
}
void AddMoveObject(std::shared_ptr<Object> object) {
move_objects.emplace_back(std::move(object));
}
void AddCopyObject(std::shared_ptr<Object> object) {
copy_objects.emplace_back(std::move(object));
} }
void AddDomainObject(std::shared_ptr<SessionRequestHandler> object) { void AddDomainObject(std::shared_ptr<SessionRequestHandler> object) {
@ -261,6 +276,10 @@ public:
return *thread; return *thread;
} }
const KThread& GetThread() const {
return *thread;
}
bool IsThreadWaiting() const { bool IsThreadWaiting() const {
return is_thread_waiting; return is_thread_waiting;
} }
@ -268,17 +287,16 @@ public:
private: private:
friend class IPC::ResponseBuilder; 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<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
Kernel::KServerSession* server_session{}; std::shared_ptr<Kernel::ServerSession> server_session;
KThread* thread; std::shared_ptr<KThread> thread;
// TODO(yuriks): Check common usage of this and optimize size accordingly // TODO(yuriks): Check common usage of this and optimize size accordingly
boost::container::small_vector<Handle, 8> move_handles; boost::container::small_vector<Handle, 8> move_handles;
boost::container::small_vector<Handle, 8> copy_handles; boost::container::small_vector<Handle, 8> copy_handles;
boost::container::small_vector<KAutoObject*, 8> move_objects; boost::container::small_vector<std::shared_ptr<Object>, 8> move_objects;
boost::container::small_vector<KAutoObject*, 8> copy_objects; boost::container::small_vector<std::shared_ptr<Object>, 8> copy_objects;
boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects; boost::container::small_vector<std::shared_ptr<SessionRequestHandler>, 8> domain_objects;
std::optional<IPC::CommandHeader> command_header; std::optional<IPC::CommandHeader> command_header;

View file

@ -7,13 +7,12 @@
#include "core/arm/exclusive_monitor.h" #include "core/arm/exclusive_monitor.h"
#include "core/core.h" #include "core/core.h"
#include "core/hle/kernel/k_condition_variable.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_scheduler.h"
#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.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_synchronization_object.h"
#include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.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_common.h"
#include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/svc_results.h"
#include "core/memory.h" #include "core/memory.h"
@ -108,8 +107,8 @@ ResultCode KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 val
// Wait for the address. // Wait for the address.
{ {
KScopedAutoObject<KThread> owner_thread; std::shared_ptr<KThread> owner_thread;
ASSERT(owner_thread.IsNull()); ASSERT(!owner_thread);
{ {
KScopedSchedulerLock sl(kernel); KScopedSchedulerLock sl(kernel);
cur_thread->SetSyncedObject(nullptr, RESULT_SUCCESS); 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); R_UNLESS(test_tag == (handle | Svc::HandleWaitMask), RESULT_SUCCESS);
// Get the lock owner thread. // Get the lock owner thread.
owner_thread = owner_thread = kernel.CurrentProcess()->GetHandleTable().Get<KThread>(handle);
kernel.CurrentProcess()->GetHandleTable().GetObjectWithoutPseudoHandle<KThread>( R_UNLESS(owner_thread, ResultInvalidHandle);
handle);
R_UNLESS(owner_thread.IsNotNull(), ResultInvalidHandle);
// Update the lock. // Update the lock.
cur_thread->SetAddressKey(addr, value); cur_thread->SetAddressKey(addr, value);
@ -140,7 +137,7 @@ ResultCode KConditionVariable::WaitForAddress(Handle handle, VAddr addr, u32 val
cur_thread->SetMutexWaitAddressForDebugging(addr); cur_thread->SetMutexWaitAddressForDebugging(addr);
} }
} }
ASSERT(owner_thread.IsNotNull()); ASSERT(owner_thread);
} }
// Remove the thread as a waiter from the lock owner. // Remove the thread as a waiter from the lock owner.
@ -179,22 +176,19 @@ KThread* KConditionVariable::SignalImpl(KThread* thread) {
KThread* thread_to_close = nullptr; KThread* thread_to_close = nullptr;
if (can_access) { if (can_access) {
if (prev_tag == Svc::InvalidHandle) { if (prev_tag == InvalidHandle) {
// If nobody held the lock previously, we're all good. // If nobody held the lock previously, we're all good.
thread->SetSyncedObject(nullptr, RESULT_SUCCESS); thread->SetSyncedObject(nullptr, RESULT_SUCCESS);
thread->Wakeup(); thread->Wakeup();
} else { } else {
// Get the previous owner. // Get the previous owner.
KThread* owner_thread = kernel.CurrentProcess() auto owner_thread = kernel.CurrentProcess()->GetHandleTable().Get<KThread>(
->GetHandleTable() prev_tag & ~Svc::HandleWaitMask);
.GetObjectWithoutPseudoHandle<KThread>(
static_cast<Handle>(prev_tag & ~Svc::HandleWaitMask))
.ReleasePointerUnsafe();
if (owner_thread) { if (owner_thread) {
// Add the thread as a waiter on the owner. // Add the thread as a waiter on the owner.
owner_thread->AddWaiter(thread); owner_thread->AddWaiter(thread);
thread_to_close = owner_thread; thread_to_close = owner_thread.get();
} else { } else {
// The lock was tagged with a thread that doesn't exist. // The lock was tagged with a thread that doesn't exist.
thread->SetSyncedObject(nullptr, ResultInvalidState); thread->SetSyncedObject(nullptr, ResultInvalidState);
@ -214,7 +208,9 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) {
// Prepare for signaling. // Prepare for signaling.
constexpr int MaxThreads = 16; constexpr int MaxThreads = 16;
KLinkedList<KThread> thread_list{kernel}; // TODO(bunnei): This should just be Thread once we implement KAutoObject instead of using
// std::shared_ptr.
std::vector<std::shared_ptr<KThread>> thread_list;
std::array<KThread*, MaxThreads> thread_array; std::array<KThread*, MaxThreads> thread_array;
s32 num_to_close{}; s32 num_to_close{};
@ -232,7 +228,7 @@ void KConditionVariable::Signal(u64 cv_key, s32 count) {
if (num_to_close < MaxThreads) { if (num_to_close < MaxThreads) {
thread_array[num_to_close++] = thread; thread_array[num_to_close++] = thread;
} else { } 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. // Close threads in the list.
for (auto it = thread_list.begin(); it != thread_list.end(); for (auto it = thread_list.begin(); it != thread_list.end(); it = thread_list.erase(it)) {
it = thread_list.erase(kernel, it)) { (*it)->Close();
(*it).Close();
} }
} }

View file

@ -3,53 +3,30 @@
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "core/hle/kernel/k_event.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_resource_limit.h" #include "core/hle/kernel/k_writable_event.h"
namespace Kernel { namespace Kernel {
KEvent::KEvent(KernelCore& kernel) KEvent::KEvent(KernelCore& kernel, std::string&& name) : Object{kernel, std::move(name)} {}
: KAutoObjectWithSlabHeapAndContainer{kernel}, readable_event{kernel}, writable_event{kernel} {}
KEvent::~KEvent() = default; KEvent::~KEvent() = default;
void KEvent::Initialize(std::string&& name_) { std::shared_ptr<KEvent> KEvent::Create(KernelCore& kernel, std::string&& name) {
// Increment reference count. return std::make_shared<KEvent>(kernel, std::move(name));
// 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();
void KEvent::Initialize() {
// Create our sub events. // Create our sub events.
KAutoObject::Create(std::addressof(readable_event)); readable_event = std::make_shared<KReadableEvent>(kernel, GetName() + ":Readable");
KAutoObject::Create(std::addressof(writable_event)); writable_event = std::make_shared<KWritableEvent>(kernel, GetName() + ":Writable");
// Initialize our sub sessions. // Initialize our sub sessions.
readable_event.Initialize(this, name_ + ":Readable"); readable_event->Initialize(this);
writable_event.Initialize(this, name_ + ":Writable"); writable_event->Initialize(this);
// Set our owner process.
owner = kernel.CurrentProcess();
if (owner) {
owner->Open();
}
// Mark initialized. // Mark initialized.
name = std::move(name_);
initialized = true; initialized = true;
} }
void KEvent::Finalize() {
KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObjectWithList>::Finalize();
}
void KEvent::PostDestroy(uintptr_t arg) {
// Release the event count resource the owner process holds.
KProcess* owner = reinterpret_cast<KProcess*>(arg);
if (owner) {
owner->GetResourceLimit()->Release(LimitableResource::Events, 1);
owner->Close();
}
}
} // namespace Kernel } // namespace Kernel

View file

@ -4,54 +4,53 @@
#pragma once #pragma once
#include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/object.h"
#include "core/hle/kernel/k_writable_event.h"
#include "core/hle/kernel/slab_helpers.h"
namespace Kernel { namespace Kernel {
class KernelCore; class KernelCore;
class KReadableEvent; class KReadableEvent;
class KWritableEvent; class KWritableEvent;
class KProcess;
class KEvent final : public KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObjectWithList> {
KERNEL_AUTOOBJECT_TRAITS(KEvent, KAutoObject);
class KEvent final : public Object {
public: public:
explicit KEvent(KernelCore& kernel); explicit KEvent(KernelCore& kernel, std::string&& name);
virtual ~KEvent(); ~KEvent() override;
void Initialize(std::string&& name); static std::shared_ptr<KEvent> Create(KernelCore& kernel, std::string&& name);
virtual void Finalize() override; void Initialize();
virtual bool IsInitialized() const override { void Finalize() override {}
return initialized;
std::string GetTypeName() const override {
return "KEvent";
} }
virtual uintptr_t GetPostDestroyArgument() const override { static constexpr HandleType HANDLE_TYPE = HandleType::Event;
return reinterpret_cast<uintptr_t>(owner); HandleType GetHandleType() const override {
return HANDLE_TYPE;
} }
static void PostDestroy(uintptr_t arg); std::shared_ptr<KReadableEvent>& GetReadableEvent() {
virtual KProcess* GetOwner() const override {
return owner;
}
KReadableEvent& GetReadableEvent() {
return readable_event; return readable_event;
} }
KWritableEvent& GetWritableEvent() { std::shared_ptr<KWritableEvent>& GetWritableEvent() {
return writable_event;
}
const std::shared_ptr<KReadableEvent>& GetReadableEvent() const {
return readable_event;
}
const std::shared_ptr<KWritableEvent>& GetWritableEvent() const {
return writable_event; return writable_event;
} }
private: private:
KReadableEvent readable_event; std::shared_ptr<KReadableEvent> readable_event;
KWritableEvent writable_event; std::shared_ptr<KWritableEvent> writable_event;
KProcess* owner{};
bool initialized{}; bool initialized{};
}; };

View file

@ -134,10 +134,6 @@ enum class KMemoryPermission : u8 {
}; };
DECLARE_ENUM_FLAG_OPERATORS(KMemoryPermission); DECLARE_ENUM_FLAG_OPERATORS(KMemoryPermission);
constexpr KMemoryPermission ConvertToKMemoryPermission(Svc::MemoryPermission perm) {
return static_cast<KMemoryPermission>(perm);
}
enum class KMemoryAttribute : u8 { enum class KMemoryAttribute : u8 {
None = 0x00, None = 0x00,
Mask = 0x7F, Mask = 0x7F,

View file

@ -11,11 +11,11 @@
#include "core/hle/kernel/k_memory_block_manager.h" #include "core/hle/kernel/k_memory_block_manager.h"
#include "core/hle/kernel/k_page_linked_list.h" #include "core/hle/kernel/k_page_linked_list.h"
#include "core/hle/kernel/k_page_table.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_resource_limit.h"
#include "core/hle/kernel/k_scoped_resource_reservation.h" #include "core/hle/kernel/k_scoped_resource_reservation.h"
#include "core/hle/kernel/k_system_control.h" #include "core/hle/kernel/k_system_control.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/svc_results.h"
#include "core/memory.h" #include "core/memory.h"
@ -420,7 +420,7 @@ ResultCode KPageTable::MapPhysicalMemory(VAddr addr, std::size_t size) {
remaining_size); remaining_size);
if (!memory_reservation.Succeeded()) { if (!memory_reservation.Succeeded()) {
LOG_ERROR(Kernel, "Could not reserve remaining {:X} bytes", remaining_size); LOG_ERROR(Kernel, "Could not reserve remaining {:X} bytes", remaining_size);
return ResultLimitReached; return ResultResourceLimitedExceeded;
} }
KPageLinkedList page_linked_list; 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); AddRegionToPages(dst_addr, num_pages, dst_pages);
if (!dst_pages.IsEqual(src_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; 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, ResultCode KPageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size,
KMemoryPermission perm) { KMemoryPermission perm) {
@ -829,7 +790,7 @@ ResultVal<VAddr> KPageTable::SetHeapSize(std::size_t size) {
if (!memory_reservation.Succeeded()) { if (!memory_reservation.Succeeded()) {
LOG_ERROR(Kernel, "Could not reserve heap extension of size {:X} bytes", delta); LOG_ERROR(Kernel, "Could not reserve heap extension of size {:X} bytes", delta);
return ResultLimitReached; return ResultResourceLimitedExceeded;
} }
KPageLinkedList page_linked_list; 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 end{addr + size};
const VAddr last{end - 1}; const VAddr last{end - 1};
const VAddr region_start{GetRegionAddress(state)}; const VAddr region_start{GetRegionAddress(state)};

View file

@ -40,7 +40,6 @@ public:
ResultCode Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size); ResultCode Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size);
ResultCode MapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state, ResultCode MapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state,
KMemoryPermission perm); KMemoryPermission perm);
ResultCode UnmapPages(VAddr addr, KPageLinkedList& page_linked_list, KMemoryState state);
ResultCode SetCodeMemoryPermission(VAddr addr, std::size_t size, KMemoryPermission perm); ResultCode SetCodeMemoryPermission(VAddr addr, std::size_t size, KMemoryPermission perm);
KMemoryInfo QueryInfo(VAddr addr); KMemoryInfo QueryInfo(VAddr addr);
ResultCode ReserveTransferMemory(VAddr addr, std::size_t size, KMemoryPermission perm); ResultCode ReserveTransferMemory(VAddr addr, std::size_t size, KMemoryPermission perm);
@ -64,8 +63,6 @@ public:
return page_table_impl; return page_table_impl;
} }
bool CanContain(VAddr addr, std::size_t size, KMemoryState state) const;
private: private:
enum class OperationType : u32 { enum class OperationType : u32 {
Map, Map,
@ -82,7 +79,6 @@ private:
ResultCode InitializeMemoryLayout(VAddr start, VAddr end); ResultCode InitializeMemoryLayout(VAddr start, VAddr end);
ResultCode MapPages(VAddr addr, const KPageLinkedList& page_linked_list, ResultCode MapPages(VAddr addr, const KPageLinkedList& page_linked_list,
KMemoryPermission perm); KMemoryPermission perm);
ResultCode UnmapPages(VAddr addr, const KPageLinkedList& page_linked_list);
void MapPhysicalMemory(KPageLinkedList& page_linked_list, VAddr start, VAddr end); void MapPhysicalMemory(KPageLinkedList& page_linked_list, VAddr start, VAddr end);
bool IsRegionMapped(VAddr address, u64 size); bool IsRegionMapped(VAddr address, u64 size);
bool IsRegionContiguous(VAddr addr, u64 size) const; bool IsRegionContiguous(VAddr addr, u64 size) const;
@ -96,6 +92,7 @@ private:
OperationType operation, PAddr map_addr = 0); OperationType operation, PAddr map_addr = 0);
constexpr VAddr GetRegionAddress(KMemoryState state) const; constexpr VAddr GetRegionAddress(KMemoryState state) const;
constexpr std::size_t GetRegionSize(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, constexpr ResultCode CheckMemoryState(const KMemoryInfo& info, KMemoryState state_mask,
KMemoryState state, KMemoryPermission perm_mask, KMemoryState state, KMemoryPermission perm_mask,
@ -219,6 +216,8 @@ public:
constexpr PAddr GetPhysicalAddr(VAddr addr) { constexpr PAddr GetPhysicalAddr(VAddr addr) {
return page_table_impl.backing_addr[addr >> PageBits] + addr; return page_table_impl.backing_addr[addr >> PageBits] + addr;
} }
private:
constexpr bool Contains(VAddr addr) const { constexpr bool Contains(VAddr addr) const {
return address_space_start <= addr && addr <= address_space_end - 1; return address_space_start <= addr && addr <= address_space_end - 1;
} }
@ -226,8 +225,6 @@ public:
return address_space_start <= addr && addr < addr + size && return address_space_start <= addr && addr < addr + size &&
addr + size - 1 <= address_space_end - 1; addr + size - 1 <= address_space_end - 1;
} }
private:
constexpr bool IsKernel() const { constexpr bool IsKernel() const {
return is_kernel; return is_kernel;
} }

View file

@ -2,18 +2,21 @@
// Licensed under GPLv2 or any later version // Licensed under GPLv2 or any later version
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include <algorithm>
#include "common/assert.h" #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_readable_event.h"
#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/object.h"
#include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/svc_results.h"
namespace Kernel { namespace Kernel {
KReadableEvent::KReadableEvent(KernelCore& kernel) : KSynchronizationObject{kernel} {} KReadableEvent::KReadableEvent(KernelCore& kernel, std::string&& name)
: KSynchronizationObject{kernel, std::move(name)} {}
KReadableEvent::~KReadableEvent() = default; KReadableEvent::~KReadableEvent() = default;
bool KReadableEvent::IsSignaled() const { bool KReadableEvent::IsSignaled() const {
@ -22,12 +25,6 @@ bool KReadableEvent::IsSignaled() const {
return is_signaled; return is_signaled;
} }
void KReadableEvent::Destroy() {
if (parent) {
parent->Close();
}
}
ResultCode KReadableEvent::Signal() { ResultCode KReadableEvent::Signal() {
KScopedSchedulerLock lk{kernel}; KScopedSchedulerLock lk{kernel};

View file

@ -4,9 +4,8 @@
#pragma once #pragma once
#include "core/hle/kernel/k_auto_object.h"
#include "core/hle/kernel/k_synchronization_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" #include "core/hle/result.h"
namespace Kernel { namespace Kernel {
@ -14,25 +13,31 @@ namespace Kernel {
class KernelCore; class KernelCore;
class KEvent; class KEvent;
class KReadableEvent : public KSynchronizationObject { class KReadableEvent final : public KSynchronizationObject {
KERNEL_AUTOOBJECT_TRAITS(KReadableEvent, KSynchronizationObject);
public: public:
explicit KReadableEvent(KernelCore& kernel); explicit KReadableEvent(KernelCore& kernel, std::string&& name);
~KReadableEvent() override; ~KReadableEvent() override;
void Initialize(KEvent* parent_, std::string&& name_) { std::string GetTypeName() const override {
is_signaled = false; return "KReadableEvent";
parent = parent_; }
name = std::move(name_);
static constexpr HandleType HANDLE_TYPE = HandleType::ReadableEvent;
HandleType GetHandleType() const override {
return HANDLE_TYPE;
} }
KEvent* GetParent() const { KEvent* GetParent() const {
return parent; return parent;
} }
virtual bool IsSignaled() const override; void Initialize(KEvent* parent_) {
virtual void Destroy() override; is_signaled = false;
parent = parent_;
}
bool IsSignaled() const override;
void Finalize() override {}
ResultCode Signal(); ResultCode Signal();
ResultCode Clear(); ResultCode Clear();

View file

@ -10,16 +10,10 @@
namespace Kernel { namespace Kernel {
constexpr s64 DefaultTimeout = 10000000000; // 10 seconds constexpr s64 DefaultTimeout = 10000000000; // 10 seconds
KResourceLimit::KResourceLimit(KernelCore& kernel) KResourceLimit::KResourceLimit(KernelCore& kernel, const Core::Timing::CoreTiming& core_timing_)
: KAutoObjectWithSlabHeapAndContainer{kernel}, lock{kernel}, cond_var{kernel} {} : Object{kernel}, lock{kernel}, cond_var{kernel}, core_timing(core_timing_) {}
KResourceLimit::~KResourceLimit() = default; 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 { s64 KResourceLimit::GetLimitValue(LimitableResource which) const {
const auto index = static_cast<std::size_t>(which); const auto index = static_cast<std::size_t>(which);
s64 value{}; s64 value{};
@ -84,7 +78,7 @@ ResultCode KResourceLimit::SetLimitValue(LimitableResource which, s64 value) {
} }
bool KResourceLimit::Reserve(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) { 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] && if (current_hints[index] + value <= limit_values[index] &&
(timeout < 0 || core_timing->GetGlobalTimeNs().count() < timeout)) { (timeout < 0 || core_timing.GetGlobalTimeNs().count() < timeout)) {
waiter_count++; waiter_count++;
cond_var.Wait(&lock, timeout); cond_var.Wait(&lock, timeout);
waiter_count--; waiter_count--;

View file

@ -8,6 +8,7 @@
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/kernel/k_light_condition_variable.h" #include "core/hle/kernel/k_light_condition_variable.h"
#include "core/hle/kernel/k_light_lock.h" #include "core/hle/kernel/k_light_lock.h"
#include "core/hle/kernel/object.h"
union ResultCode; union ResultCode;
@ -31,16 +32,10 @@ constexpr bool IsValidResourceType(LimitableResource type) {
return type < LimitableResource::Count; return type < LimitableResource::Count;
} }
class KResourceLimit final class KResourceLimit final : public Object {
: public KAutoObjectWithSlabHeapAndContainer<KResourceLimit, KAutoObjectWithList> {
KERNEL_AUTOOBJECT_TRAITS(KResourceLimit, KAutoObject);
public: public:
explicit KResourceLimit(KernelCore& kernel); explicit KResourceLimit(KernelCore& kernel, const Core::Timing::CoreTiming& core_timing_);
virtual ~KResourceLimit(); ~KResourceLimit();
void Initialize(const Core::Timing::CoreTiming* core_timing_);
virtual void Finalize() override;
s64 GetLimitValue(LimitableResource which) const; s64 GetLimitValue(LimitableResource which) const;
s64 GetCurrentValue(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);
void Release(LimitableResource which, s64 value, s64 hint); 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: private:
using ResourceArray = std::array<s64, static_cast<std::size_t>(LimitableResource::Count)>; using ResourceArray = std::array<s64, static_cast<std::size_t>(LimitableResource::Count)>;
@ -65,6 +72,6 @@ private:
mutable KLightLock lock; mutable KLightLock lock;
s32 waiter_count{}; s32 waiter_count{};
KLightConditionVariable cond_var; KLightConditionVariable cond_var;
const Core::Timing::CoreTiming* core_timing{}; const Core::Timing::CoreTiming& core_timing;
}; };
} // namespace Kernel } // namespace Kernel

View file

@ -15,12 +15,12 @@
#include "core/core.h" #include "core/core.h"
#include "core/core_timing.h" #include "core/core_timing.h"
#include "core/cpu_manager.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_scheduler.h"
#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.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.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/physical_core.h" #include "core/hle/kernel/physical_core.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/time_manager.h" #include "core/hle/kernel/time_manager.h"
namespace Kernel { namespace Kernel {
@ -71,7 +71,7 @@ u64 KScheduler::UpdateHighestPriorityThread(KThread* highest_thread) {
} }
if (state.should_count_idle) { if (state.should_count_idle) {
if (highest_thread != nullptr) { 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); process->SetRunningThread(core_id, highest_thread, state.idle_count);
} }
} else { } else {
@ -104,7 +104,7 @@ u64 KScheduler::UpdateHighestPriorityThreadsImpl(KernelCore& kernel) {
if (top_thread != nullptr) { if (top_thread != nullptr) {
// If the thread has no waiters, we need to check if the process has a thread pinned. // If the thread has no waiters, we need to check if the process has a thread pinned.
if (top_thread->GetNumKernelWaiters() == 0) { 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<s32>(core_id)); if (KThread* pinned = parent->GetPinnedThread(static_cast<s32>(core_id));
pinned != nullptr && pinned != top_thread) { pinned != nullptr && pinned != top_thread) {
// We prefer our parent's pinned thread if possible. However, we also don't // 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. // Get the current thread and process.
KThread& cur_thread = Kernel::GetCurrentThread(kernel); 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 the thread's yield count matches, there's nothing for us to do.
if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) { if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) {
@ -450,7 +450,7 @@ void KScheduler::YieldWithCoreMigration(KernelCore& kernel) {
// Get the current thread and process. // Get the current thread and process.
KThread& cur_thread = Kernel::GetCurrentThread(kernel); 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 the thread's yield count matches, there's nothing for us to do.
if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) { if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) {
@ -538,7 +538,7 @@ void KScheduler::YieldToAnyThread(KernelCore& kernel) {
// Get the current thread and process. // Get the current thread and process.
KThread& cur_thread = Kernel::GetCurrentThread(kernel); 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 the thread's yield count matches, there's nothing for us to do.
if (cur_thread.GetYieldScheduleCount() == cur_process.GetScheduledCount()) { 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; state.highest_priority_thread = nullptr;
} }
KScheduler::~KScheduler() { KScheduler::~KScheduler() = default;
if (idle_thread) {
idle_thread->Close();
idle_thread = nullptr;
}
}
KThread* KScheduler::GetCurrentThread() const { KThread* KScheduler::GetCurrentThread() const {
if (auto result = current_thread.load(); result) { if (auto result = current_thread.load(); result) {
@ -724,7 +719,7 @@ void KScheduler::ScheduleImpl() {
current_thread.store(next_thread); current_thread.store(next_thread);
KProcess* const previous_process = system.Kernel().CurrentProcess(); Process* const previous_process = system.Kernel().CurrentProcess();
UpdateLastContextSwitchTime(previous_thread, previous_process); 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 prev_switch_ticks = last_context_switch_time;
const u64 most_recent_switch_ticks = system.CoreTiming().GetCPUTicks(); const u64 most_recent_switch_ticks = system.CoreTiming().GetCPUTicks();
const u64 update_ticks = most_recent_switch_ticks - prev_switch_ticks; 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() { void KScheduler::Initialize() {
idle_thread = KThread::Create(system.Kernel()); std::string name = "Idle Thread Id:" + std::to_string(core_id);
ASSERT(KThread::InitializeIdleThread(system, idle_thread, core_id).IsSuccess()); std::function<void(void*)> init_func = Core::CpuManager::GetIdleThreadStartFunc();
idle_thread->SetName(fmt::format("IdleThread:{}", core_id)); void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater();
auto thread_res = KThread::CreateThread(
system, ThreadType::Main, name, 0, KThread::IdleThreadPriority, 0,
static_cast<u32>(core_id), 0, nullptr, std::move(init_func), init_func_parameter);
idle_thread = thread_res.Unwrap().get();
} }
KScopedSchedulerLock::KScopedSchedulerLock(KernelCore& kernel) KScopedSchedulerLock::KScopedSchedulerLock(KernelCore& kernel)

View file

@ -24,7 +24,7 @@ class System;
namespace Kernel { namespace Kernel {
class KernelCore; class KernelCore;
class KProcess; class Process;
class SchedulerLock; class SchedulerLock;
class KThread; class KThread;
@ -165,7 +165,7 @@ private:
* most recent tick count retrieved. No special arithmetic is * most recent tick count retrieved. No special arithmetic is
* applied to it. * applied to it.
*/ */
void UpdateLastContextSwitchTime(KThread* thread, KProcess* process); void UpdateLastContextSwitchTime(KThread* thread, Process* process);
static void OnSwitch(void* this_scheduler); static void OnSwitch(void* this_scheduler);
void SwitchToCurrent(); void SwitchToCurrent();
@ -173,12 +173,12 @@ private:
KThread* prev_thread{}; KThread* prev_thread{};
std::atomic<KThread*> current_thread{}; std::atomic<KThread*> current_thread{};
KThread* idle_thread{}; KThread* idle_thread;
std::shared_ptr<Common::Fiber> switch_fiber{}; std::shared_ptr<Common::Fiber> switch_fiber{};
struct SchedulingState { struct SchedulingState {
std::atomic<bool> needs_scheduling{}; std::atomic<bool> needs_scheduling;
bool interrupt_task_thread_runnable{}; bool interrupt_task_thread_runnable{};
bool should_count_idle{}; bool should_count_idle{};
u64 idle_count{}; u64 idle_count{};

View file

@ -8,14 +8,15 @@
#pragma once #pragma once
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_resource_limit.h"
#include "core/hle/kernel/process.h"
namespace Kernel { namespace Kernel {
class KScopedResourceReservation { class KScopedResourceReservation {
public: public:
explicit KScopedResourceReservation(KResourceLimit* l, LimitableResource r, s64 v, s64 timeout) explicit KScopedResourceReservation(std::shared_ptr<KResourceLimit> l, LimitableResource r,
s64 v, s64 timeout)
: resource_limit(std::move(l)), value(v), resource(r) { : resource_limit(std::move(l)), value(v), resource(r) {
if (resource_limit && value) { if (resource_limit && value) {
success = resource_limit->Reserve(resource, value, timeout); 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<KResourceLimit> l, LimitableResource r,
s64 v = 1)
: resource_limit(std::move(l)), value(v), resource(r) { : resource_limit(std::move(l)), value(v), resource(r) {
if (resource_limit && value) { if (resource_limit && value) {
success = resource_limit->Reserve(resource, 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) {} : 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(p->GetResourceLimit(), r, v) {}
~KScopedResourceReservation() noexcept { ~KScopedResourceReservation() noexcept {
@ -56,7 +58,7 @@ public:
} }
private: private:
KResourceLimit* resource_limit{}; std::shared_ptr<KResourceLimit> resource_limit;
s64 value; s64 value;
LimitableResource resource; LimitableResource resource;
bool success; bool success;

View file

@ -8,7 +8,7 @@
#pragma once #pragma once
#include "common/common_types.h" #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/k_thread.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/time_manager.h" #include "core/hle/kernel/time_manager.h"

View file

@ -8,74 +8,50 @@
#include "core/hle/kernel/k_scoped_resource_reservation.h" #include "core/hle/kernel/k_scoped_resource_reservation.h"
#include "core/hle/kernel/k_shared_memory.h" #include "core/hle/kernel/k_shared_memory.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/svc_results.h"
namespace Kernel { namespace Kernel {
KSharedMemory::KSharedMemory(KernelCore& kernel) : KAutoObjectWithSlabHeapAndContainer{kernel} {} KSharedMemory::KSharedMemory(KernelCore& kernel, Core::DeviceMemory& device_memory)
: Object{kernel}, device_memory{device_memory} {}
KSharedMemory::~KSharedMemory() { KSharedMemory::~KSharedMemory() {
kernel.GetSystemResourceLimit()->Release(LimitableResource::PhysicalMemory, size); kernel.GetSystemResourceLimit()->Release(LimitableResource::PhysicalMemory, size);
} }
ResultCode KSharedMemory::Initialize(KernelCore& kernel_, Core::DeviceMemory& device_memory_, std::shared_ptr<KSharedMemory> KSharedMemory::Create(
KProcess* owner_process_, KPageLinkedList&& page_list_, KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process,
Svc::MemoryPermission owner_permission_, KPageLinkedList&& page_list, KMemoryPermission owner_permission,
Svc::MemoryPermission user_permission_, KMemoryPermission user_permission, PAddr physical_address, std::size_t size, std::string name) {
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_;
// Get the resource limit. const auto resource_limit = kernel.GetSystemResourceLimit();
KResourceLimit* reslimit = kernel.GetSystemResourceLimit(); KScopedResourceReservation memory_reservation(resource_limit, LimitableResource::PhysicalMemory,
size);
ASSERT(memory_reservation.Succeeded());
// Reserve memory for ourselves. std::shared_ptr<KSharedMemory> shared_memory{
KScopedResourceReservation memory_reservation(reslimit, LimitableResource::PhysicalMemory, std::make_shared<KSharedMemory>(kernel, device_memory)};
size_);
R_UNLESS(memory_reservation.Succeeded(), ResultLimitReached); 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(); memory_reservation.Commit();
return shared_memory;
// 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;
} }
void KSharedMemory::Finalize() { ResultCode KSharedMemory::Map(Process& target_process, VAddr address, std::size_t size,
// Release the memory reservation. KMemoryPermission permissions) {
resource_limit->Release(LimitableResource::PhysicalMemory, size);
resource_limit->Close();
// Perform inherited finalization.
KAutoObjectWithSlabHeapAndContainer<KSharedMemory, KAutoObjectWithList>::Finalize();
}
ResultCode KSharedMemory::Map(KProcess& target_process, VAddr address, std::size_t size,
Svc::MemoryPermission permissions) {
const u64 page_count{(size + PageSize - 1) / PageSize}; const u64 page_count{(size + PageSize - 1) / PageSize};
if (page_list.GetNumPages() != page_count) { if (page_list.GetNumPages() != page_count) {
UNIMPLEMENTED_MSG("Page count does not match"); UNIMPLEMENTED_MSG("Page count does not match");
} }
const Svc::MemoryPermission expected = const KMemoryPermission expected =
&target_process == owner_process ? owner_permission : user_permission; &target_process == owner_process ? owner_permission : user_permission;
if (permissions != expected) { 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, return target_process.PageTable().MapPages(address, page_list, KMemoryState::Shared,
ConvertToKMemoryPermission(permissions)); 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);
} }
} // namespace Kernel } // namespace Kernel

View file

@ -11,27 +11,37 @@
#include "core/device_memory.h" #include "core/device_memory.h"
#include "core/hle/kernel/k_memory_block.h" #include "core/hle/kernel/k_memory_block.h"
#include "core/hle/kernel/k_page_linked_list.h" #include "core/hle/kernel/k_page_linked_list.h"
#include "core/hle/kernel/k_process.h" #include "core/hle/kernel/object.h"
#include "core/hle/kernel/slab_helpers.h" #include "core/hle/kernel/process.h"
#include "core/hle/result.h" #include "core/hle/result.h"
namespace Kernel { namespace Kernel {
class KernelCore; class KernelCore;
class KSharedMemory final class KSharedMemory final : public Object {
: public KAutoObjectWithSlabHeapAndContainer<KSharedMemory, KAutoObjectWithList> {
KERNEL_AUTOOBJECT_TRAITS(KSharedMemory, KAutoObject);
public: public:
explicit KSharedMemory(KernelCore& kernel); explicit KSharedMemory(KernelCore& kernel, Core::DeviceMemory& device_memory);
~KSharedMemory() override; ~KSharedMemory() override;
ResultCode Initialize(KernelCore& kernel_, Core::DeviceMemory& device_memory_, static std::shared_ptr<KSharedMemory> Create(
KProcess* owner_process_, KPageLinkedList&& page_list_, KernelCore& kernel, Core::DeviceMemory& device_memory, Process* owner_process,
Svc::MemoryPermission owner_permission_, KPageLinkedList&& page_list, KMemoryPermission owner_permission,
Svc::MemoryPermission user_permission_, PAddr physical_address_, KMemoryPermission user_permission, PAddr physical_address, std::size_t size,
std::size_t size_, std::string name_); 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 * 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 size Size of the shared memory block to map
* @param permissions Memory block map permissions (specified by SVC field) * @param permissions Memory block map permissions (specified by SVC field)
*/ */
ResultCode Map(KProcess& target_process, VAddr address, std::size_t size, ResultCode Map(Process& target_process, VAddr address, std::size_t size,
Svc::MemoryPermission permissions); KMemoryPermission 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);
/** /**
* Gets a pointer to the shared memory block * 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 * @return A pointer to the shared memory block from the specified offset
*/ */
u8* GetPointer(std::size_t offset = 0) { 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 * @return A pointer to the shared memory block from the specified offset
*/ */
const u8* GetPointer(std::size_t offset = 0) const { 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; void Finalize() override {}
virtual bool IsInitialized() const override {
return is_initialized;
}
static void PostDestroy([[maybe_unused]] uintptr_t arg) {}
private: private:
Core::DeviceMemory* device_memory; Core::DeviceMemory& device_memory;
KProcess* owner_process{}; Process* owner_process{};
KPageLinkedList page_list; KPageLinkedList page_list;
Svc::MemoryPermission owner_permission{}; KMemoryPermission owner_permission{};
Svc::MemoryPermission user_permission{}; KMemoryPermission user_permission{};
PAddr physical_address{}; PAddr physical_address{};
std::size_t size{}; std::size_t size{};
KResourceLimit* resource_limit{}; std::string name;
bool is_initialized{};
}; };
} // namespace Kernel } // namespace Kernel

View file

@ -97,7 +97,6 @@ public:
void FreeImpl(void* obj) { void FreeImpl(void* obj) {
// Don't allow freeing an object that wasn't allocated from this heap // Don't allow freeing an object that wasn't allocated from this heap
ASSERT(Contains(reinterpret_cast<uintptr_t>(obj))); ASSERT(Contains(reinterpret_cast<uintptr_t>(obj)));
impl.Free(obj); impl.Free(obj);
} }
@ -149,14 +148,6 @@ public:
return obj; return obj;
} }
T* AllocateWithKernel(KernelCore& kernel) {
T* obj = static_cast<T*>(AllocateImpl());
if (obj != nullptr) {
new (obj) T(kernel);
}
return obj;
}
void Free(T* obj) { void Free(T* obj) {
FreeImpl(obj); FreeImpl(obj);
} }

View file

@ -13,11 +13,6 @@
namespace Kernel { namespace Kernel {
void KSynchronizationObject::Finalize() {
this->OnFinalizeSynchronizationObject();
KAutoObject::Finalize();
}
ResultCode KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index, ResultCode KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index,
KSynchronizationObject** objects, const s32 num_objects, KSynchronizationObject** objects, const s32 num_objects,
s64 timeout) { s64 timeout) {
@ -135,7 +130,10 @@ ResultCode KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index,
return wait_result; 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; KSynchronizationObject::~KSynchronizationObject() = default;

View file

@ -6,7 +6,7 @@
#include <vector> #include <vector>
#include "core/hle/kernel/k_auto_object.h" #include "core/hle/kernel/object.h"
#include "core/hle/result.h" #include "core/hle/result.h"
namespace Kernel { namespace Kernel {
@ -16,9 +16,7 @@ class Synchronization;
class KThread; class KThread;
/// Class that represents a Kernel object that a thread can be waiting on /// Class that represents a Kernel object that a thread can be waiting on
class KSynchronizationObject : public KAutoObjectWithList { class KSynchronizationObject : public Object {
KERNEL_AUTOOBJECT_TRAITS(KSynchronizationObject, KAutoObject);
public: public:
struct ThreadListNode { struct ThreadListNode {
ThreadListNode* next{}; ThreadListNode* next{};
@ -29,18 +27,15 @@ public:
KSynchronizationObject** objects, const s32 num_objects, KSynchronizationObject** objects, const s32 num_objects,
s64 timeout); s64 timeout);
virtual void Finalize() override;
[[nodiscard]] virtual bool IsSignaled() const = 0; [[nodiscard]] virtual bool IsSignaled() const = 0;
[[nodiscard]] std::vector<KThread*> GetWaitingThreadsForDebugging() const; [[nodiscard]] std::vector<KThread*> GetWaitingThreadsForDebugging() const;
protected: protected:
explicit KSynchronizationObject(KernelCore& kernel); explicit KSynchronizationObject(KernelCore& kernel);
explicit KSynchronizationObject(KernelCore& kernel, std::string&& name);
virtual ~KSynchronizationObject(); virtual ~KSynchronizationObject();
virtual void OnFinalizeSynchronizationObject() {}
void NotifyAvailable(ResultCode result); void NotifyAvailable(ResultCode result);
void NotifyAvailable() { void NotifyAvailable() {
return this->NotifyAvailable(RESULT_SUCCESS); return this->NotifyAvailable(RESULT_SUCCESS);
@ -51,4 +46,14 @@ private:
ThreadListNode* thread_list_tail{}; ThreadListNode* thread_list_tail{};
}; };
// Specialization of DynamicObjectCast for KSynchronizationObjects
template <>
inline std::shared_ptr<KSynchronizationObject> DynamicObjectCast<KSynchronizationObject>(
std::shared_ptr<Object> object) {
if (object != nullptr && object->IsWaitable()) {
return std::static_pointer_cast<KSynchronizationObject>(object);
}
return nullptr;
}
} // namespace Kernel } // namespace Kernel

View file

@ -18,16 +18,17 @@
#include "core/core.h" #include "core/core.h"
#include "core/cpu_manager.h" #include "core/cpu_manager.h"
#include "core/hardware_properties.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_condition_variable.h"
#include "core/hle/kernel/k_handle_table.h"
#include "core/hle/kernel/k_memory_layout.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_resource_limit.h"
#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.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.h"
#include "core/hle/kernel/k_thread_queue.h" #include "core/hle/kernel/k_thread_queue.h"
#include "core/hle/kernel/kernel.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/svc_results.h"
#include "core/hle/kernel/time_manager.h" #include "core/hle/kernel/time_manager.h"
#include "core/hle/result.h" #include "core/hle/result.h"
@ -61,11 +62,11 @@ static void ResetThreadContext64(Core::ARM_Interface::ThreadContext64& context,
namespace Kernel { namespace Kernel {
KThread::KThread(KernelCore& kernel) KThread::KThread(KernelCore& kernel)
: KAutoObjectWithSlabHeapAndContainer{kernel}, activity_pause_lock{kernel} {} : KSynchronizationObject{kernel}, activity_pause_lock{kernel} {}
KThread::~KThread() = default; KThread::~KThread() = default;
ResultCode KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, s32 prio, 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 parameters are valid.
ASSERT((type == ThreadType::Main) || ASSERT((type == ThreadType::Main) ||
(Svc::HighestThreadPriority <= prio && prio <= Svc::LowestThreadPriority)); (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. // Set parent, if relevant.
if (owner != nullptr) { if (owner != nullptr) {
parent = owner; parent = owner;
parent->Open();
parent->IncrementThreadCount(); 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, ResultCode KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg,
VAddr user_stack_top, s32 prio, s32 core, KProcess* owner, VAddr user_stack_top, s32 prio, s32 core, Process* owner,
ThreadType type, std::function<void(void*)>&& init_func, ThreadType type) {
void* init_func_parameter) {
// Initialize the thread. // Initialize the thread.
R_TRY(thread->Initialize(func, arg, user_stack_top, prio, core, owner, type)); R_TRY(thread->Initialize(func, arg, user_stack_top, prio, core, owner, type));
// Initialize host context.
thread->host_context =
std::make_shared<Common::Fiber>(std::move(init_func), init_func_parameter);
return RESULT_SUCCESS; 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<KProcess*>(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() { void KThread::Finalize() {
// If the thread has an owner process, unregister it. // If the thread has an owner process, unregister it.
if (parent != nullptr) { if (parent != nullptr) {
@ -288,10 +246,8 @@ void KThread::Finalize() {
// Decrement the parent process's thread count. // Decrement the parent process's thread count.
if (parent != nullptr) { if (parent != nullptr) {
parent->DecrementThreadCount(); parent->DecrementThreadCount();
parent->GetResourceLimit()->Release(LimitableResource::Threads, 1);
} }
// Perform inherited finalization.
KAutoObjectWithSlabHeapAndContainer<KThread, KSynchronizationObject>::Finalize();
} }
bool KThread::IsSignaled() const { bool KThread::IsSignaled() const {
@ -338,9 +294,6 @@ void KThread::StartTermination() {
// Register terminated dpc flag. // Register terminated dpc flag.
RegisterDpc(DpcFlag::Terminated); RegisterDpc(DpcFlag::Terminated);
// Close the thread.
this->Close();
} }
void KThread::Pin() { void KThread::Pin() {
@ -979,7 +932,7 @@ void KThread::Exit() {
// Release the thread resource hint from parent. // Release the thread resource hint from parent.
if (parent != nullptr) { 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; resource_limit_release_hint = true;
} }
@ -1042,6 +995,56 @@ std::shared_ptr<Common::Fiber>& KThread::GetHostContext() {
return host_context; return host_context;
} }
ResultVal<std::shared_ptr<KThread>> 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<KThread> thread = std::make_shared<KThread>(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::shared_ptr<KThread>>(std::move(thread));
}
ResultVal<std::shared_ptr<KThread>> 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<void(void*)>&& 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<Common::Fiber>(std::move(thread_start_func), thread_start_parameter);
}
return thread_result;
}
ResultVal<std::shared_ptr<KThread>> 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<void(void*)> 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) { KThread* GetCurrentThreadPointer(KernelCore& kernel) {
return kernel.GetCurrentEmuThread(); return kernel.GetCurrentEmuThread();
} }

View file

@ -19,7 +19,7 @@
#include "core/hle/kernel/k_light_lock.h" #include "core/hle/kernel/k_light_lock.h"
#include "core/hle/kernel/k_spin_lock.h" #include "core/hle/kernel/k_spin_lock.h"
#include "core/hle/kernel/k_synchronization_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/kernel/svc_common.h" #include "core/hle/kernel/svc_common.h"
#include "core/hle/kernel/svc_types.h" #include "core/hle/kernel/svc_types.h"
#include "core/hle/result.h" #include "core/hle/result.h"
@ -37,7 +37,7 @@ namespace Kernel {
class GlobalSchedulerContext; class GlobalSchedulerContext;
class KernelCore; class KernelCore;
class KProcess; class Process;
class KScheduler; class KScheduler;
class KThreadQueue; class KThreadQueue;
@ -99,13 +99,9 @@ enum class ThreadWaitReasonForDebugging : u32 {
[[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel); [[nodiscard]] KThread& GetCurrentThread(KernelCore& kernel);
[[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel); [[nodiscard]] s32 GetCurrentCoreId(KernelCore& kernel);
class KThread final : public KAutoObjectWithSlabHeapAndContainer<KThread, KSynchronizationObject>, class KThread final : public KSynchronizationObject, public boost::intrusive::list_base_hook<> {
public boost::intrusive::list_base_hook<> {
KERNEL_AUTOOBJECT_TRAITS(KThread, KSynchronizationObject);
private:
friend class KScheduler; friend class KScheduler;
friend class KProcess; friend class Process;
public: public:
static constexpr s32 DefaultThreadPriority = 44; static constexpr s32 DefaultThreadPriority = 44;
@ -119,10 +115,74 @@ public:
using ThreadContext64 = Core::ARM_Interface::ThreadContext64; using ThreadContext64 = Core::ARM_Interface::ThreadContext64;
using WaiterList = boost::intrusive::list<KThread>; using WaiterList = boost::intrusive::list<KThread>;
/**
* 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<std::shared_ptr<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);
/**
* 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<std::shared_ptr<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<void(void*)>&& 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<std::shared_ptr<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);
[[nodiscard]] std::string GetName() const override {
return name;
}
void SetName(std::string new_name) { void SetName(std::string new_name) {
name = std::move(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 * Gets the thread's current priority
* @return The current thread's priority * @return The current thread's priority
@ -197,6 +257,10 @@ public:
void Suspend(); void Suspend();
void Finalize() override;
bool IsSignaled() const override;
void SetSyncedObject(KSynchronizationObject* obj, ResultCode wait_res) { void SetSyncedObject(KSynchronizationObject* obj, ResultCode wait_res) {
synced_object = obj; synced_object = obj;
wait_result = wait_res; wait_result = wait_res;
@ -290,11 +354,11 @@ public:
current_core_id = core; current_core_id = core;
} }
[[nodiscard]] KProcess* GetOwnerProcess() { [[nodiscard]] Process* GetOwnerProcess() {
return parent; return parent;
} }
[[nodiscard]] const KProcess* GetOwnerProcess() const { [[nodiscard]] const Process* GetOwnerProcess() const {
return parent; return parent;
} }
@ -358,40 +422,6 @@ public:
return termination_requested || GetRawState() == ThreadState::Terminated; 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<uintptr_t>(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 { struct StackParameters {
u8 svc_permission[0x10]; u8 svc_permission[0x10];
std::atomic<u8> dpc_flags; std::atomic<u8> dpc_flags;
@ -641,13 +671,11 @@ private:
void StartTermination(); void StartTermination();
[[nodiscard]] ResultCode Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack_top, [[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, [[nodiscard]] static ResultCode InitializeThread(KThread* thread, KThreadFunction func,
uintptr_t arg, VAddr user_stack_top, s32 prio, uintptr_t arg, VAddr user_stack_top, s32 prio,
s32 core, KProcess* owner, ThreadType type, s32 core, Process* owner, ThreadType type);
std::function<void(void*)>&& init_func,
void* init_func_parameter);
static void RestorePriority(KernelCore& kernel, KThread* thread); static void RestorePriority(KernelCore& kernel, KThread* thread);
@ -669,7 +697,7 @@ private:
std::atomic<s64> cpu_time{}; std::atomic<s64> cpu_time{};
KSynchronizationObject* synced_object{}; KSynchronizationObject* synced_object{};
VAddr address_key{}; VAddr address_key{};
KProcess* parent{}; Process* parent{};
VAddr kernel_stack_top{}; VAddr kernel_stack_top{};
u32* light_ipc_data{}; u32* light_ipc_data{};
VAddr tls_address{}; VAddr tls_address{};
@ -714,6 +742,7 @@ private:
VAddr mutex_wait_address_for_debugging{}; VAddr mutex_wait_address_for_debugging{};
ThreadWaitReasonForDebugging wait_reason_for_debugging{}; ThreadWaitReasonForDebugging wait_reason_for_debugging{};
ThreadType thread_type_for_debugging{}; ThreadType thread_type_for_debugging{};
std::string name;
public: public:
using ConditionVariableThreadTreeType = ConditionVariableThreadTree; using ConditionVariableThreadTreeType = ConditionVariableThreadTree;

View file

@ -8,28 +8,20 @@
namespace Kernel { namespace Kernel {
KWritableEvent::KWritableEvent(KernelCore& kernel) : KAutoObjectWithSlabHeapAndContainer{kernel} {} KWritableEvent::KWritableEvent(KernelCore& kernel, std::string&& name)
: Object{kernel, std::move(name)} {}
KWritableEvent::~KWritableEvent() = default; KWritableEvent::~KWritableEvent() = default;
void KWritableEvent::Initialize(KEvent* parent_, std::string&& name_) { void KWritableEvent::Initialize(KEvent* parent_) {
parent = parent_; parent = parent_;
name = std::move(name_);
parent->GetReadableEvent().Open();
} }
ResultCode KWritableEvent::Signal() { ResultCode KWritableEvent::Signal() {
return parent->GetReadableEvent().Signal(); return parent->GetReadableEvent()->Signal();
} }
ResultCode KWritableEvent::Clear() { ResultCode KWritableEvent::Clear() {
return parent->GetReadableEvent().Clear(); return parent->GetReadableEvent()->Clear();
}
void KWritableEvent::Destroy() {
// Close our references.
parent->GetReadableEvent().Close();
parent->Close();
} }
} // namespace Kernel } // namespace Kernel

View file

@ -4,8 +4,7 @@
#pragma once #pragma once
#include "core/hle/kernel/k_auto_object.h" #include "core/hle/kernel/object.h"
#include "core/hle/kernel/slab_helpers.h"
#include "core/hle/result.h" #include "core/hle/result.h"
namespace Kernel { namespace Kernel {
@ -13,19 +12,24 @@ namespace Kernel {
class KernelCore; class KernelCore;
class KEvent; class KEvent;
class KWritableEvent final class KWritableEvent final : public Object {
: public KAutoObjectWithSlabHeapAndContainer<KWritableEvent, KAutoObjectWithList> {
KERNEL_AUTOOBJECT_TRAITS(KWritableEvent, KAutoObject);
public: public:
explicit KWritableEvent(KernelCore& kernel); explicit KWritableEvent(KernelCore& kernel, std::string&& name);
~KWritableEvent() override; ~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 Signal();
ResultCode Clear(); ResultCode Clear();

View file

@ -26,12 +26,10 @@
#include "core/cpu_manager.h" #include "core/cpu_manager.h"
#include "core/device_memory.h" #include "core/device_memory.h"
#include "core/hardware_properties.h" #include "core/hardware_properties.h"
#include "core/hle/kernel/init/init_slab_setup.h" #include "core/hle/kernel/client_port.h"
#include "core/hle/kernel/k_client_port.h" #include "core/hle/kernel/handle_table.h"
#include "core/hle/kernel/k_handle_table.h"
#include "core/hle/kernel/k_memory_layout.h" #include "core/hle/kernel/k_memory_layout.h"
#include "core/hle/kernel/k_memory_manager.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_resource_limit.h"
#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_scheduler.h"
#include "core/hle/kernel/k_shared_memory.h" #include "core/hle/kernel/k_shared_memory.h"
@ -39,6 +37,7 @@
#include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/physical_core.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/service_thread.h"
#include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/svc_results.h"
#include "core/hle/kernel/time_manager.h" #include "core/hle/kernel/time_manager.h"
@ -52,7 +51,7 @@ namespace Kernel {
struct KernelCore::Impl { struct KernelCore::Impl {
explicit Impl(Core::System& system, KernelCore& kernel) 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) { void SetMulticore(bool is_multicore) {
this->is_multicore = is_multicore; this->is_multicore = is_multicore;
@ -60,7 +59,8 @@ struct KernelCore::Impl {
void Initialize(KernelCore& kernel) { void Initialize(KernelCore& kernel) {
global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel); global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel);
global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel);
RegisterHostThread();
service_thread_manager = service_thread_manager =
std::make_unique<Common::ThreadWorker>(1, "yuzu:ServiceThreadManager"); std::make_unique<Common::ThreadWorker>(1, "yuzu:ServiceThreadManager");
@ -69,20 +69,14 @@ struct KernelCore::Impl {
InitializePhysicalCores(); InitializePhysicalCores();
// Derive the initial memory layout from the emulated board // Derive the initial memory layout from the emulated board
Init::InitializeSlabResourceCounts(kernel);
KMemoryLayout memory_layout; KMemoryLayout memory_layout;
DeriveInitialMemoryLayout(memory_layout); DeriveInitialMemoryLayout(memory_layout);
Init::InitializeSlabHeaps(system, memory_layout);
// Initialize kernel memory and resources.
InitializeSystemResourceLimit(kernel, system.CoreTiming(), memory_layout);
InitializeMemoryLayout(memory_layout); InitializeMemoryLayout(memory_layout);
InitializePageSlab(); InitializeSystemResourceLimit(kernel, system.CoreTiming(), memory_layout);
InitializeSlabHeaps();
InitializeSchedulers(); InitializeSchedulers();
InitializeSuspendThreads(); InitializeSuspendThreads();
InitializePreemption(kernel); InitializePreemption(kernel);
RegisterHostThread();
} }
void InitializeCores() { void InitializeCores() {
@ -99,49 +93,34 @@ struct KernelCore::Impl {
service_threads.clear(); service_threads.clear();
next_object_id = 0; next_object_id = 0;
next_kernel_process_id = KProcess::InitialKIPIDMin; next_kernel_process_id = Process::InitialKIPIDMin;
next_user_process_id = KProcess::ProcessIDMin; next_user_process_id = Process::ProcessIDMin;
next_thread_id = 1; next_thread_id = 1;
for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
if (suspend_threads[core_id]) { if (suspend_threads[i]) {
suspend_threads[core_id]->Close(); suspend_threads[i].reset();
suspend_threads[core_id] = nullptr;
} }
schedulers[core_id].reset();
} }
cores.clear(); cores.clear();
if (current_process) { current_process = nullptr;
current_process->Close();
current_process = nullptr;
}
global_handle_table.reset(); global_handle_table.Clear();
preemption_event = nullptr; preemption_event = nullptr;
for (auto& iter : named_ports) {
iter.second->Close();
}
named_ports.clear(); named_ports.clear();
exclusive_monitor.reset(); exclusive_monitor.reset();
// Cleanup persistent kernel objects hid_shared_mem = nullptr;
auto CleanupObject = [](KAutoObject* obj) { font_shared_mem = nullptr;
if (obj) { irs_shared_mem = nullptr;
obj->Close(); time_shared_mem = nullptr;
obj = nullptr;
} system_resource_limit = nullptr;
};
CleanupObject(hid_shared_mem);
CleanupObject(font_shared_mem);
CleanupObject(irs_shared_mem);
CleanupObject(time_shared_mem);
CleanupObject(system_resource_limit);
// Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others // Next host thead ID to use, 0-3 IDs represent core threads, >3 represent others
next_host_thread_id = Core::Hardware::NUM_CPU_CORES; next_host_thread_id = Core::Hardware::NUM_CPU_CORES;
@ -166,9 +145,7 @@ struct KernelCore::Impl {
void InitializeSystemResourceLimit(KernelCore& kernel, void InitializeSystemResourceLimit(KernelCore& kernel,
const Core::Timing::CoreTiming& core_timing, const Core::Timing::CoreTiming& core_timing,
const KMemoryLayout& memory_layout) { const KMemoryLayout& memory_layout) {
system_resource_limit = KResourceLimit::Create(system.Kernel()); system_resource_limit = std::make_shared<KResourceLimit>(kernel, core_timing);
system_resource_limit->Initialize(&core_timing);
const auto [total_size, kernel_size] = memory_layout.GetTotalAndKernelMemorySizes(); const auto [total_size, kernel_size] = memory_layout.GetTotalAndKernelMemorySizes();
// If setting the default system values fails, then something seriously wrong has occurred. // If setting the default system values fails, then something seriously wrong has occurred.
@ -212,16 +189,19 @@ struct KernelCore::Impl {
} }
void InitializeSuspendThreads() { void InitializeSuspendThreads() {
for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
suspend_threads[core_id] = KThread::Create(system.Kernel()); std::string name = "Suspend Thread Id:" + std::to_string(i);
ASSERT(KThread::InitializeHighPriorityThread(system, suspend_threads[core_id], {}, {}, std::function<void(void*)> init_func = Core::CpuManager::GetSuspendThreadStartFunc();
core_id) void* init_func_parameter = system.GetCpuManager().GetStartFuncParamater();
.IsSuccess()); auto thread_res = KThread::CreateThread(
suspend_threads[core_id]->SetName(fmt::format("SuspendThread:{}", core_id)); system, ThreadType::HighPriority, std::move(name), 0, 0, 0, static_cast<u32>(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; current_process = process;
if (process == nullptr) { if (process == nullptr) {
return; 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 // Gets the dummy KThread for the caller, allocating a new one if this is the first time
KThread* GetHostDummyThread() { KThread* GetHostDummyThread() {
auto make_thread = [this]() { const thread_local auto thread =
std::unique_ptr<KThread> thread = std::make_unique<KThread>(system.Kernel()); KThread::CreateThread(
KAutoObject::Create(thread.get()); system, ThreadType::Main, fmt::format("DummyThread:{}", GetHostThreadId()), 0,
ASSERT(KThread::InitializeDummyThread(thread.get()).IsSuccess()); KThread::DefaultThreadPriority, 0, static_cast<u32>(3), 0, nullptr)
thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId())); .Unwrap();
return std::move(thread);
};
thread_local auto thread = make_thread();
return thread.get(); return thread.get();
} }
@ -395,8 +371,7 @@ struct KernelCore::Impl {
const size_t resource_region_size = memory_layout.GetResourceRegionSizeForInit(); const size_t resource_region_size = memory_layout.GetResourceRegionSizeForInit();
// Determine the size of the slab region. // Determine the size of the slab region.
const size_t slab_region_size = const size_t slab_region_size = Common::AlignUp(KernelSlabHeapSize, PageSize);
Common::AlignUp(Init::CalculateTotalSlabHeapSize(system.Kernel()), PageSize);
ASSERT(slab_region_size <= resource_region_size); ASSERT(slab_region_size <= resource_region_size);
// Setup the slab region. // 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 irs_phys_addr{system_pool.GetAddress() + hid_size + font_size};
const PAddr time_phys_addr{system_pool.GetAddress() + hid_size + font_size + irs_size}; const PAddr time_phys_addr{system_pool.GetAddress() + hid_size + font_size + irs_size};
hid_shared_mem = KSharedMemory::Create(system.Kernel()); hid_shared_mem = Kernel::KSharedMemory::Create(
font_shared_mem = KSharedMemory::Create(system.Kernel()); system.Kernel(), system.DeviceMemory(), nullptr, {hid_phys_addr, hid_size / PageSize},
irs_shared_mem = KSharedMemory::Create(system.Kernel()); KMemoryPermission::None, KMemoryPermission::Read, hid_phys_addr, hid_size,
time_shared_mem = KSharedMemory::Create(system.Kernel()); "HID:SharedMemory");
font_shared_mem = Kernel::KSharedMemory::Create(
hid_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, system.Kernel(), system.DeviceMemory(), nullptr, {font_phys_addr, font_size / PageSize},
{hid_phys_addr, hid_size / PageSize}, KMemoryPermission::None, KMemoryPermission::Read, font_phys_addr, font_size,
Svc::MemoryPermission::None, Svc::MemoryPermission::Read, "Font:SharedMemory");
hid_phys_addr, hid_size, "HID:SharedMemory"); irs_shared_mem = Kernel::KSharedMemory::Create(
font_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, system.Kernel(), system.DeviceMemory(), nullptr, {irs_phys_addr, irs_size / PageSize},
{font_phys_addr, font_size / PageSize}, KMemoryPermission::None, KMemoryPermission::Read, irs_phys_addr, irs_size,
Svc::MemoryPermission::None, Svc::MemoryPermission::Read, "IRS:SharedMemory");
font_phys_addr, font_size, "Font:SharedMemory"); time_shared_mem = Kernel::KSharedMemory::Create(
irs_shared_mem->Initialize(system.Kernel(), system.DeviceMemory(), nullptr, system.Kernel(), system.DeviceMemory(), nullptr, {time_phys_addr, time_size / PageSize},
{irs_phys_addr, irs_size / PageSize}, KMemoryPermission::None, KMemoryPermission::Read, time_phys_addr, time_size,
Svc::MemoryPermission::None, Svc::MemoryPermission::Read, "Time:SharedMemory");
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");
} }
void InitializePageSlab() { void InitializeSlabHeaps() {
// Allocate slab heaps // Allocate slab heaps
user_slab_heap_pages = std::make_unique<KSlabHeap<Page>>(); user_slab_heap_pages = std::make_unique<KSlabHeap<Page>>();
@ -626,33 +596,30 @@ struct KernelCore::Impl {
// Reserve slab heaps // Reserve slab heaps
ASSERT( ASSERT(
system_resource_limit->Reserve(LimitableResource::PhysicalMemory, user_slab_heap_size)); system_resource_limit->Reserve(LimitableResource::PhysicalMemory, user_slab_heap_size));
// Initialize slab heap // Initialize slab heaps
user_slab_heap_pages->Initialize( user_slab_heap_pages->Initialize(
system.DeviceMemory().GetPointer(Core::DramMemoryMap::SlabHeapBase), system.DeviceMemory().GetPointer(Core::DramMemoryMap::SlabHeapBase),
user_slab_heap_size); user_slab_heap_size);
} }
std::atomic<u32> next_object_id{0}; std::atomic<u32> next_object_id{0};
std::atomic<u64> next_kernel_process_id{KProcess::InitialKIPIDMin}; std::atomic<u64> next_kernel_process_id{Process::InitialKIPIDMin};
std::atomic<u64> next_user_process_id{KProcess::ProcessIDMin}; std::atomic<u64> next_user_process_id{Process::ProcessIDMin};
std::atomic<u64> next_thread_id{1}; std::atomic<u64> next_thread_id{1};
// Lists all processes that exist in the current session. // Lists all processes that exist in the current session.
std::vector<KProcess*> process_list; std::vector<std::shared_ptr<Process>> process_list;
KProcess* current_process{}; Process* current_process = nullptr;
std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context; std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context;
Kernel::TimeManager time_manager; Kernel::TimeManager time_manager;
Init::KSlabResourceCounts slab_resource_counts{}; std::shared_ptr<KResourceLimit> system_resource_limit;
KResourceLimit* system_resource_limit{};
std::shared_ptr<Core::Timing::EventType> preemption_event; std::shared_ptr<Core::Timing::EventType> preemption_event;
// This is the kernel's handle table or supervisor handle table which // This is the kernel's handle table or supervisor handle table which
// stores all the objects in place. // stores all the objects in place.
std::unique_ptr<KHandleTable> global_handle_table; HandleTable global_handle_table;
KAutoObjectWithListContainer object_list_container;
/// Map of named ports managed by the kernel, which can be retrieved using /// Map of named ports managed by the kernel, which can be retrieved using
/// the ConnectToPort SVC. /// the ConnectToPort SVC.
@ -669,10 +636,10 @@ struct KernelCore::Impl {
std::unique_ptr<KSlabHeap<Page>> user_slab_heap_pages; std::unique_ptr<KSlabHeap<Page>> user_slab_heap_pages;
// Shared memory for services // Shared memory for services
Kernel::KSharedMemory* hid_shared_mem{}; std::shared_ptr<Kernel::KSharedMemory> hid_shared_mem;
Kernel::KSharedMemory* font_shared_mem{}; std::shared_ptr<Kernel::KSharedMemory> font_shared_mem;
Kernel::KSharedMemory* irs_shared_mem{}; std::shared_ptr<Kernel::KSharedMemory> irs_shared_mem;
Kernel::KSharedMemory* time_shared_mem{}; std::shared_ptr<Kernel::KSharedMemory> time_shared_mem;
// Threads used for services // Threads used for services
std::unordered_set<std::shared_ptr<Kernel::ServiceThread>> service_threads; std::unordered_set<std::shared_ptr<Kernel::ServiceThread>> service_threads;
@ -681,7 +648,7 @@ struct KernelCore::Impl {
// the release of itself // the release of itself
std::unique_ptr<Common::ThreadWorker> service_thread_manager; std::unique_ptr<Common::ThreadWorker> service_thread_manager;
std::array<KThread*, Core::Hardware::NUM_CPU_CORES> suspend_threads; std::array<std::shared_ptr<KThread>, Core::Hardware::NUM_CPU_CORES> suspend_threads{};
std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{};
std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{};
@ -696,14 +663,15 @@ struct KernelCore::Impl {
}; };
KernelCore::KernelCore(Core::System& system) : impl{std::make_unique<Impl>(system, *this)} {} KernelCore::KernelCore(Core::System& system) : impl{std::make_unique<Impl>(system, *this)} {}
KernelCore::~KernelCore() = default; KernelCore::~KernelCore() {
Shutdown();
}
void KernelCore::SetMulticore(bool is_multicore) { void KernelCore::SetMulticore(bool is_multicore) {
impl->SetMulticore(is_multicore); impl->SetMulticore(is_multicore);
} }
void KernelCore::Initialize() { void KernelCore::Initialize() {
slab_heap_container = std::make_unique<SlabHeapContainer>();
impl->Initialize(*this); impl->Initialize(*this);
} }
@ -715,35 +683,31 @@ void KernelCore::Shutdown() {
impl->Shutdown(); impl->Shutdown();
} }
const KResourceLimit* KernelCore::GetSystemResourceLimit() const { std::shared_ptr<KResourceLimit> KernelCore::GetSystemResourceLimit() const {
return impl->system_resource_limit; return impl->system_resource_limit;
} }
KResourceLimit* KernelCore::GetSystemResourceLimit() { std::shared_ptr<KThread> KernelCore::RetrieveThreadFromGlobalHandleTable(Handle handle) const {
return impl->system_resource_limit; return impl->global_handle_table.Get<KThread>(handle);
} }
KScopedAutoObject<KThread> KernelCore::RetrieveThreadFromGlobalHandleTable(Handle handle) const { void KernelCore::AppendNewProcess(std::shared_ptr<Process> process) {
return impl->global_handle_table->GetObject<KThread>(handle); impl->process_list.push_back(std::move(process));
} }
void KernelCore::AppendNewProcess(KProcess* process) { void KernelCore::MakeCurrentProcess(Process* process) {
impl->process_list.push_back(process);
}
void KernelCore::MakeCurrentProcess(KProcess* process) {
impl->MakeCurrentProcess(process); impl->MakeCurrentProcess(process);
} }
KProcess* KernelCore::CurrentProcess() { Process* KernelCore::CurrentProcess() {
return impl->current_process; return impl->current_process;
} }
const KProcess* KernelCore::CurrentProcess() const { const Process* KernelCore::CurrentProcess() const {
return impl->current_process; return impl->current_process;
} }
const std::vector<KProcess*>& KernelCore::GetProcessList() const { const std::vector<std::shared_ptr<Process>>& KernelCore::GetProcessList() const {
return impl->process_list; return impl->process_list;
} }
@ -817,14 +781,6 @@ const Core::ExclusiveMonitor& KernelCore::GetExclusiveMonitor() const {
return *impl->exclusive_monitor; 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() { void KernelCore::InvalidateAllInstructionCaches() {
for (auto& physical_core : impl->cores) { for (auto& physical_core : impl->cores) {
physical_core.ArmInterface().ClearInstructionCache(); physical_core.ArmInterface().ClearInstructionCache();
@ -844,9 +800,8 @@ void KernelCore::PrepareReschedule(std::size_t id) {
// TODO: Reimplement, this // TODO: Reimplement, this
} }
void KernelCore::AddNamedPort(std::string name, KClientPort* port) { void KernelCore::AddNamedPort(std::string name, std::shared_ptr<ClientPort> port) {
port->Open(); impl->named_ports.emplace(std::move(name), std::move(port));
impl->named_ports.emplace(std::move(name), port);
} }
KernelCore::NamedPortTable::iterator KernelCore::FindNamedPort(const std::string& name) { KernelCore::NamedPortTable::iterator KernelCore::FindNamedPort(const std::string& name) {
@ -878,12 +833,12 @@ u64 KernelCore::CreateNewUserProcessID() {
return impl->next_user_process_id++; return impl->next_user_process_id++;
} }
KHandleTable& KernelCore::GlobalHandleTable() { Kernel::HandleTable& KernelCore::GlobalHandleTable() {
return *impl->global_handle_table; return impl->global_handle_table;
} }
const KHandleTable& KernelCore::GlobalHandleTable() const { const Kernel::HandleTable& KernelCore::GlobalHandleTable() const {
return *impl->global_handle_table; return impl->global_handle_table;
} }
void KernelCore::RegisterCoreThread(std::size_t core_id) { void KernelCore::RegisterCoreThread(std::size_t core_id) {
@ -955,9 +910,9 @@ void KernelCore::Suspend(bool in_suspention) {
{ {
KScopedSchedulerLock lock(*this); KScopedSchedulerLock lock(*this);
const auto state = should_suspend ? ThreadState::Runnable : ThreadState::Waiting; const auto state = should_suspend ? ThreadState::Runnable : ThreadState::Waiting;
for (u32 core_id = 0; core_id < Core::Hardware::NUM_CPU_CORES; core_id++) { for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) {
impl->suspend_threads[core_id]->SetState(state); impl->suspend_threads[i]->SetState(state);
impl->suspend_threads[core_id]->SetWaitReasonForDebugging( impl->suspend_threads[i]->SetWaitReasonForDebugging(
ThreadWaitReasonForDebugging::Suspended); ThreadWaitReasonForDebugging::Suspended);
} }
} }
@ -997,14 +952,6 @@ void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> 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 { bool KernelCore::IsPhantomModeForSingleCore() const {
return impl->IsPhantomModeForSingleCore(); return impl->IsPhantomModeForSingleCore();
} }

View file

@ -11,10 +11,8 @@
#include <vector> #include <vector>
#include "core/arm/cpu_interrupt_handler.h" #include "core/arm/cpu_interrupt_handler.h"
#include "core/hardware_properties.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/memory_types.h"
#include "core/hle/kernel/svc_common.h" #include "core/hle/kernel/object.h"
namespace Core { namespace Core {
class CPUInterruptHandler; class CPUInterruptHandler;
@ -29,32 +27,20 @@ struct EventType;
namespace Kernel { namespace Kernel {
class KClientPort; class ClientPort;
class GlobalSchedulerContext; class GlobalSchedulerContext;
class KAutoObjectWithListContainer; class HandleTable;
class KClientSession;
class KEvent;
class KHandleTable;
class KLinkedListNode;
class KMemoryManager; class KMemoryManager;
class KPort;
class KProcess;
class KResourceLimit; class KResourceLimit;
class KScheduler; class KScheduler;
class KSession;
class KSharedMemory; class KSharedMemory;
class KThread; class KThread;
class KTransferMemory;
class KWritableEvent;
class PhysicalCore; class PhysicalCore;
class Process;
class ServiceThread; class ServiceThread;
class Synchronization; class Synchronization;
class TimeManager; class TimeManager;
namespace Init {
struct KSlabResourceCounts;
}
template <typename T> template <typename T>
class KSlabHeap; class KSlabHeap;
@ -65,7 +51,7 @@ constexpr EmuThreadHandle EmuThreadHandleReserved{1ULL << 63};
/// Represents a single instance of the kernel. /// Represents a single instance of the kernel.
class KernelCore { class KernelCore {
private: private:
using NamedPortTable = std::unordered_map<std::string, KClientPort*>; using NamedPortTable = std::unordered_map<std::string, std::shared_ptr<ClientPort>>;
public: public:
/// Constructs an instance of the kernel using the given System /// Constructs an instance of the kernel using the given System
@ -97,28 +83,25 @@ public:
void Shutdown(); void Shutdown();
/// Retrieves a shared pointer to the system resource limit instance. /// Retrieves a shared pointer to the system resource limit instance.
const KResourceLimit* GetSystemResourceLimit() const; std::shared_ptr<KResourceLimit> GetSystemResourceLimit() const;
/// Retrieves a shared pointer to the system resource limit instance.
KResourceLimit* GetSystemResourceLimit();
/// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table. /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table.
KScopedAutoObject<KThread> RetrieveThreadFromGlobalHandleTable(Handle handle) const; std::shared_ptr<KThread> RetrieveThreadFromGlobalHandleTable(Handle handle) const;
/// Adds the given shared pointer to an internal list of active processes. /// Adds the given shared pointer to an internal list of active processes.
void AppendNewProcess(KProcess* process); void AppendNewProcess(std::shared_ptr<Process> process);
/// Makes the given process the new current process. /// Makes the given process the new current process.
void MakeCurrentProcess(KProcess* process); void MakeCurrentProcess(Process* process);
/// Retrieves a pointer to the current process. /// Retrieves a pointer to the current process.
KProcess* CurrentProcess(); Process* CurrentProcess();
/// Retrieves a const pointer to the current process. /// Retrieves a const pointer to the current process.
const KProcess* CurrentProcess() const; const Process* CurrentProcess() const;
/// Retrieves the list of processes. /// Retrieves the list of processes.
const std::vector<KProcess*>& GetProcessList() const; const std::vector<std::shared_ptr<Process>>& GetProcessList() const;
/// Gets the sole instance of the global scheduler /// Gets the sole instance of the global scheduler
Kernel::GlobalSchedulerContext& GlobalSchedulerContext(); Kernel::GlobalSchedulerContext& GlobalSchedulerContext();
@ -160,10 +143,6 @@ public:
const Core::ExclusiveMonitor& GetExclusiveMonitor() const; const Core::ExclusiveMonitor& GetExclusiveMonitor() const;
KAutoObjectWithListContainer& ObjectListContainer();
const KAutoObjectWithListContainer& ObjectListContainer() const;
std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& Interrupts(); std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& Interrupts();
const std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& Interrupts() const; const std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES>& Interrupts() const;
@ -173,7 +152,7 @@ public:
void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size);
/// Adds a port to the named port table /// Adds a port to the named port table
void AddNamedPort(std::string name, KClientPort* port); void AddNamedPort(std::string name, std::shared_ptr<ClientPort> port);
/// Finds a port within the named port table with the given name. /// Finds a port within the named port table with the given name.
NamedPortTable::iterator FindNamedPort(const std::string& 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. * 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 * While these are allocated per ServerSession, these need to be owned and managed outside of
* of ServerSession to avoid a circular dependency. * ServerSession to avoid a circular dependency.
* @param name String name for the ServerSession creating this thread, used for debug * @param name String name for the ServerSession creating this thread, used for debug purposes.
* purposes.
* @returns The a weak pointer newly created service thread. * @returns The a weak pointer newly created service thread.
*/ */
std::weak_ptr<Kernel::ServiceThread> CreateServiceThread(const std::string& name); std::weak_ptr<Kernel::ServiceThread> CreateServiceThread(const std::string& name);
@ -265,42 +243,9 @@ public:
bool IsPhantomModeForSingleCore() const; bool IsPhantomModeForSingleCore() const;
void SetIsPhantomModeForSingleCore(bool value); void SetIsPhantomModeForSingleCore(bool value);
/// Gets the slab heap for the specified kernel object type.
template <typename T>
KSlabHeap<T>& SlabHeap() {
if constexpr (std::is_same_v<T, KClientSession>) {
return slab_heap_container->client_session;
} else if constexpr (std::is_same_v<T, KEvent>) {
return slab_heap_container->event;
} else if constexpr (std::is_same_v<T, KLinkedListNode>) {
return slab_heap_container->linked_list_node;
} else if constexpr (std::is_same_v<T, KPort>) {
return slab_heap_container->port;
} else if constexpr (std::is_same_v<T, KProcess>) {
return slab_heap_container->process;
} else if constexpr (std::is_same_v<T, KResourceLimit>) {
return slab_heap_container->resource_limit;
} else if constexpr (std::is_same_v<T, KSession>) {
return slab_heap_container->session;
} else if constexpr (std::is_same_v<T, KSharedMemory>) {
return slab_heap_container->shared_memory;
} else if constexpr (std::is_same_v<T, KThread>) {
return slab_heap_container->thread;
} else if constexpr (std::is_same_v<T, KTransferMemory>) {
return slab_heap_container->transfer_memory;
} else if constexpr (std::is_same_v<T, KWritableEvent>) {
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: private:
friend class KProcess; friend class Object;
friend class Process;
friend class KThread; friend class KThread;
/// Creates a new object ID, incrementing the internal object ID counter. /// Creates a new object ID, incrementing the internal object ID counter.
@ -316,33 +261,14 @@ private:
u64 CreateNewThreadID(); u64 CreateNewThreadID();
/// Provides a reference to the global handle table. /// Provides a reference to the global handle table.
KHandleTable& GlobalHandleTable(); Kernel::HandleTable& GlobalHandleTable();
/// Provides a const reference to the global handle table. /// Provides a const reference to the global handle table.
const KHandleTable& GlobalHandleTable() const; const Kernel::HandleTable& GlobalHandleTable() const;
struct Impl; struct Impl;
std::unique_ptr<Impl> impl; std::unique_ptr<Impl> impl;
bool exception_exited{}; bool exception_exited{};
private:
/// Helper to encapsulate all slab heaps in a single heap allocated container
struct SlabHeapContainer {
KSlabHeap<KClientSession> client_session;
KSlabHeap<KEvent> event;
KSlabHeap<KLinkedListNode> linked_list_node;
KSlabHeap<KPort> port;
KSlabHeap<KProcess> process;
KSlabHeap<KResourceLimit> resource_limit;
KSlabHeap<KSession> session;
KSlabHeap<KSharedMemory> shared_memory;
KSlabHeap<KThread> thread;
KSlabHeap<KTransferMemory> transfer_memory;
KSlabHeap<KWritableEvent> writeable_event;
};
std::unique_ptr<SlabHeapContainer> slab_heap_container;
}; };
} // namespace Kernel } // namespace Kernel

View file

@ -6,7 +6,7 @@
#include "common/bit_util.h" #include "common/bit_util.h"
#include "common/logging/log.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/k_page_table.h"
#include "core/hle/kernel/process_capability.h" #include "core/hle/kernel/process_capability.h"
#include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/svc_results.h"
@ -99,7 +99,7 @@ void ProcessCapabilities::InitializeForMetadatalessProcess() {
interrupt_capabilities.set(); interrupt_capabilities.set();
// Allow using the maximum possible amount of handles // Allow using the maximum possible amount of handles
handle_table_size = static_cast<s32>(KHandleTable::MaxTableSize); handle_table_size = static_cast<s32>(HandleTable::MAX_COUNT);
// Allow all debugging capabilities. // Allow all debugging capabilities.
is_debuggable = true; is_debuggable = true;
@ -159,7 +159,7 @@ ResultCode ProcessCapabilities::ParseSingleFlagCapability(u32& set_flags, u32& s
const auto type = GetCapabilityType(flag); const auto type = GetCapabilityType(flag);
if (type == CapabilityType::Unset) { if (type == CapabilityType::Unset) {
return ResultInvalidArgument; return ResultInvalidCapabilityDescriptor;
} }
// Bail early on ignorable entries, as one would expect, // 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); LOG_ERROR(Kernel, "Invalid capability type! type={}", type);
return ResultInvalidArgument; return ResultInvalidCapabilityDescriptor;
} }
void ProcessCapabilities::Clear() { void ProcessCapabilities::Clear() {
@ -225,7 +225,7 @@ ResultCode ProcessCapabilities::HandlePriorityCoreNumFlags(u32 flags) {
if (priority_mask != 0 || core_mask != 0) { if (priority_mask != 0 || core_mask != 0) {
LOG_ERROR(Kernel, "Core or priority mask are not zero! priority_mask={}, core_mask={}", LOG_ERROR(Kernel, "Core or priority mask are not zero! priority_mask={}, core_mask={}",
priority_mask, core_mask); priority_mask, core_mask);
return ResultInvalidArgument; return ResultInvalidCapabilityDescriptor;
} }
const u32 core_num_min = (flags >> 16) & 0xFF; const u32 core_num_min = (flags >> 16) & 0xFF;
@ -329,7 +329,7 @@ ResultCode ProcessCapabilities::HandleProgramTypeFlags(u32 flags) {
const u32 reserved = flags >> 17; const u32 reserved = flags >> 17;
if (reserved != 0) { if (reserved != 0) {
LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved); LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved);
return ResultReservedUsed; return ResultReservedValue;
} }
program_type = static_cast<ProgramType>((flags >> 14) & 0b111); program_type = static_cast<ProgramType>((flags >> 14) & 0b111);
@ -349,7 +349,7 @@ ResultCode ProcessCapabilities::HandleKernelVersionFlags(u32 flags) {
LOG_ERROR(Kernel, LOG_ERROR(Kernel,
"Kernel version is non zero or flags are too small! major_version={}, flags={}", "Kernel version is non zero or flags are too small! major_version={}, flags={}",
major_version, flags); major_version, flags);
return ResultInvalidArgument; return ResultInvalidCapabilityDescriptor;
} }
kernel_version = flags; kernel_version = flags;
@ -360,7 +360,7 @@ ResultCode ProcessCapabilities::HandleHandleTableFlags(u32 flags) {
const u32 reserved = flags >> 26; const u32 reserved = flags >> 26;
if (reserved != 0) { if (reserved != 0) {
LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved); LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved);
return ResultReservedUsed; return ResultReservedValue;
} }
handle_table_size = static_cast<s32>((flags >> 16) & 0x3FF); handle_table_size = static_cast<s32>((flags >> 16) & 0x3FF);
@ -371,7 +371,7 @@ ResultCode ProcessCapabilities::HandleDebugFlags(u32 flags) {
const u32 reserved = flags >> 19; const u32 reserved = flags >> 19;
if (reserved != 0) { if (reserved != 0) {
LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved); LOG_ERROR(Kernel, "Reserved value is non-zero! reserved={}", reserved);
return ResultReservedUsed; return ResultReservedValue;
} }
is_debuggable = (flags & 0x20000) != 0; is_debuggable = (flags & 0x20000) != 0;

View file

@ -13,8 +13,8 @@
#include "common/scope_exit.h" #include "common/scope_exit.h"
#include "common/thread.h" #include "common/thread.h"
#include "core/core.h" #include "core/core.h"
#include "core/hle/kernel/k_session.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/server_session.h"
#include "core/hle/kernel/service_thread.h" #include "core/hle/kernel/service_thread.h"
#include "core/hle/lock.h" #include "core/hle/lock.h"
#include "video_core/renderer_base.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); explicit Impl(KernelCore& kernel, std::size_t num_threads, const std::string& name);
~Impl(); ~Impl();
void QueueSyncRequest(KSession& session, std::shared_ptr<HLERequestContext>&& context); void QueueSyncRequest(ServerSession& session, std::shared_ptr<HLERequestContext>&& context);
private: private:
std::vector<std::thread> threads; std::vector<std::thread> 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<HLERequestContext>&& context) { std::shared_ptr<HLERequestContext>&& context) {
{ {
std::unique_lock lock{queue_mutex}; std::unique_lock lock{queue_mutex};
// Open a reference to the session to ensure it is not closes while the service request // ServerSession owns the service thread, so we cannot caption a strong pointer here in the
// completes asynchronously. // event that the ServerSession is terminated.
session.Open(); std::weak_ptr<ServerSession> weak_ptr{SharedFrom(&session)};
requests.emplace([weak_ptr, context{std::move(context)}]() {
requests.emplace([session_ptr{&session}, context{std::move(context)}]() { if (auto strong_ptr = weak_ptr.lock()) {
// Close the reference. strong_ptr->CompleteSyncRequest(*context);
SCOPE_EXIT({ session_ptr->Close(); });
// If the session has been closed, we are done.
if (session_ptr->IsServerClosed()) {
return;
} }
// Complete the service request.
KScopedAutoObject server_session{&session_ptr->GetServerSession()};
server_session->CompleteSyncRequest(*context);
}); });
} }
condition.notify_one(); condition.notify_one();
@ -111,7 +102,7 @@ ServiceThread::ServiceThread(KernelCore& kernel, std::size_t num_threads, const
ServiceThread::~ServiceThread() = default; ServiceThread::~ServiceThread() = default;
void ServiceThread::QueueSyncRequest(KSession& session, void ServiceThread::QueueSyncRequest(ServerSession& session,
std::shared_ptr<HLERequestContext>&& context) { std::shared_ptr<HLERequestContext>&& context) {
impl->QueueSyncRequest(session, std::move(context)); impl->QueueSyncRequest(session, std::move(context));
} }

View file

@ -11,14 +11,14 @@ namespace Kernel {
class HLERequestContext; class HLERequestContext;
class KernelCore; class KernelCore;
class KSession; class ServerSession;
class ServiceThread final { class ServiceThread final {
public: public:
explicit ServiceThread(KernelCore& kernel, std::size_t num_threads, const std::string& name); explicit ServiceThread(KernelCore& kernel, std::size_t num_threads, const std::string& name);
~ServiceThread(); ~ServiceThread();
void QueueSyncRequest(KSession& session, std::shared_ptr<HLERequestContext>&& context); void QueueSyncRequest(ServerSession& session, std::shared_ptr<HLERequestContext>&& context);
private: private:
class Impl; class Impl;

File diff suppressed because it is too large Load diff

View file

@ -6,24 +6,9 @@
#include "common/common_types.h" #include "common/common_types.h"
namespace Kernel {
using Handle = u32;
}
namespace Kernel::Svc { namespace Kernel::Svc {
constexpr s32 ArgumentHandleCountMax = 0x40; constexpr s32 ArgumentHandleCountMax = 0x40;
constexpr u32 HandleWaitMask{1u << 30}; 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 } // namespace Kernel::Svc

View file

@ -10,18 +10,18 @@ namespace Kernel {
// Confirmed Switch kernel error codes // Confirmed Switch kernel error codes
constexpr ResultCode ResultOutOfSessions{ErrorModule::Kernel, 7}; constexpr ResultCode ResultMaxConnectionsReached{ErrorModule::Kernel, 7};
constexpr ResultCode ResultInvalidArgument{ErrorModule::Kernel, 14}; constexpr ResultCode ResultInvalidCapabilityDescriptor{ErrorModule::Kernel, 14};
constexpr ResultCode ResultNoSynchronizationObject{ErrorModule::Kernel, 57}; constexpr ResultCode ResultNoSynchronizationObject{ErrorModule::Kernel, 57};
constexpr ResultCode ResultTerminationRequested{ErrorModule::Kernel, 59}; constexpr ResultCode ResultTerminationRequested{ErrorModule::Kernel, 59};
constexpr ResultCode ResultInvalidSize{ErrorModule::Kernel, 101}; constexpr ResultCode ResultInvalidSize{ErrorModule::Kernel, 101};
constexpr ResultCode ResultInvalidAddress{ErrorModule::Kernel, 102}; constexpr ResultCode ResultInvalidAddress{ErrorModule::Kernel, 102};
constexpr ResultCode ResultOutOfResource{ErrorModule::Kernel, 103}; constexpr ResultCode ResultOutOfResource{ErrorModule::Kernel, 103};
constexpr ResultCode ResultOutOfMemory{ErrorModule::Kernel, 104}; 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 ResultInvalidCurrentMemory{ErrorModule::Kernel, 106};
constexpr ResultCode ResultInvalidNewMemoryPermission{ErrorModule::Kernel, 108}; constexpr ResultCode ResultInvalidMemoryPermissions{ErrorModule::Kernel, 108};
constexpr ResultCode ResultInvalidMemoryRegion{ErrorModule::Kernel, 110}; constexpr ResultCode ResultInvalidMemoryRange{ErrorModule::Kernel, 110};
constexpr ResultCode ResultInvalidPriority{ErrorModule::Kernel, 112}; constexpr ResultCode ResultInvalidPriority{ErrorModule::Kernel, 112};
constexpr ResultCode ResultInvalidCoreId{ErrorModule::Kernel, 113}; constexpr ResultCode ResultInvalidCoreId{ErrorModule::Kernel, 113};
constexpr ResultCode ResultInvalidHandle{ErrorModule::Kernel, 114}; constexpr ResultCode ResultInvalidHandle{ErrorModule::Kernel, 114};
@ -33,11 +33,9 @@ constexpr ResultCode ResultOutOfRange{ErrorModule::Kernel, 119};
constexpr ResultCode ResultInvalidEnumValue{ErrorModule::Kernel, 120}; constexpr ResultCode ResultInvalidEnumValue{ErrorModule::Kernel, 120};
constexpr ResultCode ResultNotFound{ErrorModule::Kernel, 121}; constexpr ResultCode ResultNotFound{ErrorModule::Kernel, 121};
constexpr ResultCode ResultBusy{ErrorModule::Kernel, 122}; 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 ResultInvalidState{ErrorModule::Kernel, 125};
constexpr ResultCode ResultReservedUsed{ErrorModule::Kernel, 126}; constexpr ResultCode ResultReservedValue{ErrorModule::Kernel, 126};
constexpr ResultCode ResultPortClosed{ErrorModule::Kernel, 131}; constexpr ResultCode ResultResourceLimitedExceeded{ErrorModule::Kernel, 132};
constexpr ResultCode ResultLimitReached{ErrorModule::Kernel, 132};
constexpr ResultCode ResultInvalidId{ErrorModule::Kernel, 519};
} // namespace Kernel } // namespace Kernel

View file

@ -154,28 +154,15 @@ void SvcWrap64(Core::System& system) {
FuncReturn(system, retval); FuncReturn(system, retval);
} }
// Used by GetResourceLimitLimitValue.
template <ResultCode func(Core::System&, u64*, Handle, LimitableResource)>
void SvcWrap64(Core::System& system) {
u64 param_1 = 0;
const u32 retval = func(system, &param_1, static_cast<Handle>(Param(system, 1)),
static_cast<LimitableResource>(Param(system, 2)))
.raw;
system.CurrentArmInterface().SetReg(1, param_1);
FuncReturn(system, retval);
}
template <ResultCode func(Core::System&, u32, u64)> template <ResultCode func(Core::System&, u32, u64)>
void SvcWrap64(Core::System& system) { void SvcWrap64(Core::System& system) {
FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1)).raw); FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1)).raw);
} }
// Used by SetResourceLimitLimitValue template <ResultCode func(Core::System&, u32, u32, u64)>
template <ResultCode func(Core::System&, Handle, LimitableResource, u64)>
void SvcWrap64(Core::System& system) { void SvcWrap64(Core::System& system) {
FuncReturn(system, func(system, static_cast<Handle>(Param(system, 0)), FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)),
static_cast<LimitableResource>(Param(system, 1)), Param(system, 2)) static_cast<u32>(Param(system, 1)), Param(system, 2))
.raw); .raw);
} }
@ -232,11 +219,10 @@ void SvcWrap64(Core::System& system) {
func(system, Param(system, 0), Param(system, 1), static_cast<u32>(Param(system, 2))).raw); func(system, Param(system, 0), Param(system, 1), static_cast<u32>(Param(system, 2))).raw);
} }
// Used by MapSharedMemory template <ResultCode func(Core::System&, u32, u64, u64, u32)>
template <ResultCode func(Core::System&, Handle, u64, u64, Svc::MemoryPermission)>
void SvcWrap64(Core::System& system) { void SvcWrap64(Core::System& system) {
FuncReturn(system, func(system, static_cast<Handle>(Param(system, 0)), Param(system, 1), FuncReturn(system, func(system, static_cast<u32>(Param(system, 0)), Param(system, 1),
Param(system, 2), static_cast<Svc::MemoryPermission>(Param(system, 3))) Param(system, 2), static_cast<u32>(Param(system, 3)))
.raw); .raw);
} }
@ -266,13 +252,11 @@ void SvcWrap64(Core::System& system) {
.raw); .raw);
} }
// Used by GetInfo template <ResultCode func(Core::System&, u64*, u64, u64, u64)>
template <ResultCode func(Core::System&, u64*, u64, Handle, u64)>
void SvcWrap64(Core::System& system) { void SvcWrap64(Core::System& system) {
u64 param_1 = 0; u64 param_1 = 0;
const u32 retval = func(system, &param_1, Param(system, 1), const u32 retval =
static_cast<Handle>(Param(system, 2)), Param(system, 3)) func(system, &param_1, Param(system, 1), Param(system, 2), Param(system, 3)).raw;
.raw;
system.CurrentArmInterface().SetReg(1, param_1); system.CurrentArmInterface().SetReg(1, param_1);
FuncReturn(system, retval); FuncReturn(system, retval);
@ -289,12 +273,11 @@ void SvcWrap64(Core::System& system) {
FuncReturn(system, retval); FuncReturn(system, retval);
} }
// Used by CreateTransferMemory template <ResultCode func(Core::System&, u32*, u64, u64, u32)>
template <ResultCode func(Core::System&, Handle*, u64, u64, Svc::MemoryPermission)>
void SvcWrap64(Core::System& system) { void SvcWrap64(Core::System& system) {
u32 param_1 = 0; u32 param_1 = 0;
const u32 retval = func(system, &param_1, Param(system, 1), Param(system, 2), const u32 retval = func(system, &param_1, Param(system, 1), Param(system, 2),
static_cast<Svc::MemoryPermission>(Param(system, 3))) static_cast<u32>(Param(system, 3)))
.raw; .raw;
system.CurrentArmInterface().SetReg(1, param_1); system.CurrentArmInterface().SetReg(1, param_1);
@ -554,16 +537,6 @@ void SvcWrap32(Core::System& system) {
FuncReturn(system, retval); FuncReturn(system, retval);
} }
// Used by MapSharedMemory32
template <ResultCode func(Core::System&, Handle, u32, u32, Svc::MemoryPermission)>
void SvcWrap32(Core::System& system) {
const u32 retval = func(system, static_cast<Handle>(Param(system, 0)),
static_cast<u32>(Param(system, 1)), static_cast<u32>(Param(system, 2)),
static_cast<Svc::MemoryPermission>(Param(system, 3)))
.raw;
FuncReturn(system, retval);
}
// Used by SetThreadCoreMask32 // Used by SetThreadCoreMask32
template <ResultCode func(Core::System&, Handle, s32, u32, u32)> template <ResultCode func(Core::System&, Handle, s32, u32, u32)>
void SvcWrap32(Core::System& system) { void SvcWrap32(Core::System& system) {
@ -613,12 +586,11 @@ void SvcWrap32(Core::System& system) {
} }
// Used by CreateTransferMemory32 // Used by CreateTransferMemory32
template <ResultCode func(Core::System&, Handle*, u32, u32, Svc::MemoryPermission)> template <ResultCode func(Core::System&, Handle*, u32, u32, u32)>
void SvcWrap32(Core::System& system) { void SvcWrap32(Core::System& system) {
Handle handle = 0; Handle handle = 0;
const u32 retval = func(system, &handle, Param32(system, 1), Param32(system, 2), const u32 retval =
static_cast<Svc::MemoryPermission>(Param32(system, 3))) func(system, &handle, Param32(system, 1), Param32(system, 2), Param32(system, 3)).raw;
.raw;
system.CurrentArmInterface().SetReg(1, handle); system.CurrentArmInterface().SetReg(1, handle);
FuncReturn(system, retval); FuncReturn(system, retval);
} }

View file

@ -6,6 +6,7 @@
#include "core/core.h" #include "core/core.h"
#include "core/core_timing.h" #include "core/core_timing.h"
#include "core/core_timing_util.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_scheduler.h"
#include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
@ -14,12 +15,16 @@
namespace Kernel { namespace Kernel {
TimeManager::TimeManager(Core::System& system_) : system{system_} { TimeManager::TimeManager(Core::System& system_) : system{system_} {
time_manager_event_type = time_manager_event_type = Core::Timing::CreateEvent(
Core::Timing::CreateEvent("Kernel::TimeManagerCallback", "Kernel::TimeManagerCallback",
[this](std::uintptr_t thread_handle, std::chrono::nanoseconds) { [this](std::uintptr_t thread_handle, std::chrono::nanoseconds) {
KThread* thread = reinterpret_cast<KThread*>(thread_handle); std::shared_ptr<KThread> thread;
thread->Wakeup(); {
}); std::lock_guard lock{mutex};
thread = SharedFrom<KThread>(reinterpret_cast<KThread*>(thread_handle));
}
thread->Wakeup();
});
} }
void TimeManager::ScheduleTimeEvent(KThread* thread, s64 nanoseconds) { void TimeManager::ScheduleTimeEvent(KThread* thread, s64 nanoseconds) {

View file

@ -8,6 +8,8 @@
#include <mutex> #include <mutex>
#include <unordered_map> #include <unordered_map>
#include "core/hle/kernel/object.h"
namespace Core { namespace Core {
class System; class System;
} // namespace Core } // namespace Core

View file

@ -16,8 +16,8 @@
#include "core/file_sys/control_metadata.h" #include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h" #include "core/file_sys/patch_manager.h"
#include "core/hle/ipc_helpers.h" #include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/kernel.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.h"
#include "core/hle/service/acc/acc_aa.h" #include "core/hle/service/acc/acc_aa.h"
#include "core/hle/service/acc/acc_su.h" #include "core/hle/service/acc/acc_su.h"

View file

@ -15,11 +15,11 @@
#include "core/file_sys/savedata_factory.h" #include "core/file_sys/savedata_factory.h"
#include "core/hle/ipc_helpers.h" #include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/k_event.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_readable_event.h"
#include "core/hle/kernel/k_transfer_memory.h"
#include "core/hle/kernel/k_writable_event.h" #include "core/hle/kernel/k_writable_event.h"
#include "core/hle/kernel/kernel.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/acc/profile_manager.h"
#include "core/hle/service/am/am.h" #include "core/hle/service/am/am.h"
#include "core/hle/service/am/applet_ae.h" #include "core/hle/service/am/applet_ae.h"
@ -42,7 +42,6 @@
#include "core/hle/service/set/set.h" #include "core/hle/service/set/set.h"
#include "core/hle/service/sm/sm.h" #include "core/hle/service/sm/sm.h"
#include "core/hle/service/vi/vi.h" #include "core/hle/service/vi/vi.h"
#include "core/memory.h"
namespace Service::AM { namespace Service::AM {
@ -254,8 +253,7 @@ IDebugFunctions::IDebugFunctions(Core::System& system_)
IDebugFunctions::~IDebugFunctions() = default; IDebugFunctions::~IDebugFunctions() = default;
ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nvflinger_) ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nvflinger_)
: ServiceFramework{system_, "ISelfController"}, nvflinger{nvflinger_}, : ServiceFramework{system_, "ISelfController"}, nvflinger{nvflinger_} {
launchable_event{system.Kernel()}, accumulated_suspended_tick_changed_event{system.Kernel()} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &ISelfController::Exit, "Exit"}, {0, &ISelfController::Exit, "Exit"},
@ -308,20 +306,19 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv
RegisterHandlers(functions); RegisterHandlers(functions);
Kernel::KAutoObject::Create(std::addressof(launchable_event)); auto& kernel = system.Kernel();
launchable_event = Kernel::KEvent::Create(kernel, "ISelfController:LaunchableEvent");
launchable_event.Initialize("ISelfController:LaunchableEvent"); launchable_event->Initialize();
// This event is created by AM on the first time GetAccumulatedSuspendedTickChangedEvent() is // 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 // 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 // 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 // suspended if the event has previously been created by a call to
// GetAccumulatedSuspendedTickChangedEvent. // GetAccumulatedSuspendedTickChangedEvent.
accumulated_suspended_tick_changed_event =
Kernel::KAutoObject::Create(std::addressof(accumulated_suspended_tick_changed_event)); Kernel::KEvent::Create(kernel, "ISelfController:AccumulatedSuspendedTickChangedEvent");
accumulated_suspended_tick_changed_event.Initialize( accumulated_suspended_tick_changed_event->Initialize();
"ISelfController:AccumulatedSuspendedTickChangedEvent"); accumulated_suspended_tick_changed_event->GetWritableEvent()->Signal();
accumulated_suspended_tick_changed_event.GetWritableEvent().Signal();
} }
ISelfController::~ISelfController() = default; ISelfController::~ISelfController() = default;
@ -380,11 +377,11 @@ void ISelfController::LeaveFatalSection(Kernel::HLERequestContext& ctx) {
void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) { void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_AM, "(STUBBED) called"); LOG_WARNING(Service_AM, "(STUBBED) called");
launchable_event.GetWritableEvent().Signal(); launchable_event->GetWritableEvent()->Signal();
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(launchable_event.GetReadableEvent()); rb.PushCopyObjects(launchable_event->GetReadableEvent());
} }
void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) { void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) {
@ -563,7 +560,7 @@ void ISelfController::GetAccumulatedSuspendedTickChangedEvent(Kernel::HLERequest
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); 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) { void ISelfController::SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestContext& ctx) {
@ -581,40 +578,39 @@ void ISelfController::SetAlbumImageTakenNotificationEnabled(Kernel::HLERequestCo
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel) AppletMessageQueue::AppletMessageQueue(Kernel::KernelCore& kernel) {
: on_new_message{kernel}, on_operation_mode_changed{kernel} { on_new_message = Kernel::KEvent::Create(kernel, "AMMessageQueue:OnMessageReceived");
on_new_message->Initialize();
Kernel::KAutoObject::Create(std::addressof(on_new_message)); on_operation_mode_changed =
Kernel::KAutoObject::Create(std::addressof(on_operation_mode_changed)); Kernel::KEvent::Create(kernel, "AMMessageQueue:OperationModeChanged");
on_operation_mode_changed->Initialize();
on_new_message.Initialize("AMMessageQueue:OnMessageReceived");
on_operation_mode_changed.Initialize("AMMessageQueue:OperationModeChanged");
} }
AppletMessageQueue::~AppletMessageQueue() = default; AppletMessageQueue::~AppletMessageQueue() = default;
Kernel::KReadableEvent& AppletMessageQueue::GetMessageReceiveEvent() { const std::shared_ptr<Kernel::KReadableEvent>& AppletMessageQueue::GetMessageReceiveEvent() const {
return on_new_message.GetReadableEvent(); return on_new_message->GetReadableEvent();
} }
Kernel::KReadableEvent& AppletMessageQueue::GetOperationModeChangedEvent() { const std::shared_ptr<Kernel::KReadableEvent>& AppletMessageQueue::GetOperationModeChangedEvent()
return on_operation_mode_changed.GetReadableEvent(); const {
return on_operation_mode_changed->GetReadableEvent();
} }
void AppletMessageQueue::PushMessage(AppletMessage msg) { void AppletMessageQueue::PushMessage(AppletMessage msg) {
messages.push(msg); messages.push(msg);
on_new_message.GetWritableEvent().Signal(); on_new_message->GetWritableEvent()->Signal();
} }
AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() { AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() {
if (messages.empty()) { if (messages.empty()) {
on_new_message.GetWritableEvent().Clear(); on_new_message->GetWritableEvent()->Clear();
return AppletMessage::NoMessage; return AppletMessage::NoMessage;
} }
auto msg = messages.front(); auto msg = messages.front();
messages.pop(); messages.pop();
if (messages.empty()) { if (messages.empty()) {
on_new_message.GetWritableEvent().Clear(); on_new_message->GetWritableEvent()->Clear();
} }
return msg; return msg;
} }
@ -634,7 +630,7 @@ void AppletMessageQueue::FocusStateChanged() {
void AppletMessageQueue::OperationModeChanged() { void AppletMessageQueue::OperationModeChanged() {
PushMessage(AppletMessage::OperationModeChanged); PushMessage(AppletMessage::OperationModeChanged);
PushMessage(AppletMessage::PerformanceModeChanged); PushMessage(AppletMessage::PerformanceModeChanged);
on_operation_mode_changed.GetWritableEvent().Signal(); on_operation_mode_changed->GetWritableEvent()->Signal();
} }
ICommonStateGetter::ICommonStateGetter(Core::System& system_, ICommonStateGetter::ICommonStateGetter(Core::System& system_,
@ -931,9 +927,11 @@ private:
void GetAppletStateChangedEvent(Kernel::HLERequestContext& ctx) { void GetAppletStateChangedEvent(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_AM, "called"); LOG_DEBUG(Service_AM, "called");
const auto event = applet->GetBroker().GetStateChangedEvent();
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(applet->GetBroker().GetStateChangedEvent()); rb.PushCopyObjects(event);
} }
void IsCompleted(Kernel::HLERequestContext& ctx) { void IsCompleted(Kernel::HLERequestContext& ctx) {
@ -1215,16 +1213,16 @@ void ILibraryAppletCreator::CreateTransferMemoryStorage(Kernel::HLERequestContex
} }
auto transfer_mem = auto transfer_mem =
system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(handle); system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(handle);
if (transfer_mem.IsNull()) { if (transfer_mem == nullptr) {
LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle); LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_UNKNOWN); rb.Push(RESULT_UNKNOWN);
return; 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(); const u8* const mem_end = mem_begin + transfer_mem->GetSize();
std::vector<u8> memory{mem_begin, mem_end}; std::vector<u8> memory{mem_begin, mem_end};
@ -1249,16 +1247,16 @@ void ILibraryAppletCreator::CreateHandleStorage(Kernel::HLERequestContext& ctx)
} }
auto transfer_mem = auto transfer_mem =
system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>(handle); system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(handle);
if (transfer_mem.IsNull()) { if (transfer_mem == nullptr) {
LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle); LOG_ERROR(Service_AM, "transfer_mem is a nullptr for handle={:08X}", handle);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_UNKNOWN); rb.Push(RESULT_UNKNOWN);
return; 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(); const u8* const mem_end = mem_begin + transfer_mem->GetSize();
std::vector<u8> memory{mem_begin, mem_end}; std::vector<u8> memory{mem_begin, mem_end};
@ -1268,9 +1266,7 @@ void ILibraryAppletCreator::CreateHandleStorage(Kernel::HLERequestContext& ctx)
} }
IApplicationFunctions::IApplicationFunctions(Core::System& system_) IApplicationFunctions::IApplicationFunctions(Core::System& system_)
: ServiceFramework{system_, "IApplicationFunctions"}, gpu_error_detected_event{system.Kernel()}, : ServiceFramework{system_, "IApplicationFunctions"} {
friend_invitation_storage_channel_event{system.Kernel()},
health_warning_disappeared_system_event{system.Kernel()} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"}, {1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
@ -1338,15 +1334,16 @@ IApplicationFunctions::IApplicationFunctions(Core::System& system_)
RegisterHandlers(functions); RegisterHandlers(functions);
Kernel::KAutoObject::Create(std::addressof(gpu_error_detected_event)); auto& kernel = system.Kernel();
Kernel::KAutoObject::Create(std::addressof(friend_invitation_storage_channel_event)); gpu_error_detected_event =
Kernel::KAutoObject::Create(std::addressof(health_warning_disappeared_system_event)); Kernel::KEvent::Create(kernel, "IApplicationFunctions:GpuErrorDetectedSystemEvent");
gpu_error_detected_event->Initialize();
gpu_error_detected_event.Initialize("IApplicationFunctions:GpuErrorDetectedSystemEvent"); friend_invitation_storage_channel_event =
friend_invitation_storage_channel_event.Initialize( Kernel::KEvent::Create(kernel, "IApplicationFunctions:FriendInvitationStorageChannelEvent");
"IApplicationFunctions:FriendInvitationStorageChannelEvent"); friend_invitation_storage_channel_event->Initialize();
health_warning_disappeared_system_event.Initialize( health_warning_disappeared_system_event =
"IApplicationFunctions:HealthWarningDisappearedSystemEvent"); Kernel::KEvent::Create(kernel, "IApplicationFunctions:HealthWarningDisappearedSystemEvent");
health_warning_disappeared_system_event->Initialize();
} }
IApplicationFunctions::~IApplicationFunctions() = default; IApplicationFunctions::~IApplicationFunctions() = default;
@ -1743,7 +1740,7 @@ void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(Kernel::HLERequestCon
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(gpu_error_detected_event.GetReadableEvent()); rb.PushCopyObjects(gpu_error_detected_event->GetReadableEvent());
} }
void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx) { void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERequestContext& ctx) {
@ -1751,7 +1748,7 @@ void IApplicationFunctions::GetFriendInvitationStorageChannelEvent(Kernel::HLERe
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(friend_invitation_storage_channel_event.GetReadableEvent()); rb.PushCopyObjects(friend_invitation_storage_channel_event->GetReadableEvent());
} }
void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel( void IApplicationFunctions::TryPopFromFriendInvitationStorageChannel(
@ -1767,7 +1764,7 @@ void IApplicationFunctions::GetHealthWarningDisappearedSystemEvent(Kernel::HLERe
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); 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, 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_) IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_)
: ServiceFramework{system_, "IHomeMenuFunctions"}, pop_from_general_channel_event{ : ServiceFramework{system_, "IHomeMenuFunctions"} {
system.Kernel()} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{10, &IHomeMenuFunctions::RequestToGetForeground, "RequestToGetForeground"}, {10, &IHomeMenuFunctions::RequestToGetForeground, "RequestToGetForeground"},
@ -1807,8 +1803,9 @@ IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_)
RegisterHandlers(functions); RegisterHandlers(functions);
Kernel::KAutoObject::Create(std::addressof(pop_from_general_channel_event)); pop_from_general_channel_event =
pop_from_general_channel_event.Initialize("IHomeMenuFunctions:PopFromGeneralChannelEvent"); Kernel::KEvent::Create(system.Kernel(), "IHomeMenuFunctions:PopFromGeneralChannelEvent");
pop_from_general_channel_event->Initialize();
} }
IHomeMenuFunctions::~IHomeMenuFunctions() = default; IHomeMenuFunctions::~IHomeMenuFunctions() = default;
@ -1825,7 +1822,7 @@ void IHomeMenuFunctions::GetPopFromGeneralChannelEvent(Kernel::HLERequestContext
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); 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_) IGlobalStateController::IGlobalStateController(Core::System& system_)

View file

@ -8,12 +8,12 @@
#include <memory> #include <memory>
#include <queue> #include <queue>
#include "core/hle/kernel/k_event.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Kernel { namespace Kernel {
class KernelCore; class KernelCore;
class KTransferMemory; class KEvent;
class TransferMemory;
} // namespace Kernel } // namespace Kernel
namespace Service::NVFlinger { namespace Service::NVFlinger {
@ -56,8 +56,8 @@ public:
explicit AppletMessageQueue(Kernel::KernelCore& kernel); explicit AppletMessageQueue(Kernel::KernelCore& kernel);
~AppletMessageQueue(); ~AppletMessageQueue();
Kernel::KReadableEvent& GetMessageReceiveEvent(); const std::shared_ptr<Kernel::KReadableEvent>& GetMessageReceiveEvent() const;
Kernel::KReadableEvent& GetOperationModeChangedEvent(); const std::shared_ptr<Kernel::KReadableEvent>& GetOperationModeChangedEvent() const;
void PushMessage(AppletMessage msg); void PushMessage(AppletMessage msg);
AppletMessage PopMessage(); AppletMessage PopMessage();
std::size_t GetMessageCount() const; std::size_t GetMessageCount() const;
@ -67,8 +67,8 @@ public:
private: private:
std::queue<AppletMessage> messages; std::queue<AppletMessage> messages;
Kernel::KEvent on_new_message; std::shared_ptr<Kernel::KEvent> on_new_message;
Kernel::KEvent on_operation_mode_changed; std::shared_ptr<Kernel::KEvent> on_operation_mode_changed;
}; };
class IWindowController final : public ServiceFramework<IWindowController> { class IWindowController final : public ServiceFramework<IWindowController> {
@ -156,8 +156,8 @@ private:
}; };
NVFlinger::NVFlinger& nvflinger; NVFlinger::NVFlinger& nvflinger;
Kernel::KEvent launchable_event; std::shared_ptr<Kernel::KEvent> launchable_event;
Kernel::KEvent accumulated_suspended_tick_changed_event; std::shared_ptr<Kernel::KEvent> accumulated_suspended_tick_changed_event;
u32 idle_time_detection_extension = 0; u32 idle_time_detection_extension = 0;
u64 num_fatal_sections_entered = 0; u64 num_fatal_sections_entered = 0;
@ -300,9 +300,9 @@ private:
bool launch_popped_application_specific = false; bool launch_popped_application_specific = false;
bool launch_popped_account_preselect = false; bool launch_popped_account_preselect = false;
s32 previous_program_index{-1}; s32 previous_program_index{-1};
Kernel::KEvent gpu_error_detected_event; std::shared_ptr<Kernel::KEvent> gpu_error_detected_event;
Kernel::KEvent friend_invitation_storage_channel_event; std::shared_ptr<Kernel::KEvent> friend_invitation_storage_channel_event;
Kernel::KEvent health_warning_disappeared_system_event; std::shared_ptr<Kernel::KEvent> health_warning_disappeared_system_event;
}; };
class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> { class IHomeMenuFunctions final : public ServiceFramework<IHomeMenuFunctions> {
@ -314,7 +314,7 @@ private:
void RequestToGetForeground(Kernel::HLERequestContext& ctx); void RequestToGetForeground(Kernel::HLERequestContext& ctx);
void GetPopFromGeneralChannelEvent(Kernel::HLERequestContext& ctx); void GetPopFromGeneralChannelEvent(Kernel::HLERequestContext& ctx);
Kernel::KEvent pop_from_general_channel_event; std::shared_ptr<Kernel::KEvent> pop_from_general_channel_event;
}; };
class IGlobalStateController final : public ServiceFramework<IGlobalStateController> { class IGlobalStateController final : public ServiceFramework<IGlobalStateController> {

View file

@ -12,8 +12,10 @@
#include "core/frontend/applets/profile_select.h" #include "core/frontend/applets/profile_select.h"
#include "core/frontend/applets/software_keyboard.h" #include "core/frontend/applets/software_keyboard.h"
#include "core/frontend/applets/web_browser.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_readable_event.h"
#include "core/hle/kernel/k_writable_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/am.h"
#include "core/hle/service/am/applet_ae.h" #include "core/hle/service/am/applet_ae.h"
#include "core/hle/service/am/applet_oe.h" #include "core/hle/service/am/applet_oe.h"
@ -29,16 +31,16 @@
namespace Service::AM::Applets { namespace Service::AM::Applets {
AppletDataBroker::AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_) AppletDataBroker::AppletDataBroker(Core::System& system_, LibraryAppletMode applet_mode_)
: system{system_}, applet_mode{applet_mode_}, state_changed_event{system.Kernel()}, : system{system_}, applet_mode{applet_mode_} {
pop_out_data_event{system.Kernel()}, pop_interactive_out_data_event{system.Kernel()} { state_changed_event =
Kernel::KEvent::Create(system.Kernel(), "ILibraryAppletAccessor:StateChangedEvent");
Kernel::KAutoObject::Create(std::addressof(state_changed_event)); state_changed_event->Initialize();
Kernel::KAutoObject::Create(std::addressof(pop_out_data_event)); pop_out_data_event =
Kernel::KAutoObject::Create(std::addressof(pop_interactive_out_data_event)); Kernel::KEvent::Create(system.Kernel(), "ILibraryAppletAccessor:PopDataOutEvent");
pop_out_data_event->Initialize();
state_changed_event.Initialize("ILibraryAppletAccessor:StateChangedEvent"); pop_interactive_out_data_event = Kernel::KEvent::Create(
pop_out_data_event.Initialize("ILibraryAppletAccessor:PopDataOutEvent"); system.Kernel(), "ILibraryAppletAccessor:PopInteractiveDataOutEvent");
pop_interactive_out_data_event.Initialize("ILibraryAppletAccessor:PopInteractiveDataOutEvent"); pop_interactive_out_data_event->Initialize();
} }
AppletDataBroker::~AppletDataBroker() = default; AppletDataBroker::~AppletDataBroker() = default;
@ -65,7 +67,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() {
auto out = std::move(out_channel.front()); auto out = std::move(out_channel.front());
out_channel.pop_front(); out_channel.pop_front();
pop_out_data_event.GetWritableEvent().Clear(); pop_out_data_event->GetWritableEvent()->Clear();
return out; return out;
} }
@ -84,7 +86,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopInteractiveDataToGame() {
auto out = std::move(out_interactive_channel.front()); auto out = std::move(out_interactive_channel.front());
out_interactive_channel.pop_front(); out_interactive_channel.pop_front();
pop_interactive_out_data_event.GetWritableEvent().Clear(); pop_interactive_out_data_event->GetWritableEvent()->Clear();
return out; return out;
} }
@ -103,7 +105,7 @@ void AppletDataBroker::PushNormalDataFromGame(std::shared_ptr<IStorage>&& storag
void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage) { void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage) {
out_channel.emplace_back(std::move(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<IStorage>&& storage) { void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage) {
@ -112,11 +114,11 @@ void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& s
void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage) { void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage) {
out_interactive_channel.emplace_back(std::move(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() { void AppletDataBroker::SignalStateChanged() const {
state_changed_event.GetWritableEvent().Signal(); state_changed_event->GetWritableEvent()->Signal();
switch (applet_mode) { switch (applet_mode) {
case LibraryAppletMode::AllForeground: case LibraryAppletMode::AllForeground:
@ -140,16 +142,16 @@ void AppletDataBroker::SignalStateChanged() {
} }
} }
Kernel::KReadableEvent& AppletDataBroker::GetNormalDataEvent() { std::shared_ptr<Kernel::KReadableEvent> AppletDataBroker::GetNormalDataEvent() const {
return pop_out_data_event.GetReadableEvent(); return pop_out_data_event->GetReadableEvent();
} }
Kernel::KReadableEvent& AppletDataBroker::GetInteractiveDataEvent() { std::shared_ptr<Kernel::KReadableEvent> AppletDataBroker::GetInteractiveDataEvent() const {
return pop_interactive_out_data_event.GetReadableEvent(); return pop_interactive_out_data_event->GetReadableEvent();
} }
Kernel::KReadableEvent& AppletDataBroker::GetStateChangedEvent() { std::shared_ptr<Kernel::KReadableEvent> AppletDataBroker::GetStateChangedEvent() const {
return state_changed_event.GetReadableEvent(); return state_changed_event->GetReadableEvent();
} }
Applet::Applet(Core::System& system_, LibraryAppletMode applet_mode_) Applet::Applet(Core::System& system_, LibraryAppletMode applet_mode_)

View file

@ -8,7 +8,7 @@
#include <queue> #include <queue>
#include "common/swap.h" #include "common/swap.h"
#include "core/hle/kernel/k_event.h" #include "core/hle/kernel/object.h"
union ResultCode; union ResultCode;
@ -95,11 +95,11 @@ public:
void PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage); void PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage);
void PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage); void PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage);
void SignalStateChanged(); void SignalStateChanged() const;
Kernel::KReadableEvent& GetNormalDataEvent(); std::shared_ptr<Kernel::KReadableEvent> GetNormalDataEvent() const;
Kernel::KReadableEvent& GetInteractiveDataEvent(); std::shared_ptr<Kernel::KReadableEvent> GetInteractiveDataEvent() const;
Kernel::KReadableEvent& GetStateChangedEvent(); std::shared_ptr<Kernel::KReadableEvent> GetStateChangedEvent() const;
private: private:
Core::System& system; Core::System& system;
@ -119,13 +119,13 @@ private:
// PopInteractiveDataToGame and PushInteractiveDataFromApplet // PopInteractiveDataToGame and PushInteractiveDataFromApplet
std::deque<std::shared_ptr<IStorage>> out_interactive_channel; std::deque<std::shared_ptr<IStorage>> out_interactive_channel;
Kernel::KEvent state_changed_event; std::shared_ptr<Kernel::KEvent> state_changed_event;
// Signaled on PushNormalDataFromApplet // Signaled on PushNormalDataFromApplet
Kernel::KEvent pop_out_data_event; std::shared_ptr<Kernel::KEvent> pop_out_data_event;
// Signaled on PushInteractiveDataFromApplet // Signaled on PushInteractiveDataFromApplet
Kernel::KEvent pop_interactive_out_data_event; std::shared_ptr<Kernel::KEvent> pop_interactive_out_data_event;
}; };
class Applet { class Applet {

View file

@ -9,7 +9,7 @@
#include "common/string_util.h" #include "common/string_util.h"
#include "core/core.h" #include "core/core.h"
#include "core/frontend/applets/error.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/am.h"
#include "core/hle/service/am/applets/error.h" #include "core/hle/service/am/applets/error.h"
#include "core/reporter.h" #include "core/reporter.h"

View file

@ -9,7 +9,7 @@
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/core.h" #include "core/core.h"
#include "core/frontend/applets/general_frontend.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/result.h"
#include "core/hle/service/am/am.h" #include "core/hle/service/am/am.h"
#include "core/hle/service/am/applets/general_backend.h" #include "core/hle/service/am/applets/general_backend.h"

View file

@ -17,7 +17,7 @@
#include "core/file_sys/system_archive/system_archive.h" #include "core/file_sys/system_archive/system_archive.h"
#include "core/file_sys/vfs_vector.h" #include "core/file_sys/vfs_vector.h"
#include "core/frontend/applets/web_browser.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/result.h"
#include "core/hle/service/am/am.h" #include "core/hle/service/am/am.h"
#include "core/hle/service/am/applets/web_browser.h" #include "core/hle/service/am/applets/web_browser.h"

View file

@ -16,9 +16,10 @@
#include "core/file_sys/patch_manager.h" #include "core/file_sys/patch_manager.h"
#include "core/file_sys/registered_cache.h" #include "core/file_sys/registered_cache.h"
#include "core/hle/ipc_helpers.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/k_readable_event.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/process.h"
#include "core/hle/service/aoc/aoc_u.h" #include "core/hle/service/aoc/aoc_u.h"
#include "core/loader/loader.h" #include "core/loader/loader.h"
@ -49,7 +50,7 @@ static std::vector<u64> AccumulateAOCTitleIDs(Core::System& system) {
class IPurchaseEventManager final : public ServiceFramework<IPurchaseEventManager> { class IPurchaseEventManager final : public ServiceFramework<IPurchaseEventManager> {
public: public:
explicit IPurchaseEventManager(Core::System& system_) explicit IPurchaseEventManager(Core::System& system_)
: ServiceFramework{system_, "IPurchaseEventManager"}, purchased_event{system.Kernel()} { : ServiceFramework{system_, "IPurchaseEventManager"} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IPurchaseEventManager::SetDefaultDeliveryTarget, "SetDefaultDeliveryTarget"}, {0, &IPurchaseEventManager::SetDefaultDeliveryTarget, "SetDefaultDeliveryTarget"},
@ -62,8 +63,9 @@ public:
RegisterHandlers(functions); RegisterHandlers(functions);
Kernel::KAutoObject::Create(std::addressof(purchased_event)); purchased_event =
purchased_event.Initialize("IPurchaseEventManager:PurchasedEvent"); Kernel::KEvent::Create(system.Kernel(), "IPurchaseEventManager:PurchasedEvent");
purchased_event->Initialize();
} }
private: private:
@ -96,15 +98,14 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(purchased_event.GetReadableEvent()); rb.PushCopyObjects(purchased_event->GetReadableEvent());
} }
Kernel::KEvent purchased_event; std::shared_ptr<Kernel::KEvent> purchased_event;
}; };
AOC_U::AOC_U(Core::System& system_) AOC_U::AOC_U(Core::System& system_)
: ServiceFramework{system_, "aoc:u"}, add_on_content{AccumulateAOCTitleIDs(system)}, : ServiceFramework{system_, "aoc:u"}, add_on_content{AccumulateAOCTitleIDs(system)} {
aoc_change_event{system.Kernel()} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, nullptr, "CountAddOnContentByApplicationId"}, {0, nullptr, "CountAddOnContentByApplicationId"},
@ -126,8 +127,9 @@ AOC_U::AOC_U(Core::System& system_)
RegisterHandlers(functions); RegisterHandlers(functions);
Kernel::KAutoObject::Create(std::addressof(aoc_change_event)); auto& kernel = system.Kernel();
aoc_change_event.Initialize("GetAddOnContentListChanged:Event"); aoc_change_event = Kernel::KEvent::Create(kernel, "GetAddOnContentListChanged:Event");
aoc_change_event->Initialize();
} }
AOC_U::~AOC_U() = default; AOC_U::~AOC_U() = default;
@ -254,7 +256,7 @@ void AOC_U::GetAddOnContentListChangedEvent(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(aoc_change_event.GetReadableEvent()); rb.PushCopyObjects(aoc_change_event->GetReadableEvent());
} }
void AOC_U::CreateEcPurchasedEventManager(Kernel::HLERequestContext& ctx) { void AOC_U::CreateEcPurchasedEventManager(Kernel::HLERequestContext& ctx) {

View file

@ -4,7 +4,6 @@
#pragma once #pragma once
#include "core/hle/kernel/k_event.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Core { namespace Core {
@ -32,7 +31,7 @@ private:
void CreatePermanentEcPurchasedEventManager(Kernel::HLERequestContext& ctx); void CreatePermanentEcPurchasedEventManager(Kernel::HLERequestContext& ctx);
std::vector<u64> add_on_content; std::vector<u64> add_on_content;
Kernel::KEvent aoc_change_event; std::shared_ptr<Kernel::KEvent> aoc_change_event;
}; };
/// Registers all AOC services with the specified service manager. /// Registers all AOC services with the specified service manager.

View file

@ -43,9 +43,9 @@ class IAudioOut final : public ServiceFramework<IAudioOut> {
public: public:
IAudioOut(Core::System& system_, AudoutParams audio_params_, AudioCore::AudioOut& audio_core_, IAudioOut(Core::System& system_, AudoutParams audio_params_, AudioCore::AudioOut& audio_core_,
std::string&& device_name_, std::string&& unique_name) std::string&& device_name_, std::string&& unique_name)
: ServiceFramework{system_, "IAudioOut"}, audio_core{audio_core_}, device_name{std::move( : ServiceFramework{system_, "IAudioOut"}, audio_core{audio_core_},
device_name_)}, device_name{std::move(device_name_)}, audio_params{audio_params_}, main_memory{
audio_params{audio_params_}, buffer_event{system.Kernel()}, main_memory{system.Memory()} { system.Memory()} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IAudioOut::GetAudioOutState, "GetAudioOutState"}, {0, &IAudioOut::GetAudioOutState, "GetAudioOutState"},
@ -67,13 +67,13 @@ public:
RegisterHandlers(functions); RegisterHandlers(functions);
// This is the event handle used to check if the audio buffer was released // This is the event handle used to check if the audio buffer was released
Kernel::KAutoObject::Create(std::addressof(buffer_event)); buffer_event = Kernel::KEvent::Create(system.Kernel(), "IAudioOutBufferReleased");
buffer_event.Initialize("IAudioOutBufferReleased"); buffer_event->Initialize();
stream = audio_core.OpenStream(system.CoreTiming(), audio_params.sample_rate, stream = audio_core.OpenStream(system.CoreTiming(), audio_params.sample_rate,
audio_params.channel_count, std::move(unique_name), [this] { audio_params.channel_count, std::move(unique_name), [this] {
const auto guard = LockService(); const auto guard = LockService();
buffer_event.GetWritableEvent().Signal(); buffer_event->GetWritableEvent()->Signal();
}); });
} }
@ -126,7 +126,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(buffer_event.GetReadableEvent()); rb.PushCopyObjects(buffer_event->GetReadableEvent());
} }
void AppendAudioOutBufferImpl(Kernel::HLERequestContext& ctx) { void AppendAudioOutBufferImpl(Kernel::HLERequestContext& ctx) {
@ -220,7 +220,7 @@ private:
[[maybe_unused]] AudoutParams audio_params{}; [[maybe_unused]] AudoutParams audio_params{};
/// This is the event handle used to check if the audio buffer was released /// This is the event handle used to check if the audio buffer was released
Kernel::KEvent buffer_event; std::shared_ptr<Kernel::KEvent> buffer_event;
Core::Memory::Memory& main_memory; Core::Memory::Memory& main_memory;
}; };

View file

@ -30,7 +30,7 @@ public:
explicit IAudioRenderer(Core::System& system_, explicit IAudioRenderer(Core::System& system_,
const AudioCommon::AudioRendererParameter& audren_params, const AudioCommon::AudioRendererParameter& audren_params,
const std::size_t instance_number) const std::size_t instance_number)
: ServiceFramework{system_, "IAudioRenderer"}, system_event{system.Kernel()} { : ServiceFramework{system_, "IAudioRenderer"} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IAudioRenderer::GetSampleRate, "GetSampleRate"}, {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"},
@ -49,13 +49,13 @@ public:
// clang-format on // clang-format on
RegisterHandlers(functions); RegisterHandlers(functions);
Kernel::KAutoObject::Create(std::addressof(system_event)); system_event = Kernel::KEvent::Create(system.Kernel(), "IAudioRenderer:SystemEvent");
system_event.Initialize("IAudioRenderer:SystemEvent"); system_event->Initialize();
renderer = std::make_unique<AudioCore::AudioRenderer>( renderer = std::make_unique<AudioCore::AudioRenderer>(
system.CoreTiming(), system.Memory(), audren_params, system.CoreTiming(), system.Memory(), audren_params,
[this]() { [this]() {
const auto guard = LockService(); const auto guard = LockService();
system_event.GetWritableEvent().Signal(); system_event->GetWritableEvent()->Signal();
}, },
instance_number); instance_number);
} }
@ -128,7 +128,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(system_event.GetReadableEvent()); rb.PushCopyObjects(system_event->GetReadableEvent());
} }
void SetRenderingTimeLimit(Kernel::HLERequestContext& ctx) { void SetRenderingTimeLimit(Kernel::HLERequestContext& ctx) {
@ -162,7 +162,7 @@ private:
rb.Push(ERR_NOT_SUPPORTED); rb.Push(ERR_NOT_SUPPORTED);
} }
Kernel::KEvent system_event; std::shared_ptr<Kernel::KEvent> system_event;
std::unique_ptr<AudioCore::AudioRenderer> renderer; std::unique_ptr<AudioCore::AudioRenderer> renderer;
u32 rendering_time_limit_percent = 100; u32 rendering_time_limit_percent = 100;
}; };
@ -170,9 +170,7 @@ private:
class IAudioDevice final : public ServiceFramework<IAudioDevice> { class IAudioDevice final : public ServiceFramework<IAudioDevice> {
public: public:
explicit IAudioDevice(Core::System& system_, u32_le revision_num) explicit IAudioDevice(Core::System& system_, u32_le revision_num)
: ServiceFramework{system_, "IAudioDevice"}, revision{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()} {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"}, {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"},
{1, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolume"}, {1, &IAudioDevice::SetAudioDeviceOutputVolume, "SetAudioDeviceOutputVolume"},
@ -190,17 +188,20 @@ public:
}; };
RegisterHandlers(functions); RegisterHandlers(functions);
Kernel::KAutoObject::Create(std::addressof(buffer_event)); auto& kernel = system.Kernel();
buffer_event.Initialize("IAudioOutBufferReleasedEvent"); buffer_event = Kernel::KEvent::Create(kernel, "IAudioOutBufferReleasedEvent");
buffer_event->Initialize();
// Should be similar to audio_output_device_switch_event // Should be similar to audio_output_device_switch_event
Kernel::KAutoObject::Create(std::addressof(audio_input_device_switch_event)); audio_input_device_switch_event =
audio_input_device_switch_event.Initialize("IAudioDevice:AudioInputDeviceSwitchedEvent"); 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 // Should only be signalled when an audio output device has been changed, example: speaker
// to headset // to headset
Kernel::KAutoObject::Create(std::addressof(audio_output_device_switch_event)); audio_output_device_switch_event =
audio_output_device_switch_event.Initialize("IAudioDevice:AudioOutputDeviceSwitchedEvent"); Kernel::KEvent::Create(kernel, "IAudioDevice:AudioOutputDeviceSwitchedEvent");
audio_output_device_switch_event->Initialize();
} }
private: private:
@ -289,11 +290,11 @@ private:
void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) { void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_Audio, "(STUBBED) called"); LOG_WARNING(Service_Audio, "(STUBBED) called");
buffer_event.GetWritableEvent().Signal(); buffer_event->GetWritableEvent()->Signal();
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(buffer_event.GetReadableEvent()); rb.PushCopyObjects(buffer_event->GetReadableEvent());
} }
void GetActiveChannelCount(Kernel::HLERequestContext& ctx) { void GetActiveChannelCount(Kernel::HLERequestContext& ctx) {
@ -310,7 +311,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); 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) { void QueryAudioDeviceOutputEvent(Kernel::HLERequestContext& ctx) {
@ -318,13 +319,13 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(audio_output_device_switch_event.GetReadableEvent()); rb.PushCopyObjects(audio_output_device_switch_event->GetReadableEvent());
} }
u32_le revision = 0; u32_le revision = 0;
Kernel::KEvent buffer_event; std::shared_ptr<Kernel::KEvent> buffer_event;
Kernel::KEvent audio_input_device_switch_event; std::shared_ptr<Kernel::KEvent> audio_input_device_switch_event;
Kernel::KEvent audio_output_device_switch_event; std::shared_ptr<Kernel::KEvent> audio_output_device_switch_event;
}; // namespace Audio }; // namespace Audio

View file

@ -5,6 +5,7 @@
#include "common/hex_util.h" #include "common/hex_util.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/core.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_readable_event.h"
#include "core/hle/kernel/k_writable_event.h" #include "core/hle/kernel/k_writable_event.h"
#include "core/hle/lock.h" #include "core/hle/lock.h"
@ -13,14 +14,14 @@
namespace Service::BCAT { namespace Service::BCAT {
ProgressServiceBackend::ProgressServiceBackend(Kernel::KernelCore& kernel, ProgressServiceBackend::ProgressServiceBackend(Kernel::KernelCore& kernel,
std::string_view event_name) std::string_view event_name) {
: update_event{kernel} { event = Kernel::KEvent::Create(kernel,
Kernel::KAutoObject::Create(std::addressof(update_event)); "ProgressServiceBackend:UpdateEvent:" + std::string(event_name));
update_event.Initialize("ProgressServiceBackend:UpdateEvent:" + std::string(event_name)); event->Initialize();
} }
Kernel::KReadableEvent& ProgressServiceBackend::GetEvent() { std::shared_ptr<Kernel::KReadableEvent> ProgressServiceBackend::GetEvent() const {
return update_event.GetReadableEvent(); return event->GetReadableEvent();
} }
DeliveryCacheProgressImpl& ProgressServiceBackend::GetImpl() { DeliveryCacheProgressImpl& ProgressServiceBackend::GetImpl() {
@ -85,12 +86,12 @@ void ProgressServiceBackend::FinishDownload(ResultCode result) {
SignalUpdate(); SignalUpdate();
} }
void ProgressServiceBackend::SignalUpdate() { void ProgressServiceBackend::SignalUpdate() const {
if (need_hle_lock) { if (need_hle_lock) {
std::lock_guard lock(HLE::g_hle_lock); std::lock_guard lock(HLE::g_hle_lock);
update_event.GetWritableEvent().Signal(); event->GetWritableEvent()->Signal();
} else { } else {
update_event.GetWritableEvent().Signal(); event->GetWritableEvent()->Signal();
} }
} }

View file

@ -11,7 +11,6 @@
#include "common/common_types.h" #include "common/common_types.h"
#include "core/file_sys/vfs_types.h" #include "core/file_sys/vfs_types.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/result.h" #include "core/hle/result.h"
namespace Core { namespace Core {
@ -99,13 +98,13 @@ public:
private: private:
explicit ProgressServiceBackend(Kernel::KernelCore& kernel, std::string_view event_name); explicit ProgressServiceBackend(Kernel::KernelCore& kernel, std::string_view event_name);
Kernel::KReadableEvent& GetEvent(); std::shared_ptr<Kernel::KReadableEvent> GetEvent() const;
DeliveryCacheProgressImpl& GetImpl(); DeliveryCacheProgressImpl& GetImpl();
void SignalUpdate(); void SignalUpdate() const;
DeliveryCacheProgressImpl impl{}; DeliveryCacheProgressImpl impl{};
Kernel::KEvent update_event; std::shared_ptr<Kernel::KEvent> event;
bool need_hle_lock = false; bool need_hle_lock = false;
}; };

View file

@ -12,9 +12,9 @@
#include "core/core.h" #include "core/core.h"
#include "core/file_sys/vfs.h" #include "core/file_sys/vfs.h"
#include "core/hle/ipc_helpers.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_readable_event.h"
#include "core/hle/kernel/k_writable_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/backend/backend.h"
#include "core/hle/service/bcat/bcat.h" #include "core/hle/service/bcat/bcat.h"
#include "core/hle/service/bcat/module.h" #include "core/hle/service/bcat/module.h"
@ -88,9 +88,11 @@ struct DeliveryCacheDirectoryEntry {
class IDeliveryCacheProgressService final : public ServiceFramework<IDeliveryCacheProgressService> { class IDeliveryCacheProgressService final : public ServiceFramework<IDeliveryCacheProgressService> {
public: public:
explicit IDeliveryCacheProgressService(Core::System& system_, Kernel::KReadableEvent& event_, explicit IDeliveryCacheProgressService(Core::System& system_,
std::shared_ptr<Kernel::KReadableEvent> event_,
const DeliveryCacheProgressImpl& impl_) const DeliveryCacheProgressImpl& impl_)
: ServiceFramework{system_, "IDeliveryCacheProgressService"}, event{event_}, impl{impl_} { : ServiceFramework{system_, "IDeliveryCacheProgressService"}, event{std::move(event_)},
impl{impl_} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IDeliveryCacheProgressService::GetEvent, "GetEvent"}, {0, &IDeliveryCacheProgressService::GetEvent, "GetEvent"},
@ -119,7 +121,7 @@ private:
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
Kernel::KReadableEvent& event; std::shared_ptr<Kernel::KReadableEvent> event;
const DeliveryCacheProgressImpl& impl; const DeliveryCacheProgressImpl& impl;
}; };

View file

@ -17,8 +17,7 @@ namespace Service::BtDrv {
class Bt final : public ServiceFramework<Bt> { class Bt final : public ServiceFramework<Bt> {
public: public:
explicit Bt(Core::System& system_) explicit Bt(Core::System& system_) : ServiceFramework{system_, "bt"} {
: ServiceFramework{system_, "bt"}, register_event{system.Kernel()} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, nullptr, "LeClientReadCharacteristic"}, {0, nullptr, "LeClientReadCharacteristic"},
@ -35,8 +34,9 @@ public:
// clang-format on // clang-format on
RegisterHandlers(functions); RegisterHandlers(functions);
Kernel::KAutoObject::Create(std::addressof(register_event)); auto& kernel = system.Kernel();
register_event.Initialize("BT:RegisterEvent"); register_event = Kernel::KEvent::Create(kernel, "BT:RegisterEvent");
register_event->Initialize();
} }
private: private:
@ -45,10 +45,10 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(register_event.GetReadableEvent()); rb.PushCopyObjects(register_event->GetReadableEvent());
} }
Kernel::KEvent register_event; std::shared_ptr<Kernel::KEvent> register_event;
}; };
class BtDrv final : public ServiceFramework<BtDrv> { class BtDrv final : public ServiceFramework<BtDrv> {

View file

@ -18,10 +18,7 @@ namespace Service::BTM {
class IBtmUserCore final : public ServiceFramework<IBtmUserCore> { class IBtmUserCore final : public ServiceFramework<IBtmUserCore> {
public: public:
explicit IBtmUserCore(Core::System& system_) explicit IBtmUserCore(Core::System& system_) : ServiceFramework{system_, "IBtmUserCore"} {
: ServiceFramework{system_, "IBtmUserCore"}, scan_event{system.Kernel()},
connection_event{system.Kernel()}, service_discovery{system.Kernel()},
config_event{system.Kernel()} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IBtmUserCore::AcquireBleScanEvent, "AcquireBleScanEvent"}, {0, &IBtmUserCore::AcquireBleScanEvent, "AcquireBleScanEvent"},
@ -60,15 +57,15 @@ public:
// clang-format on // clang-format on
RegisterHandlers(functions); RegisterHandlers(functions);
Kernel::KAutoObject::Create(std::addressof(scan_event)); auto& kernel = system.Kernel();
Kernel::KAutoObject::Create(std::addressof(connection_event)); scan_event = Kernel::KEvent::Create(kernel, "IBtmUserCore:ScanEvent");
Kernel::KAutoObject::Create(std::addressof(service_discovery)); scan_event->Initialize();
Kernel::KAutoObject::Create(std::addressof(config_event)); connection_event = Kernel::KEvent::Create(kernel, "IBtmUserCore:ConnectionEvent");
connection_event->Initialize();
scan_event.Initialize("IBtmUserCore:ScanEvent"); service_discovery = Kernel::KEvent::Create(kernel, "IBtmUserCore:Discovery");
connection_event.Initialize("IBtmUserCore:ConnectionEvent"); service_discovery->Initialize();
service_discovery.Initialize("IBtmUserCore:Discovery"); config_event = Kernel::KEvent::Create(kernel, "IBtmUserCore:ConfigEvent");
config_event.Initialize("IBtmUserCore:ConfigEvent"); config_event->Initialize();
} }
private: private:
@ -77,7 +74,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(scan_event.GetReadableEvent()); rb.PushCopyObjects(scan_event->GetReadableEvent());
} }
void AcquireBleConnectionEvent(Kernel::HLERequestContext& ctx) { void AcquireBleConnectionEvent(Kernel::HLERequestContext& ctx) {
@ -85,7 +82,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(connection_event.GetReadableEvent()); rb.PushCopyObjects(connection_event->GetReadableEvent());
} }
void AcquireBleServiceDiscoveryEvent(Kernel::HLERequestContext& ctx) { void AcquireBleServiceDiscoveryEvent(Kernel::HLERequestContext& ctx) {
@ -93,7 +90,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(service_discovery.GetReadableEvent()); rb.PushCopyObjects(service_discovery->GetReadableEvent());
} }
void AcquireBleMtuConfigEvent(Kernel::HLERequestContext& ctx) { void AcquireBleMtuConfigEvent(Kernel::HLERequestContext& ctx) {
@ -101,13 +98,13 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(config_event.GetReadableEvent()); rb.PushCopyObjects(config_event->GetReadableEvent());
} }
Kernel::KEvent scan_event; std::shared_ptr<Kernel::KEvent> scan_event;
Kernel::KEvent connection_event; std::shared_ptr<Kernel::KEvent> connection_event;
Kernel::KEvent service_discovery; std::shared_ptr<Kernel::KEvent> service_discovery;
Kernel::KEvent config_event; std::shared_ptr<Kernel::KEvent> config_event;
}; };
class BTM_USR final : public ServiceFramework<BTM_USR> { class BTM_USR final : public ServiceFramework<BTM_USR> {

View file

@ -12,7 +12,7 @@
#include "common/swap.h" #include "common/swap.h"
#include "core/core.h" #include "core/core.h"
#include "core/hle/ipc_helpers.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.h"
#include "core/hle/service/fatal/fatal_p.h" #include "core/hle/service/fatal/fatal_p.h"
#include "core/hle/service/fatal/fatal_u.h" #include "core/hle/service/fatal/fatal_u.h"

View file

@ -21,7 +21,7 @@
#include "core/file_sys/sdmc_factory.h" #include "core/file_sys/sdmc_factory.h"
#include "core/file_sys/vfs.h" #include "core/file_sys/vfs.h"
#include "core/file_sys/vfs_offset.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/filesystem.h"
#include "core/hle/service/filesystem/fsp_ldr.h" #include "core/hle/service/filesystem/fsp_ldr.h"
#include "core/hle/service/filesystem/fsp_pr.h" #include "core/hle/service/filesystem/fsp_pr.h"

View file

@ -25,7 +25,7 @@
#include "core/file_sys/system_archive/system_archive.h" #include "core/file_sys/system_archive/system_archive.h"
#include "core/file_sys/vfs.h" #include "core/file_sys/vfs.h"
#include "core/hle/ipc_helpers.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/filesystem.h"
#include "core/hle/service/filesystem/fsp_srv.h" #include "core/hle/service/filesystem/fsp_srv.h"
#include "core/reporter.h" #include "core/reporter.h"

View file

@ -185,8 +185,7 @@ private:
class INotificationService final : public ServiceFramework<INotificationService> { class INotificationService final : public ServiceFramework<INotificationService> {
public: public:
explicit INotificationService(Common::UUID uuid_, Core::System& system_) explicit INotificationService(Common::UUID uuid_, Core::System& system_)
: ServiceFramework{system_, "INotificationService"}, uuid{uuid_}, notification_event{ : ServiceFramework{system_, "INotificationService"}, uuid{uuid_} {
system.Kernel()} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &INotificationService::GetEvent, "GetEvent"}, {0, &INotificationService::GetEvent, "GetEvent"},
@ -197,8 +196,9 @@ public:
RegisterHandlers(functions); RegisterHandlers(functions);
Kernel::KAutoObject::Create(std::addressof(notification_event)); notification_event =
notification_event.Initialize("INotificationService:NotifyEvent"); Kernel::KEvent::Create(system.Kernel(), "INotificationService:NotifyEvent");
notification_event->Initialize();
} }
private: private:
@ -207,7 +207,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(notification_event.GetReadableEvent()); rb.PushCopyObjects(notification_event->GetReadableEvent());
} }
void Clear(Kernel::HLERequestContext& ctx) { void Clear(Kernel::HLERequestContext& ctx) {
@ -273,7 +273,7 @@ private:
}; };
Common::UUID uuid{Common::INVALID_UUID}; Common::UUID uuid{Common::INVALID_UUID};
Kernel::KEvent notification_event; std::shared_ptr<Kernel::KEvent> notification_event;
std::queue<SizedNotificationInfo> notifications; std::queue<SizedNotificationInfo> notifications;
States states{}; States states{};
}; };

View file

@ -9,8 +9,8 @@
#include "core/file_sys/control_metadata.h" #include "core/file_sys/control_metadata.h"
#include "core/hle/ipc_helpers.h" #include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/hle_ipc.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/kernel.h"
#include "core/hle/kernel/process.h"
#include "core/hle/service/glue/arp.h" #include "core/hle/service/glue/arp.h"
#include "core/hle/service/glue/errors.h" #include "core/hle/service/glue/errors.h"
#include "core/hle/service/glue/manager.h" #include "core/hle/service/glue/manager.h"

View file

@ -159,7 +159,7 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
const auto controller_type = connected_controllers[controller_idx].type; const auto controller_type = connected_controllers[controller_idx].type;
auto& controller = shared_memory_entries[controller_idx]; auto& controller = shared_memory_entries[controller_idx];
if (controller_type == NPadControllerType::None) { if (controller_type == NPadControllerType::None) {
styleset_changed_events[controller_idx]->GetWritableEvent().Signal(); styleset_changed_events[controller_idx]->GetWritableEvent()->Signal();
return; return;
} }
controller.style_set.raw = 0; // Zero out controller.style_set.raw = 0; // Zero out
@ -253,8 +253,9 @@ void Controller_NPad::InitNewlyAddedController(std::size_t controller_idx) {
void Controller_NPad::OnInit() { void Controller_NPad::OnInit() {
auto& kernel = system.Kernel(); auto& kernel = system.Kernel();
for (std::size_t i = 0; i < styleset_changed_events.size(); ++i) { for (std::size_t i = 0; i < styleset_changed_events.size(); ++i) {
styleset_changed_events[i] = Kernel::KEvent::Create(kernel); styleset_changed_events[i] =
styleset_changed_events[i]->Initialize(fmt::format("npad:NpadStyleSetChanged_{}", i)); Kernel::KEvent::Create(kernel, fmt::format("npad:NpadStyleSetChanged_{}", i));
styleset_changed_events[i]->Initialize();
} }
if (!IsControllerActivated()) { if (!IsControllerActivated()) {
@ -340,11 +341,6 @@ void Controller_NPad::OnRelease() {
VibrateControllerAtIndex(npad_idx, device_idx, {}); 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) { 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]; return vibration_devices_mounted[npad_index][device_index];
} }
Kernel::KReadableEvent& Controller_NPad::GetStyleSetChangedEvent(u32 npad_id) { std::shared_ptr<Kernel::KReadableEvent> Controller_NPad::GetStyleSetChangedEvent(
return styleset_changed_events[NPadIdToIndex(npad_id)]->GetReadableEvent(); 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 { 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) { void Controller_NPad::AddNewControllerAt(NPadControllerType controller, std::size_t npad_index) {

View file

@ -11,6 +11,7 @@
#include "common/quaternion.h" #include "common/quaternion.h"
#include "common/settings.h" #include "common/settings.h"
#include "core/frontend/input.h" #include "core/frontend/input.h"
#include "core/hle/kernel/object.h"
#include "core/hle/service/hid/controllers/controller_base.h" #include "core/hle/service/hid/controllers/controller_base.h"
namespace Kernel { namespace Kernel {
@ -198,7 +199,7 @@ public:
bool IsVibrationDeviceMounted(const DeviceHandle& vibration_device_handle) const; bool IsVibrationDeviceMounted(const DeviceHandle& vibration_device_handle) const;
Kernel::KReadableEvent& GetStyleSetChangedEvent(u32 npad_id); std::shared_ptr<Kernel::KReadableEvent> GetStyleSetChangedEvent(u32 npad_id) const;
void SignalStyleSetChangedEvent(u32 npad_id) const; void SignalStyleSetChangedEvent(u32 npad_id) const;
// Adds a new controller at an index. // Adds a new controller at an index.
@ -572,9 +573,8 @@ private:
NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual}; NpadHandheldActivationMode handheld_activation_mode{NpadHandheldActivationMode::Dual};
NpadCommunicationMode communication_mode{NpadCommunicationMode::Default}; NpadCommunicationMode communication_mode{NpadCommunicationMode::Default};
// Each controller should have their own styleset changed event // Each controller should have their own styleset changed event
std::array<Kernel::KEvent*, 10> styleset_changed_events{}; std::array<std::shared_ptr<Kernel::KEvent>, 10> styleset_changed_events;
std::array<std::array<std::chrono::steady_clock::time_point, 2>, 10> std::array<std::array<std::chrono::steady_clock::time_point, 2>, 10> last_vibration_timepoints;
last_vibration_timepoints{};
std::array<std::array<VibrationValue, 2>, 10> latest_vibration_values{}; std::array<std::array<VibrationValue, 2>, 10> latest_vibration_values{};
bool permit_vibration_session_enabled{false}; bool permit_vibration_session_enabled{false};
std::array<std::array<bool, 2>, 10> vibration_devices_mounted{}; std::array<std::array<bool, 2>, 10> vibration_devices_mounted{};

View file

@ -13,18 +13,18 @@
#include "core/frontend/input.h" #include "core/frontend/input.h"
#include "core/hardware_properties.h" #include "core/hardware_properties.h"
#include "core/hle/ipc_helpers.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_readable_event.h"
#include "core/hle/kernel/k_shared_memory.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/k_writable_event.h"
#include "core/hle/kernel/kernel.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/errors.h"
#include "core/hle/service/hid/hid.h" #include "core/hle/service/hid/hid.h"
#include "core/hle/service/hid/irs.h" #include "core/hle/service/hid/irs.h"
#include "core/hle/service/hid/xcd.h" #include "core/hle/service/hid/xcd.h"
#include "core/hle/service/service.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/console_sixaxis.h"
#include "core/hle/service/hid/controllers/controller_base.h" #include "core/hle/service/hid/controllers/controller_base.h"
@ -53,6 +53,9 @@ IAppletResource::IAppletResource(Core::System& system_)
}; };
RegisterHandlers(functions); RegisterHandlers(functions);
auto& kernel = system.Kernel();
shared_mem = SharedFrom(&kernel.GetHidSharedMem());
MakeController<Controller_DebugPad>(HidController::DebugPad); MakeController<Controller_DebugPad>(HidController::DebugPad);
MakeController<Controller_Touchscreen>(HidController::Touchscreen); MakeController<Controller_Touchscreen>(HidController::Touchscreen);
MakeController<Controller_Mouse>(HidController::Mouse); MakeController<Controller_Mouse>(HidController::Mouse);
@ -115,7 +118,7 @@ void IAppletResource::GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(&system.Kernel().GetHidSharedMem()); rb.PushCopyObjects(shared_mem);
} }
void IAppletResource::UpdateControllers(std::uintptr_t user_data, void IAppletResource::UpdateControllers(std::uintptr_t user_data,
@ -127,8 +130,7 @@ void IAppletResource::UpdateControllers(std::uintptr_t user_data,
if (should_reload) { if (should_reload) {
controller->OnLoadInputDevices(); controller->OnLoadInputDevices();
} }
controller->OnUpdate(core_timing, system.Kernel().GetHidSharedMem().GetPointer(), controller->OnUpdate(core_timing, shared_mem->GetPointer(), SHARED_MEMORY_SIZE);
SHARED_MEMORY_SIZE);
} }
// If ns_late is higher than the update rate ignore the delay // 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(); auto& core_timing = system.CoreTiming();
controllers[static_cast<size_t>(HidController::NPad)]->OnMotionUpdate( controllers[static_cast<size_t>(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 is higher than the update rate ignore the delay
if (ns_late > motion_update_ns) { 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_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"); ASSERT_MSG(t_mem_2_size == 0x7F000, "t_mem_2_size is not 0x7F000 bytes");
auto t_mem_1 = system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>( auto t_mem_1 =
t_mem_1_handle); system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(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); LOG_ERROR(Service_HID, "t_mem_1 is a nullptr for handle=0x{:08X}", t_mem_1_handle);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_UNKNOWN); rb.Push(RESULT_UNKNOWN);
return; return;
} }
auto t_mem_2 = system.CurrentProcess()->GetHandleTable().GetObject<Kernel::KTransferMemory>( auto t_mem_2 =
t_mem_2_handle); system.CurrentProcess()->GetHandleTable().Get<Kernel::TransferMemory>(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); LOG_ERROR(Service_HID, "t_mem_2 is a nullptr for handle=0x{:08X}", t_mem_2_handle);
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_UNKNOWN); rb.Push(RESULT_UNKNOWN);
@ -1522,7 +1524,7 @@ void Hid::InitializeSevenSixAxisSensor(Kernel::HLERequestContext& ctx) {
.ActivateController(); .ActivateController();
applet_resource->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor) applet_resource->GetController<Controller_ConsoleSixAxis>(HidController::ConsoleSixAxisSensor)
.SetTransferMemoryPointer(system.Memory().GetPointer(t_mem_1->GetSourceAddress())); .SetTransferMemoryPointer(t_mem_1->GetPointer());
LOG_WARNING(Service_HID, LOG_WARNING(Service_HID,
"called, t_mem_1_handle=0x{:08X}, t_mem_2_handle=0x{:08X}, " "called, t_mem_1_handle=0x{:08X}, t_mem_2_handle=0x{:08X}, "

View file

@ -13,6 +13,10 @@ namespace Core::Timing {
struct EventType; struct EventType;
} }
namespace Kernel {
class KSharedMemory;
}
namespace Service::SM { namespace Service::SM {
class ServiceManager; class ServiceManager;
} }
@ -65,6 +69,8 @@ private:
void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late); void UpdateControllers(std::uintptr_t user_data, std::chrono::nanoseconds ns_late);
void UpdateMotion(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<Kernel::KSharedMemory> shared_mem;
std::shared_ptr<Core::Timing::EventType> pad_update_event; std::shared_ptr<Core::Timing::EventType> pad_update_event;
std::shared_ptr<Core::Timing::EventType> motion_update_event; std::shared_ptr<Core::Timing::EventType> motion_update_event;

View file

@ -37,6 +37,10 @@ IRS::IRS(Core::System& system_) : ServiceFramework{system_, "irs"} {
// clang-format on // clang-format on
RegisterHandlers(functions); RegisterHandlers(functions);
auto& kernel = system.Kernel();
shared_mem = SharedFrom(&kernel.GetIrsSharedMem());
} }
void IRS::ActivateIrsensor(Kernel::HLERequestContext& ctx) { void IRS::ActivateIrsensor(Kernel::HLERequestContext& ctx) {
@ -58,7 +62,7 @@ void IRS::GetIrsensorSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(&system.Kernel().GetIrsSharedMem()); rb.PushCopyObjects(shared_mem);
} }
void IRS::StopImageProcessor(Kernel::HLERequestContext& ctx) { void IRS::StopImageProcessor(Kernel::HLERequestContext& ctx) {

View file

@ -4,12 +4,17 @@
#pragma once #pragma once
#include "core/hle/kernel/object.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Core { namespace Core {
class System; class System;
} }
namespace Kernel {
class KSharedMemory;
}
namespace Service::HID { namespace Service::HID {
class IRS final : public ServiceFramework<IRS> { class IRS final : public ServiceFramework<IRS> {
@ -37,6 +42,7 @@ private:
void StopImageProcessorAsync(Kernel::HLERequestContext& ctx); void StopImageProcessorAsync(Kernel::HLERequestContext& ctx);
void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx); void ActivateIrsensorWithFunctionLevel(Kernel::HLERequestContext& ctx);
std::shared_ptr<Kernel::KSharedMemory> shared_mem;
const u32 device_handle{0xABCD}; const u32 device_handle{0xABCD};
}; };

View file

@ -12,8 +12,8 @@
#include "core/core.h" #include "core/core.h"
#include "core/hle/ipc_helpers.h" #include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/k_page_table.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/k_system_control.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/svc_results.h"
#include "core/hle/service/ldr/ldr.h" #include "core/hle/service/ldr/ldr.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
@ -321,7 +321,7 @@ public:
return addr; return addr;
} }
ResultVal<VAddr> MapProcessCodeMemory(Kernel::KProcess* process, VAddr baseAddress, ResultVal<VAddr> MapProcessCodeMemory(Kernel::Process* process, VAddr baseAddress,
u64 size) const { u64 size) const {
for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) { for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) {
auto& page_table{process->PageTable()}; auto& page_table{process->PageTable()};
@ -342,7 +342,7 @@ public:
return ERROR_INSUFFICIENT_ADDRESS_SPACE; return ERROR_INSUFFICIENT_ADDRESS_SPACE;
} }
ResultVal<VAddr> MapNro(Kernel::KProcess* process, VAddr nro_addr, std::size_t nro_size, ResultVal<VAddr> 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 { VAddr bss_addr, std::size_t bss_size, std::size_t size) const {
for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) { for (std::size_t retry = 0; retry < MAXIMUM_MAP_RETRIES; retry++) {
auto& page_table{process->PageTable()}; auto& page_table{process->PageTable()};
@ -378,7 +378,7 @@ public:
return ERROR_INSUFFICIENT_ADDRESS_SPACE; 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 { VAddr start) const {
const VAddr text_start{start + nro_header.segment_headers[TEXT_INDEX].memory_offset}; 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}; const VAddr ro_start{start + nro_header.segment_headers[RO_INDEX].memory_offset};

View file

@ -4,6 +4,7 @@
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/hle/ipc_helpers.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/mm/mm_u.h"
#include "core/hle/service/sm/sm.h" #include "core/hle/service/sm/sm.h"

View file

@ -8,6 +8,7 @@
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/core.h" #include "core/core.h"
#include "core/hle/ipc_helpers.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_readable_event.h"
#include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/k_writable_event.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> module_, Core::System& system_, Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& system_,
const char* name) const char* name)
: ServiceFramework{system_, name}, nfc_tag_load{system.Kernel()}, module{std::move(module_)} { : ServiceFramework{system_, name}, module{std::move(module_)} {
Kernel::KAutoObject::Create(std::addressof(nfc_tag_load)); auto& kernel = system.Kernel();
nfc_tag_load.Initialize("IUser:NFCTagDetected"); nfc_tag_load = Kernel::KEvent::Create(kernel, "IUser:NFCTagDetected");
nfc_tag_load->Initialize();
} }
Module::Interface::~Interface() = default; Module::Interface::~Interface() = default;
@ -33,8 +35,7 @@ Module::Interface::~Interface() = default;
class IUser final : public ServiceFramework<IUser> { class IUser final : public ServiceFramework<IUser> {
public: public:
explicit IUser(Module::Interface& nfp_interface_, Core::System& system_) explicit IUser(Module::Interface& nfp_interface_, Core::System& system_)
: ServiceFramework{system_, "NFP::IUser"}, nfp_interface{nfp_interface_}, : ServiceFramework{system_, "NFP::IUser"}, nfp_interface{nfp_interface_} {
deactivate_event{system.Kernel()}, availability_change_event{system.Kernel()} {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IUser::Initialize, "Initialize"}, {0, &IUser::Initialize, "Initialize"},
{1, &IUser::Finalize, "Finalize"}, {1, &IUser::Finalize, "Finalize"},
@ -64,11 +65,11 @@ public:
}; };
RegisterHandlers(functions); RegisterHandlers(functions);
Kernel::KAutoObject::Create(std::addressof(deactivate_event)); auto& kernel = system.Kernel();
Kernel::KAutoObject::Create(std::addressof(availability_change_event)); deactivate_event = Kernel::KEvent::Create(kernel, "IUser:DeactivateEvent");
deactivate_event->Initialize();
deactivate_event.Initialize("IUser:DeactivateEvent"); availability_change_event = Kernel::KEvent::Create(kernel, "IUser:AvailabilityChangeEvent");
availability_change_event.Initialize("IUser:AvailabilityChangeEvent"); availability_change_event->Initialize();
} }
private: private:
@ -166,7 +167,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(deactivate_event.GetReadableEvent()); rb.PushCopyObjects(deactivate_event->GetReadableEvent());
} }
void StopDetection(Kernel::HLERequestContext& ctx) { void StopDetection(Kernel::HLERequestContext& ctx) {
@ -175,7 +176,7 @@ private:
switch (device_state) { switch (device_state) {
case DeviceState::TagFound: case DeviceState::TagFound:
case DeviceState::TagNearby: case DeviceState::TagNearby:
deactivate_event.GetWritableEvent().Signal(); deactivate_event->GetWritableEvent()->Signal();
device_state = DeviceState::Initialized; device_state = DeviceState::Initialized;
break; break;
case DeviceState::SearchingForTag: case DeviceState::SearchingForTag:
@ -264,7 +265,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(availability_change_event.GetReadableEvent()); rb.PushCopyObjects(availability_change_event->GetReadableEvent());
} }
void GetRegisterInfo(Kernel::HLERequestContext& ctx) { void GetRegisterInfo(Kernel::HLERequestContext& ctx) {
@ -318,9 +319,9 @@ private:
const u32 npad_id{0}; // Player 1 controller const u32 npad_id{0}; // Player 1 controller
State state{State::NonInitialized}; State state{State::NonInitialized};
DeviceState device_state{DeviceState::Initialized}; DeviceState device_state{DeviceState::Initialized};
Module::Interface& nfp_interface; std::shared_ptr<Kernel::KEvent> deactivate_event;
Kernel::KEvent deactivate_event; std::shared_ptr<Kernel::KEvent> availability_change_event;
Kernel::KEvent availability_change_event; const Module::Interface& nfp_interface;
}; };
void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) { void Module::Interface::CreateUserInterface(Kernel::HLERequestContext& ctx) {
@ -338,12 +339,12 @@ bool Module::Interface::LoadAmiibo(const std::vector<u8>& buffer) {
} }
std::memcpy(&amiibo, buffer.data(), sizeof(amiibo)); std::memcpy(&amiibo, buffer.data(), sizeof(amiibo));
nfc_tag_load.GetWritableEvent().Signal(); nfc_tag_load->GetWritableEvent()->Signal();
return true; return true;
} }
Kernel::KReadableEvent& Module::Interface::GetNFCEvent() { const std::shared_ptr<Kernel::KReadableEvent>& Module::Interface::GetNFCEvent() const {
return nfc_tag_load.GetReadableEvent(); return nfc_tag_load->GetReadableEvent();
} }
const Module::Interface::AmiiboFile& Module::Interface::GetAmiiboBuffer() const { const Module::Interface::AmiiboFile& Module::Interface::GetAmiiboBuffer() const {

View file

@ -7,7 +7,6 @@
#include <array> #include <array>
#include <vector> #include <vector>
#include "core/hle/kernel/k_event.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
namespace Kernel { namespace Kernel {
@ -39,11 +38,11 @@ public:
void CreateUserInterface(Kernel::HLERequestContext& ctx); void CreateUserInterface(Kernel::HLERequestContext& ctx);
bool LoadAmiibo(const std::vector<u8>& buffer); bool LoadAmiibo(const std::vector<u8>& buffer);
Kernel::KReadableEvent& GetNFCEvent(); const std::shared_ptr<Kernel::KReadableEvent>& GetNFCEvent() const;
const AmiiboFile& GetAmiiboBuffer() const; const AmiiboFile& GetAmiiboBuffer() const;
private: private:
Kernel::KEvent nfc_tag_load; std::shared_ptr<Kernel::KEvent> nfc_tag_load;
AmiiboFile amiibo{}; AmiiboFile amiibo{};
protected: protected:

View file

@ -127,8 +127,7 @@ public:
class IRequest final : public ServiceFramework<IRequest> { class IRequest final : public ServiceFramework<IRequest> {
public: public:
explicit IRequest(Core::System& system_) explicit IRequest(Core::System& system_) : ServiceFramework{system_, "IRequest"} {
: ServiceFramework{system_, "IRequest"}, event1{system.Kernel()}, event2{system.Kernel()} {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IRequest::GetRequestState, "GetRequestState"}, {0, &IRequest::GetRequestState, "GetRequestState"},
{1, &IRequest::GetResult, "GetResult"}, {1, &IRequest::GetResult, "GetResult"},
@ -158,11 +157,12 @@ public:
}; };
RegisterHandlers(functions); RegisterHandlers(functions);
Kernel::KAutoObject::Create(std::addressof(event1)); auto& kernel = system.Kernel();
Kernel::KAutoObject::Create(std::addressof(event2));
event1.Initialize("IRequest:Event1"); event1 = Kernel::KEvent::Create(kernel, "IRequest:Event1");
event2.Initialize("IRequest:Event2"); event1->Initialize();
event2 = Kernel::KEvent::Create(kernel, "IRequest:Event2");
event2->Initialize();
} }
private: private:
@ -198,7 +198,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 2}; IPC::ResponseBuilder rb{ctx, 2, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(event1.GetReadableEvent(), event2.GetReadableEvent()); rb.PushCopyObjects(event1->GetReadableEvent(), event2->GetReadableEvent());
} }
void Cancel(Kernel::HLERequestContext& ctx) { void Cancel(Kernel::HLERequestContext& ctx) {
@ -229,7 +229,7 @@ private:
rb.Push<u32>(0); rb.Push<u32>(0);
} }
Kernel::KEvent event1, event2; std::shared_ptr<Kernel::KEvent> event1, event2;
}; };
class INetworkProfile final : public ServiceFramework<INetworkProfile> { class INetworkProfile final : public ServiceFramework<INetworkProfile> {

View file

@ -300,8 +300,7 @@ class IEnsureNetworkClockAvailabilityService final
: public ServiceFramework<IEnsureNetworkClockAvailabilityService> { : public ServiceFramework<IEnsureNetworkClockAvailabilityService> {
public: public:
explicit IEnsureNetworkClockAvailabilityService(Core::System& system_) explicit IEnsureNetworkClockAvailabilityService(Core::System& system_)
: ServiceFramework{system_, "IEnsureNetworkClockAvailabilityService"}, : ServiceFramework{system_, "IEnsureNetworkClockAvailabilityService"} {
finished_event{system.Kernel()} {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IEnsureNetworkClockAvailabilityService::StartTask, "StartTask"}, {0, &IEnsureNetworkClockAvailabilityService::StartTask, "StartTask"},
{1, &IEnsureNetworkClockAvailabilityService::GetFinishNotificationEvent, {1, &IEnsureNetworkClockAvailabilityService::GetFinishNotificationEvent,
@ -313,17 +312,19 @@ public:
}; };
RegisterHandlers(functions); RegisterHandlers(functions);
Kernel::KAutoObject::Create(std::addressof(finished_event)); auto& kernel = system.Kernel();
finished_event.Initialize("IEnsureNetworkClockAvailabilityService:FinishEvent"); finished_event =
Kernel::KEvent::Create(kernel, "IEnsureNetworkClockAvailabilityService:FinishEvent");
finished_event->Initialize();
} }
private: private:
Kernel::KEvent finished_event; std::shared_ptr<Kernel::KEvent> finished_event;
void StartTask(Kernel::HLERequestContext& ctx) { void StartTask(Kernel::HLERequestContext& ctx) {
// No need to connect to the internet, just finish the task straight away. // No need to connect to the internet, just finish the task straight away.
LOG_DEBUG(Service_NIM, "called"); LOG_DEBUG(Service_NIM, "called");
finished_event.GetWritableEvent().Signal(); finished_event->GetWritableEvent()->Signal();
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }
@ -333,7 +334,7 @@ private:
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(finished_event.GetReadableEvent()); rb.PushCopyObjects(finished_event->GetReadableEvent());
} }
void GetResult(Kernel::HLERequestContext& ctx) { void GetResult(Kernel::HLERequestContext& ctx) {
@ -345,7 +346,7 @@ private:
void Cancel(Kernel::HLERequestContext& ctx) { void Cancel(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_NIM, "called"); LOG_DEBUG(Service_NIM, "called");
finished_event.GetWritableEvent().Clear(); finished_event->GetWritableEvent()->Clear();
IPC::ResponseBuilder rb{ctx, 2}; IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
} }

View file

@ -130,6 +130,9 @@ struct PL_U::Impl {
} }
} }
/// Handle to shared memory region designated for a shared font
std::shared_ptr<Kernel::KSharedMemory> shared_font_mem;
/// Backing memory for the shared font data /// Backing memory for the shared font data
std::shared_ptr<Kernel::PhysicalMemory> shared_font; std::shared_ptr<Kernel::PhysicalMemory> shared_font;
@ -257,13 +260,14 @@ void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) {
// Create shared font memory object // Create shared font memory object
auto& kernel = system.Kernel(); 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()); impl->shared_font->size());
IPC::ResponseBuilder rb{ctx, 2, 1}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(&kernel.GetFontSharedMem()); rb.PushCopyObjects(impl->shared_font_mem);
} }
void PL_U::GetSharedFontInOrderOfPriority(Kernel::HLERequestContext& ctx) { void PL_U::GetSharedFontInOrderOfPriority(Kernel::HLERequestContext& ctx) {

View file

@ -102,20 +102,20 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
return NvResult::Success; return NvResult::Success;
} }
auto& event = events_interface.events[event_id]; auto event = events_interface.events[event_id];
auto& gpu = system.GPU(); auto& gpu = system.GPU();
// This is mostly to take into account unimplemented features. As synced // This is mostly to take into account unimplemented features. As synced
// gpu is always synced. // gpu is always synced.
if (!gpu.IsAsync()) { if (!gpu.IsAsync()) {
event.event->GetWritableEvent().Signal(); event.event->GetWritableEvent()->Signal();
return NvResult::Success; return NvResult::Success;
} }
auto lock = gpu.LockSync(); auto lock = gpu.LockSync();
const u32 current_syncpoint_value = event.fence.value; const u32 current_syncpoint_value = event.fence.value;
const s32 diff = current_syncpoint_value - params.threshold; const s32 diff = current_syncpoint_value - params.threshold;
if (diff >= 0) { if (diff >= 0) {
event.event->GetWritableEvent().Signal(); event.event->GetWritableEvent()->Signal();
params.value = current_syncpoint_value; params.value = current_syncpoint_value;
std::memcpy(output.data(), &params, sizeof(params)); std::memcpy(output.data(), &params, sizeof(params));
return NvResult::Success; return NvResult::Success;
@ -142,7 +142,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000; params.value = ((params.syncpt_id & 0xfff) << 16) | 0x10000000;
} }
params.value |= event_id; params.value |= event_id;
event.event->GetWritableEvent().Clear(); event.event->GetWritableEvent()->Clear();
gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value); gpu.RegisterSyncptInterrupt(params.syncpt_id, target_value);
std::memcpy(output.data(), &params, sizeof(params)); std::memcpy(output.data(), &params, sizeof(params));
return NvResult::Timeout; return NvResult::Timeout;

View file

@ -187,8 +187,8 @@ void NVDRV::QueryEvent(Kernel::HLERequestContext& ctx) {
if (event_id < MaxNvEvents) { if (event_id < MaxNvEvents) {
IPC::ResponseBuilder rb{ctx, 3, 1}; IPC::ResponseBuilder rb{ctx, 3, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
auto& event = nvdrv->GetEvent(event_id); auto event = nvdrv->GetEvent(event_id);
event.Clear(); event->Clear();
rb.PushCopyObjects(event); rb.PushCopyObjects(event);
rb.PushEnum(NvResult::Success); rb.PushEnum(NvResult::Success);
} else { } else {

View file

@ -42,8 +42,9 @@ void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger
Module::Module(Core::System& system) : syncpoint_manager{system.GPU()} { Module::Module(Core::System& system) : syncpoint_manager{system.GPU()} {
auto& kernel = system.Kernel(); auto& kernel = system.Kernel();
for (u32 i = 0; i < MaxNvEvents; i++) { for (u32 i = 0; i < MaxNvEvents; i++) {
events_interface.events[i].event = Kernel::KEvent::Create(kernel); std::string event_label = fmt::format("NVDRV::NvEvent_{}", i);
events_interface.events[i].event->Initialize(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.status[i] = EventState::Free;
events_interface.registered[i] = false; events_interface.registered[i] = false;
} }
@ -63,12 +64,7 @@ Module::Module(Core::System& system) : syncpoint_manager{system.GPU()} {
std::make_shared<Devices::nvhost_vic>(system, nvmap_dev, syncpoint_manager); std::make_shared<Devices::nvhost_vic>(system, nvmap_dev, syncpoint_manager);
} }
Module::~Module() { Module::~Module() = default;
for (u32 i = 0; i < MaxNvEvents; i++) {
events_interface.events[i].event->Close();
events_interface.events[i].event = nullptr;
}
}
NvResult Module::VerifyFD(DeviceFD fd) const { NvResult Module::VerifyFD(DeviceFD fd) const {
if (fd < 0) { 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 && if (events_interface.assigned_syncpt[i] == syncpoint_id &&
events_interface.assigned_value[i] == value) { events_interface.assigned_value[i] == value) {
events_interface.LiberateEvent(i); 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<Kernel::KReadableEvent> Module::GetEvent(const u32 event_id) const {
return events_interface.events[event_id].event->GetReadableEvent(); return events_interface.events[event_id].event->GetReadableEvent();
} }
Kernel::KWritableEvent& Module::GetEventWriteable(const u32 event_id) { std::shared_ptr<Kernel::KWritableEvent> Module::GetEventWriteable(const u32 event_id) const {
return events_interface.events[event_id].event->GetWritableEvent(); return events_interface.events[event_id].event->GetWritableEvent();
} }

View file

@ -35,7 +35,7 @@ class nvdevice;
/// Represents an Nvidia event /// Represents an Nvidia event
struct NvEvent { struct NvEvent {
Kernel::KEvent* event{}; std::shared_ptr<Kernel::KEvent> event;
Fence fence{}; Fence fence{};
}; };
@ -136,9 +136,9 @@ public:
void SignalSyncpt(const u32 syncpoint_id, const u32 value); void SignalSyncpt(const u32 syncpoint_id, const u32 value);
Kernel::KReadableEvent& GetEvent(u32 event_id); std::shared_ptr<Kernel::KReadableEvent> GetEvent(u32 event_id) const;
Kernel::KWritableEvent& GetEventWriteable(u32 event_id); std::shared_ptr<Kernel::KWritableEvent> GetEventWriteable(u32 event_id) const;
private: private:
/// Manages syncpoints on the host /// Manages syncpoints on the host

View file

@ -7,6 +7,7 @@
#include "common/assert.h" #include "common/assert.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/core.h" #include "core/core.h"
#include "core/hle/kernel/k_event.h"
#include "core/hle/kernel/k_writable_event.h" #include "core/hle/kernel/k_writable_event.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/service/nvflinger/buffer_queue.h" #include "core/hle/service/nvflinger/buffer_queue.h"
@ -14,9 +15,9 @@
namespace Service::NVFlinger { namespace Service::NVFlinger {
BufferQueue::BufferQueue(Kernel::KernelCore& kernel, u32 id, u64 layer_id) BufferQueue::BufferQueue(Kernel::KernelCore& kernel, u32 id, u64 layer_id)
: id(id), layer_id(layer_id), buffer_wait_event{kernel} { : id(id), layer_id(layer_id) {
Kernel::KAutoObject::Create(std::addressof(buffer_wait_event)); buffer_wait_event = Kernel::KEvent::Create(kernel, "BufferQueue:WaitEvent");
buffer_wait_event.Initialize("BufferQueue:WaitEvent"); buffer_wait_event->Initialize();
} }
BufferQueue::~BufferQueue() = default; BufferQueue::~BufferQueue() = default;
@ -41,7 +42,7 @@ void BufferQueue::SetPreallocatedBuffer(u32 slot, const IGBPBuffer& igbp_buffer)
.multi_fence = {}, .multi_fence = {},
}; };
buffer_wait_event.GetWritableEvent().Signal(); buffer_wait_event->GetWritableEvent()->Signal();
} }
std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::DequeueBuffer(u32 width, std::optional<std::pair<u32, Service::Nvidia::MultiFence*>> BufferQueue::DequeueBuffer(u32 width,
@ -119,7 +120,7 @@ void BufferQueue::CancelBuffer(u32 slot, const Service::Nvidia::MultiFence& mult
} }
free_buffers_condition.notify_one(); free_buffers_condition.notify_one();
buffer_wait_event.GetWritableEvent().Signal(); buffer_wait_event->GetWritableEvent()->Signal();
} }
std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() { std::optional<std::reference_wrapper<const BufferQueue::Buffer>> BufferQueue::AcquireBuffer() {
@ -154,7 +155,7 @@ void BufferQueue::ReleaseBuffer(u32 slot) {
} }
free_buffers_condition.notify_one(); free_buffers_condition.notify_one();
buffer_wait_event.GetWritableEvent().Signal(); buffer_wait_event->GetWritableEvent()->Signal();
} }
void BufferQueue::Connect() { void BufferQueue::Connect() {
@ -169,7 +170,7 @@ void BufferQueue::Disconnect() {
std::unique_lock lock{queue_sequence_mutex}; std::unique_lock lock{queue_sequence_mutex};
queue_sequence.clear(); queue_sequence.clear();
} }
buffer_wait_event.GetWritableEvent().Signal(); buffer_wait_event->GetWritableEvent()->Signal();
is_connect = false; is_connect = false;
free_buffers_condition.notify_one(); free_buffers_condition.notify_one();
} }
@ -188,12 +189,12 @@ u32 BufferQueue::Query(QueryType type) {
return 0; return 0;
} }
Kernel::KWritableEvent& BufferQueue::GetWritableBufferWaitEvent() { std::shared_ptr<Kernel::KWritableEvent> BufferQueue::GetWritableBufferWaitEvent() const {
return buffer_wait_event.GetWritableEvent(); return buffer_wait_event->GetWritableEvent();
} }
Kernel::KReadableEvent& BufferQueue::GetBufferWaitEvent() { std::shared_ptr<Kernel::KReadableEvent> BufferQueue::GetBufferWaitEvent() const {
return buffer_wait_event.GetReadableEvent(); return buffer_wait_event->GetReadableEvent();
} }
} // namespace Service::NVFlinger } // namespace Service::NVFlinger

View file

@ -13,8 +13,7 @@
#include "common/common_funcs.h" #include "common/common_funcs.h"
#include "common/math_util.h" #include "common/math_util.h"
#include "common/swap.h" #include "common/swap.h"
#include "core/hle/kernel/k_event.h" #include "core/hle/kernel/object.h"
#include "core/hle/kernel/k_readable_event.h"
#include "core/hle/service/nvdrv/nvdata.h" #include "core/hle/service/nvdrv/nvdata.h"
namespace Kernel { namespace Kernel {
@ -116,9 +115,9 @@ public:
return is_connect; return is_connect;
} }
Kernel::KWritableEvent& GetWritableBufferWaitEvent(); std::shared_ptr<Kernel::KWritableEvent> GetWritableBufferWaitEvent() const;
Kernel::KReadableEvent& GetBufferWaitEvent(); std::shared_ptr<Kernel::KReadableEvent> GetBufferWaitEvent() const;
private: private:
BufferQueue(const BufferQueue&) = delete; BufferQueue(const BufferQueue&) = delete;
@ -130,7 +129,7 @@ private:
std::list<u32> free_buffers; std::list<u32> free_buffers;
std::array<Buffer, buffer_slots> buffers; std::array<Buffer, buffer_slots> buffers;
std::list<u32> queue_sequence; std::list<u32> queue_sequence;
Kernel::KEvent buffer_wait_event; std::shared_ptr<Kernel::KEvent> buffer_wait_event;
std::mutex free_buffers_mutex; std::mutex free_buffers_mutex;
std::condition_variable free_buffers_condition; std::condition_variable free_buffers_condition;

View file

@ -165,7 +165,7 @@ std::optional<u32> NVFlinger::FindBufferQueueId(u64 display_id, u64 layer_id) co
return layer->GetBufferQueue().GetId(); return layer->GetBufferQueue().GetId();
} }
Kernel::KReadableEvent* NVFlinger::FindVsyncEvent(u64 display_id) { std::shared_ptr<Kernel::KReadableEvent> NVFlinger::FindVsyncEvent(u64 display_id) const {
const auto lock_guard = Lock(); const auto lock_guard = Lock();
auto* const display = FindDisplay(display_id); auto* const display = FindDisplay(display_id);
@ -173,7 +173,7 @@ Kernel::KReadableEvent* NVFlinger::FindVsyncEvent(u64 display_id) {
return nullptr; return nullptr;
} }
return &display->GetVSyncEvent(); return display->GetVSyncEvent();
} }
BufferQueue* NVFlinger::FindBufferQueue(u32 id) { BufferQueue* NVFlinger::FindBufferQueue(u32 id) {

View file

@ -5,7 +5,6 @@
#pragma once #pragma once
#include <atomic> #include <atomic>
#include <list>
#include <memory> #include <memory>
#include <mutex> #include <mutex>
#include <optional> #include <optional>
@ -15,6 +14,7 @@
#include <vector> #include <vector>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/kernel/object.h"
namespace Common { namespace Common {
class Event; class Event;
@ -72,7 +72,7 @@ public:
/// Gets the vsync event for the specified display. /// Gets the vsync event for the specified display.
/// ///
/// If an invalid display ID is provided, then nullptr is returned. /// If an invalid display ID is provided, then nullptr is returned.
[[nodiscard]] Kernel::KReadableEvent* FindVsyncEvent(u64 display_id); [[nodiscard]] std::shared_ptr<Kernel::KReadableEvent> FindVsyncEvent(u64 display_id) const;
/// Obtains a buffer queue identified by the ID. /// Obtains a buffer queue identified by the ID.
[[nodiscard]] BufferQueue* FindBufferQueue(u32 id); [[nodiscard]] BufferQueue* FindBufferQueue(u32 id);
@ -106,7 +106,7 @@ private:
std::shared_ptr<Nvidia::Module> nvdrv; std::shared_ptr<Nvidia::Module> nvdrv;
std::list<VI::Display> displays; std::vector<VI::Display> displays;
std::vector<std::unique_ptr<BufferQueue>> buffer_queues; std::vector<std::unique_ptr<BufferQueue>> buffer_queues;
/// Id to use for the next layer that is created, this counter is shared among all displays. /// Id to use for the next layer that is created, this counter is shared among all displays.

View file

@ -7,7 +7,7 @@
#include "core/file_sys/control_metadata.h" #include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h" #include "core/file_sys/patch_manager.h"
#include "core/hle/ipc_helpers.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/module.h"
#include "core/hle/service/pctl/pctl.h" #include "core/hle/service/pctl/pctl.h"

View file

@ -4,8 +4,8 @@
#include "core/core.h" #include "core/core.h"
#include "core/hle/ipc_helpers.h" #include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/k_process.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/process.h"
#include "core/hle/service/pm/pm.h" #include "core/hle/service/pm/pm.h"
#include "core/hle/service/service.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}; constexpr u64 NO_PROCESS_FOUND_PID{0};
std::optional<Kernel::KProcess*> SearchProcessList( std::optional<std::shared_ptr<Kernel::Process>> SearchProcessList(
const std::vector<Kernel::KProcess*>& process_list, const std::vector<std::shared_ptr<Kernel::Process>>& process_list,
std::function<bool(Kernel::KProcess*)> predicate) { std::function<bool(const std::shared_ptr<Kernel::Process>&)> predicate) {
const auto iter = std::find_if(process_list.begin(), process_list.end(), predicate); const auto iter = std::find_if(process_list.begin(), process_list.end(), predicate);
if (iter == process_list.end()) { if (iter == process_list.end()) {
@ -30,9 +30,9 @@ std::optional<Kernel::KProcess*> SearchProcessList(
} }
void GetApplicationPidGeneric(Kernel::HLERequestContext& ctx, void GetApplicationPidGeneric(Kernel::HLERequestContext& ctx,
const std::vector<Kernel::KProcess*>& process_list) { const std::vector<std::shared_ptr<Kernel::Process>>& process_list) {
const auto process = SearchProcessList(process_list, [](const auto& process) { 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}; IPC::ResponseBuilder rb{ctx, 4};
@ -125,7 +125,8 @@ private:
class Info final : public ServiceFramework<Info> { class Info final : public ServiceFramework<Info> {
public: public:
explicit Info(Core::System& system_, const std::vector<Kernel::KProcess*>& process_list_) explicit Info(Core::System& system_,
const std::vector<std::shared_ptr<Kernel::Process>>& process_list_)
: ServiceFramework{system_, "pm:info"}, process_list{process_list_} { : ServiceFramework{system_, "pm:info"}, process_list{process_list_} {
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &Info::GetTitleId, "GetTitleId"}, {0, &Info::GetTitleId, "GetTitleId"},
@ -155,7 +156,7 @@ private:
rb.Push((*process)->GetTitleID()); rb.Push((*process)->GetTitleID());
} }
const std::vector<Kernel::KProcess*>& process_list; const std::vector<std::shared_ptr<Kernel::Process>>& process_list;
}; };
class Shell final : public ServiceFramework<Shell> { class Shell final : public ServiceFramework<Shell> {

View file

@ -6,7 +6,7 @@
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/core.h" #include "core/core.h"
#include "core/hle/ipc_helpers.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/acc/profile_manager.h"
#include "core/hle/service/prepo/prepo.h" #include "core/hle/service/prepo/prepo.h"
#include "core/hle/service/service.h" #include "core/hle/service/service.h"
@ -60,7 +60,7 @@ private:
const auto process_id = rp.PopRaw<u64>(); const auto process_id = rp.PopRaw<u64>();
const auto data1 = ctx.ReadBuffer(0); const auto data1 = ctx.ReadBuffer(0);
const auto data2 = [&ctx] { const auto data2 = [ctx] {
if (ctx.CanReadBuffer(1)) { if (ctx.CanReadBuffer(1)) {
return ctx.ReadBuffer(1); return ctx.ReadBuffer(1);
} }
@ -87,7 +87,7 @@ private:
const auto process_id = rp.PopRaw<u64>(); const auto process_id = rp.PopRaw<u64>();
const auto data1 = ctx.ReadBuffer(0); const auto data1 = ctx.ReadBuffer(0);
const auto data2 = [&ctx] { const auto data2 = [ctx] {
if (ctx.CanReadBuffer(1)) { if (ctx.CanReadBuffer(1)) {
return ctx.ReadBuffer(1); return ctx.ReadBuffer(1);
} }
@ -139,7 +139,7 @@ private:
const auto title_id = rp.PopRaw<u64>(); const auto title_id = rp.PopRaw<u64>();
const auto data1 = ctx.ReadBuffer(0); const auto data1 = ctx.ReadBuffer(0);
const auto data2 = [&ctx] { const auto data2 = [ctx] {
if (ctx.CanReadBuffer(1)) { if (ctx.CanReadBuffer(1)) {
return ctx.ReadBuffer(1); return ctx.ReadBuffer(1);
} }
@ -163,7 +163,7 @@ private:
const auto title_id = rp.PopRaw<u64>(); const auto title_id = rp.PopRaw<u64>();
const auto data1 = ctx.ReadBuffer(0); const auto data1 = ctx.ReadBuffer(0);
const auto data2 = [&ctx] { const auto data2 = [ctx] {
if (ctx.CanReadBuffer(1)) { if (ctx.CanReadBuffer(1)) {
return ctx.ReadBuffer(1); return ctx.ReadBuffer(1);
} }

View file

@ -19,8 +19,7 @@ namespace Service::PSM {
class IPsmSession final : public ServiceFramework<IPsmSession> { class IPsmSession final : public ServiceFramework<IPsmSession> {
public: public:
explicit IPsmSession(Core::System& system_) explicit IPsmSession(Core::System& system_) : ServiceFramework{system_, "IPsmSession"} {
: ServiceFramework{system_, "IPsmSession"}, state_change_event{system.Kernel()} {
// clang-format off // clang-format off
static const FunctionInfo functions[] = { static const FunctionInfo functions[] = {
{0, &IPsmSession::BindStateChangeEvent, "BindStateChangeEvent"}, {0, &IPsmSession::BindStateChangeEvent, "BindStateChangeEvent"},
@ -33,27 +32,28 @@ public:
RegisterHandlers(functions); RegisterHandlers(functions);
Kernel::KAutoObject::Create(std::addressof(state_change_event)); state_change_event =
state_change_event.Initialize("IPsmSession::state_change_event"); Kernel::KEvent::Create(system_.Kernel(), "IPsmSession::state_change_event");
state_change_event->Initialize();
} }
~IPsmSession() override = default; ~IPsmSession() override = default;
void SignalChargerTypeChanged() { void SignalChargerTypeChanged() {
if (should_signal && should_signal_charger_type) { if (should_signal && should_signal_charger_type) {
state_change_event.GetWritableEvent().Signal(); state_change_event->GetWritableEvent()->Signal();
} }
} }
void SignalPowerSupplyChanged() { void SignalPowerSupplyChanged() {
if (should_signal && should_signal_power_supply) { if (should_signal && should_signal_power_supply) {
state_change_event.GetWritableEvent().Signal(); state_change_event->GetWritableEvent()->Signal();
} }
} }
void SignalBatteryVoltageStateChanged() { void SignalBatteryVoltageStateChanged() {
if (should_signal && should_signal_battery_voltage) { 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}; IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(state_change_event.GetReadableEvent()); rb.PushCopyObjects(state_change_event->GetReadableEvent());
} }
void UnbindStateChangeEvent(Kernel::HLERequestContext& ctx) { void UnbindStateChangeEvent(Kernel::HLERequestContext& ctx) {
@ -114,7 +114,7 @@ private:
bool should_signal_power_supply{}; bool should_signal_power_supply{};
bool should_signal_battery_voltage{}; bool should_signal_battery_voltage{};
bool should_signal{}; bool should_signal{};
Kernel::KEvent state_change_event; std::shared_ptr<Kernel::KEvent> state_change_event;
}; };
class PSM final : public ServiceFramework<PSM> { class PSM final : public ServiceFramework<PSM> {

View file

@ -11,11 +11,11 @@
#include "core/core.h" #include "core/core.h"
#include "core/hle/ipc.h" #include "core/hle/ipc.h"
#include "core/hle/ipc_helpers.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/k_process.h"
#include "core/hle/kernel/k_server_port.h"
#include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/k_thread.h"
#include "core/hle/kernel/kernel.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/acc/acc.h"
#include "core/hle/service/am/am.h" #include "core/hle/service/am/am.h"
#include "core/hle/service/aoc/aoc_u.h" #include "core/hle/service/aoc/aoc_u.h"
@ -116,11 +116,10 @@ void ServiceFrameworkBase::InstallAsNamedPort(Kernel::KernelCore& kernel) {
ASSERT(!port_installed); ASSERT(!port_installed);
auto* port = Kernel::KPort::Create(kernel); auto [server_port, client_port] =
port->Initialize(max_sessions, false, service_name); Kernel::ServerPort::CreatePortPair(kernel, max_sessions, service_name);
port->GetServerPort().SetHleHandler(shared_from_this()); server_port->SetHleHandler(shared_from_this());
kernel.AddNamedPort(service_name, &port->GetClientPort()); kernel.AddNamedPort(service_name, std::move(client_port));
port_installed = true; port_installed = true;
} }

View file

@ -11,6 +11,7 @@
#include "common/common_types.h" #include "common/common_types.h"
#include "common/spin_lock.h" #include "common/spin_lock.h"
#include "core/hle/kernel/hle_ipc.h" #include "core/hle/kernel/hle_ipc.h"
#include "core/hle/kernel/object.h"
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Namespace Service // Namespace Service
@ -20,8 +21,11 @@ class System;
} }
namespace Kernel { namespace Kernel {
class ClientPort;
class ServerPort;
class ServerSession;
class HLERequestContext; class HLERequestContext;
} } // namespace Kernel
namespace Service { namespace Service {

View file

@ -7,7 +7,7 @@
#include "core/file_sys/errors.h" #include "core/file_sys/errors.h"
#include "core/file_sys/system_archive/system_version.h" #include "core/file_sys/system_archive/system_version.h"
#include "core/hle/ipc_helpers.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/filesystem/filesystem.h"
#include "core/hle/service/set/set_sys.h" #include "core/hle/service/set/set_sys.h"

View file

@ -5,16 +5,16 @@
#include "common/assert.h" #include "common/assert.h"
#include "common/logging/log.h" #include "common/logging/log.h"
#include "core/hle/ipc_helpers.h" #include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/k_client_session.h" #include "core/hle/kernel/client_session.h"
#include "core/hle/kernel/k_server_session.h" #include "core/hle/kernel/server_session.h"
#include "core/hle/kernel/k_session.h" #include "core/hle/kernel/session.h"
#include "core/hle/service/sm/controller.h" #include "core/hle/service/sm/controller.h"
namespace Service::SM { namespace Service::SM {
void Controller::ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx) { void Controller::ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx) {
ASSERT_MSG(ctx.Session()->IsSession(), "Session is already a domain"); 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(); ctx.Session()->ConvertToDomain();
IPC::ResponseBuilder rb{ctx, 3}; 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}; IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
rb.Push(RESULT_SUCCESS); rb.Push(RESULT_SUCCESS);
rb.PushMoveObjects(ctx.Session()->GetParent()->GetClientSession()); rb.PushMoveObjects(ctx.Session()->GetParent()->Client());
} }
void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) { void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) {

Some files were not shown because too many files have changed in this diff Show more