-
Notifications
You must be signed in to change notification settings - Fork 652
Added MSVC utime_now implementation #425
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -29,6 +29,25 @@ either expressed or implied, of the Regents of The University of Michigan. | |||||||||||||
| #include <math.h> | ||||||||||||||
| #include "time_util.h" | ||||||||||||||
|
|
||||||||||||||
| #ifdef _MSC_VER | ||||||||||||||
|
|
||||||||||||||
| static INIT_ONCE profiler_initd = INIT_ONCE_STATIC_INIT; // static-initialization struct | ||||||||||||||
| static volatile LONGLONG profiler_perf_frequency; | ||||||||||||||
|
|
||||||||||||||
| static BOOL __stdcall profiler_init(PINIT_ONCE init_once, PVOID parameter, LPVOID *context) | ||||||||||||||
| { | ||||||||||||||
| (void) init_once; | ||||||||||||||
| (void) parameter; | ||||||||||||||
| (void) context; | ||||||||||||||
|
|
||||||||||||||
| LARGE_INTEGER freq; | ||||||||||||||
| QueryPerformanceFrequency(&freq); | ||||||||||||||
|
||||||||||||||
| QueryPerformanceFrequency(&freq); | |
| if (!QueryPerformanceFrequency(&freq) || freq.QuadPart == 0) { | |
| /* Fallback to a safe non-zero value if high-resolution counter is unavailable. */ | |
| profiler_perf_frequency = 1; | |
| return true; | |
| } |
Copilot
AI
Feb 13, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code uses Windows API types and functions (INIT_ONCE, INIT_ONCE_STATIC_INIT, PINIT_ONCE, PVOID, LPVOID, BOOL, LONGLONG, LARGE_INTEGER, QueryPerformanceFrequency, InitOnceExecuteOnce, QueryPerformanceCounter) but doesn't explicitly include windows.h. While these may be available through the indirect inclusion of winsock2.h in time_util.h, this creates a fragile dependency. Consider adding an explicit include for windows.h in the _MSC_VER section to make the dependency clear and avoid potential compilation issues.
Copilot
AI
Feb 13, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, QueryPerformanceCounter can fail (returning FALSE) if the system doesn't support a high-resolution performance counter. If it fails, counter.QuadPart will be uninitialized, leading to undefined behavior. Consider checking the return value and handling the failure case appropriately.
Copilot
AI
Feb 13, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The arithmetic operation (counter.QuadPart * 1000000LL) / profiler_perf_frequency could overflow for large counter values. QueryPerformanceCounter returns monotonically increasing values that can become very large over time. To prevent overflow, consider reordering the calculation to divide before multiplying, or use a more careful calculation like: (counter.QuadPart / profiler_perf_frequency) * 1000000LL + ((counter.QuadPart % profiler_perf_frequency) * 1000000LL) / profiler_perf_frequency. This preserves precision while avoiding overflow.
| // convert to microseconds | |
| return (int64_t) (counter.QuadPart * 1000000LL) / profiler_perf_frequency; | |
| // convert to microseconds without risking overflow in intermediate multiplication | |
| int64_t whole = (int64_t)((counter.QuadPart / profiler_perf_frequency) * 1000000LL); | |
| int64_t frac = (int64_t)(((counter.QuadPart % profiler_perf_frequency) * 1000000LL) / profiler_perf_frequency); | |
| return whole + frac; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable profiler_perf_frequency is declared as 'volatile LONGLONG', but this is unnecessary and potentially confusing. The InitOnceExecuteOnce function provides proper memory barriers to ensure visibility of the initialized value across threads. The volatile keyword doesn't provide the atomicity or memory ordering guarantees needed for multi-threaded access - it only prevents compiler optimizations. Since InitOnceExecuteOnce handles synchronization, the volatile qualifier can be removed.