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:


 804 // whether it can actually be made to (DLD, 9/13/05).
 805 
 806 bool os::supports_vtime() { return false; }
 807 bool os::enable_vtime() { return false; }
 808 bool os::vtime_enabled() { return false; }
 809 double os::elapsedVTime() {
 810   // better than nothing, but not much
 811   return elapsedTime();
 812 }
 813 
 814 jlong os::javaTimeMillis() {
 815   if (UseFakeTimers) {
 816     return fake_time++;
 817   } else {
 818     FILETIME wt;
 819     GetSystemTimeAsFileTime(&wt);
 820     return windows_to_java_time(wt);
 821   }
 822 }
 823 
 824 #define NANOS_PER_SEC         CONST64(1000000000)
 825 #define NANOS_PER_MILLISEC    1000000
 826 jlong os::javaTimeNanos() {
 827   if (!has_performance_count) {
 828     return javaTimeMillis() * NANOS_PER_MILLISEC; // the best we can do.
 829   } else {
 830     LARGE_INTEGER current_count;
 831     QueryPerformanceCounter(&current_count);
 832     double current = as_long(current_count);
 833     double freq = performance_frequency;
 834     jlong time = (jlong)((current/freq) * NANOS_PER_SEC);
 835     return time;
 836   }
 837 }
 838 
 839 void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
 840   if (!has_performance_count) {
 841     // javaTimeMillis() doesn't have much percision,
 842     // but it is not going to wrap -- so all 64 bits
 843     info_ptr->max_value = ALL_64_BITS;
 844 
 845     // this is a wall clock timer, so may skip
 846     info_ptr->may_skip_backward = true;
 847     info_ptr->may_skip_forward = true;
 848   } else {
 849     jlong freq = performance_frequency;
 850     if (freq < NANOS_PER_SEC) {
 851       // the performance counter is 64 bits and we will
 852       // be multiplying it -- so no wrap in 64 bits
 853       info_ptr->max_value = ALL_64_BITS;
 854     } else if (freq > NANOS_PER_SEC) {
 855       // use the max value the counter can reach to
 856       // determine the max value which could be returned
 857       julong max_counter = (julong)ALL_64_BITS;
 858       info_ptr->max_value = (jlong)(max_counter / (freq / NANOS_PER_SEC));
 859     } else {
 860       // the performance counter is 64 bits and we will
 861       // be using it directly -- so no wrap in 64 bits
 862       info_ptr->max_value = ALL_64_BITS;
 863     }
 864 
 865     // using a counter, so no skipping
 866     info_ptr->may_skip_backward = false;
 867     info_ptr->may_skip_forward = false;
 868   }
 869   info_ptr->kind = JVMTI_TIMER_ELAPSED;                // elapsed not CPU time
 870 }
 871 
 872 char* os::local_time_string(char *buf, size_t buflen) {
 873   SYSTEMTIME st;
 874   GetLocalTime(&st);
 875   jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",
 876                st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
 877   return buf;
 878 }




 804 // whether it can actually be made to (DLD, 9/13/05).
 805 
 806 bool os::supports_vtime() { return false; }
 807 bool os::enable_vtime() { return false; }
 808 bool os::vtime_enabled() { return false; }
 809 double os::elapsedVTime() {
 810   // better than nothing, but not much
 811   return elapsedTime();
 812 }
 813 
 814 jlong os::javaTimeMillis() {
 815   if (UseFakeTimers) {
 816     return fake_time++;
 817   } else {
 818     FILETIME wt;
 819     GetSystemTimeAsFileTime(&wt);
 820     return windows_to_java_time(wt);
 821   }
 822 }
 823 


 824 jlong os::javaTimeNanos() {
 825   if (!has_performance_count) {
 826     return javaTimeMillis() * NANOSECS_PER_MILLISEC; // the best we can do.
 827   } else {
 828     LARGE_INTEGER current_count;
 829     QueryPerformanceCounter(&current_count);
 830     double current = as_long(current_count);
 831     double freq = performance_frequency;
 832     jlong time = (jlong)((current/freq) * NANOSECS_PER_SEC);
 833     return time;
 834   }
 835 }
 836 
 837 void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
 838   if (!has_performance_count) {
 839     // javaTimeMillis() doesn't have much percision,
 840     // but it is not going to wrap -- so all 64 bits
 841     info_ptr->max_value = ALL_64_BITS;
 842 
 843     // this is a wall clock timer, so may skip
 844     info_ptr->may_skip_backward = true;
 845     info_ptr->may_skip_forward = true;
 846   } else {
 847     jlong freq = performance_frequency;
 848     if (freq < NANOSECS_PER_SEC) {
 849       // the performance counter is 64 bits and we will
 850       // be multiplying it -- so no wrap in 64 bits
 851       info_ptr->max_value = ALL_64_BITS;
 852     } else if (freq > NANOSECS_PER_SEC) {
 853       // use the max value the counter can reach to
 854       // determine the max value which could be returned
 855       julong max_counter = (julong)ALL_64_BITS;
 856       info_ptr->max_value = (jlong)(max_counter / (freq / NANOSECS_PER_SEC));
 857     } else {
 858       // the performance counter is 64 bits and we will
 859       // be using it directly -- so no wrap in 64 bits
 860       info_ptr->max_value = ALL_64_BITS;
 861     }
 862 
 863     // using a counter, so no skipping
 864     info_ptr->may_skip_backward = false;
 865     info_ptr->may_skip_forward = false;
 866   }
 867   info_ptr->kind = JVMTI_TIMER_ELAPSED;                // elapsed not CPU time
 868 }
 869 
 870 char* os::local_time_string(char *buf, size_t buflen) {
 871   SYSTEMTIME st;
 872   GetLocalTime(&st);
 873   jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",
 874                st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond);
 875   return buf;
 876 }