diff src/share/vm/memory/genCollectedHeap.cpp @ 4712:e7dead7e90af

7117303: VM uses non-monotonic time source and complains that it is non-monotonic Summary: Replaces calls to os::javaTimeMillis(), which does not (and cannot) guarantee monotonicity, in GC code to an equivalent expression that uses os::javaTimeNanos(). os::javaTimeNanos is guaranteed monotonically non-decreasing if the underlying platform provides a monotonic time source. Changes in OS files are to make use of the newly defined constants in globalDefinitions.hpp. Reviewed-by: dholmes, ysr
author johnc
date Mon, 19 Dec 2011 10:02:05 -0800
parents 3c648b9ad052
children 441e946dc1af
line wrap: on
line diff
--- a/src/share/vm/memory/genCollectedHeap.cpp	Fri Dec 16 11:40:00 2011 -0800
+++ b/src/share/vm/memory/genCollectedHeap.cpp	Mon Dec 19 10:02:05 2011 -0800
@@ -1460,26 +1460,22 @@
 };
 
 jlong GenCollectedHeap::millis_since_last_gc() {
-  jlong now = os::javaTimeMillis();
+  // We need a monotonically non-deccreasing time in ms but
+  // os::javaTimeMillis() does not guarantee monotonicity.
+  jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
   GenTimeOfLastGCClosure tolgc_cl(now);
   // iterate over generations getting the oldest
   // time that a generation was collected
   generation_iterate(&tolgc_cl, false);
   tolgc_cl.do_generation(perm_gen());
-  // XXX Despite the assert above, since javaTimeMillis()
-  // doesnot guarantee monotonically increasing return
-  // values (note, i didn't say "strictly monotonic"),
-  // we need to guard against getting back a time
-  // later than now. This should be fixed by basing
-  // on someting like gethrtime() which guarantees
-  // monotonicity. Note that cond_wait() is susceptible
-  // to a similar problem, because its interface is
-  // based on absolute time in the form of the
-  // system time's notion of UCT. See also 4506635
-  // for yet another problem of similar nature. XXX
+
+  // javaTimeNanos() is guaranteed to be monotonically non-decreasing
+  // provided the underlying platform provides such a time source
+  // (and it is bug free). So we still have to guard against getting
+  // back a time later than 'now'.
   jlong retVal = now - tolgc_cl.time();
   if (retVal < 0) {
-    NOT_PRODUCT(warning("time warp: %d", retVal);)
+    NOT_PRODUCT(warning("time warp: "INT64_FORMAT, retVal);)
     return 0;
   }
   return retVal;