diff --git a/src/common/utils/time.hpp b/src/common/utils/time.hpp index b887e789..fdc3d89f 100644 --- a/src/common/utils/time.hpp +++ b/src/common/utils/time.hpp @@ -3,6 +3,12 @@ #include #include "../platform/platform.hpp" +#if defined(_MSC_VER) +#include +#pragma intrinsic(__rdtsc) +#elif defined(__x86_64__) || defined(__i386__) || defined(__amd64__) +#include +#endif constexpr auto HUNDRED_NANOSECONDS_IN_ONE_SECOND = 10000000LL; constexpr auto EPOCH_DIFFERENCE_1601_TO_1970_SECONDS = 11644473600LL; @@ -29,6 +35,19 @@ namespace utils { return std::chrono::steady_clock::now(); } + + // Returns the current timestamp counter value. RDTSC on x86/x64, or just time since epoch for ARM + /// TODO: find better solution for ARM and Figure out better CPU base frequency heuristics + virtual uint64_t timestamp_counter() + { +#if defined(_M_X64) || defined(_M_AMD64) || defined(_M_IX86) || defined(__x86_64__) || defined(__i386__) || \ + defined(__amd64__) + return __rdtsc(); // any x86 system will have this instrinsic +#else + const auto count = std::chrono::high_resolution_clock::now().time_since_epoch().count(); + return static_cast((count * 38LL) / 10LL); +#endif + } }; class tick_clock : public clock diff --git a/src/windows-emulator/windows_emulator.cpp b/src/windows-emulator/windows_emulator.cpp index e87f7044..8bdb30bb 100644 --- a/src/windows-emulator/windows_emulator.cpp +++ b/src/windows-emulator/windows_emulator.cpp @@ -448,9 +448,9 @@ void windows_emulator::setup_hooks() }); this->emu().hook_instruction(x64_hookable_instructions::rdtsc, [&] { - const auto instructions = this->executed_instructions_; - this->emu().reg(x64_register::rax, instructions & 0xFFFFFFFF); - this->emu().reg(x64_register::rdx, (instructions >> 32) & 0xFFFFFFFF); + const auto ticks = this->clock_->timestamp_counter(); + this->emu().reg(x64_register::rax, ticks & 0xFFFFFFFF); + this->emu().reg(x64_register::rdx, (ticks >> 32) & 0xFFFFFFFF); return instruction_hook_continuation::skip_instruction; });