From d959306719630883f44221c5642ca22885b26d59 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 2 Nov 2025 10:44:20 +0000 Subject: [PATCH] Add deterministic QueryPerformanceCounter/Frequency mocks Implemented Windows high-resolution timing mocks for deterministic simulation: **mock_QueryPerformanceCounter:** - Returns deterministic counter based on simulated_time - Uses fixed 10 MHz frequency (10,000,000 counts/second) - Calculation: count = (tv_sec * freq) + (tv_nsec * freq / 1e9) - Validates NULL pointer with ERROR_INVALID_PARAMETER - Provides consistent, reproducible timing across test runs **mock_QueryPerformanceFrequency:** - Returns fixed frequency of 10 MHz (10,000,000 Hz) - Common frequency on modern Windows systems - Ensures deterministic behavior (no variation between runs) - Validates NULL pointer with ERROR_INVALID_PARAMETER **Integration:** - Added function declarations to system.h - Macros already existed (sys_QueryPerformanceCounter/Frequency) - Complements existing mock_clock_gettime on Linux - Both platforms now have deterministic high-resolution timing This ensures Windows code using QueryPerformanceCounter for timing, benchmarking, or rate limiting behaves deterministically in tests. The fixed 10 MHz frequency provides nanosecond-level precision (100ns per tick) suitable for most timing needs. --- src/system.c | 31 +++++++++++++++++++++++++++++++ src/system.h | 2 ++ 2 files changed, 33 insertions(+) diff --git a/src/system.c b/src/system.c index 564c389..b80c3b0 100644 --- a/src/system.c +++ b/src/system.c @@ -1183,6 +1183,37 @@ int mock__mkdir(char *path) return _mkdir(path); } +BOOL mock_QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount) +{ + if (lpPerformanceCount == NULL) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + // Use simulated time to generate deterministic performance counter + // Frequency is 10 MHz (10,000,000 counts per second) + const LONGLONG frequency = 10000000LL; + + LONGLONG count = (LONGLONG)simulated_time.tv_sec * frequency; + count += ((LONGLONG)simulated_time.tv_nsec * frequency) / 1000000000LL; + + lpPerformanceCount->QuadPart = count; + return TRUE; +} + +BOOL mock_QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency) +{ + if (lpFrequency == NULL) { + SetLastError(ERROR_INVALID_PARAMETER); + return FALSE; + } + + // Return fixed frequency of 10 MHz for deterministic behavior + // This is a common frequency on modern systems + lpFrequency->QuadPart = 10000000LL; // 10 million counts per second + return TRUE; +} + #else int mock_clock_gettime(clockid_t clockid, struct timespec *tp) diff --git a/src/system.h b/src/system.h index d16e504..ca6614d 100644 --- a/src/system.h +++ b/src/system.h @@ -61,6 +61,8 @@ BOOL mock_FlushFileBuffers(HANDLE handle); BOOL mock_ReadFile(HANDLE handle, char *dst, DWORD len, DWORD *num, OVERLAPPED *ov); BOOL mock_WriteFile(HANDLE handle, char *src, DWORD len, DWORD *num, OVERLAPPED *ov); BOOL mock_GetFileSizeEx(HANDLE handle, LARGE_INTEGER *buf); +BOOL mock_QueryPerformanceCounter(LARGE_INTEGER *lpPerformanceCount); +BOOL mock_QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency); char* mock__fullpath(char *path, char *dst, int cap); int mock__mkdir(char *path); #else