Просмотр исходного кода

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

bunnei 4 лет назад
Родитель
Сommit
864523327f
2 измененных файлов с 26 добавлено и 4 удалено
  1. 13 1
      src/core/hle/kernel/kernel.cpp
  2. 13 3
      src/core/hle/kernel/kernel.h

+ 13 - 1
src/core/hle/kernel/kernel.cpp

@@ -61,6 +61,7 @@ struct KernelCore::Impl {
         global_scheduler_context = std::make_unique<Kernel::GlobalSchedulerContext>(kernel);
         global_handle_table = std::make_unique<Kernel::KHandleTable>(kernel);
         global_handle_table->Initialize(KHandleTable::MaxTableSize);
+        default_service_thread = CreateServiceThread(kernel, "DefaultServiceThread");
 
         is_phantom_mode_for_singlecore = false;
 
@@ -677,6 +678,12 @@ struct KernelCore::Impl {
 
     void ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) {
         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(
                 [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;
 
     // 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;
 
     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);
 }
 
+std::weak_ptr<Kernel::ServiceThread> KernelCore::GetDefaultServiceThread() const {
+    return impl->default_service_thread;
+}
+
 void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) {
     impl->ReleaseServiceThread(service_thread);
 }

+ 13 - 3
src/core/hle/kernel/kernel.h

@@ -271,15 +271,25 @@ 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.
+     * Creates a host thread to execute HLE service requests, 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. 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
      * purposes.
      * @returns The a weak pointer newly created service thread.
      */
     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
      * the ServerSession associated with the thread is destroyed.