From 1021009296dec4fecece597b07f87702fb66e9db Mon Sep 17 00:00:00 2001 From: momo5502 Date: Sat, 26 Oct 2024 10:06:02 +0200 Subject: [PATCH] Fix instruction execution counting --- src/test-sample/test.cpp | 3 +- src/windows-emulator-test/emulation_test.cpp | 31 +++++++++++++++++-- .../emulation_test_utils.hpp | 14 ++++++--- .../serialization_test.cpp | 10 +++--- src/windows-emulator/windows_emulator.cpp | 21 ++++++------- 5 files changed, 56 insertions(+), 23 deletions(-) diff --git a/src/test-sample/test.cpp b/src/test-sample/test.cpp index 7cb28819..58aa7538 100644 --- a/src/test-sample/test.cpp +++ b/src/test-sample/test.cpp @@ -35,7 +35,8 @@ bool test_threads() ++counter; std::this_thread::yield(); ++counter; - std::this_thread::sleep_for(std::chrono::milliseconds(100)); + // Host scheduling/cpu performance can have impact on emulator scheduling + //std::this_thread::sleep_for(std::chrono::milliseconds(100)); ++counter; }); } diff --git a/src/windows-emulator-test/emulation_test.cpp b/src/windows-emulator-test/emulation_test.cpp index 2088359d..81b57ae3 100644 --- a/src/windows-emulator-test/emulation_test.cpp +++ b/src/windows-emulator-test/emulation_test.cpp @@ -8,12 +8,12 @@ namespace test emu.logger.disable_output(true); emu.start(); - ASSER_TERMINATED_SUCCESSFULLY(emu); + ASSERT_TERMINATED_SUCCESSFULLY(emu); } TEST(EmulationTest, CountedEmulationWorks) { - constexpr auto count = 123; + constexpr auto count = 200000; windows_emulator emu{ "./test-sample.exe" }; emu.logger.disable_output(true); @@ -21,4 +21,31 @@ namespace test ASSERT_EQ(emu.process().executed_instructions, count); } + + TEST(EmulationTest, CountedEmulationIsAccurate) + { + windows_emulator emu{ "./test-sample.exe" }; + emu.logger.disable_output(true); + emu.start(); + + ASSERT_TERMINATED_SUCCESSFULLY(emu); + + const auto executedInstructions = emu.process().executed_instructions; + + windows_emulator new_emu{ "./test-sample.exe" }; + new_emu.logger.disable_output(true); + + constexpr auto offset = 1; + const auto instructionsToExecute = executedInstructions - offset; + + new_emu.start({}, instructionsToExecute); + + ASSERT_EQ(new_emu.process().executed_instructions, instructionsToExecute); + ASSERT_NOT_TERMINATED(new_emu); + + new_emu.start({}, offset); + + ASSERT_TERMINATED_SUCCESSFULLY(new_emu); + ASSERT_EQ(new_emu.process().executed_instructions, executedInstructions); + } } diff --git a/src/windows-emulator-test/emulation_test_utils.hpp b/src/windows-emulator-test/emulation_test_utils.hpp index 3a6b5c62..dc9d64ba 100644 --- a/src/windows-emulator-test/emulation_test_utils.hpp +++ b/src/windows-emulator-test/emulation_test_utils.hpp @@ -3,11 +3,17 @@ #include #include -#define ASSER_TERMINATED_WITH_STATUS(win_emu, status) \ +#define ASSERT_NOT_TERMINATED(win_emu) \ + do { \ + ASSERT_FALSE(win_emu.process().exit_status.has_value()); \ + } while(false) + + +#define ASSERT_TERMINATED_WITH_STATUS(win_emu, status) \ do { \ ASSERT_TRUE(win_emu.process().exit_status.has_value()); \ ASSERT_EQ(*win_emu.process().exit_status, status); \ - } while(false) + } while(false) -#define ASSER_TERMINATED_SUCCESSFULLY(win_emu) \ - ASSER_TERMINATED_WITH_STATUS(win_emu, STATUS_SUCCESS) +#define ASSERT_TERMINATED_SUCCESSFULLY(win_emu) \ + ASSERT_TERMINATED_WITH_STATUS(win_emu, STATUS_SUCCESS) diff --git a/src/windows-emulator-test/serialization_test.cpp b/src/windows-emulator-test/serialization_test.cpp index a07d970a..90019cda 100644 --- a/src/windows-emulator-test/serialization_test.cpp +++ b/src/windows-emulator-test/serialization_test.cpp @@ -8,7 +8,7 @@ namespace test emu1.logger.disable_output(true); emu1.start(); - ASSER_TERMINATED_SUCCESSFULLY(emu1); + ASSERT_TERMINATED_SUCCESSFULLY(emu1); utils::buffer_serializer serializer1{}; emu1.serialize(serializer1); @@ -33,7 +33,7 @@ namespace test emu1.logger.disable_output(true); emu1.start(); - ASSER_TERMINATED_SUCCESSFULLY(emu1); + ASSERT_TERMINATED_SUCCESSFULLY(emu1); utils::buffer_serializer serializer1{}; emu1.serialize(serializer1); @@ -42,7 +42,7 @@ namespace test emu2.logger.disable_output(true); emu2.start(); - ASSER_TERMINATED_SUCCESSFULLY(emu2); + ASSERT_TERMINATED_SUCCESSFULLY(emu2); utils::buffer_serializer serializer2{}; emu2.serialize(serializer2); @@ -66,10 +66,10 @@ namespace test new_emu.deserialize(deserializer); new_emu.start(); - ASSER_TERMINATED_SUCCESSFULLY(new_emu); + ASSERT_TERMINATED_SUCCESSFULLY(new_emu); emu.start(); - ASSER_TERMINATED_SUCCESSFULLY(emu); + ASSERT_TERMINATED_SUCCESSFULLY(emu); // TODO: Fix that :( /*utils::buffer_serializer serializer1{}; diff --git a/src/windows-emulator/windows_emulator.cpp b/src/windows-emulator/windows_emulator.cpp index 684537fe..dbb12a48 100644 --- a/src/windows-emulator/windows_emulator.cpp +++ b/src/windows-emulator/windows_emulator.cpp @@ -4,7 +4,7 @@ #include -constexpr auto MAX_INSTRUCTIONS_PER_TIME_SLICE = 10000; +constexpr auto MAX_INSTRUCTIONS_PER_TIME_SLICE = 100000; namespace { @@ -867,8 +867,11 @@ void windows_emulator::start(std::chrono::nanoseconds timeout, size_t count) const auto use_count = count > 0; const auto use_timeout = timeout != std::chrono::nanoseconds{}; - auto start_time = std::chrono::high_resolution_clock::now(); - auto start_instructions = this->process().executed_instructions; + const auto start_time = std::chrono::high_resolution_clock::now(); + const auto start_instructions = this->process().executed_instructions; + + const auto target_time = start_time + timeout; + const auto target_instructions = start_instructions + count; while (true) { @@ -887,29 +890,25 @@ void windows_emulator::start(std::chrono::nanoseconds timeout, size_t count) if (use_timeout) { const auto now = std::chrono::high_resolution_clock::now(); - const auto diff = now - start_time; - if (diff >= timeout) + if (now >= target_time) { break; } - timeout = timeout - diff; - start_time = now; + timeout = target_time - now; } if (use_count) { const auto current_instructions = this->process().executed_instructions; - const auto diff = current_instructions - start_instructions; - if (diff >= count) + if (current_instructions >= target_instructions) { break; } - count = diff; - start_instructions = current_instructions; + count = target_instructions - current_instructions; } } }