Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Nov 2015 12:11:32 -0500 (EST)
From:      Daniel Eischen <deischen@freebsd.org>
To:        Achilleas Mantzios <achill@matrix.gatewaynet.com>
Cc:        freebsd-java@freebsd.org
Subject:   Re: Thread.sleep is very incorrect on kern.hz FreeBSD-10 + openjdk8.
Message-ID:  <Pine.GSO.4.64.1511121143140.25792@sea.ntplx.net>
In-Reply-To: <5644BD96.9000005@matrix.gatewaynet.com>
References:  <5644BB9A.4060807@smartspb.net> <5644BD96.9000005@matrix.gatewaynet.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, 12 Nov 2015, Achilleas Mantzios wrote:

> On 12/11/2015 18:17, Sergey Potapov wrote:
>> Hello!
>> 
>> FreeBSD-10.1 without tunning.
>> openjdk8     without tunning (pkg install).
>> 
>> 
>> Thread.sleep depends on kern.hz sysctl variable.
>> 
>> Simple program and more detailed version information attched.
>> openjdk7 tested with kern.hz=2000 -- same results.
>> 
>> kern.hz: 100
>> 
>> 1000 times Thread.sleep(1)                           19994 milliseconds
>> 1000 times Thread.sleep(2)                           19997 milliseconds
>> 1000 times TimeUnit.MICROSECONDS.sleep(100)          20000 milliseconds
>> 
>> kern.hz: 1000
>> 
>> 1000 times Thread.sleep(1)                            2002 milliseconds
>> 1000 times Thread.sleep(2)                            3000 milliseconds
>> 1000 times TimeUnit.MICROSECONDS.sleep(100)           2001 milliseconds
>> 
>> 
>> kern.hz: 2000
>> 
>> 1000 times Thread.sleep(1)                            1500 milliseconds
>> 1000 times Thread.sleep(2)                            2500 milliseconds
>> 1000 times TimeUnit.MICROSECONDS.sleep(100)           1500 milliseconds

What timer are you using (kern.eventtimer.timer ?) and what scheduler
(kern.sched.name)?  Can you repeat the test by just using a C program
and nanosleep()?

Sleep is at the mercy of the granularity of HZ.  If you ask to sleep
for 1 millisecond at time T+.5msec, the kernel checks for wakeups
at time T+1msec, but your thread isn't ready then - it has only slept
for .5msec.  So the next chance for a wakeup is at T+2msec.  Hence, you
effectively sleep for 1.5msec.

When you are calling Thread.sleep(1) in a tight loop, most of the time
you are probably going to be woken up just after a kernel timing tick.
That means you will go to sleep just after the tick, e.g. T+.01msec,
so the kernel can't wake you up at T+1msec because you haven't slept
for the entire time.  This is for HZ=100 example.  It is similar for
other HZ, and is probably why your sleep times all seem to have an
extra kernel tick per sleep.

You could also try Thread.sleep(0, 900000) which would be just under
1msec.  If your program knows HZ, it could sleep for 1/2 of that
relative tick, so on average it might sleep 1 tick.

-- 
DE



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.GSO.4.64.1511121143140.25792>