aboutsummaryrefslogtreecommitdiff
path: root/src/common/x64/cpu_wait.cpp
diff options
context:
space:
mode:
authorlizzie <lizzie@eden-emu.dev>2026-05-30 21:59:10 +0200
committercrueter <crueter@eden-emu.dev>2026-05-30 21:59:10 +0200
commit7c32cf03a1ce2a88b5bda041a5aebc8405fe634d (patch)
tree8eabbb338cceebd7f018a7c442a304fd66c68adc /src/common/x64/cpu_wait.cpp
parentff7bbaea7db5a9a9528c1ef087d3a49a18931b52 (diff)
[core/core_timing] better MWAITX and WAITPKG delays (#3984)
This implements MWAITX and WAITPKG extensions (umonitor, mwait) for CPUs that support them. Reduces wait times and bypasses the timing stuff from the OS that is slow (windows notably). generally it should answer within 0.2 to 0.5 microsecs (since most requests wait for that long). Also does a general rework of static ctors and stuff Signed-off-by: lizzie <lizzie@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3984 Reviewed-by: MaranBr <maranbr@eden-emu.dev> Reviewed-by: crueter <crueter@eden-emu.dev>
Diffstat (limited to 'src/common/x64/cpu_wait.cpp')
-rw-r--r--src/common/x64/cpu_wait.cpp75
1 files changed, 0 insertions, 75 deletions
diff --git a/src/common/x64/cpu_wait.cpp b/src/common/x64/cpu_wait.cpp
deleted file mode 100644
index 85d27161ba..0000000000
--- a/src/common/x64/cpu_wait.cpp
+++ /dev/null
@@ -1,75 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
-// SPDX-License-Identifier: GPL-3.0-or-later
-
-#include <thread>
-
-#ifdef _MSC_VER
-#include <intrin.h>
-#endif
-
-#include "common/x64/cpu_detect.h"
-#include "common/x64/cpu_wait.h"
-#include "common/x64/rdtsc.h"
-
-namespace Common::X64 {
-
-namespace {
-
-// 100,000 cycles is a reasonable amount of time to wait to save on CPU resources.
-// For reference:
-// At 1 GHz, 100K cycles is 100us
-// At 2 GHz, 100K cycles is 50us
-// At 4 GHz, 100K cycles is 25us
-constexpr auto PauseCycles = 100'000U;
-
-} // Anonymous namespace
-
-#if defined(_MSC_VER) && !defined(__clang__)
-__forceinline static void TPAUSE() {
- static constexpr auto RequestC02State = 0U;
- _tpause(RequestC02State, FencedRDTSC() + PauseCycles);
-}
-
-__forceinline static void MWAITX() {
- static constexpr auto EnableWaitTimeFlag = 1U << 1;
- static constexpr auto RequestC1State = 0U;
-
- // monitor_var should be aligned to a cache line.
- alignas(64) u64 monitor_var{};
- _mm_monitorx(&monitor_var, 0, 0);
- _mm_mwaitx(EnableWaitTimeFlag, RequestC1State, PauseCycles);
-}
-#else
-static void TPAUSE() {
- static constexpr auto RequestC02State = 0U;
- const auto tsc = FencedRDTSC() + PauseCycles;
- const auto eax = static_cast<u32>(tsc & 0xFFFFFFFF);
- const auto edx = static_cast<u32>(tsc >> 32);
- asm volatile("tpause %0" : : "r"(RequestC02State), "d"(edx), "a"(eax));
-}
-
-static void MWAITX() {
- static constexpr auto EnableWaitTimeFlag = 1U << 1;
- static constexpr auto RequestC1State = 0U;
-
- // monitor_var should be aligned to a cache line.
- alignas(64) u64 monitor_var{};
- asm volatile("monitorx" : : "a"(&monitor_var), "c"(0), "d"(0));
- asm volatile("mwaitx" : : "a"(RequestC1State), "b"(PauseCycles), "c"(EnableWaitTimeFlag));
-}
-#endif
-
-void MicroSleep() {
- static const bool has_waitpkg = GetCPUCaps().waitpkg;
- static const bool has_monitorx = GetCPUCaps().monitorx;
-
- if (has_waitpkg) {
- TPAUSE();
- } else if (has_monitorx) {
- MWAITX();
- } else {
- std::this_thread::yield();
- }
-}
-
-} // namespace Common::X64