diff --git a/src/video_core/rasterizer_interface.h b/src/video_core/rasterizer_interface.h
index f968b5b164..07939432f3 100644
--- a/src/video_core/rasterizer_interface.h
+++ b/src/video_core/rasterizer_interface.h
@@ -4,10 +4,10 @@
 
 #pragma once
 
-#include <atomic>
 #include <functional>
 #include <optional>
 #include <span>
+#include <stop_token>
 #include "common/common_types.h"
 #include "video_core/engines/fermi_2d.h"
 #include "video_core/gpu.h"
@@ -123,7 +123,7 @@ public:
     virtual void UpdatePagesCachedCount(VAddr addr, u64 size, int delta) {}
 
     /// Initialize disk cached resources for the game being emulated
-    virtual void LoadDiskResources(u64 title_id, const std::atomic_bool& stop_loading,
+    virtual void LoadDiskResources(u64 title_id, std::stop_token stop_loading,
                                    const DiskResourceLoadCallback& callback) {}
 
     /// Grant access to the Guest Driver Profile for recording/obtaining info on the guest driver.
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.cpp b/src/video_core/renderer_opengl/gl_rasterizer.cpp
index f87bb269b6..eb8bdaa85a 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.cpp
+++ b/src/video_core/renderer_opengl/gl_rasterizer.cpp
@@ -351,7 +351,7 @@ void RasterizerOpenGL::SetupShaders(bool is_indexed) {
     }
 }
 
-void RasterizerOpenGL::LoadDiskResources(u64 title_id, const std::atomic_bool& stop_loading,
+void RasterizerOpenGL::LoadDiskResources(u64 title_id, std::stop_token stop_loading,
                                          const VideoCore::DiskResourceLoadCallback& callback) {
     shader_cache.LoadDiskCache(title_id, stop_loading, callback);
 }
diff --git a/src/video_core/renderer_opengl/gl_rasterizer.h b/src/video_core/renderer_opengl/gl_rasterizer.h
index 76298517f5..9995a563b6 100644
--- a/src/video_core/renderer_opengl/gl_rasterizer.h
+++ b/src/video_core/renderer_opengl/gl_rasterizer.h
@@ -94,7 +94,7 @@ public:
                                const Tegra::Engines::Fermi2D::Config& copy_config) override;
     bool AccelerateDisplay(const Tegra::FramebufferConfig& config, VAddr framebuffer_addr,
                            u32 pixel_stride) override;
-    void LoadDiskResources(u64 title_id, const std::atomic_bool& stop_loading,
+    void LoadDiskResources(u64 title_id, std::stop_token stop_loading,
                            const VideoCore::DiskResourceLoadCallback& callback) override;
 
     /// Returns true when there are commands queued to the OpenGL server.
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.cpp b/src/video_core/renderer_opengl/gl_shader_cache.cpp
index 5cf7cd1512..5a01c59ec8 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.cpp
+++ b/src/video_core/renderer_opengl/gl_shader_cache.cpp
@@ -331,7 +331,7 @@ ShaderCacheOpenGL::ShaderCacheOpenGL(RasterizerOpenGL& rasterizer_,
 
 ShaderCacheOpenGL::~ShaderCacheOpenGL() = default;
 
-void ShaderCacheOpenGL::LoadDiskCache(u64 title_id, const std::atomic_bool& stop_loading,
+void ShaderCacheOpenGL::LoadDiskCache(u64 title_id, std::stop_token stop_loading,
                                       const VideoCore::DiskResourceLoadCallback& callback) {
     disk_cache.BindTitleID(title_id);
     const std::optional transferable = disk_cache.LoadTransferable();
@@ -372,7 +372,7 @@ void ShaderCacheOpenGL::LoadDiskCache(u64 title_id, const std::atomic_bool& stop
         const auto scope = context->Acquire();
 
         for (std::size_t i = begin; i < end; ++i) {
-            if (stop_loading) {
+            if (stop_loading.stop_requested()) {
                 return;
             }
             const auto& entry = (*transferable)[i];
@@ -435,7 +435,7 @@ void ShaderCacheOpenGL::LoadDiskCache(u64 title_id, const std::atomic_bool& stop
         precompiled_cache_altered = true;
         return;
     }
-    if (stop_loading) {
+    if (stop_loading.stop_requested()) {
         return;
     }
 
diff --git a/src/video_core/renderer_opengl/gl_shader_cache.h b/src/video_core/renderer_opengl/gl_shader_cache.h
index 2aed0697e3..b30308b6f3 100644
--- a/src/video_core/renderer_opengl/gl_shader_cache.h
+++ b/src/video_core/renderer_opengl/gl_shader_cache.h
@@ -127,7 +127,7 @@ public:
     ~ShaderCacheOpenGL() override;
 
     /// Loads disk cache for the current game
-    void LoadDiskCache(u64 title_id, const std::atomic_bool& stop_loading,
+    void LoadDiskCache(u64 title_id, std::stop_token stop_loading,
                        const VideoCore::DiskResourceLoadCallback& callback);
 
     /// Gets the current specified shader stage program
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index 86495803e0..7524e3c407 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -51,11 +51,11 @@ void EmuThread::run() {
     Common::SetCurrentThreadName(name.c_str());
 
     auto& system = Core::System::GetInstance();
+    auto& gpu = system.GPU();
+    auto stop_token = stop_source.get_token();
 
     system.RegisterHostThread();
 
-    auto& gpu = system.GPU();
-
     // Main process has been loaded. Make the context current to this thread and begin GPU and CPU
     // execution.
     gpu.Start();
@@ -65,7 +65,7 @@ void EmuThread::run() {
     emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
 
     system.Renderer().ReadRasterizer()->LoadDiskResources(
-        system.CurrentProcess()->GetTitleID(), stop_run,
+        system.CurrentProcess()->GetTitleID(), stop_token,
         [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) {
             emit LoadProgress(stage, value, total);
         });
@@ -78,7 +78,7 @@ void EmuThread::run() {
     // so that the DebugModeLeft signal can be emitted before the
     // next execution step
     bool was_active = false;
-    while (!stop_run) {
+    while (!stop_token.stop_requested()) {
         if (running) {
             if (was_active) {
                 emit DebugModeLeft();
@@ -100,7 +100,7 @@ void EmuThread::run() {
             }
             running_guard = false;
 
-            if (!stop_run) {
+            if (!stop_token.stop_requested()) {
                 was_active = true;
                 emit DebugModeEntered();
             }
@@ -108,7 +108,7 @@ void EmuThread::run() {
             UNIMPLEMENTED();
         } else {
             std::unique_lock lock{running_mutex};
-            running_cv.wait(lock, [this] { return IsRunning() || exec_step || stop_run; });
+            running_cv.wait(lock, stop_token, [this] { return IsRunning() || exec_step; });
         }
     }
 
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h
index acfe2bc8c0..402dd2ee17 100644
--- a/src/yuzu/bootmanager.h
+++ b/src/yuzu/bootmanager.h
@@ -89,16 +89,16 @@ public:
      * Requests for the emulation thread to stop running
      */
     void RequestStop() {
-        stop_run = true;
+        stop_source.request_stop();
         SetRunning(false);
     }
 
 private:
     bool exec_step = false;
     bool running = false;
-    std::atomic_bool stop_run{false};
+    std::stop_source stop_source;
     std::mutex running_mutex;
-    std::condition_variable running_cv;
+    std::condition_variable_any running_cv;
     Common::Event running_wait{};
     std::atomic_bool running_guard{false};
 
diff --git a/src/yuzu_cmd/yuzu.cpp b/src/yuzu_cmd/yuzu.cpp
index 584967f5c9..50e3883122 100644
--- a/src/yuzu_cmd/yuzu.cpp
+++ b/src/yuzu_cmd/yuzu.cpp
@@ -219,7 +219,7 @@ int main(int argc, char** argv) {
     system.GPU().Start();
 
     system.Renderer().ReadRasterizer()->LoadDiskResources(
-        system.CurrentProcess()->GetTitleID(), false,
+        system.CurrentProcess()->GetTitleID(), std::stop_token{},
         [](VideoCore::LoadCallbackStage, size_t value, size_t total) {});
 
     void(system.Run());