On Thu, 20 Apr 2023 09:29:43 GMT, Aleksey Shipilev <[email protected]> wrote:
>> Java API has the `Thread.sleep(millis, nanos)` method exposed to users. The
>> documentation for that method clearly says the precision and accuracy are
>> dependent on the underlying system behavior. However, it always rounds up
>> `nanos` to 1ms when doing the actual sleep. This means users cannot do the
>> micro-second precision sleeps, even when the underlying platform allows it.
>> Sub-millisecond sleeps are useful to build interesting primitives, like the
>> rate limiters that run with >1000 RPS.
>>
>> When faced with this, some users reach for more awkward APIs like
>> `java.util.concurrent.locks.LockSupport.parkNanos`. The use of that API for
>> sleeps is not in line with its intent, and while it "seems to work", it
>> might have interesting interactions with other uses of `LockSupport`.
>> Additionally, these "sleeps" are no longer visible to monitoring tools as
>> "normal sleeps", e.g. as `Thread.sleep` events. Therefore, it would be
>> prudent to improve current `Thread.sleep(millis, nanos)` for sub-millisecond
>> granularity.
>>
>> Fortunately, the underlying code is almost ready for this, at least on POSIX
>> side. I skipped Windows paths, because its timers are still no good. Note
>> that on both Linux and MacOS timers oversleep by about 50us. I have a few
>> ideas how to improve the accuracy for them, which would be a topic for a
>> separate PR.
>>
>> Additional testing:
>> - [x] New regression test
>> - [x] New benchmark
>> - [x] Linux x86_64 `tier1`
>> - [x] Linux AArch64 `tier1`
>
> Aleksey Shipilev has updated the pull request incrementally with one
> additional commit since the last revision:
>
> Handle overflows
src/hotspot/os/posix/os_posix.cpp line 1342:
> 1340: }
> 1341:
> 1342: static jlong nanos_to_nanos_bounded(jlong nanos) {
I don't think we actually need this for nanos. There is no overflow potential
and the MAX_SECS limit will be handled later.
src/hotspot/share/runtime/javaThread.cpp line 1987:
> 1985: jlong nanos;
> 1986: if (millis > max_jlong / NANOUNITS_PER_MILLIUNIT) {
> 1987: // Conversion to nanos would overflow, saturate at max
Good catch! I had assumed `millis_to_nanos` handled this.
-------------
PR Review Comment: https://git.openjdk.org/jdk/pull/13225#discussion_r1172488236
PR Review Comment: https://git.openjdk.org/jdk/pull/13225#discussion_r1172490688