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/os/windows/vm/os_windows.cpp
          +++ new/src/os/windows/vm/os_windows.cpp
↓ open down ↓ 813 lines elided ↑ open up ↑
 814  814  jlong os::javaTimeMillis() {
 815  815    if (UseFakeTimers) {
 816  816      return fake_time++;
 817  817    } else {
 818  818      FILETIME wt;
 819  819      GetSystemTimeAsFileTime(&wt);
 820  820      return windows_to_java_time(wt);
 821  821    }
 822  822  }
 823  823  
 824      -#define NANOS_PER_SEC         CONST64(1000000000)
 825      -#define NANOS_PER_MILLISEC    1000000
 826  824  jlong os::javaTimeNanos() {
 827  825    if (!has_performance_count) {
 828      -    return javaTimeMillis() * NANOS_PER_MILLISEC; // the best we can do.
      826 +    return javaTimeMillis() * NANOSECS_PER_MILLISEC; // the best we can do.
 829  827    } else {
 830  828      LARGE_INTEGER current_count;
 831  829      QueryPerformanceCounter(&current_count);
 832  830      double current = as_long(current_count);
 833  831      double freq = performance_frequency;
 834      -    jlong time = (jlong)((current/freq) * NANOS_PER_SEC);
      832 +    jlong time = (jlong)((current/freq) * NANOSECS_PER_SEC);
 835  833      return time;
 836  834    }
 837  835  }
 838  836  
 839  837  void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
 840  838    if (!has_performance_count) {
 841  839      // javaTimeMillis() doesn't have much percision,
 842  840      // but it is not going to wrap -- so all 64 bits
 843  841      info_ptr->max_value = ALL_64_BITS;
 844  842  
 845  843      // this is a wall clock timer, so may skip
 846  844      info_ptr->may_skip_backward = true;
 847  845      info_ptr->may_skip_forward = true;
 848  846    } else {
 849  847      jlong freq = performance_frequency;
 850      -    if (freq < NANOS_PER_SEC) {
      848 +    if (freq < NANOSECS_PER_SEC) {
 851  849        // the performance counter is 64 bits and we will
 852  850        // be multiplying it -- so no wrap in 64 bits
 853  851        info_ptr->max_value = ALL_64_BITS;
 854      -    } else if (freq > NANOS_PER_SEC) {
      852 +    } else if (freq > NANOSECS_PER_SEC) {
 855  853        // use the max value the counter can reach to
 856  854        // determine the max value which could be returned
 857  855        julong max_counter = (julong)ALL_64_BITS;
 858      -      info_ptr->max_value = (jlong)(max_counter / (freq / NANOS_PER_SEC));
      856 +      info_ptr->max_value = (jlong)(max_counter / (freq / NANOSECS_PER_SEC));
 859  857      } else {
 860  858        // the performance counter is 64 bits and we will
 861  859        // be using it directly -- so no wrap in 64 bits
 862  860        info_ptr->max_value = ALL_64_BITS;
 863  861      }
 864  862  
 865  863      // using a counter, so no skipping
 866  864      info_ptr->may_skip_backward = false;
 867  865      info_ptr->may_skip_forward = false;
 868  866    }
↓ open down ↓ 4500 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX