From 06b85f3e2b7a660b19d095b9490058c0b0695f93 Mon Sep 17 00:00:00 2001 From: Aidan Lee Date: Thu, 5 Jun 2025 18:40:32 +0100 Subject: [PATCH] add millisecond resolution timer --- include/hx/StdLibs.h | 1 + src/hx/StdLibs.cpp | 34 ++++++++++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/include/hx/StdLibs.h b/include/hx/StdLibs.h index 6565cc9c8..7918e5138 100644 --- a/include/hx/StdLibs.h +++ b/include/hx/StdLibs.h @@ -43,6 +43,7 @@ Array __hxcpp_resource_bytes(String inName); // System access Array __get_args(); double __time_stamp(); +::cpp::Int64 __time_stamp_ms(); HXCPP_EXTERN_CLASS_ATTRIBUTES void __hxcpp_print_string(const String &inV); HXCPP_EXTERN_CLASS_ATTRIBUTES void __hxcpp_println_string(const String &inV); diff --git a/src/hx/StdLibs.cpp b/src/hx/StdLibs.cpp index f4c4890c7..cd6a3ed5d 100644 --- a/src/hx/StdLibs.cpp +++ b/src/hx/StdLibs.cpp @@ -242,8 +242,17 @@ int __hxcpp_irand(int inMax) return (lo | (mid<<12) | (hi<<24) ) % inMax; } +#ifdef HX_WINDOWS +LARGE_INTEGER qpcFrequency; +#endif + void __hxcpp_stdlibs_boot() { +#ifdef HX_WINDOWS + // MSDN states that QueryPerformanceFrequency will always succeed on XP and above, so I'm ignoring the result. + QueryPerformanceFrequency(&qpcFrequency); +#endif + #if defined(_MSC_VER) && !defined(HX_WINRT) HMODULE kernel32 = LoadLibraryA("kernel32"); if (kernel32) @@ -327,10 +336,7 @@ double __time_stamp() if (t0==0) { t0 = now; - __int64 freq; - QueryPerformanceFrequency((LARGE_INTEGER*)&freq); - if (freq!=0) - period = 1.0/freq; + period = 1.0/qpcFrequency.QuadPart; } if (period!=0) return (now-t0)*period; @@ -349,6 +355,26 @@ double __time_stamp() #endif } +::cpp::Int64 __time_stamp_ms() +{ +#ifdef HX_WINDOWS + // MSDN states that QueryPerformanceCounter will always succeed on XP and above, so I'm ignoring the result. + auto now = LARGE_INTEGER{ 0 }; + QueryPerformanceCounter(&now); + + return now.QuadPart * LONGLONG{ 1000 } / qpcFrequency.QuadPart; +#else + auto time = timespec(); + + if (clock_gettime(CLOCK_MONOTONIC, &time)) + { + throw ::Dynamic(HX_CSTRING("Failed to get the monotonic clock time")); + } + + return time.tv_sec * 1000 + (time.tv_nsec / 1000000); +#endif +} + #if defined(HX_WINDOWS) && !defined(HX_WINRT) /*