src/os/windows/vm/os_windows.cpp

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:

*** 819,839 **** GetSystemTimeAsFileTime(&wt); return windows_to_java_time(wt); } } - #define NANOS_PER_SEC CONST64(1000000000) - #define NANOS_PER_MILLISEC 1000000 jlong os::javaTimeNanos() { if (!has_performance_count) { ! return javaTimeMillis() * NANOS_PER_MILLISEC; // the best we can do. } else { LARGE_INTEGER current_count; QueryPerformanceCounter(&current_count); double current = as_long(current_count); double freq = performance_frequency; ! jlong time = (jlong)((current/freq) * NANOS_PER_SEC); return time; } } void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { --- 819,837 ---- GetSystemTimeAsFileTime(&wt); return windows_to_java_time(wt); } } jlong os::javaTimeNanos() { if (!has_performance_count) { ! return javaTimeMillis() * NANOSECS_PER_MILLISEC; // the best we can do. } else { LARGE_INTEGER current_count; QueryPerformanceCounter(&current_count); double current = as_long(current_count); double freq = performance_frequency; ! jlong time = (jlong)((current/freq) * NANOSECS_PER_SEC); return time; } } void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
*** 845,863 **** // this is a wall clock timer, so may skip info_ptr->may_skip_backward = true; info_ptr->may_skip_forward = true; } else { jlong freq = performance_frequency; ! if (freq < NANOS_PER_SEC) { // the performance counter is 64 bits and we will // be multiplying it -- so no wrap in 64 bits info_ptr->max_value = ALL_64_BITS; ! } else if (freq > NANOS_PER_SEC) { // use the max value the counter can reach to // determine the max value which could be returned julong max_counter = (julong)ALL_64_BITS; ! info_ptr->max_value = (jlong)(max_counter / (freq / NANOS_PER_SEC)); } else { // the performance counter is 64 bits and we will // be using it directly -- so no wrap in 64 bits info_ptr->max_value = ALL_64_BITS; } --- 843,861 ---- // this is a wall clock timer, so may skip info_ptr->may_skip_backward = true; info_ptr->may_skip_forward = true; } else { jlong freq = performance_frequency; ! if (freq < NANOSECS_PER_SEC) { // the performance counter is 64 bits and we will // be multiplying it -- so no wrap in 64 bits info_ptr->max_value = ALL_64_BITS; ! } else if (freq > NANOSECS_PER_SEC) { // use the max value the counter can reach to // determine the max value which could be returned julong max_counter = (julong)ALL_64_BITS; ! info_ptr->max_value = (jlong)(max_counter / (freq / NANOSECS_PER_SEC)); } else { // the performance counter is 64 bits and we will // be using it directly -- so no wrap in 64 bits info_ptr->max_value = ALL_64_BITS; }