From 039844bbb9a7e955c3f01b53e1a87c1c0868bf17 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 2 Dec 2020 18:08:35 -0800 Subject: hle: kernel: Rewrite scheduler implementation based on Mesopshere. --- src/core/hle/kernel/server_session.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/hle/kernel/server_session.cpp') diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 8c19f25341..bf2c900280 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -14,9 +14,9 @@ #include "core/hle/kernel/client_session.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/hle_ipc.h" +#include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/process.h" -#include "core/hle/kernel/scheduler.h" #include "core/hle/kernel/server_session.h" #include "core/hle/kernel/session.h" #include "core/hle/kernel/thread.h" -- cgit v1.2.3 From de522657dd2516cf4a4222aa7392f1031aee98f3 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 3 Dec 2020 22:26:42 -0800 Subject: hle: kernel: Migrate to KScopedSchedulerLock. --- src/core/CMakeLists.txt | 1 + src/core/hle/kernel/address_arbiter.cpp | 10 +++---- src/core/hle/kernel/global_scheduler_context.h | 12 +++++++- src/core/hle/kernel/k_scheduler.cpp | 15 ++++------ src/core/hle/kernel/k_scheduler.h | 10 +++---- src/core/hle/kernel/k_scoped_lock.h | 39 ++++++++++++++++++++++++++ src/core/hle/kernel/kernel.cpp | 4 +-- src/core/hle/kernel/mutex.cpp | 6 ++-- src/core/hle/kernel/process.cpp | 8 +++--- src/core/hle/kernel/readable_event.cpp | 2 +- src/core/hle/kernel/server_session.cpp | 2 +- src/core/hle/kernel/svc.cpp | 8 +++--- src/core/hle/kernel/synchronization.cpp | 4 +-- src/core/hle/kernel/thread.cpp | 17 ++++++----- src/core/hle/kernel/time_manager.cpp | 2 +- 15 files changed, 92 insertions(+), 48 deletions(-) create mode 100644 src/core/hle/kernel/k_scoped_lock.h (limited to 'src/core/hle/kernel/server_session.cpp') diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 5f6dce52a7..eb1fbcb61b 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -159,6 +159,7 @@ add_library(core STATIC hle/kernel/k_scheduler.cpp hle/kernel/k_scheduler.h hle/kernel/k_scheduler_lock.h + hle/kernel/k_scoped_lock.h hle/kernel/k_scoped_scheduler_lock_and_sleep.h hle/kernel/kernel.cpp hle/kernel/kernel.h diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp index ac49131735..20ffa7d476 100644 --- a/src/core/hle/kernel/address_arbiter.cpp +++ b/src/core/hle/kernel/address_arbiter.cpp @@ -59,7 +59,7 @@ ResultCode AddressArbiter::SignalToAddress(VAddr address, SignalType type, s32 v } ResultCode AddressArbiter::SignalToAddressOnly(VAddr address, s32 num_to_wake) { - SchedulerLock lock(system.Kernel()); + KScopedSchedulerLock lock(system.Kernel()); const std::vector> waiting_threads = GetThreadsWaitingOnAddress(address); WakeThreads(waiting_threads, num_to_wake); @@ -68,7 +68,7 @@ ResultCode AddressArbiter::SignalToAddressOnly(VAddr address, s32 num_to_wake) { ResultCode AddressArbiter::IncrementAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake) { - SchedulerLock lock(system.Kernel()); + KScopedSchedulerLock lock(system.Kernel()); auto& memory = system.Memory(); // Ensure that we can write to the address. @@ -93,7 +93,7 @@ ResultCode AddressArbiter::IncrementAndSignalToAddressIfEqual(VAddr address, s32 ResultCode AddressArbiter::ModifyByWaitingCountAndSignalToAddressIfEqual(VAddr address, s32 value, s32 num_to_wake) { - SchedulerLock lock(system.Kernel()); + KScopedSchedulerLock lock(system.Kernel()); auto& memory = system.Memory(); // Ensure that we can write to the address. @@ -211,7 +211,7 @@ ResultCode AddressArbiter::WaitForAddressIfLessThan(VAddr address, s32 value, s6 } { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); if (current_thread->IsWaitingForArbitration()) { RemoveThread(SharedFrom(current_thread)); current_thread->WaitForArbitration(false); @@ -266,7 +266,7 @@ ResultCode AddressArbiter::WaitForAddressIfEqual(VAddr address, s32 value, s64 t } { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); if (current_thread->IsWaitingForArbitration()) { RemoveThread(SharedFrom(current_thread)); current_thread->WaitForArbitration(false); diff --git a/src/core/hle/kernel/global_scheduler_context.h b/src/core/hle/kernel/global_scheduler_context.h index 39c383746a..c4bc23eedd 100644 --- a/src/core/hle/kernel/global_scheduler_context.h +++ b/src/core/hle/kernel/global_scheduler_context.h @@ -27,6 +27,8 @@ class GlobalSchedulerContext final { friend class KScheduler; public: + using LockType = KAbstractSchedulerLock; + explicit GlobalSchedulerContext(KernelCore& kernel); ~GlobalSchedulerContext(); @@ -53,8 +55,16 @@ public: /// Returns true if the global scheduler lock is acquired bool IsLocked() const; + LockType& SchedulerLock() { + return scheduler_lock; + } + + const LockType& SchedulerLock() const { + return scheduler_lock; + } + private: - friend class SchedulerLock; + friend class KScopedSchedulerLock; friend class KScopedSchedulerLockAndSleep; KernelCore& kernel; diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index 4661474989..9645fee226 100644 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp @@ -410,7 +410,7 @@ void KScheduler::YieldWithoutCoreMigration() { /* Perform the yield. */ { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); const auto cur_state = cur_thread.scheduling_state; if (cur_state == static_cast(ThreadSchedStatus::Runnable)) { @@ -451,7 +451,7 @@ void KScheduler::YieldWithCoreMigration() { /* Perform the yield. */ { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); const auto cur_state = cur_thread.scheduling_state; if (cur_state == static_cast(ThreadSchedStatus::Runnable)) { @@ -541,7 +541,7 @@ void KScheduler::YieldToAnyThread() { /* Perform the yield. */ { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); const auto cur_state = cur_thread.scheduling_state; if (cur_state == static_cast(ThreadSchedStatus::Runnable)) { @@ -793,12 +793,9 @@ void KScheduler::Initialize() { } } -SchedulerLock::SchedulerLock(KernelCore& kernel) : kernel{kernel} { - kernel.GlobalSchedulerContext().Lock(); -} +KScopedSchedulerLock::KScopedSchedulerLock(KernelCore& kernel) + : KScopedLock(kernel.GlobalSchedulerContext().SchedulerLock()) {} -SchedulerLock::~SchedulerLock() { - kernel.GlobalSchedulerContext().Unlock(); -} +KScopedSchedulerLock::~KScopedSchedulerLock() = default; } // namespace Kernel diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h index 5ba0f3c323..d52ecc0db4 100644 --- a/src/core/hle/kernel/k_scheduler.h +++ b/src/core/hle/kernel/k_scheduler.h @@ -14,6 +14,7 @@ #include "core/hle/kernel/global_scheduler_context.h" #include "core/hle/kernel/k_priority_queue.h" #include "core/hle/kernel/k_scheduler_lock.h" +#include "core/hle/kernel/k_scoped_lock.h" namespace Common { class Fiber; @@ -198,13 +199,10 @@ private: Common::SpinLock guard{}; }; -class SchedulerLock { +class KScopedSchedulerLock : KScopedLock { public: - [[nodiscard]] explicit SchedulerLock(KernelCore& kernel); - ~SchedulerLock(); - -protected: - KernelCore& kernel; + explicit KScopedSchedulerLock(KernelCore& kernel); + ~KScopedSchedulerLock(); }; } // namespace Kernel diff --git a/src/core/hle/kernel/k_scoped_lock.h b/src/core/hle/kernel/k_scoped_lock.h new file mode 100644 index 0000000000..03320859fd --- /dev/null +++ b/src/core/hle/kernel/k_scoped_lock.h @@ -0,0 +1,39 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +// This file references various implementation details from Atmosphere, an open-source firmware for +// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. + +#pragma once + +#include "common/common_types.h" + +namespace Kernel { + +template +concept KLockable = !std::is_reference::value && requires(T & t) { + { t.Lock() } + ->std::same_as; + { t.Unlock() } + ->std::same_as; +}; + +template +requires KLockable class KScopedLock : NonCopyable { + +private: + T* lock_ptr; + +public: + explicit KScopedLock(T* l) : lock_ptr(l) { + this->lock_ptr->Lock(); + } + explicit KScopedLock(T& l) : KScopedLock(std::addressof(l)) { /* ... */ + } + ~KScopedLock() { + this->lock_ptr->Unlock(); + } +}; + +} // namespace Kernel diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index b74e34c40d..04cae3a433 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -146,7 +146,7 @@ struct KernelCore::Impl { preemption_event = Core::Timing::CreateEvent( "PreemptionCallback", [this, &kernel](std::uintptr_t, std::chrono::nanoseconds) { { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); global_scheduler_context->PreemptThreads(); } const auto time_interval = std::chrono::nanoseconds{ @@ -612,7 +612,7 @@ const Kernel::SharedMemory& KernelCore::GetTimeSharedMem() const { void KernelCore::Suspend(bool in_suspention) { const bool should_suspend = exception_exited || in_suspention; { - SchedulerLock lock(*this); + KScopedSchedulerLock lock(*this); ThreadStatus status = should_suspend ? ThreadStatus::Ready : ThreadStatus::WaitSleep; for (std::size_t i = 0; i < Core::Hardware::NUM_CPU_CORES; i++) { impl->suspend_threads[i]->SetStatus(status); diff --git a/src/core/hle/kernel/mutex.cpp b/src/core/hle/kernel/mutex.cpp index 6299b1342a..4f8075e0e9 100644 --- a/src/core/hle/kernel/mutex.cpp +++ b/src/core/hle/kernel/mutex.cpp @@ -75,7 +75,7 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle, std::shared_ptr current_thread = SharedFrom(kernel.CurrentScheduler()->GetCurrentThread()); { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); // The mutex address must be 4-byte aligned if ((address % sizeof(u32)) != 0) { return ERR_INVALID_ADDRESS; @@ -114,7 +114,7 @@ ResultCode Mutex::TryAcquire(VAddr address, Handle holding_thread_handle, } { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); auto* owner = current_thread->GetLockOwner(); if (owner != nullptr) { owner->RemoveMutexWaiter(current_thread); @@ -153,7 +153,7 @@ std::pair> Mutex::Unlock(std::shared_ptr current_thread = SharedFrom(kernel.CurrentScheduler()->GetCurrentThread()); diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 238c03a13f..b905b486a7 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -54,7 +54,7 @@ void SetupMainThread(Core::System& system, Process& owner_process, u32 priority, auto& kernel = system.Kernel(); // Threads by default are dormant, wake up the main thread so it runs when the scheduler fires { - SchedulerLock lock{kernel}; + KScopedSchedulerLock lock{kernel}; thread->SetStatus(ThreadStatus::Ready); } } @@ -213,7 +213,7 @@ void Process::UnregisterThread(const Thread* thread) { } ResultCode Process::ClearSignalState() { - SchedulerLock lock(system.Kernel()); + KScopedSchedulerLock lock(system.Kernel()); if (status == ProcessStatus::Exited) { LOG_ERROR(Kernel, "called on a terminated process instance."); return ERR_INVALID_STATE; @@ -347,7 +347,7 @@ static auto FindTLSPageWithAvailableSlots(std::vector& tls_pages) { } VAddr Process::CreateTLSRegion() { - SchedulerLock lock(system.Kernel()); + KScopedSchedulerLock lock(system.Kernel()); if (auto tls_page_iter{FindTLSPageWithAvailableSlots(tls_pages)}; tls_page_iter != tls_pages.cend()) { return *tls_page_iter->ReserveSlot(); @@ -378,7 +378,7 @@ VAddr Process::CreateTLSRegion() { } void Process::FreeTLSRegion(VAddr tls_address) { - SchedulerLock lock(system.Kernel()); + KScopedSchedulerLock lock(system.Kernel()); const VAddr aligned_address = Common::AlignDown(tls_address, Core::Memory::PAGE_SIZE); auto iter = std::find_if(tls_pages.begin(), tls_pages.end(), [aligned_address](const auto& page) { diff --git a/src/core/hle/kernel/readable_event.cpp b/src/core/hle/kernel/readable_event.cpp index 927f88fed9..cea262ce02 100644 --- a/src/core/hle/kernel/readable_event.cpp +++ b/src/core/hle/kernel/readable_event.cpp @@ -39,7 +39,7 @@ void ReadableEvent::Clear() { } ResultCode ReadableEvent::Reset() { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); if (!is_signaled) { LOG_TRACE(Kernel, "Handle is not signaled! object_id={}, object_type={}, object_name={}", GetObjectId(), GetTypeName(), GetName()); diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index bf2c900280..78e41b13ed 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -171,7 +171,7 @@ ResultCode ServerSession::CompleteSyncRequest() { // Some service requests require the thread to block { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); if (!context.IsThreadWaiting()) { context.GetThread().ResumeFromWait(); context.GetThread().SetSynchronizationResults(nullptr, result); diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 2760a307c4..30d60aeb62 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -345,7 +345,7 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) { auto thread = kernel.CurrentScheduler()->GetCurrentThread(); { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); thread->InvalidateHLECallback(); thread->SetStatus(ThreadStatus::WaitIPC); session->SendSyncRequest(SharedFrom(thread), system.Memory(), system.CoreTiming()); @@ -359,7 +359,7 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) { } { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); auto* sync_object = thread->GetHLESyncObject(); sync_object->RemoveWaitingThread(SharedFrom(thread)); } @@ -1691,7 +1691,7 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add } { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); auto* owner = current_thread->GetLockOwner(); if (owner != nullptr) { @@ -1724,7 +1724,7 @@ static void SignalProcessWideKey(Core::System& system, VAddr condition_variable_ // Retrieve a list of all threads that are waiting for this condition variable. auto& kernel = system.Kernel(); - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); auto* const current_process = kernel.CurrentProcess(); std::vector> waiting_threads = current_process->GetConditionVariableThreads(condition_variable_addr); diff --git a/src/core/hle/kernel/synchronization.cpp b/src/core/hle/kernel/synchronization.cpp index 6651ad90cd..d3f520ea2d 100644 --- a/src/core/hle/kernel/synchronization.cpp +++ b/src/core/hle/kernel/synchronization.cpp @@ -19,7 +19,7 @@ Synchronization::Synchronization(Core::System& system) : system{system} {} void Synchronization::SignalObject(SynchronizationObject& obj) const { auto& kernel = system.Kernel(); - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); if (obj.IsSignaled()) { for (auto thread : obj.GetWaitingThreads()) { if (thread->GetSchedulingStatus() == ThreadSchedStatus::Paused) { @@ -90,7 +90,7 @@ std::pair Synchronization::WaitFor( } { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); ResultCode signaling_result = thread->GetSignalingResult(); SynchronizationObject* signaling_object = thread->GetSignalingObject(); thread->SetSynchronizationObjects(nullptr); diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp index 6f89238caa..a4f9e0d97a 100644 --- a/src/core/hle/kernel/thread.cpp +++ b/src/core/hle/kernel/thread.cpp @@ -51,7 +51,7 @@ Thread::~Thread() = default; void Thread::Stop() { { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); SetStatus(ThreadStatus::Dead); Signal(); kernel.GlobalHandleTable().Close(global_handle); @@ -68,7 +68,7 @@ void Thread::Stop() { } void Thread::ResumeFromWait() { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); switch (status) { case ThreadStatus::Paused: case ThreadStatus::WaitSynch: @@ -100,19 +100,18 @@ void Thread::ResumeFromWait() { } void Thread::OnWakeUp() { - SchedulerLock lock(kernel); - + KScopedSchedulerLock lock(kernel); SetStatus(ThreadStatus::Ready); } ResultCode Thread::Start() { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); SetStatus(ThreadStatus::Ready); return RESULT_SUCCESS; } void Thread::CancelWait() { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); if (GetSchedulingStatus() != ThreadSchedStatus::Paused || !is_waiting_on_sync) { is_sync_cancelled = true; return; @@ -228,7 +227,7 @@ ResultVal> Thread::Create(Core::System& system, ThreadTy } void Thread::SetPriority(u32 priority) { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); ASSERT_MSG(priority <= THREADPRIO_LOWEST && priority >= THREADPRIO_HIGHEST, "Invalid priority value."); nominal_priority = priority; @@ -365,7 +364,7 @@ bool Thread::InvokeHLECallback(std::shared_ptr thread) { } ResultCode Thread::SetActivity(ThreadActivity value) { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); auto sched_status = GetSchedulingStatus(); @@ -435,7 +434,7 @@ void Thread::SetCurrentPriority(u32 new_priority) { } ResultCode Thread::SetCoreAndAffinityMask(s32 new_core, u64 new_affinity_mask) { - SchedulerLock lock(kernel); + KScopedSchedulerLock lock(kernel); const auto HighestSetCore = [](u64 mask, u32 max_cores) { for (s32 core = static_cast(max_cores - 1); core >= 0; core--) { if (((mask >> core) & 1) != 0) { diff --git a/src/core/hle/kernel/time_manager.cpp b/src/core/hle/kernel/time_manager.cpp index 8e47696946..aea53cdb0a 100644 --- a/src/core/hle/kernel/time_manager.cpp +++ b/src/core/hle/kernel/time_manager.cpp @@ -18,7 +18,7 @@ TimeManager::TimeManager(Core::System& system_) : system{system_} { time_manager_event_type = Core::Timing::CreateEvent( "Kernel::TimeManagerCallback", [this](std::uintptr_t thread_handle, std::chrono::nanoseconds) { - const SchedulerLock lock(system.Kernel()); + const KScopedSchedulerLock lock(system.Kernel()); const auto proper_handle = static_cast(thread_handle); if (cancelled_events[proper_handle]) { return; -- cgit v1.2.3 From 8f135703dc018fffb9003e92cf64414a9f202f6c Mon Sep 17 00:00:00 2001 From: Lioncash Date: Mon, 7 Dec 2020 22:00:34 -0500 Subject: core: Remove unnecessary enum casts in log calls Follows the video core PR. fmt doesn't require casts for enum classes anymore, so we can remove quite a few casts. --- src/core/core.cpp | 5 ++-- src/core/file_sys/content_archive.cpp | 19 ++++++++------ src/core/frontend/applets/error.cpp | 7 +++--- src/core/hle/kernel/process_capability.cpp | 2 +- src/core/hle/kernel/resource_limit.cpp | 4 +-- src/core/hle/kernel/server_session.cpp | 3 +-- src/core/hle/service/am/am.cpp | 12 ++++----- src/core/hle/service/am/applets/error.cpp | 4 +-- .../hle/service/am/applets/general_backend.cpp | 4 +-- src/core/hle/service/apm/controller.cpp | 3 +-- src/core/hle/service/apm/interface.cpp | 7 +++--- src/core/hle/service/fatal/fatal.cpp | 5 ++-- src/core/hle/service/filesystem/filesystem.cpp | 16 ++++++------ src/core/hle/service/filesystem/fsp_srv.cpp | 29 ++++++++++------------ src/core/hle/service/friend/friend.cpp | 3 +-- src/core/hle/service/lm/lm.cpp | 2 +- src/core/hle/service/ns/pl_u.cpp | 9 +++---- src/core/hle/service/nvflinger/buffer_queue.cpp | 2 +- src/core/hle/service/prepo/prepo.cpp | 4 +-- src/core/hle/service/service.cpp | 2 +- src/core/hle/service/set/set_sys.cpp | 4 +-- src/core/hle/service/sockets/bsd.cpp | 6 ++--- src/core/hle/service/sockets/sockets_translate.cpp | 12 ++++----- src/core/hle/service/vi/vi.cpp | 10 ++++---- src/core/network/network.cpp | 12 ++++----- 25 files changed, 90 insertions(+), 96 deletions(-) (limited to 'src/core/hle/kernel/server_session.cpp') diff --git a/src/core/core.cpp b/src/core/core.cpp index 01e4faac8f..7e3c546186 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -237,7 +237,7 @@ struct System::Impl { Kernel::Process::Create(system, "main", Kernel::Process::ProcessType::Userland); const auto [load_result, load_parameters] = app_loader->Load(*main_process, system); if (load_result != Loader::ResultStatus::Success) { - LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", static_cast(load_result)); + LOG_CRITICAL(Core, "Failed to load ROM (Error {})!", load_result); Shutdown(); return static_cast(static_cast(ResultStatus::ErrorLoader) + @@ -267,8 +267,7 @@ struct System::Impl { u64 title_id{0}; if (app_loader->ReadProgramId(title_id) != Loader::ResultStatus::Success) { - LOG_ERROR(Core, "Failed to find title id for ROM (Error {})", - static_cast(load_result)); + LOG_ERROR(Core, "Failed to find title id for ROM (Error {})", load_result); } perf_stats = std::make_unique(title_id); // Reset counters and set time origin to current frame diff --git a/src/core/file_sys/content_archive.cpp b/src/core/file_sys/content_archive.cpp index 76af47ff9e..363ff980f8 100644 --- a/src/core/file_sys/content_archive.cpp +++ b/src/core/file_sys/content_archive.cpp @@ -410,8 +410,9 @@ u8 NCA::GetCryptoRevision() const { std::optional NCA::GetKeyAreaKey(NCASectionCryptoType type) const { const auto master_key_id = GetCryptoRevision(); - if (!keys.HasKey(Core::Crypto::S128KeyType::KeyArea, master_key_id, header.key_index)) - return {}; + if (!keys.HasKey(Core::Crypto::S128KeyType::KeyArea, master_key_id, header.key_index)) { + return std::nullopt; + } std::vector key_area(header.key_area.begin(), header.key_area.end()); Core::Crypto::AESCipher cipher( @@ -420,15 +421,17 @@ std::optional NCA::GetKeyAreaKey(NCASectionCryptoType type cipher.Transcode(key_area.data(), key_area.size(), key_area.data(), Core::Crypto::Op::Decrypt); Core::Crypto::Key128 out; - if (type == NCASectionCryptoType::XTS) + if (type == NCASectionCryptoType::XTS) { std::copy(key_area.begin(), key_area.begin() + 0x10, out.begin()); - else if (type == NCASectionCryptoType::CTR || type == NCASectionCryptoType::BKTR) + } else if (type == NCASectionCryptoType::CTR || type == NCASectionCryptoType::BKTR) { std::copy(key_area.begin() + 0x20, key_area.begin() + 0x30, out.begin()); - else + } else { LOG_CRITICAL(Crypto, "Called GetKeyAreaKey on invalid NCASectionCryptoType type={:02X}", - static_cast(type)); + type); + } + u128 out_128{}; - memcpy(out_128.data(), out.data(), 16); + std::memcpy(out_128.data(), out.data(), sizeof(u128)); LOG_TRACE(Crypto, "called with crypto_rev={:02X}, kak_index={:02X}, key={:016X}{:016X}", master_key_id, header.key_index, out_128[1], out_128[0]); @@ -507,7 +510,7 @@ VirtualFile NCA::Decrypt(const NCASectionHeader& s_header, VirtualFile in, u64 s // TODO(DarkLordZach): Find a test case for XTS-encrypted NCAs default: LOG_ERROR(Crypto, "called with unhandled crypto type={:02X}", - static_cast(s_header.raw.header.crypto_type)); + s_header.raw.header.crypto_type); return nullptr; } } diff --git a/src/core/frontend/applets/error.cpp b/src/core/frontend/applets/error.cpp index 4002a92118..dceb20ff87 100644 --- a/src/core/frontend/applets/error.cpp +++ b/src/core/frontend/applets/error.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/logging/log.h" #include "core/frontend/applets/error.h" namespace Core::Frontend { @@ -10,7 +11,7 @@ ErrorApplet::~ErrorApplet() = default; void DefaultErrorApplet::ShowError(ResultCode error, std::function finished) const { LOG_CRITICAL(Service_Fatal, "Application requested error display: {:04}-{:04} (raw={:08X})", - static_cast(error.module.Value()), error.description.Value(), error.raw); + error.module.Value(), error.description.Value(), error.raw); } void DefaultErrorApplet::ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time, @@ -18,7 +19,7 @@ void DefaultErrorApplet::ShowErrorWithTimestamp(ResultCode error, std::chrono::s LOG_CRITICAL( Service_Fatal, "Application requested error display: {:04X}-{:04X} (raw={:08X}) with timestamp={:016X}", - static_cast(error.module.Value()), error.description.Value(), error.raw, time.count()); + error.module.Value(), error.description.Value(), error.raw, time.count()); } void DefaultErrorApplet::ShowCustomErrorText(ResultCode error, std::string main_text, @@ -26,7 +27,7 @@ void DefaultErrorApplet::ShowCustomErrorText(ResultCode error, std::string main_ std::function finished) const { LOG_CRITICAL(Service_Fatal, "Application requested custom error with error_code={:04X}-{:04X} (raw={:08X})", - static_cast(error.module.Value()), error.description.Value(), error.raw); + error.module.Value(), error.description.Value(), error.raw); LOG_CRITICAL(Service_Fatal, " Main Text: {}", main_text); LOG_CRITICAL(Service_Fatal, " Detail Text: {}", detail_text); } diff --git a/src/core/hle/kernel/process_capability.cpp b/src/core/hle/kernel/process_capability.cpp index 63880f13d4..0f128c586d 100644 --- a/src/core/hle/kernel/process_capability.cpp +++ b/src/core/hle/kernel/process_capability.cpp @@ -199,7 +199,7 @@ ResultCode ProcessCapabilities::ParseSingleFlagCapability(u32& set_flags, u32& s break; } - LOG_ERROR(Kernel, "Invalid capability type! type={}", static_cast(type)); + LOG_ERROR(Kernel, "Invalid capability type! type={}", type); return ERR_INVALID_CAPABILITY_DESCRIPTOR; } diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp index 212e442f42..7bf50339d2 100644 --- a/src/core/hle/kernel/resource_limit.cpp +++ b/src/core/hle/kernel/resource_limit.cpp @@ -65,8 +65,8 @@ ResultCode ResourceLimit::SetLimitValue(ResourceType resource, s64 value) { limit[index] = value; return RESULT_SUCCESS; } else { - LOG_ERROR(Kernel, "Limit value is too large! resource={}, value={}, index={}", - static_cast(resource), value, index); + LOG_ERROR(Kernel, "Limit value is too large! resource={}, value={}, index={}", resource, + value, index); return ERR_INVALID_STATE; } } diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 8c19f25341..ae088cf41a 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -130,8 +130,7 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con } } - LOG_CRITICAL(IPC, "Unknown domain command={}", - static_cast(domain_message_header.command.Value())); + LOG_CRITICAL(IPC, "Unknown domain command={}", domain_message_header.command.Value()); ASSERT(false); return RESULT_SUCCESS; } diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 38d877f6e6..cb13210e59 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -1092,14 +1092,14 @@ void ILibraryAppletCreator::CreateLibraryApplet(Kernel::HLERequestContext& ctx) const auto applet_id = rp.PopRaw(); const auto applet_mode = rp.PopRaw(); - LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", - static_cast(applet_id), applet_mode); + LOG_DEBUG(Service_AM, "called with applet_id={:08X}, applet_mode={:08X}", applet_id, + applet_mode); const auto& applet_manager{system.GetAppletManager()}; const auto applet = applet_manager.GetApplet(applet_id); if (applet == nullptr) { - LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", static_cast(applet_id)); + LOG_ERROR(Service_AM, "Applet doesn't exist! applet_id={}", applet_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_UNKNOWN); @@ -1290,7 +1290,7 @@ void IApplicationFunctions::PopLaunchParameter(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto kind = rp.PopEnum(); - LOG_DEBUG(Service_AM, "called, kind={:08X}", static_cast(kind)); + LOG_DEBUG(Service_AM, "called, kind={:08X}", kind); if (kind == LaunchParameterKind::ApplicationSpecific && !launch_popped_application_specific) { const auto backend = BCAT::CreateBackendFromSettings(system, [this](u64 tid) { @@ -1537,8 +1537,8 @@ void IApplicationFunctions::GetSaveDataSize(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto [type, user_id] = rp.PopRaw(); - LOG_DEBUG(Service_AM, "called with type={:02X}, user_id={:016X}{:016X}", static_cast(type), - user_id[1], user_id[0]); + LOG_DEBUG(Service_AM, "called with type={:02X}, user_id={:016X}{:016X}", type, user_id[1], + user_id[0]); const auto size = system.GetFileSystemController().ReadSaveDataSize( type, system.CurrentProcess()->GetTitleID(), user_id); diff --git a/src/core/hle/service/am/applets/error.cpp b/src/core/hle/service/am/applets/error.cpp index dcd4b2a352..d855050821 100644 --- a/src/core/hle/service/am/applets/error.cpp +++ b/src/core/hle/service/am/applets/error.cpp @@ -125,7 +125,7 @@ void Error::Initialize() { error_code = Decode64BitError(args->error_record.error_code_64); break; default: - UNIMPLEMENTED_MSG("Unimplemented LibAppletError mode={:02X}!", static_cast(mode)); + UNIMPLEMENTED_MSG("Unimplemented LibAppletError mode={:02X}!", mode); } } @@ -179,7 +179,7 @@ void Error::Execute() { error_code, std::chrono::seconds{args->error_record.posix_time}, callback); break; default: - UNIMPLEMENTED_MSG("Unimplemented LibAppletError mode={:02X}!", static_cast(mode)); + UNIMPLEMENTED_MSG("Unimplemented LibAppletError mode={:02X}!", mode); DisplayCompleted(); } } diff --git a/src/core/hle/service/am/applets/general_backend.cpp b/src/core/hle/service/am/applets/general_backend.cpp index bdb6fd464f..a1b91b4c38 100644 --- a/src/core/hle/service/am/applets/general_backend.cpp +++ b/src/core/hle/service/am/applets/general_backend.cpp @@ -90,7 +90,7 @@ void Auth::Execute() { const auto unimplemented_log = [this] { UNIMPLEMENTED_MSG("Unimplemented Auth applet type for type={:08X}, arg0={:02X}, " "arg1={:02X}, arg2={:02X}", - static_cast(type), arg0, arg1, arg2); + type, arg0, arg1, arg2); }; switch (type) { @@ -193,7 +193,7 @@ void PhotoViewer::Execute() { frontend.ShowAllPhotos(callback); break; default: - UNIMPLEMENTED_MSG("Unimplemented PhotoViewer applet mode={:02X}!", static_cast(mode)); + UNIMPLEMENTED_MSG("Unimplemented PhotoViewer applet mode={:02X}!", mode); } } diff --git a/src/core/hle/service/apm/controller.cpp b/src/core/hle/service/apm/controller.cpp index ce993bad30..03636642b5 100644 --- a/src/core/hle/service/apm/controller.cpp +++ b/src/core/hle/service/apm/controller.cpp @@ -48,8 +48,7 @@ void Controller::SetPerformanceConfiguration(PerformanceMode mode, [config](const auto& entry) { return entry.first == config; }); if (iter == config_to_speed.cend()) { - LOG_ERROR(Service_APM, "Invalid performance configuration value provided: {}", - static_cast(config)); + LOG_ERROR(Service_APM, "Invalid performance configuration value provided: {}", config); return; } diff --git a/src/core/hle/service/apm/interface.cpp b/src/core/hle/service/apm/interface.cpp index 89442e21ea..298f6d5204 100644 --- a/src/core/hle/service/apm/interface.cpp +++ b/src/core/hle/service/apm/interface.cpp @@ -28,8 +28,7 @@ private: const auto mode = rp.PopEnum(); const auto config = rp.PopEnum(); - LOG_DEBUG(Service_APM, "called mode={} config={}", static_cast(mode), - static_cast(config)); + LOG_DEBUG(Service_APM, "called mode={} config={}", mode, config); controller.SetPerformanceConfiguration(mode, config); @@ -41,7 +40,7 @@ private: IPC::RequestParser rp{ctx}; const auto mode = rp.PopEnum(); - LOG_DEBUG(Service_APM, "called mode={}", static_cast(mode)); + LOG_DEBUG(Service_APM, "called mode={}", mode); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); @@ -111,7 +110,7 @@ void APM_Sys::SetCpuBoostMode(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto mode = rp.PopEnum(); - LOG_DEBUG(Service_APM, "called, mode={:08X}", static_cast(mode)); + LOG_DEBUG(Service_APM, "called, mode={:08X}", mode); controller.SetFromCpuBoostMode(mode); diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp index 9b7672a918..13147472ef 100644 --- a/src/core/hle/service/fatal/fatal.cpp +++ b/src/core/hle/service/fatal/fatal.cpp @@ -111,8 +111,9 @@ static void GenerateErrorReport(Core::System& system, ResultCode error_code, static void ThrowFatalError(Core::System& system, ResultCode error_code, FatalType fatal_type, const FatalInfo& info) { - LOG_ERROR(Service_Fatal, "Threw fatal error type {} with error code 0x{:X}", - static_cast(fatal_type), error_code.raw); + LOG_ERROR(Service_Fatal, "Threw fatal error type {} with error code 0x{:X}", fatal_type, + error_code.raw); + switch (fatal_type) { case FatalType::ErrorReportAndScreen: GenerateErrorReport(system, error_code, info); diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index ca93062cfe..6af818b5a5 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -301,7 +301,7 @@ ResultVal FileSystemController::OpenRomFSCurrentProcess() ResultVal FileSystemController::OpenRomFS( u64 title_id, FileSys::StorageId storage_id, FileSys::ContentRecordType type) const { LOG_TRACE(Service_FS, "Opening RomFS for title_id={:016X}, storage_id={:02X}, type={:02X}", - title_id, static_cast(storage_id), static_cast(type)); + title_id, storage_id, type); if (romfs_factory == nullptr) { // TODO(bunnei): Find a better error code for this @@ -313,8 +313,8 @@ ResultVal FileSystemController::OpenRomFS( ResultVal FileSystemController::CreateSaveData( FileSys::SaveDataSpaceId space, const FileSys::SaveDataAttribute& save_struct) const { - LOG_TRACE(Service_FS, "Creating Save Data for space_id={:01X}, save_struct={}", - static_cast(space), save_struct.DebugInfo()); + LOG_TRACE(Service_FS, "Creating Save Data for space_id={:01X}, save_struct={}", space, + save_struct.DebugInfo()); if (save_data_factory == nullptr) { return FileSys::ERROR_ENTITY_NOT_FOUND; @@ -325,8 +325,8 @@ ResultVal FileSystemController::CreateSaveData( ResultVal FileSystemController::OpenSaveData( FileSys::SaveDataSpaceId space, const FileSys::SaveDataAttribute& attribute) const { - LOG_TRACE(Service_FS, "Opening Save Data for space_id={:01X}, save_struct={}", - static_cast(space), attribute.DebugInfo()); + LOG_TRACE(Service_FS, "Opening Save Data for space_id={:01X}, save_struct={}", space, + attribute.DebugInfo()); if (save_data_factory == nullptr) { return FileSys::ERROR_ENTITY_NOT_FOUND; @@ -337,7 +337,7 @@ ResultVal FileSystemController::OpenSaveData( ResultVal FileSystemController::OpenSaveDataSpace( FileSys::SaveDataSpaceId space) const { - LOG_TRACE(Service_FS, "Opening Save Data Space for space_id={:01X}", static_cast(space)); + LOG_TRACE(Service_FS, "Opening Save Data Space for space_id={:01X}", space); if (save_data_factory == nullptr) { return FileSys::ERROR_ENTITY_NOT_FOUND; @@ -358,7 +358,7 @@ ResultVal FileSystemController::OpenSDMC() const { ResultVal FileSystemController::OpenBISPartition( FileSys::BisPartitionId id) const { - LOG_TRACE(Service_FS, "Opening BIS Partition with id={:08X}", static_cast(id)); + LOG_TRACE(Service_FS, "Opening BIS Partition with id={:08X}", id); if (bis_factory == nullptr) { return FileSys::ERROR_ENTITY_NOT_FOUND; @@ -374,7 +374,7 @@ ResultVal FileSystemController::OpenBISPartition( ResultVal FileSystemController::OpenBISPartitionStorage( FileSys::BisPartitionId id) const { - LOG_TRACE(Service_FS, "Opening BIS Partition Storage with id={:08X}", static_cast(id)); + LOG_TRACE(Service_FS, "Opening BIS Partition Storage with id={:08X}", id); if (bis_factory == nullptr) { return FileSys::ERROR_ENTITY_NOT_FOUND; diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index b3480494c5..ef15160bf1 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -413,7 +413,7 @@ public: const auto mode = static_cast(rp.Pop()); - LOG_DEBUG(Service_FS, "called. file={}, mode={}", name, static_cast(mode)); + LOG_DEBUG(Service_FS, "called. file={}, mode={}", name, mode); auto result = backend.OpenFile(name, mode); if (result.Failed()) { @@ -553,8 +553,7 @@ private: const auto save_root = fsc.OpenSaveDataSpace(space); if (save_root.Failed() || *save_root == nullptr) { - LOG_ERROR(Service_FS, "The save root for the space_id={:02X} was invalid!", - static_cast(space)); + LOG_ERROR(Service_FS, "The save root for the space_id={:02X} was invalid!", space); return; } @@ -795,8 +794,7 @@ void FSP_SRV::OpenFileSystemWithPatch(Kernel::HLERequestContext& ctx) { const auto type = rp.PopRaw(); const auto title_id = rp.PopRaw(); - LOG_WARNING(Service_FS, "(STUBBED) called with type={}, title_id={:016X}", - static_cast(type), title_id); + LOG_WARNING(Service_FS, "(STUBBED) called with type={}, title_id={:016X}", type, title_id); IPC::ResponseBuilder rb{ctx, 2, 0, 0}; rb.Push(RESULT_UNKNOWN); @@ -883,7 +881,7 @@ void FSP_SRV::OpenReadOnlySaveDataFileSystem(Kernel::HLERequestContext& ctx) { void FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto space = rp.PopRaw(); - LOG_INFO(Service_FS, "called, space={}", static_cast(space)); + LOG_INFO(Service_FS, "called, space={}", space); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(RESULT_SUCCESS); @@ -915,10 +913,10 @@ void FSP_SRV::ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute( "(STUBBED) called, flags={}, space_id={}, attribute.title_id={:016X}\n" "attribute.user_id={:016X}{:016X}, attribute.save_id={:016X}\n" "attribute.type={}, attribute.rank={}, attribute.index={}", - flags, static_cast(parameters.space_id), parameters.attribute.title_id, + flags, parameters.space_id, parameters.attribute.title_id, parameters.attribute.user_id[1], parameters.attribute.user_id[0], - parameters.attribute.save_id, static_cast(parameters.attribute.type), - static_cast(parameters.attribute.rank), parameters.attribute.index); + parameters.attribute.save_id, parameters.attribute.type, parameters.attribute.rank, + parameters.attribute.index); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); @@ -951,7 +949,7 @@ void FSP_SRV::OpenDataStorageByDataId(Kernel::HLERequestContext& ctx) { const auto title_id = rp.PopRaw(); LOG_DEBUG(Service_FS, "called with storage_id={:02X}, unknown={:08X}, title_id={:016X}", - static_cast(storage_id), unknown, title_id); + storage_id, unknown, title_id); auto data = fsc.OpenRomFS(title_id, storage_id, FileSys::ContentRecordType::Data); @@ -968,7 +966,7 @@ void FSP_SRV::OpenDataStorageByDataId(Kernel::HLERequestContext& ctx) { // TODO(DarkLordZach): Find the right error code to use here LOG_ERROR(Service_FS, "could not open data storage with title_id={:016X}, storage_id={:02X}", title_id, - static_cast(storage_id)); + storage_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_UNKNOWN); return; @@ -987,11 +985,10 @@ void FSP_SRV::OpenDataStorageByDataId(Kernel::HLERequestContext& ctx) { void FSP_SRV::OpenPatchDataStorageByCurrentProcess(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; - auto storage_id = rp.PopRaw(); - auto title_id = rp.PopRaw(); + const auto storage_id = rp.PopRaw(); + const auto title_id = rp.PopRaw(); - LOG_DEBUG(Service_FS, "called with storage_id={:02X}, title_id={:016X}", - static_cast(storage_id), title_id); + LOG_DEBUG(Service_FS, "called with storage_id={:02X}, title_id={:016X}", storage_id, title_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(FileSys::ERROR_ENTITY_NOT_FOUND); @@ -1001,7 +998,7 @@ void FSP_SRV::SetGlobalAccessLogMode(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; log_mode = rp.PopEnum(); - LOG_DEBUG(Service_FS, "called, log_mode={:08X}", static_cast(log_mode)); + LOG_DEBUG(Service_FS, "called, log_mode={:08X}", log_mode); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(RESULT_SUCCESS); diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index 40a2895947..c5b053c31b 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp @@ -229,8 +229,7 @@ private: break; default: // HOS seems not have an error case for an unknown notification - LOG_WARNING(Service_ACC, "Unknown notification {:08X}", - static_cast(notification.notification_type)); + LOG_WARNING(Service_ACC, "Unknown notification {:08X}", notification.notification_type); break; } diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp index f884b2735a..8e49b068c7 100644 --- a/src/core/hle/service/lm/lm.cpp +++ b/src/core/hle/service/lm/lm.cpp @@ -68,7 +68,7 @@ private: IPC::RequestParser rp{ctx}; const auto destination = rp.PopEnum(); - LOG_DEBUG(Service_LM, "called, destination={:08X}", static_cast(destination)); + LOG_DEBUG(Service_LM, "called, destination={:08X}", destination); manager.SetDestination(destination); diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index ccc137e402..c8a2158458 100644 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp @@ -182,21 +182,18 @@ PL_U::PL_U(Core::System& system_) } if (!romfs) { - LOG_ERROR(Service_NS, "Failed to find or synthesize {:016X}! Skipping", - static_cast(font.first)); + LOG_ERROR(Service_NS, "Failed to find or synthesize {:016X}! Skipping", font.first); continue; } const auto extracted_romfs = FileSys::ExtractRomFS(romfs); if (!extracted_romfs) { - LOG_ERROR(Service_NS, "Failed to extract RomFS for {:016X}! Skipping", - static_cast(font.first)); + LOG_ERROR(Service_NS, "Failed to extract RomFS for {:016X}! Skipping", font.first); continue; } const auto font_fp = extracted_romfs->GetFile(font.second); if (!font_fp) { - LOG_ERROR(Service_NS, "{:016X} has no file \"{}\"! Skipping", - static_cast(font.first), font.second); + LOG_ERROR(Service_NS, "{:016X} has no file \"{}\"! Skipping", font.first, font.second); continue; } std::vector font_data_u32(font_fp->GetSize() / sizeof(u32)); diff --git a/src/core/hle/service/nvflinger/buffer_queue.cpp b/src/core/hle/service/nvflinger/buffer_queue.cpp index b89a2d41be..191286ce99 100644 --- a/src/core/hle/service/nvflinger/buffer_queue.cpp +++ b/src/core/hle/service/nvflinger/buffer_queue.cpp @@ -153,7 +153,7 @@ void BufferQueue::Disconnect() { } u32 BufferQueue::Query(QueryType type) { - LOG_WARNING(Service, "(STUBBED) called type={}", static_cast(type)); + LOG_WARNING(Service, "(STUBBED) called type={}", type); switch (type) { case QueryType::NativeWindowFormat: diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp index 392fda73e1..b417624c9e 100644 --- a/src/core/hle/service/prepo/prepo.cpp +++ b/src/core/hle/service/prepo/prepo.cpp @@ -65,7 +65,7 @@ private: } LOG_DEBUG(Service_PREPO, "called, type={:02X}, process_id={:016X}, data1_size={:016X}", - static_cast(Type), process_id, data[0].size()); + Type, process_id, data[0].size()); const auto& reporter{system.GetReporter()}; reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), data, process_id); @@ -92,7 +92,7 @@ private: LOG_DEBUG( Service_PREPO, "called, type={:02X}, user_id={:016X}{:016X}, process_id={:016X}, data1_size={:016X}", - static_cast(Type), user_id[1], user_id[0], process_id, data[0].size()); + Type, user_id[1], user_id[0], process_id, data[0].size()); const auto& reporter{system.GetReporter()}; reporter.SavePlayReport(Type, system.CurrentProcess()->GetTitleID(), data, process_id, diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 360e0bf370..abf3d1ea3b 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -181,7 +181,7 @@ ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& co break; } default: - UNIMPLEMENTED_MSG("command_type={}", static_cast(context.GetCommandType())); + UNIMPLEMENTED_MSG("command_type={}", context.GetCommandType()); } context.WriteToOutgoingCommandBuffer(context.GetThread()); diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp index 19b8f113db..b58b2c8c57 100644 --- a/src/core/hle/service/set/set_sys.cpp +++ b/src/core/hle/service/set/set_sys.cpp @@ -34,9 +34,9 @@ void GetFirmwareVersionImpl(Kernel::HLERequestContext& ctx, GetFirmwareVersionTy // consistence (currently reports as 5.1.0-0.0) const auto archive = FileSys::SystemArchive::SystemVersion(); - const auto early_exit_failure = [&ctx](const std::string& desc, ResultCode code) { + const auto early_exit_failure = [&ctx](std::string_view desc, ResultCode code) { LOG_ERROR(Service_SET, "General failure while attempting to resolve firmware version ({}).", - desc.c_str()); + desc); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(code); }; diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index a9875b9a66..c6dc5304aa 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -30,7 +30,7 @@ bool IsConnectionBased(Type type) { case Type::DGRAM: return false; default: - UNIMPLEMENTED_MSG("Unimplemented type={}", static_cast(type)); + UNIMPLEMENTED_MSG("Unimplemented type={}", type); return false; } } @@ -636,7 +636,7 @@ std::pair BSD::FcntlImpl(s32 fd, FcntlCmd cmd, s32 arg) { return {0, Errno::SUCCESS}; } default: - UNIMPLEMENTED_MSG("Unimplemented cmd={}", static_cast(cmd)); + UNIMPLEMENTED_MSG("Unimplemented cmd={}", cmd); return {-1, Errno::SUCCESS}; } } @@ -679,7 +679,7 @@ Errno BSD::SetSockOptImpl(s32 fd, u32 level, OptName optname, size_t optlen, con case OptName::RCVTIMEO: return Translate(socket->SetRcvTimeo(value)); default: - UNIMPLEMENTED_MSG("Unimplemented optname={}", static_cast(optname)); + UNIMPLEMENTED_MSG("Unimplemented optname={}", optname); return Errno::SUCCESS; } } diff --git a/src/core/hle/service/sockets/sockets_translate.cpp b/src/core/hle/service/sockets/sockets_translate.cpp index 2e626fd869..6ddf3f6f9b 100644 --- a/src/core/hle/service/sockets/sockets_translate.cpp +++ b/src/core/hle/service/sockets/sockets_translate.cpp @@ -27,7 +27,7 @@ Errno Translate(Network::Errno value) { case Network::Errno::NOTCONN: return Errno::NOTCONN; default: - UNIMPLEMENTED_MSG("Unimplemented errno={}", static_cast(value)); + UNIMPLEMENTED_MSG("Unimplemented errno={}", value); return Errno::SUCCESS; } } @@ -41,7 +41,7 @@ Network::Domain Translate(Domain domain) { case Domain::INET: return Network::Domain::INET; default: - UNIMPLEMENTED_MSG("Unimplemented domain={}", static_cast(domain)); + UNIMPLEMENTED_MSG("Unimplemented domain={}", domain); return {}; } } @@ -51,7 +51,7 @@ Domain Translate(Network::Domain domain) { case Network::Domain::INET: return Domain::INET; default: - UNIMPLEMENTED_MSG("Unimplemented domain={}", static_cast(domain)); + UNIMPLEMENTED_MSG("Unimplemented domain={}", domain); return {}; } } @@ -63,7 +63,7 @@ Network::Type Translate(Type type) { case Type::DGRAM: return Network::Type::DGRAM; default: - UNIMPLEMENTED_MSG("Unimplemented type={}", static_cast(type)); + UNIMPLEMENTED_MSG("Unimplemented type={}", type); } } @@ -84,7 +84,7 @@ Network::Protocol Translate(Type type, Protocol protocol) { case Protocol::UDP: return Network::Protocol::UDP; default: - UNIMPLEMENTED_MSG("Unimplemented protocol={}", static_cast(protocol)); + UNIMPLEMENTED_MSG("Unimplemented protocol={}", protocol); return Network::Protocol::TCP; } } @@ -157,7 +157,7 @@ Network::ShutdownHow Translate(ShutdownHow how) { case ShutdownHow::RDWR: return Network::ShutdownHow::RDWR; default: - UNIMPLEMENTED_MSG("Unimplemented how={}", static_cast(how)); + UNIMPLEMENTED_MSG("Unimplemented how={}", how); return {}; } } diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 422e9e02f9..5d8841ae82 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -528,7 +528,7 @@ private: const u32 flags = rp.Pop(); LOG_DEBUG(Service_VI, "called. id=0x{:08X} transaction={:X}, flags=0x{:08X}", id, - static_cast(transaction), flags); + transaction, flags); const auto guard = nv_flinger.Lock(); auto& buffer_queue = nv_flinger.FindBufferQueue(id); @@ -1066,8 +1066,8 @@ private: const auto scaling_mode = rp.PopEnum(); const u64 unknown = rp.Pop(); - LOG_DEBUG(Service_VI, "called. scaling_mode=0x{:08X}, unknown=0x{:016X}", - static_cast(scaling_mode), unknown); + LOG_DEBUG(Service_VI, "called. scaling_mode=0x{:08X}, unknown=0x{:016X}", scaling_mode, + unknown); IPC::ResponseBuilder rb{ctx, 2}; @@ -1210,7 +1210,7 @@ private: void ConvertScalingMode(Kernel::HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto mode = rp.PopEnum(); - LOG_DEBUG(Service_VI, "called mode={}", static_cast(mode)); + LOG_DEBUG(Service_VI, "called mode={}", mode); const auto converted_mode = ConvertScalingModeImpl(mode); @@ -1311,7 +1311,7 @@ void detail::GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, Core::System& const auto policy = rp.PopEnum(); if (!IsValidServiceAccess(permission, policy)) { - LOG_ERROR(Service_VI, "Permission denied for policy {}", static_cast(policy)); + LOG_ERROR(Service_VI, "Permission denied for policy {}", policy); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ERR_PERMISSION_DENIED); return; diff --git a/src/core/network/network.cpp b/src/core/network/network.cpp index 5a8cc6fc2f..f0c4b88fcf 100644 --- a/src/core/network/network.cpp +++ b/src/core/network/network.cpp @@ -63,7 +63,7 @@ sockaddr TranslateFromSockAddrIn(SockAddrIn input) { result.sin_family = AF_INET; break; default: - UNIMPLEMENTED_MSG("Unhandled sockaddr family={}", static_cast(input.family)); + UNIMPLEMENTED_MSG("Unhandled sockaddr family={}", input.family); result.sin_family = AF_INET; break; } @@ -133,7 +133,7 @@ sockaddr TranslateFromSockAddrIn(SockAddrIn input) { result.sin_family = AF_INET; break; default: - UNIMPLEMENTED_MSG("Unhandled sockaddr family={}", static_cast(input.family)); + UNIMPLEMENTED_MSG("Unhandled sockaddr family={}", input.family); result.sin_family = AF_INET; break; } @@ -186,7 +186,7 @@ int TranslateDomain(Domain domain) { case Domain::INET: return AF_INET; default: - UNIMPLEMENTED_MSG("Unimplemented domain={}", static_cast(domain)); + UNIMPLEMENTED_MSG("Unimplemented domain={}", domain); return 0; } } @@ -198,7 +198,7 @@ int TranslateType(Type type) { case Type::DGRAM: return SOCK_DGRAM; default: - UNIMPLEMENTED_MSG("Unimplemented type={}", static_cast(type)); + UNIMPLEMENTED_MSG("Unimplemented type={}", type); return 0; } } @@ -210,7 +210,7 @@ int TranslateProtocol(Protocol protocol) { case Protocol::UDP: return IPPROTO_UDP; default: - UNIMPLEMENTED_MSG("Unimplemented protocol={}", static_cast(protocol)); + UNIMPLEMENTED_MSG("Unimplemented protocol={}", protocol); return 0; } } @@ -482,7 +482,7 @@ Errno Socket::Shutdown(ShutdownHow how) { host_how = SD_BOTH; break; default: - UNIMPLEMENTED_MSG("Unimplemented flag how={}", static_cast(how)); + UNIMPLEMENTED_MSG("Unimplemented flag how={}", how); return Errno::SUCCESS; } if (shutdown(fd, host_how) != SOCKET_ERROR) { -- cgit v1.2.3 From 56be5d7ba92cd2661a71e9b874c1dacb1f029369 Mon Sep 17 00:00:00 2001 From: bunnei Date: Wed, 9 Dec 2020 21:27:05 -0800 Subject: core: hle: server_session: Use separate threads for each service connection. --- src/core/CMakeLists.txt | 2 + src/core/hle/kernel/kernel.cpp | 2 +- src/core/hle/kernel/server_session.cpp | 20 ++----- src/core/hle/kernel/server_session.h | 12 ++-- src/core/hle/kernel/service_thread.cpp | 100 +++++++++++++++++++++++++++++++++ src/core/hle/kernel/service_thread.h | 27 +++++++++ 6 files changed, 140 insertions(+), 23 deletions(-) create mode 100644 src/core/hle/kernel/service_thread.cpp create mode 100644 src/core/hle/kernel/service_thread.h (limited to 'src/core/hle/kernel/server_session.cpp') diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 59bd3d2a66..87712a3ceb 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -202,6 +202,8 @@ add_library(core STATIC hle/kernel/server_port.h hle/kernel/server_session.cpp hle/kernel/server_session.h + hle/kernel/service_thread.cpp + hle/kernel/service_thread.h hle/kernel/session.cpp hle/kernel/session.h hle/kernel/shared_memory.cpp diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 04cae3a433..1bf4c33557 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -329,7 +329,7 @@ struct KernelCore::Impl { std::atomic registered_thread_ids{Core::Hardware::NUM_CPU_CORES}; // Number of host threads is a relatively high number to avoid overflowing - static constexpr size_t NUM_REGISTRABLE_HOST_THREADS = 64; + static constexpr size_t NUM_REGISTRABLE_HOST_THREADS = 1024; std::atomic num_host_threads{0}; std::array, NUM_REGISTRABLE_HOST_THREADS> register_host_thread_keys{}; diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index a35c8aa4be..079c3911a7 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -32,12 +32,9 @@ ResultVal> ServerSession::Create(KernelCore& kern std::string name) { std::shared_ptr session{std::make_shared(kernel)}; - session->request_event = - Core::Timing::CreateEvent(name, [session](std::uintptr_t, std::chrono::nanoseconds) { - session->CompleteSyncRequest(); - }); session->name = std::move(name); session->parent = std::move(parent); + session->service_thread = std::make_unique(kernel); return MakeResult(std::move(session)); } @@ -142,16 +139,12 @@ ResultCode ServerSession::QueueSyncRequest(std::shared_ptr thread, std::make_shared(kernel, memory, SharedFrom(this), std::move(thread)); context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf); - request_queue.Push(std::move(context)); + service_thread->QueueSyncRequest(*this, std::move(context)); return RESULT_SUCCESS; } -ResultCode ServerSession::CompleteSyncRequest() { - ASSERT(!request_queue.Empty()); - - auto& context = *request_queue.Front(); - +ResultCode ServerSession::CompleteSyncRequest(HLERequestContext& context) { ResultCode result = RESULT_SUCCESS; // If the session has been converted to a domain, handle the domain request if (IsDomain() && context.HasDomainMessageHeader()) { @@ -177,18 +170,13 @@ ResultCode ServerSession::CompleteSyncRequest() { } } - request_queue.Pop(); - return result; } ResultCode ServerSession::HandleSyncRequest(std::shared_ptr thread, Core::Memory::Memory& memory, Core::Timing::CoreTiming& core_timing) { - const ResultCode result = QueueSyncRequest(std::move(thread), memory); - const auto delay = std::chrono::nanoseconds{kernel.IsMulticore() ? 0 : 20000}; - core_timing.ScheduleEvent(delay, request_event, {}); - return result; + return QueueSyncRequest(std::move(thread), memory); } } // namespace Kernel diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index d23e9ec68f..8466b03e60 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -10,6 +10,7 @@ #include #include "common/threadsafe_queue.h" +#include "core/hle/kernel/service_thread.h" #include "core/hle/kernel/synchronization_object.h" #include "core/hle/result.h" @@ -43,6 +44,8 @@ class Thread; * TLS buffer and control is transferred back to it. */ class ServerSession final : public SynchronizationObject { + friend class ServiceThread; + public: explicit ServerSession(KernelCore& kernel); ~ServerSession() override; @@ -132,7 +135,7 @@ private: ResultCode QueueSyncRequest(std::shared_ptr thread, Core::Memory::Memory& memory); /// Completes a sync request from the emulated application. - ResultCode CompleteSyncRequest(); + ResultCode CompleteSyncRequest(HLERequestContext& context); /// Handles a SyncRequest to a domain, forwarding the request to the proper object or closing an /// object handle. @@ -163,11 +166,8 @@ private: /// The name of this session (optional) std::string name; - /// Core timing event used to schedule the service request at some point in the future - std::shared_ptr request_event; - - /// Queue of scheduled service requests - Common::MPSCQueue> request_queue; + /// Thread to dispatch service requests + std::unique_ptr service_thread; }; } // namespace Kernel diff --git a/src/core/hle/kernel/service_thread.cpp b/src/core/hle/kernel/service_thread.cpp new file mode 100644 index 0000000000..59a6045df5 --- /dev/null +++ b/src/core/hle/kernel/service_thread.cpp @@ -0,0 +1,100 @@ +// Copyright 2020 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include +#include +#include +#include +#include + +#include "common/assert.h" +#include "common/scope_exit.h" +#include "core/core.h" +#include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/server_session.h" +#include "core/hle/kernel/service_thread.h" +#include "core/hle/lock.h" +#include "video_core/renderer_base.h" + +namespace Kernel { + +class ServiceThread::Impl final { +public: + explicit Impl(KernelCore& kernel); + ~Impl(); + + void QueueSyncRequest(ServerSession& session, std::shared_ptr&& context); + +private: + std::vector threads; + std::queue> requests; + std::mutex queue_mutex; + std::condition_variable condition; + bool stop{}; +}; + +ServiceThread::Impl::Impl(KernelCore& kernel) { + constexpr std::size_t SizeOfPool{1}; + for (std::size_t i = 0; i < SizeOfPool; ++i) + threads.emplace_back([&] { + // Wait for first request before trying to acquire a render context + { + std::unique_lock lock{queue_mutex}; + condition.wait(lock, [this] { return stop || !requests.empty(); }); + } + + kernel.RegisterHostThread(); + + while (true) { + std::function task; + + { + std::unique_lock lock{queue_mutex}; + condition.wait(lock, [this] { return stop || !requests.empty(); }); + if (stop && requests.empty()) { + return; + } + task = std::move(requests.front()); + requests.pop(); + } + + task(); + } + }); +} + +void ServiceThread::Impl::QueueSyncRequest(ServerSession& session, + std::shared_ptr&& context) { + { + std::unique_lock lock{queue_mutex}; + requests.emplace([session{SharedFrom(&session)}, context{std::move(context)}]() { + session->CompleteSyncRequest(*context); + return; + }); + } + condition.notify_one(); +} + +ServiceThread::Impl::~Impl() { + { + std::unique_lock lock{queue_mutex}; + stop = true; + } + condition.notify_all(); + for (std::thread& thread : threads) { + thread.join(); + } +} + +ServiceThread::ServiceThread(KernelCore& kernel) : impl{std::make_unique(kernel)} {} + +ServiceThread::~ServiceThread() = default; + +void ServiceThread::QueueSyncRequest(ServerSession& session, + std::shared_ptr&& context) { + impl->QueueSyncRequest(session, std::move(context)); +} + +} // namespace Kernel diff --git a/src/core/hle/kernel/service_thread.h b/src/core/hle/kernel/service_thread.h new file mode 100644 index 0000000000..d252490bba --- /dev/null +++ b/src/core/hle/kernel/service_thread.h @@ -0,0 +1,27 @@ +// Copyright 2020 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include + +namespace Kernel { + +class HLERequestContext; +class KernelCore; +class ServerSession; + +class ServiceThread final { +public: + explicit ServiceThread(KernelCore& kernel); + ~ServiceThread(); + + void QueueSyncRequest(ServerSession& session, std::shared_ptr&& context); + +private: + class Impl; + std::unique_ptr impl; +}; + +} // namespace Kernel -- cgit v1.2.3 From 3d7b4bfa48c78084ae39f7f1603d808ee6943b93 Mon Sep 17 00:00:00 2001 From: bunnei Date: Thu, 10 Dec 2020 16:03:35 -0800 Subject: hle: kernel: service_thread: Add parameter for thread pool size. --- src/core/hle/kernel/server_session.cpp | 2 +- src/core/hle/kernel/service_thread.cpp | 10 +++++----- src/core/hle/kernel/service_thread.h | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/core/hle/kernel/server_session.cpp') diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 079c3911a7..ed42452ffd 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -34,7 +34,7 @@ ResultVal> ServerSession::Create(KernelCore& kern session->name = std::move(name); session->parent = std::move(parent); - session->service_thread = std::make_unique(kernel); + session->service_thread = std::make_unique(kernel, 1); return MakeResult(std::move(session)); } diff --git a/src/core/hle/kernel/service_thread.cpp b/src/core/hle/kernel/service_thread.cpp index 59a6045df5..4ceb7e56a4 100644 --- a/src/core/hle/kernel/service_thread.cpp +++ b/src/core/hle/kernel/service_thread.cpp @@ -22,7 +22,7 @@ namespace Kernel { class ServiceThread::Impl final { public: - explicit Impl(KernelCore& kernel); + explicit Impl(KernelCore& kernel, std::size_t num_threads); ~Impl(); void QueueSyncRequest(ServerSession& session, std::shared_ptr&& context); @@ -35,9 +35,8 @@ private: bool stop{}; }; -ServiceThread::Impl::Impl(KernelCore& kernel) { - constexpr std::size_t SizeOfPool{1}; - for (std::size_t i = 0; i < SizeOfPool; ++i) +ServiceThread::Impl::Impl(KernelCore& kernel, std::size_t num_threads) { + for (std::size_t i = 0; i < num_threads; ++i) threads.emplace_back([&] { // Wait for first request before trying to acquire a render context { @@ -88,7 +87,8 @@ ServiceThread::Impl::~Impl() { } } -ServiceThread::ServiceThread(KernelCore& kernel) : impl{std::make_unique(kernel)} {} +ServiceThread::ServiceThread(KernelCore& kernel, std::size_t num_threads) + : impl{std::make_unique(kernel, num_threads)} {} ServiceThread::~ServiceThread() = default; diff --git a/src/core/hle/kernel/service_thread.h b/src/core/hle/kernel/service_thread.h index d252490bba..91ad7ae856 100644 --- a/src/core/hle/kernel/service_thread.h +++ b/src/core/hle/kernel/service_thread.h @@ -14,7 +14,7 @@ class ServerSession; class ServiceThread final { public: - explicit ServiceThread(KernelCore& kernel); + explicit ServiceThread(KernelCore& kernel, std::size_t num_threads); ~ServiceThread(); void QueueSyncRequest(ServerSession& session, std::shared_ptr&& context); -- cgit v1.2.3 From b2ef309edb314b365ba49e1439cfc2e1ced98bc0 Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 29 Dec 2020 01:06:39 -0800 Subject: hle: kernel: service_thread: Add thread name and take weak_ptr of ServerSession. --- src/core/hle/kernel/server_session.cpp | 2 +- src/core/hle/kernel/service_thread.cpp | 28 +++++++++++++++++++--------- src/core/hle/kernel/service_thread.h | 3 ++- 3 files changed, 22 insertions(+), 11 deletions(-) (limited to 'src/core/hle/kernel/server_session.cpp') diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index ed42452ffd..947f4a133b 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -34,7 +34,7 @@ ResultVal> ServerSession::Create(KernelCore& kern session->name = std::move(name); session->parent = std::move(parent); - session->service_thread = std::make_unique(kernel, 1); + session->service_thread = std::make_unique(kernel, 1, session->name); return MakeResult(std::move(session)); } diff --git a/src/core/hle/kernel/service_thread.cpp b/src/core/hle/kernel/service_thread.cpp index 4ceb7e56a4..1c134777f7 100644 --- a/src/core/hle/kernel/service_thread.cpp +++ b/src/core/hle/kernel/service_thread.cpp @@ -11,6 +11,7 @@ #include "common/assert.h" #include "common/scope_exit.h" +#include "common/thread.h" #include "core/core.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/server_session.h" @@ -22,7 +23,7 @@ namespace Kernel { class ServiceThread::Impl final { public: - explicit Impl(KernelCore& kernel, std::size_t num_threads); + explicit Impl(KernelCore& kernel, std::size_t num_threads, const std::string& name); ~Impl(); void QueueSyncRequest(ServerSession& session, std::shared_ptr&& context); @@ -32,12 +33,16 @@ private: std::queue> requests; std::mutex queue_mutex; std::condition_variable condition; + const std::string service_name; bool stop{}; }; -ServiceThread::Impl::Impl(KernelCore& kernel, std::size_t num_threads) { +ServiceThread::Impl::Impl(KernelCore& kernel, std::size_t num_threads, const std::string& name) + : service_name{name} { for (std::size_t i = 0; i < num_threads; ++i) - threads.emplace_back([&] { + threads.emplace_back([this, &kernel] { + Common::SetCurrentThreadName(std::string{"Hle_" + service_name}.c_str()); + // Wait for first request before trying to acquire a render context { std::unique_lock lock{queue_mutex}; @@ -52,7 +57,7 @@ ServiceThread::Impl::Impl(KernelCore& kernel, std::size_t num_threads) { { std::unique_lock lock{queue_mutex}; condition.wait(lock, [this] { return stop || !requests.empty(); }); - if (stop && requests.empty()) { + if (stop || requests.empty()) { return; } task = std::move(requests.front()); @@ -68,9 +73,14 @@ void ServiceThread::Impl::QueueSyncRequest(ServerSession& session, std::shared_ptr&& context) { { std::unique_lock lock{queue_mutex}; - requests.emplace([session{SharedFrom(&session)}, context{std::move(context)}]() { - session->CompleteSyncRequest(*context); - return; + + // ServerSession owns the service thread, so we cannot caption a strong pointer here in the + // event that the ServerSession is terminated. + std::weak_ptr weak_ptr{SharedFrom(&session)}; + requests.emplace([weak_ptr, context{std::move(context)}]() { + if (auto strong_ptr = weak_ptr.lock()) { + strong_ptr->CompleteSyncRequest(*context); + } }); } condition.notify_one(); @@ -87,8 +97,8 @@ ServiceThread::Impl::~Impl() { } } -ServiceThread::ServiceThread(KernelCore& kernel, std::size_t num_threads) - : impl{std::make_unique(kernel, num_threads)} {} +ServiceThread::ServiceThread(KernelCore& kernel, std::size_t num_threads, const std::string& name) + : impl{std::make_unique(kernel, num_threads, name)} {} ServiceThread::~ServiceThread() = default; diff --git a/src/core/hle/kernel/service_thread.h b/src/core/hle/kernel/service_thread.h index 91ad7ae856..025ab8fb54 100644 --- a/src/core/hle/kernel/service_thread.h +++ b/src/core/hle/kernel/service_thread.h @@ -5,6 +5,7 @@ #pragma once #include +#include namespace Kernel { @@ -14,7 +15,7 @@ class ServerSession; class ServiceThread final { public: - explicit ServiceThread(KernelCore& kernel, std::size_t num_threads); + explicit ServiceThread(KernelCore& kernel, std::size_t num_threads, const std::string& name); ~ServiceThread(); void QueueSyncRequest(ServerSession& session, std::shared_ptr&& context); -- cgit v1.2.3 From 67051cf10ca1d7b662255361e6aab232bfa55b2b Mon Sep 17 00:00:00 2001 From: bunnei Date: Tue, 15 Dec 2020 00:41:48 -0800 Subject: hle: kernel: Move ServiceThread ownership to KernelCore. - Fixes a circular dependency which prevented threads from being released on shutdown. --- src/core/hle/kernel/kernel.cpp | 21 ++++++++++++++++++++- src/core/hle/kernel/kernel.h | 17 +++++++++++++++++ src/core/hle/kernel/server_session.cpp | 13 ++++++++++--- src/core/hle/kernel/server_session.h | 2 +- 4 files changed, 48 insertions(+), 5 deletions(-) (limited to 'src/core/hle/kernel/server_session.cpp') diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 312c64c179..5f917686fe 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include #include "common/assert.h" @@ -35,6 +35,7 @@ #include "core/hle/kernel/physical_core.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/resource_limit.h" +#include "core/hle/kernel/service_thread.h" #include "core/hle/kernel/shared_memory.h" #include "core/hle/kernel/synchronization.h" #include "core/hle/kernel/thread.h" @@ -107,6 +108,9 @@ struct KernelCore::Impl { std::fill(register_host_thread_keys.begin(), register_host_thread_keys.end(), std::thread::id{}); std::fill(register_host_thread_values.begin(), register_host_thread_values.end(), 0); + + // Ensures all service threads gracefully shutdown + service_threads.clear(); } void InitializePhysicalCores() { @@ -345,6 +349,9 @@ struct KernelCore::Impl { std::shared_ptr irs_shared_mem; std::shared_ptr time_shared_mem; + // Threads used for services + std::unordered_set> service_threads; + std::array, Core::Hardware::NUM_CPU_CORES> suspend_threads{}; std::array interrupts{}; std::array, Core::Hardware::NUM_CPU_CORES> schedulers{}; @@ -639,4 +646,16 @@ void KernelCore::ExitSVCProfile() { MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[core]); } +std::weak_ptr KernelCore::CreateServiceThread(const std::string& name) { + auto service_thread = std::make_shared(*this, 1, name); + impl->service_threads.emplace(service_thread); + return service_thread; +} + +void KernelCore::ReleaseServiceThread(std::weak_ptr service_thread) { + if (auto strong_ptr = service_thread.lock()) { + impl->service_threads.erase(strong_ptr); + } +} + } // namespace Kernel diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 5846c3f39c..e3169f5a7e 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -42,6 +42,7 @@ class Process; class ResourceLimit; class KScheduler; class SharedMemory; +class ServiceThread; class Synchronization; class Thread; class TimeManager; @@ -227,6 +228,22 @@ public: void ExitSVCProfile(); + /** + * Creates an HLE service thread, which are used to execute service routines asynchronously. + * While these are allocated per ServerSession, these need to be owned and managed outside of + * ServerSession to avoid a circular dependency. + * @param name String name for the ServerSession creating this thread, used for debug purposes. + * @returns The a weak pointer newly created service thread. + */ + std::weak_ptr CreateServiceThread(const std::string& name); + + /** + * Releases a HLE service thread, instructing KernelCore to free it. This should be called when + * the ServerSession associated with the thread is destroyed. + * @param service_thread Service thread to release. + */ + void ReleaseServiceThread(std::weak_ptr service_thread); + private: friend class Object; friend class Process; diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 947f4a133b..b40fe39163 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -25,7 +25,10 @@ namespace Kernel { ServerSession::ServerSession(KernelCore& kernel) : SynchronizationObject{kernel} {} -ServerSession::~ServerSession() = default; + +ServerSession::~ServerSession() { + kernel.ReleaseServiceThread(service_thread); +} ResultVal> ServerSession::Create(KernelCore& kernel, std::shared_ptr parent, @@ -34,7 +37,7 @@ ResultVal> ServerSession::Create(KernelCore& kern session->name = std::move(name); session->parent = std::move(parent); - session->service_thread = std::make_unique(kernel, 1, session->name); + session->service_thread = kernel.CreateServiceThread(session->name); return MakeResult(std::move(session)); } @@ -139,7 +142,11 @@ ResultCode ServerSession::QueueSyncRequest(std::shared_ptr thread, std::make_shared(kernel, memory, SharedFrom(this), std::move(thread)); context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf); - service_thread->QueueSyncRequest(*this, std::move(context)); + + if (auto strong_ptr = service_thread.lock()) { + strong_ptr->QueueSyncRequest(*this, std::move(context)); + return RESULT_SUCCESS; + } return RESULT_SUCCESS; } diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 8466b03e60..e8d1d99ea9 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h @@ -167,7 +167,7 @@ private: std::string name; /// Thread to dispatch service requests - std::unique_ptr service_thread; + std::weak_ptr service_thread; }; } // namespace Kernel -- cgit v1.2.3