From 8562b516c0e3fa25a65e440db29cd474c0cbb896 Mon Sep 17 00:00:00 2001
From: ReinUsesLisp <reinuseslisp@airmail.cc>
Date: Sun, 28 Jun 2020 21:42:57 -0300
Subject: [PATCH] core_timing,scheduler: Use std::scoped_lock when possible

Simplifies the cognitive load of procedures using locks and makes locks
safe against exceptions.
---
 src/core/core_timing.cpp          |  6 ++----
 src/core/hle/kernel/scheduler.cpp | 21 ++++++++++-----------
 2 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index 5c83c41a40..a63e604610 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -172,7 +172,7 @@ void CoreTiming::ClearPendingEvents() {
 }
 
 void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) {
-    basic_lock.lock();
+    std::scoped_lock lock{basic_lock};
 
     const auto itr = std::remove_if(event_queue.begin(), event_queue.end(), [&](const Event& e) {
         return e.type.lock().get() == event_type.get();
@@ -183,12 +183,10 @@ void CoreTiming::RemoveEvent(const std::shared_ptr<EventType>& event_type) {
         event_queue.erase(itr, event_queue.end());
         std::make_heap(event_queue.begin(), event_queue.end(), std::greater<>());
     }
-    basic_lock.unlock();
 }
 
 std::optional<s64> CoreTiming::Advance() {
-    std::scoped_lock advance_scope{advance_lock};
-    std::scoped_lock basic_scope{basic_lock};
+    std::scoped_lock lock{advance_lock, basic_lock};
     global_timer = GetGlobalTimeNs().count();
 
     while (!event_queue.empty() && event_queue.front().time <= global_timer) {
diff --git a/src/core/hle/kernel/scheduler.cpp b/src/core/hle/kernel/scheduler.cpp
index 2b12c0dbf4..7b929781c8 100644
--- a/src/core/hle/kernel/scheduler.cpp
+++ b/src/core/hle/kernel/scheduler.cpp
@@ -6,6 +6,7 @@
 // licensed under GPLv2 or later under exception provided by the author.
 
 #include <algorithm>
+#include <mutex>
 #include <set>
 #include <unordered_set>
 #include <utility>
@@ -31,22 +32,20 @@ GlobalScheduler::GlobalScheduler(KernelCore& kernel) : kernel{kernel} {}
 GlobalScheduler::~GlobalScheduler() = default;
 
 void GlobalScheduler::AddThread(std::shared_ptr<Thread> thread) {
-    global_list_guard.lock();
+    std::scoped_lock lock{global_list_guard};
     thread_list.push_back(std::move(thread));
-    global_list_guard.unlock();
 }
 
 void GlobalScheduler::RemoveThread(std::shared_ptr<Thread> thread) {
-    global_list_guard.lock();
+    std::scoped_lock lock{global_list_guard};
     thread_list.erase(std::remove(thread_list.begin(), thread_list.end(), thread),
                       thread_list.end());
-    global_list_guard.unlock();
 }
 
 u32 GlobalScheduler::SelectThreads() {
     ASSERT(is_locked);
     const auto update_thread = [](Thread* thread, Scheduler& sched) {
-        sched.guard.lock();
+        std::scoped_lock lock{sched.guard};
         if (thread != sched.selected_thread_set.get()) {
             if (thread == nullptr) {
                 ++sched.idle_selection_count;
@@ -57,7 +56,6 @@ u32 GlobalScheduler::SelectThreads() {
             sched.is_context_switch_pending || (sched.selected_thread_set != sched.current_thread);
         sched.is_context_switch_pending = reschedule_pending;
         std::atomic_thread_fence(std::memory_order_seq_cst);
-        sched.guard.unlock();
         return reschedule_pending;
     };
     if (!is_reselection_pending.load()) {
@@ -757,11 +755,12 @@ void Scheduler::OnSwitch(void* this_scheduler) {
 
 void Scheduler::SwitchToCurrent() {
     while (true) {
-        guard.lock();
-        selected_thread = selected_thread_set;
-        current_thread = selected_thread;
-        is_context_switch_pending = false;
-        guard.unlock();
+        {
+            std::scoped_lock lock{guard};
+            selected_thread = selected_thread_set;
+            current_thread = selected_thread;
+            is_context_switch_pending = false;
+        }
         while (!is_context_switch_pending) {
             if (current_thread != nullptr && !current_thread->IsHLEThread()) {
                 current_thread->context_guard.lock();
-- 
GitLab