Print this page
rev 2869 : 7117303: VM uses non-monotonic time source and complains that it is non-monotonic
Summary: Replaces calls to os::javaTimeMillis(), which does not guarantee montonicity, in GC code to os::javaTimeNanos() with a suitable conversion factor. os::javaTimeNanos() mostly guarantees montonicity depending on the underlying OS implementation and, as a result, a better alternative. Changes in OS files are to make use of the newly defined constants in globalDefinitions.hpp.
Reviewed-by:

Split Close
Expand all
Collapse all
          --- old/src/share/vm/memory/genCollectedHeap.cpp
          +++ new/src/share/vm/memory/genCollectedHeap.cpp
↓ open down ↓ 1452 lines elided ↑ open up ↑
1453 1453    GenTimeOfLastGCClosure(jlong now) : _time(now), _now(now) { }
1454 1454  
1455 1455    jlong time() { return _time; }
1456 1456  
1457 1457    void do_generation(Generation* gen) {
1458 1458      _time = MIN2(_time, gen->time_of_last_gc(_now));
1459 1459    }
1460 1460  };
1461 1461  
1462 1462  jlong GenCollectedHeap::millis_since_last_gc() {
1463      -  jlong now = os::javaTimeMillis();
     1463 +  // os::javaTimeMillis() does not guarantee monotonicity.
     1464 +  jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
1464 1465    GenTimeOfLastGCClosure tolgc_cl(now);
1465 1466    // iterate over generations getting the oldest
1466 1467    // time that a generation was collected
1467 1468    generation_iterate(&tolgc_cl, false);
1468 1469    tolgc_cl.do_generation(perm_gen());
1469      -  // XXX Despite the assert above, since javaTimeMillis()
1470      -  // doesnot guarantee monotonically increasing return
1471      -  // values (note, i didn't say "strictly monotonic"),
1472      -  // we need to guard against getting back a time
1473      -  // later than now. This should be fixed by basing
1474      -  // on someting like gethrtime() which guarantees
1475      -  // monotonicity. Note that cond_wait() is susceptible
1476      -  // to a similar problem, because its interface is
1477      -  // based on absolute time in the form of the
1478      -  // system time's notion of UCT. See also 4506635
1479      -  // for yet another problem of similar nature. XXX
     1470 +  // XXX Since javaTimeNanos() mostly guarantees monotonically
     1471 +  // increasing return values, depending upon the underlying
     1472 +  // os-dependent implementation, we still need to guard against
     1473 +  // getting back a time later than now. This should be fixed
     1474 +  // by basing the implementation on something like gethrtime()
     1475 +  // which does guarantee monotonicity.
     1476 +  // Note that cond_wait() is susceptible to a similar problem,
     1477 +  // because its interface is based on absolute time in the form
     1478 +  // of the system time's notion of UCT. See also 4506635 for yet
     1479 +  // another problem of similar nature. XXX
1480 1480    jlong retVal = now - tolgc_cl.time();
1481 1481    if (retVal < 0) {
1482      -    NOT_PRODUCT(warning("time warp: %d", retVal);)
     1482 +    NOT_PRODUCT(warning("time warp: "INT64_FORMAT, retVal);)
1483 1483      return 0;
1484 1484    }
1485 1485    return retVal;
1486 1486  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX