Browse Source

[gpu] Fix infinite hangup/freezes at shutdown/reset (#4395)

Thread may be destroyed at dtor(), but it hasn't fully shut down, so before notify shutdown, request immediate stop (effective immediately).

Like the issue was that the thread didn't want to stop running, thus it would hang, it would also reference objects which were being destroyed without waiting for them to actually be destroyed
So it would reference invalid data
This PR tells the thread: "hey, STOP now, and DESTROY yourself"
So all of that should be avoided

Signed-off-by: lizzie <lizzie@eden-emu.dev>

- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4395
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
pull/4334/head
lizzie 1 day ago
committed by crueter
parent
commit
c95ad020fb
No known key found for this signature in database GPG Key ID: 425ACD2D4830EBC6
  1. 9
      src/video_core/gpu.cpp
  2. 7
      src/video_core/gpu_thread.cpp
  3. 2
      src/video_core/gpu_thread.h

9
src/video_core/gpu.cpp

@ -55,8 +55,8 @@ constexpr u64 GpuClockMultiplier(Settings::GpuClock clock) {
struct GPU::Impl {
explicit Impl(Core::System& system_, bool is_async_, bool use_nvdec_)
: gpu_thread{system_}
, system{system_}
: system{system_}
, gpu_thread{system_}
, use_nvdec{use_nvdec_}
, shader_notify()
, is_async{is_async_}
@ -182,6 +182,7 @@ struct GPU::Impl {
}
void NotifyShutdown() {
gpu_thread.NotifyShutdown();
std::unique_lock lk{sync_mutex};
shutting_down.store(true, std::memory_order::relaxed);
sync_cv.notify_all();
@ -301,12 +302,12 @@ struct GPU::Impl {
return out;
}
Core::System& system;
// Destruction of thread must be done before all (non trivial)
// previous members has been destroyed
VideoCommon::GPUThread::ThreadManager gpu_thread;
Core::System& system;
std::unique_ptr<VideoCore::RendererBase> renderer;
const bool use_nvdec;

7
src/video_core/gpu_thread.cpp

@ -114,4 +114,11 @@ u64 ThreadManager::PushCommand(CommandData&& command_data, bool block, bool is_a
return fence;
}
void ThreadManager::NotifyShutdown() {
if (thread.joinable()) {
thread.request_stop();
thread.join();
}
}
} // namespace VideoCommon::GPUThread

2
src/video_core/gpu_thread.h

@ -125,6 +125,8 @@ public:
void TickGPU(bool is_async);
void NotifyShutdown();
private:
/// Pushes a command to be executed by the GPU thread
u64 PushCommand(CommandData&& command_data, bool block, bool is_async);

Loading…
Cancel
Save