From 07b6ec3c7e059431163f7ca8c98cd0c06276c460 Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Sun, 6 Nov 2022 00:51:43 +0100 Subject: [PATCH] early-access version 3091 --- README.md | 2 +- src/core/hle/kernel/k_thread.cpp | 4 +-- src/core/hle/kernel/k_thread.h | 2 +- src/core/hle/kernel/kernel.cpp | 49 ++++++++++++++++++-------- src/core/hle/kernel/kernel.h | 2 +- src/core/hle/kernel/service_thread.cpp | 24 +++++++++---- 6 files changed, 57 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index bf951cc85..ed9fa0d7d 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 3090. +This is the source code for early-access 3091. ## Legal Notice diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 04fda2e77..d11967bf5 100755 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -263,9 +263,9 @@ Result KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_ R_SUCCEED(); } -Result KThread::InitializeDummyThread(KThread* thread) { +Result KThread::InitializeDummyThread(KThread* thread, KProcess* owner) { // Initialize the thread. - R_TRY(thread->Initialize({}, {}, {}, DummyThreadPriority, 3, {}, ThreadType::Dummy)); + R_TRY(thread->Initialize({}, {}, {}, DummyThreadPriority, 3, owner, ThreadType::Dummy)); // Initialize emulation parameters. thread->stack_parameters.disable_count = 0; diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index 6d3632288..3e6f58233 100755 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h @@ -415,7 +415,7 @@ public: static void PostDestroy(uintptr_t arg); - [[nodiscard]] static Result InitializeDummyThread(KThread* thread); + [[nodiscard]] static Result InitializeDummyThread(KThread* thread, KProcess* owner); [[nodiscard]] static Result InitializeMainThread(Core::System& system, KThread* thread, s32 virt_core); diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 04ab6a041..8be7fc377 100755 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -91,7 +91,7 @@ struct KernelCore::Impl { pt_heap_region.GetSize()); } - RegisterHostThread(); + RegisterHostThread(nullptr); default_service_thread = CreateServiceThread(kernel, "DefaultServiceThread"); } @@ -373,15 +373,18 @@ struct KernelCore::Impl { } // Gets the dummy KThread for the caller, allocating a new one if this is the first time - KThread* GetHostDummyThread() { + KThread* GetHostDummyThread(KThread* existing_thread) { auto initialize = [this](KThread* thread) { - ASSERT(KThread::InitializeDummyThread(thread).IsSuccess()); + ASSERT(KThread::InitializeDummyThread(thread, nullptr).IsSuccess()); thread->SetName(fmt::format("DummyThread:{}", GetHostThreadId())); return thread; }; - thread_local auto raw_thread = KThread(system.Kernel()); - thread_local auto thread = initialize(&raw_thread); + thread_local KThread raw_thread{system.Kernel()}; + thread_local KThread* thread = nullptr; + if (thread == nullptr) { + thread = (existing_thread == nullptr) ? initialize(&raw_thread) : existing_thread; + } return thread; } @@ -396,9 +399,9 @@ struct KernelCore::Impl { } /// Registers a new host thread by allocating a host thread ID for it - void RegisterHostThread() { + void RegisterHostThread(KThread* existing_thread) { [[maybe_unused]] const auto this_id = GetHostThreadId(); - [[maybe_unused]] const auto dummy_thread = GetHostDummyThread(); + [[maybe_unused]] const auto dummy_thread = GetHostDummyThread(existing_thread); } [[nodiscard]] u32 GetCurrentHostThreadID() { @@ -429,7 +432,7 @@ struct KernelCore::Impl { KThread* GetCurrentEmuThread() { const auto thread_id = GetCurrentHostThreadID(); if (thread_id >= Core::Hardware::NUM_CPU_CORES) { - return GetHostDummyThread(); + return GetHostDummyThread(nullptr); } return current_thread; @@ -1122,8 +1125,12 @@ void KernelCore::RegisterCoreThread(std::size_t core_id) { impl->RegisterCoreThread(core_id); } -void KernelCore::RegisterHostThread() { - impl->RegisterHostThread(); +void KernelCore::RegisterHostThread(KThread* existing_thread) { + impl->RegisterHostThread(existing_thread); + + if (existing_thread != nullptr) { + ASSERT(GetCurrentEmuThread() == existing_thread); + } } u32 KernelCore::GetCurrentHostThreadID() const { @@ -1198,16 +1205,28 @@ void KernelCore::Suspend(bool suspended) { const bool should_suspend{exception_exited || suspended}; const auto activity = should_suspend ? ProcessActivity::Paused : ProcessActivity::Runnable; - for (auto* process : GetProcessList()) { - process->SetActivity(activity); + std::vector> process_threads; + { + KScopedSchedulerLock sl{*this}; + + if (auto* process = CurrentProcess(); process != nullptr) { + process->SetActivity(activity); + + if (!should_suspend) { + // Runnable now; no need to wait. + return; + } - if (should_suspend) { - // Wait for execution to stop for (auto* thread : process->GetThreadList()) { - thread->WaitUntilSuspended(); + process_threads.emplace_back(thread); } } } + + // Wait for execution to stop. + for (auto& thread : process_threads) { + thread->WaitUntilSuspended(); + } } void KernelCore::ShutdownCores() { diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 9fbbf4fa8..b87714c4a 100755 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -240,7 +240,7 @@ public: void RegisterCoreThread(std::size_t core_id); /// Register the current thread as a non CPU core thread. - void RegisterHostThread(); + void RegisterHostThread(KThread* existing_thread = nullptr); /// Gets the virtual memory manager for the kernel. KMemoryManager& MemoryManager(); diff --git a/src/core/hle/kernel/service_thread.cpp b/src/core/hle/kernel/service_thread.cpp index 207531198..e326d1374 100755 --- a/src/core/hle/kernel/service_thread.cpp +++ b/src/core/hle/kernel/service_thread.cpp @@ -36,11 +36,12 @@ public: private: KernelCore& kernel; - std::jthread m_thread; + std::jthread m_host_thread; std::mutex m_session_mutex; std::map> m_sessions; KEvent* m_wakeup_event; KProcess* m_process; + KThread* m_thread; std::atomic m_shutdown_requested; const std::string m_service_name; }; @@ -132,7 +133,7 @@ void ServiceThread::Impl::SessionClosed(KServerSession* server_session, void ServiceThread::Impl::LoopProcess() { Common::SetCurrentThreadName(m_service_name.c_str()); - kernel.RegisterHostThread(); + kernel.RegisterHostThread(m_thread); while (!m_shutdown_requested.load()) { WaitAndProcessImpl(); @@ -160,7 +161,7 @@ ServiceThread::Impl::~Impl() { // Shut down the processing thread. m_shutdown_requested.store(true); m_wakeup_event->Signal(); - m_thread.join(); + m_host_thread.join(); // Lock mutex. m_session_mutex.lock(); @@ -177,6 +178,9 @@ ServiceThread::Impl::~Impl() { m_wakeup_event->GetReadableEvent().Close(); m_wakeup_event->Close(); + // Close thread. + m_thread->Close(); + // Close process. m_process->Close(); } @@ -199,11 +203,19 @@ ServiceThread::Impl::Impl(KernelCore& kernel_, const std::string& service_name) // Commit the event reservation. event_reservation.Commit(); - // Register the event. - KEvent::Register(kernel, m_wakeup_event); + // Reserve a new thread from the process resource limit + KScopedResourceReservation thread_reservation(m_process, LimitableResource::Threads); + ASSERT(thread_reservation.Succeeded()); + + // Initialize thread. + m_thread = KThread::Create(kernel); + ASSERT(KThread::InitializeDummyThread(m_thread, m_process).IsSuccess()); + + // Commit the thread reservation. + thread_reservation.Commit(); // Start thread. - m_thread = std::jthread([this] { LoopProcess(); }); + m_host_thread = std::jthread([this] { LoopProcess(); }); } ServiceThread::ServiceThread(KernelCore& kernel, const std::string& name)