Include suspend time on minipal ticks for Unix-like systems#119443
Include suspend time on minipal ticks for Unix-like systems#119443marzent wants to merge 2 commits intodotnet:mainfrom
Conversation
Uses CLOCK_MONOTONIC_RAW for hires and CLOCK_MONOTONIC_RAW_APPROX for lowres ticks. Fixes dotnet#119437
There was a problem hiding this comment.
Pull Request Overview
This PR updates the time measurement implementation on Unix-like systems to include suspend time in the clock measurements. The change switches from uptime-based clocks to suspend-inclusive clocks to provide more accurate time tracking across system sleep/wake cycles.
Key changes:
- Switch from
CLOCK_UPTIME_RAWtoCLOCK_MONOTONIC_RAWon macOS systems - Prefer
CLOCK_BOOTTIMEoverCLOCK_MONOTONICon Linux when available - Remove the
CLOCK_MONOTONIC_COARSEoptimization in favor of consistent suspend-inclusive timing
Uses CLOCK_BOOTTIME for hires/lowres ticks. Fixes [dotnet#119437](dotnet#119437)
080aa9b to
390cd2b
Compare
|
@dotnet-policy-service agree |
|
How does this change interact with existing places that deal with timeouts and use the existing timer? For example, SystemNative_LowLevelMonitor_TimedWait that is still on CLOCK_MONOTONIC plan and it combines it with TickCount that is on CLOCK_BOOTTIME plan now.
I am changing the area to System.Threading. |
This is actually a really good question. Since the timeout passed into SystemNative_LowLevelMonitor_TimedWait is relative this doesn't really make a difference, except for if the pthread condition variable does count time in suspend or not... On macOS this is wall time in my testing (can also be verified in Apples libc source of On Linux this would create a discrepancy there (again not too sure if it is actually meaningful, and could worst case be fixed by using the appropriate clock in Notably the Windows codepath, which I believe ends up in
So with this change Linux would probably behave as "badly" as modern Windows, when combining TickCount (with suspend time) + Monitor Wait (without suspend time) here I believe. This also means that for macOS the current interaction without this PR is the TickCount (without suspend time) + Monitor Wait (with suspend time) scenario. |
|
It's worth noting that "best practice" when dealing with something like elapsed/delta times is to clamp the times that are "egregious" so that it behaves generally as expected in the face of things like a debugger breakpoint as well. There's always going to be various quirks over how timing is tracked and whether it considers low power states, clock frequency changes, app suspension, general OS thread/process management, etc. It would be "nice" if most of the OS generally followed the same behavior with regards to whether something like sleep/hibernation time (as defined by ACPI) was tracked; but it won't "fix" the broader issue here. |
|
Is there anything else that needs to be done in this PR besides the two commits? This is my first time contributing, and I’m happy to address any issues if anything needs changing. I don’t believe it’s necessary to modify |
|
This change is fixing Note that there are Windows specific places in the code like Environment.TickCount and other APIs. We may need to replicate this on non-Windows. We may even want to introduce new public APIs that expose times that align with timers used for timeouts.
|
|
@jkotas Does this PR have a reasonable path toward acceptance? |
|
I would certainly appreciate this to be consistent across platforms, and ideally such that it uses the cheapest (perf-wise) mechanisms to retrieve TickCount64. macOS isn't very cheap today for example, and it shows up in profiles there. It's not that I intrinsically care about macOS perf that much. However as it is my main dev platform I have to mentally ignore these kind of hotspots that aren't as pronounced on linux. |
It needs to address this "However, doing that is going to introduce bugs in other parts of the core libraries. The bugs that this change is introducing may be worse than the bugs that it is fixing. It is not clear what the net impact is to me." |
|
I am sorry for the late update on this, I haven't had much time to work on it lately... If my understanding is correct, we just need to provide a Linux/macOS equivalent for I will try to implement this, but it looks to be a larger change. |
|
@marzent No problem -- in that case, I'm going to move this to draft |
|
Draft Pull Request was automatically closed for 30 days of inactivity. Please let us know if you'd like to reopen it. |
On macOS, this uses
CLOCK_MONOTONIC_RAW(andCLOCK_MONOTONIC_RAW_APPROXfor low-res ticks as a mini-optimization here) and on Linux usesCLOCK_BOOTTIMEwhen available now.Emscripten only fully implements
CLOCK_MONOTONICon all platforms, so leave it at that.Of note is that this loses the optimization done in dotnet/coreclr#2293, since there is no
CLOCK_BOOTTIME_COARSE; however, as of Linux 5.0, all ofCLOCK_BOOTTIME,CLOCK_MONOTONIC, andCLOCK_MONOTONIC_COARSEare handled via a fast path in vDSO on at least x86/arm64 in the low nanosecond range.On my arm64 machine with kernel 6.15.6, I couldn't even measure a meaningful difference between any of these three at least.
Fixes #77945 and #119437