RFR 8098798: Thread.join(ms) on Linux still affected by changes to the time-of-day clock
Ivan Gerasimov
ivan.gerasimov at oracle.com
Tue Sep 4 19:38:53 UTC 2018
Thank you Roger!
I'm not sure if it plays any significant role, but an unnecessary call
to nanoTime() after wait(delay) could be avoided with the code like this:
if (millis > 0) {
if (isAlive()) {
final long startTime = System.nanoTime();
long delay = millis;
do {
wait(delay);
} while (isAlive() && (delay = millis -
TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - startTime)) > 0);
}
} else if (millis == 0) {
With kind regards,
Ivan
On 9/4/18 12:02 PM, Roger Riggs wrote:
> Hi Martin, Ivan,
>
> Thanks for the suggestions.
>
> Update in place:
> http://cr.openjdk.java.net/~rriggs/webrev-thread-early-8098798/
>
> On 8/29/2018 5:36 PM, Martin Buchholz wrote:
>> Thanks for taking this on.
>> Wait loops are notoriously hard to get right...
>>
>> One sharp corner is that wait(0) waits forever, and TimeUnit
>> conversion truncates. You can probably avoid those problems via
>> TimeUnit.timedWait.
>>
> Not trivial since a long cannot hold the combined time of millis(long)
> and nanos (long) in a TimeUnit(Nanos)
> and the cumulative wait time needs to be measured by System.nanoTime().
>
>> In code like this in j.u.c. we try to optimize away the call to
>> nanoTime when waiting is not necessary, by using a special
>> "uninitialized" initial value for remaining nanos, e.g. in
>> FutureTask.awaitDone
>>
>> long startTime = 0L; // Special value 0L means not yet parked
> ok
>>
>> (I prefer the variable name "startTime")
> ok
>>
>> (j.u.c. code can also be improved)
>>
>> (there's a pre-existing buglet - we should probably check for
>> overflow when millis = MAX_VALUE and nanos > 0 (sigh))
> ok,
>>
>> (I would reorder clauses to first check the common case millis > 0,
>> then millis == 0, last the error case millis < 0)
> ok
>>
>> (it's a bad API that millis < 0 is an error)
> too late for a behavior change though I suppose its in the direction
> of not getting error instead of the opposite....
>
>
> An Observation:
>
> Join(ms) and join(ms, ns) might wait a bit longer than strictly
> necessary because the bottom out in Object.wait(ms).
> It might be better if both ended up calling Object.wait(ms, ns).
> But since Object.wait(ms,ns) rounds up to Object.wait(ms) that won't
> make a difference and to take advantage
> of a finer clock resolution would mean native/vm changes to support
> object.wait(ms, ns).
>
> I'm inclined to address only the immediate issues raised in the early
> return and the clock dependency now.
>
> (BTW, I found no tests for Thread.sleep or .join.)
>
> Thanks, Roger
>
>>
>>
>> On Wed, Aug 29, 2018 at 1:06 PM, Roger Riggs <Roger.Riggs at oracle.com
>> <mailto:Roger.Riggs at oracle.com>> wrote:
>>
>> Please review changes for:
>>
>> 8098798: Thread.join(ms) on Linux still affected by changes to the
>> time-of-day clock
>> Use System.nanoTime to compute any remaining delay
>>
>> 8210004: Thread.sleep(millis, nanos) timeout returns early
>> Avoid an early return by rounding the milliseconds up if
>> there are any nanoseconds as was done in Object.wait(ms, ns).
>>
>> (If its not appropriate to do the two reviews together, I can
>> split them).
>>
>> Webrev:
>> http://cr.openjdk.java.net/~rriggs/webrev-thread-early-8098798/
>> <http://cr.openjdk.java.net/%7Erriggs/webrev-thread-early-8098798/>
>>
>> Thanks, Roger
>>
>>
>
>
--
With kind regards,
Ivan Gerasimov
More information about the core-libs-dev
mailing list