diff --git a/README.md b/README.md index 373e8aabe..1d46f6807 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 2662. +This is the source code for early-access 2663. ## Legal Notice diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3ad2c0950..9182dbfd4 100755 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -65,12 +65,14 @@ if (MSVC) /we4305 # 'context': truncation from 'type1' to 'type2' /we4388 # 'expression': signed/unsigned mismatch /we4389 # 'operator': signed/unsigned mismatch + /we4505 # 'function': unreferenced local function has been removed /we4547 # 'operator': operator before comma has no effect; expected operator with side-effect /we4549 # 'operator1': operator before comma has no effect; did you intend 'operator2'? /we4555 # Expression has no effect; expected expression with side-effect /we4715 # 'function': not all control paths return a value /we4834 # Discarding return value of function with 'nodiscard' attribute /we5038 # data member 'member1' will be initialized after data member 'member2' + /we5245 # 'function': unreferenced function with internal linkage has been removed ) if (ARCHITECTURE_x86_64) diff --git a/src/common/fiber.cpp b/src/common/fiber.cpp index 177a74deb..81b212e4b 100755 --- a/src/common/fiber.cpp +++ b/src/common/fiber.cpp @@ -2,10 +2,9 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include - #include "common/assert.h" #include "common/fiber.h" +#include "common/spin_lock.h" #include "common/virtual_buffer.h" #include @@ -20,7 +19,7 @@ struct Fiber::FiberImpl { VirtualBuffer stack; VirtualBuffer rewind_stack; - std::mutex guard; + SpinLock guard{}; std::function entry_point; std::function rewind_point; void* rewind_parameter{}; diff --git a/src/core/core_timing.h b/src/core/core_timing.h index 28b63be43..888828fd0 100755 --- a/src/core/core_timing.h +++ b/src/core/core_timing.h @@ -8,13 +8,13 @@ #include #include #include -#include #include #include #include #include #include "common/common_types.h" +#include "common/spin_lock.h" #include "common/thread.h" #include "common/wall_clock.h" @@ -149,8 +149,8 @@ private: std::shared_ptr ev_lost; Common::Event event{}; Common::Event pause_event{}; - std::mutex basic_lock; - std::mutex advance_lock; + Common::SpinLock basic_lock{}; + Common::SpinLock advance_lock{}; std::unique_ptr timer_thread; std::atomic paused{}; std::atomic paused_set{}; diff --git a/src/core/hle/kernel/global_scheduler_context.h b/src/core/hle/kernel/global_scheduler_context.h index 47425a3a1..6f44b534f 100755 --- a/src/core/hle/kernel/global_scheduler_context.h +++ b/src/core/hle/kernel/global_scheduler_context.h @@ -8,6 +8,7 @@ #include #include "common/common_types.h" +#include "common/spin_lock.h" #include "core/hardware_properties.h" #include "core/hle/kernel/k_priority_queue.h" #include "core/hle/kernel/k_scheduler_lock.h" @@ -79,7 +80,7 @@ private: /// Lists all thread ids that aren't deleted/etc. std::vector thread_list; - std::mutex global_list_guard; + Common::SpinLock global_list_guard{}; }; } // namespace Kernel diff --git a/src/core/hle/kernel/k_scheduler.cpp b/src/core/hle/kernel/k_scheduler.cpp index 526eb4b70..6c0bb1672 100755 --- a/src/core/hle/kernel/k_scheduler.cpp +++ b/src/core/hle/kernel/k_scheduler.cpp @@ -705,7 +705,7 @@ void KScheduler::Unload(KThread* thread) { prev_thread = nullptr; } - thread->context_guard.unlock(); + thread->context_guard.Unlock(); } void KScheduler::Reload(KThread* thread) { @@ -794,13 +794,13 @@ void KScheduler::SwitchToCurrent() { do { auto next_thread = current_thread.load(); if (next_thread != nullptr) { - const auto locked = next_thread->context_guard.try_lock(); + const auto locked = next_thread->context_guard.TryLock(); if (state.needs_scheduling.load()) { - next_thread->context_guard.unlock(); + next_thread->context_guard.Unlock(); break; } if (next_thread->GetActiveCore() != core_id) { - next_thread->context_guard.unlock(); + next_thread->context_guard.Unlock(); break; } if (!locked) { diff --git a/src/core/hle/kernel/k_spin_lock.cpp b/src/core/hle/kernel/k_spin_lock.cpp index 4df2e5c1a..4412aa4bb 100755 --- a/src/core/hle/kernel/k_spin_lock.cpp +++ b/src/core/hle/kernel/k_spin_lock.cpp @@ -35,15 +35,20 @@ void ThreadPause() { namespace Kernel { void KSpinLock::Lock() { - lck.lock(); + while (lck.test_and_set(std::memory_order_acquire)) { + ThreadPause(); + } } void KSpinLock::Unlock() { - lck.unlock(); + lck.clear(std::memory_order_release); } bool KSpinLock::TryLock() { - return lck.try_lock(); + if (lck.test_and_set(std::memory_order_acquire)) { + return false; + } + return true; } } // namespace Kernel diff --git a/src/core/hle/kernel/k_spin_lock.h b/src/core/hle/kernel/k_spin_lock.h index 7868b25a5..4d87d006a 100755 --- a/src/core/hle/kernel/k_spin_lock.h +++ b/src/core/hle/kernel/k_spin_lock.h @@ -4,7 +4,7 @@ #pragma once -#include +#include #include "core/hle/kernel/k_scoped_lock.h" @@ -25,7 +25,7 @@ public: [[nodiscard]] bool TryLock(); private: - std::mutex lck; + std::atomic_flag lck = ATOMIC_FLAG_INIT; }; // TODO(bunnei): Alias for now, in case we want to implement these accurately in the future. diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index c141fc11b..d0fd85130 100755 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h @@ -15,7 +15,6 @@ #include "common/common_types.h" #include "common/intrusive_red_black_tree.h" -#include "common/spin_lock.h" #include "core/arm/arm_interface.h" #include "core/hle/kernel/k_affinity_mask.h" #include "core/hle/kernel/k_light_lock.h" @@ -763,7 +762,7 @@ private: s8 priority_inheritance_count{}; bool resource_limit_release_hint{}; StackParameters stack_parameters{}; - Common::SpinLock context_guard{}; + KSpinLock context_guard{}; KSpinLock dummy_wait_lock{}; // For emulation diff --git a/src/core/hle/kernel/physical_core.cpp b/src/core/hle/kernel/physical_core.cpp index cc49e8c7e..18a5f40f8 100755 --- a/src/core/hle/kernel/physical_core.cpp +++ b/src/core/hle/kernel/physical_core.cpp @@ -2,6 +2,7 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include "common/spin_lock.h" #include "core/arm/cpu_interrupt_handler.h" #include "core/arm/dynarmic/arm_dynarmic_32.h" #include "core/arm/dynarmic/arm_dynarmic_64.h" @@ -15,7 +16,7 @@ namespace Kernel { PhysicalCore::PhysicalCore(std::size_t core_index_, Core::System& system_, KScheduler& scheduler_, Core::CPUInterrupts& interrupts_) : core_index{core_index_}, system{system_}, scheduler{scheduler_}, - interrupts{interrupts_}, guard{std::make_unique()} { + interrupts{interrupts_}, guard{std::make_unique()} { #ifdef ARCHITECTURE_x86_64 // TODO(bunnei): Initialization relies on a core being available. We may later replace this with // a 32-bit instance of Dynarmic. This should be abstracted out to a CPU manager. diff --git a/src/core/hle/kernel/physical_core.h b/src/core/hle/kernel/physical_core.h index f2112fc1d..16a032e89 100755 --- a/src/core/hle/kernel/physical_core.h +++ b/src/core/hle/kernel/physical_core.h @@ -6,10 +6,13 @@ #include #include -#include #include "core/arm/arm_interface.h" +namespace Common { +class SpinLock; +} + namespace Kernel { class KScheduler; } // namespace Kernel @@ -88,7 +91,7 @@ private: Core::System& system; Kernel::KScheduler& scheduler; Core::CPUInterrupts& interrupts; - std::unique_ptr guard; + std::unique_ptr guard; std::unique_ptr arm_interface; }; diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 148265218..c78b2baeb 100755 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -9,6 +9,7 @@ #include #include #include "common/common_types.h" +#include "common/spin_lock.h" #include "core/hle/kernel/hle_ipc.h" //////////////////////////////////////////////////////////////////////////////////////////////////// @@ -89,7 +90,7 @@ protected: using HandlerFnP = void (Self::*)(Kernel::HLERequestContext&); /// Used to gain exclusive access to the service members, e.g. from CoreTiming thread. - [[nodiscard]] std::scoped_lock LockService() { + [[nodiscard]] std::scoped_lock LockService() { return std::scoped_lock{lock_service}; } @@ -134,7 +135,7 @@ private: boost::container::flat_map handlers_tipc; /// Used to gain exclusive access to the service members, e.g. from CoreTiming thread. - std::mutex lock_service; + Common::SpinLock lock_service; }; /**