United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6863420 os::javaTimeNanos() go backward on Solaris x86
JDK-6863420 : os::javaTimeNanos() go backward on Solaris x86

Details
Type:
Bug
Submit Date:
2009-07-23
Status:
Closed
Updated Date:
2011-03-07
Project Name:
JDK
Resolved Date:
2011-03-07
Component:
hotspot
OS:
solaris_10
Sub-Component:
runtime
CPU:
x86
Priority:
P3
Resolution:
Fixed
Affected Versions:
hs16
Fixed Versions:
hs16 (b08)

Related Reports
Backport:
Backport:
Relates:
Relates:
Relates:
Relates:

Sub Tasks

Description
I reproduced nanoTime() go backward on our systems (Shanghai, Harpertown, Nehalem) running solaris 10 and 11.
Compiled code calls the runtime method which claims that it can't go backward.

% /java/re/jdk/7/latest/binaries/solaris-i586/bin/java NanoTimer
Spawning 1 threads
Spawning 2 threads
Spawning 3 threads
Spawning 4 threads
Spawning 5 threads
Spawning 6 threads
Spawning 7 threads
Spawning 8 threads
Spawning 9 threads
Spawning 10 threads
Spawning 11 threads
Spawning 12 threads
Spawning 13 threads
Spawning 14 threads
Spawning 15 threads
Spawning 16 threads
Spawning 17 threads
Spawning 18 threads
Spawning 19 threads
Spawning 20 threads
Spawning 21 threads
Spawning 22 threads
Backwards: start=116810214972243 end=116806060017005 time= -4154955238
Backwards: start=116810154970260 end=116806090238787 time= -4064731473
Spawning 23 threads
Spawning 24 threads
Spawning 25 threads
Spawning 26 threads
Backwards: start=116814484972775 end=116810230014943 time= -4254957832
Backwards: start=116814504969926 end=116810250009178 time= -4254960748
Backwards: start=116814404975763 end=116810230016200 time= -4174959563
Backwards: start=116814484973480 end=116810270013273 time= -4214960207
Spawning 27 threads
Spawning 28 threads
Spawning 29 threads
Spawning 30 threads
Spawning 31 threads
Spawning 32 threads

                                    

Comments
EVALUATION

The problem is non atomic load from max_hrtime in getTimeNanos() on platforms where long is kept in 2 32-bit register.

     const hrtime_t prev = max_hrtime;

'prev' could be invalid (> current time) since registers are loaded separately and store could happened in between.
It could be returned as result:

    if (now <= prev)  return prev;   // same or retrograde time;

And if the next call getTimeNanos() returns the correct time it will be less then previous result.
                                     
2009-07-23
PUBLIC COMMENTS

Problem:
The problem is non atomic load from max_hrtime in getTimeNanos()
on platforms where long is kept in 2 32-bit register.
The loaded value could be invalid (> current time) since registers
are loaded separately and store could happened in between.
It could be returned as result if it is greater then current time.
And if the next call getTimeNanos() returns the correct time
it will be less then previous result.

Solution:
Use new atomic long load method Atomic::load() which uses
FPU to move long value atomically on 32-bit x86 or
simply returns *src in other cases.
                                     
2009-07-24
SUGGESTED FIX

Use new atomic long load method Atomic::load() which uses
FPU to move long value atomically on 32-bit x86 or
simply returns *src in other cases.
                                     
2009-07-24
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-comp/hotspot/rev/665be97e8704
                                     
2009-07-27
EVALUATION

http://hg.openjdk.java.net/jdk7/hotspot-gc/hotspot/rev/665be97e8704
                                     
2009-08-10



Hardware and Software, Engineered to Work Together