hle: kernel: Create a default thread for services that do not need their own host thread.

master
bunnei 2022-03-30 21:11:11 +07:00 committed by Morph
parent 550844e5e8
commit 864523327f
2 changed files with 26 additions and 4 deletions

@ -61,6 +61,7 @@ struct KernelCore::Impl {
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); global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel);
global_handle_table->Initialize(KHandleTable::MaxTableSize); global_handle_table->Initialize(KHandleTable::MaxTableSize);
default_service_thread = CreateServiceThread(kernel, "DefaultServiceThread");
is_phantom_mode_for_singlecore = false; is_phantom_mode_for_singlecore = false;
@ -677,6 +678,12 @@ struct KernelCore::Impl {
void ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) { void ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) {
if (auto strong_ptr = service_thread.lock()) { if (auto strong_ptr = service_thread.lock()) {
if (strong_ptr == default_service_thread.lock()) {
// Nothing to do here, the service is using default_service_thread, which will be
// released on shutdown.
return;
}
service_threads_manager.QueueWork( service_threads_manager.QueueWork(
[this, strong_ptr{std::move(strong_ptr)}]() { service_threads.erase(strong_ptr); }); [this, strong_ptr{std::move(strong_ptr)}]() { service_threads.erase(strong_ptr); });
} }
@ -739,7 +746,8 @@ struct KernelCore::Impl {
std::unique_ptr<KMemoryLayout> memory_layout; std::unique_ptr<KMemoryLayout> memory_layout;
// Threads used for services // Threads used for services
std::unordered_set<std::shared_ptr<Kernel::ServiceThread>> service_threads; std::unordered_set<std::shared_ptr<ServiceThread>> service_threads;
std::weak_ptr<ServiceThread> default_service_thread;
Common::ThreadWorker service_threads_manager; Common::ThreadWorker service_threads_manager;
std::array<KThread*, Core::Hardware::NUM_CPU_CORES> suspend_threads; std::array<KThread*, Core::Hardware::NUM_CPU_CORES> suspend_threads;
@ -1065,6 +1073,10 @@ std::weak_ptr<Kernel::ServiceThread> KernelCore::CreateServiceThread(const std::
return impl->CreateServiceThread(*this, name); return impl->CreateServiceThread(*this, name);
} }
std::weak_ptr<Kernel::ServiceThread> KernelCore::GetDefaultServiceThread() const {
return impl->default_service_thread;
}
void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) { void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) {
impl->ReleaseServiceThread(service_thread); impl->ReleaseServiceThread(service_thread);
} }

@ -271,15 +271,25 @@ public:
void ExitSVCProfile(); void ExitSVCProfile();
/** /**
* Creates an HLE service thread, which are used to execute service routines asynchronously. * Creates a host thread to execute HLE service requests, which are used to execute service
* While these are allocated per ServerSession, these need to be owned and managed outside * routines asynchronously. While these are allocated per ServerSession, these need to be owned
* of ServerSession to avoid a circular dependency. * and managed outside of ServerSession to avoid a circular dependency. In general, most
* services can just use the default service thread, and not need their own host service thread.
* See GetDefaultServiceThread.
* @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);
/**
* Gets the default host service thread, which executes HLE service requests. Unless service
* requests need to block on the host, the default service thread should be used in favor of
* creating a new service thread.
* @returns The a weak pointer for the default service thread.
*/
std::weak_ptr<Kernel::ServiceThread> GetDefaultServiceThread() const;
/** /**
* Releases a HLE service thread, instructing KernelCore to free it. This should be called when * Releases a HLE service thread, instructing KernelCore to free it. This should be called when
* the ServerSession associated with the thread is destroyed. * the ServerSession associated with the thread is destroyed.