Conversation
067ecc3 to
52f5205
Compare
2b71830 to
a37b22a
Compare
1802964 to
6fd7306
Compare
8a88923 to
38dc0bb
Compare
dd5c20c to
e9a1394
Compare
dc092de to
f06e22e
Compare
7261612 to
1283f36
Compare
By using a high-resolution timer, available since Windows 10 RS4 (1803), we can attain sleeps with a 100 nanosecond precision. A handle representing the high-resolution timer is required for a thread to sleep. In order to avoid paying the cost of creating and closing the timer, it is re-set (reused). The timer needs to be stored somewhere: the domain state is not a good fit as the domain state cannot be accessed once the runtime system is released, which is typically the case before a sleep. Moreover, multiple systhreads belonging to a single domain might want to sleep simultanously. The systhread structure isn't a good fit either, as runtime threads don't have access to this. Thread-local storage is a viable option. Timer handles are created on-demand at the first `caml_win32_nanosleep` call of the thread. The first thread entering this function tests if timer handles can be created at all (with a `PINIT_ONCE`, the equivalent of `pthread_once`), as the feature might not be supported by the Windows host. Other threads then check if `have_high_resolution_timers` is `true`, and if so, attempt to create timers. It seems difficult to precisely know when to close this handle, in each and every case. To defend against mistakes, we keep a linked list of these handles. In some cases, threads will close their timer handle to prevent handle exhaustion when they exit. In the general case, they will be closed during `caml_shutdown`. This commit allows more precision in the platform spin-waits, and also avoids rounding down quirks: `Sleep(0)` will put the process at the end of the process queue, without sleeping.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
By using a high-resolution timer, available since Windows 10 RS4
(1803), we can attain sleeps with a 100 nanosecond precision.
A handle representing the high-resolution timer is required for a
thread to sleep. In order to avoid paying the cost of creating and
closing the timer, it is re-set (reused). The timer needs to be stored
somewhere: the domain state is not a good fit as the domain state
cannot be accessed once the runtime system is released, which is
typically the case before a sleep. Moreover, multiple systhreads
belonging to a single domain might want to sleep simultanously.
The systhread structure isn't a good fit either, as runtime threads
don't have access to this. Thread-local storage is a viable option.
Timer handles are created on-demand at the first
caml_win32_nanosleepcall of the thread. The first thread enteringthis function tests if timer handles can be created at all (with a
PINIT_ONCE, the equivalent ofpthread_once), as the feature mightnot be supported by the Windows host. Other threads then check if
have_high_resolution_timersistrue, and if so, attempt to createtimers.
It seems difficult to precisely know when to close this handle, in
each and every case. To defend against mistakes, we keep a linked list
of these handles. In some cases, threads will close their timer handle
to prevent handle exhaustion when they exit. In the general case, they
will be closed during
caml_shutdown.This commit allows more precision in the platform spin-waits, and also
avoids rounding down quirks:
Sleep(0)will put the process at theend of the process queue, without sleeping.