From 8562b516c0e3fa25a65e440db29cd474c0cbb896 Mon Sep 17 00:00:00 2001 From: ReinUsesLisp Date: Sun, 28 Jun 2020 21:42:57 -0300 Subject: 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 5c83c41a4..a63e60461 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& 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& 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 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 2b12c0dbf..7b929781c 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 +#include #include #include #include @@ -31,22 +32,20 @@ GlobalScheduler::GlobalScheduler(KernelCore& kernel) : kernel{kernel} {} GlobalScheduler::~GlobalScheduler() = default; void GlobalScheduler::AddThread(std::shared_ptr 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) { - 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(); -- cgit v1.2.3