7117303: VM uses non-monotonic time source and complains that it is non-monotonic
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
This commit is contained in:
parent
2768349b41
commit
870bea622a
@ -150,7 +150,6 @@
|
|||||||
|
|
||||||
// for timer info max values which include all bits
|
// for timer info max values which include all bits
|
||||||
#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
|
#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
|
||||||
#define SEC_IN_NANOSECS 1000000000LL
|
|
||||||
|
|
||||||
#define LARGEPAGES_BIT (1 << 6)
|
#define LARGEPAGES_BIT (1 << 6)
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -3445,8 +3444,6 @@ size_t os::read(int fd, void *buf, unsigned int nBytes) {
|
|||||||
// generates a SIGUSRx signal. Note that SIGUSR1 can interfere with
|
// generates a SIGUSRx signal. Note that SIGUSR1 can interfere with
|
||||||
// SIGSEGV, see 4355769.
|
// SIGSEGV, see 4355769.
|
||||||
|
|
||||||
const int NANOSECS_PER_MILLISECS = 1000000;
|
|
||||||
|
|
||||||
int os::sleep(Thread* thread, jlong millis, bool interruptible) {
|
int os::sleep(Thread* thread, jlong millis, bool interruptible) {
|
||||||
assert(thread == Thread::current(), "thread consistency check");
|
assert(thread == Thread::current(), "thread consistency check");
|
||||||
|
|
||||||
@ -3469,7 +3466,7 @@ int os::sleep(Thread* thread, jlong millis, bool interruptible) {
|
|||||||
// not a guarantee() because JVM should not abort on kernel/glibc bugs
|
// not a guarantee() because JVM should not abort on kernel/glibc bugs
|
||||||
assert(!Bsd::supports_monotonic_clock(), "time moving backwards");
|
assert(!Bsd::supports_monotonic_clock(), "time moving backwards");
|
||||||
} else {
|
} else {
|
||||||
millis -= (newtime - prevtime) / NANOSECS_PER_MILLISECS;
|
millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(millis <= 0) {
|
if(millis <= 0) {
|
||||||
@ -3508,7 +3505,7 @@ int os::sleep(Thread* thread, jlong millis, bool interruptible) {
|
|||||||
// not a guarantee() because JVM should not abort on kernel/glibc bugs
|
// not a guarantee() because JVM should not abort on kernel/glibc bugs
|
||||||
assert(!Bsd::supports_monotonic_clock(), "time moving backwards");
|
assert(!Bsd::supports_monotonic_clock(), "time moving backwards");
|
||||||
} else {
|
} else {
|
||||||
millis -= (newtime - prevtime) / NANOSECS_PER_MILLISECS;
|
millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(millis <= 0) break ;
|
if(millis <= 0) break ;
|
||||||
@ -4197,7 +4194,7 @@ jlong os::Bsd::fast_thread_cpu_time(clockid_t clockid) {
|
|||||||
int rc = os::Bsd::clock_gettime(clockid, &tp);
|
int rc = os::Bsd::clock_gettime(clockid, &tp);
|
||||||
assert(rc == 0, "clock_gettime is expected to return 0 code");
|
assert(rc == 0, "clock_gettime is expected to return 0 code");
|
||||||
|
|
||||||
return (tp.tv_sec * SEC_IN_NANOSECS) + tp.tv_nsec;
|
return (tp.tv_sec * NANOSECS_PER_SEC) + tp.tv_nsec;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -5522,9 +5519,6 @@ void os::PlatformEvent::unpark() {
|
|||||||
* is no need to track notifications.
|
* is no need to track notifications.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define NANOSECS_PER_SEC 1000000000
|
|
||||||
#define NANOSECS_PER_MILLISEC 1000000
|
|
||||||
#define MAX_SECS 100000000
|
#define MAX_SECS 100000000
|
||||||
/*
|
/*
|
||||||
* This code is common to bsd and solaris and will be moved to a
|
* This code is common to bsd and solaris and will be moved to a
|
||||||
|
@ -127,7 +127,6 @@
|
|||||||
|
|
||||||
// for timer info max values which include all bits
|
// for timer info max values which include all bits
|
||||||
#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
|
#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
|
||||||
#define SEC_IN_NANOSECS 1000000000LL
|
|
||||||
|
|
||||||
#define LARGEPAGES_BIT (1 << 6)
|
#define LARGEPAGES_BIT (1 << 6)
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
@ -3259,8 +3258,6 @@ size_t os::read(int fd, void *buf, unsigned int nBytes) {
|
|||||||
// generates a SIGUSRx signal. Note that SIGUSR1 can interfere with
|
// generates a SIGUSRx signal. Note that SIGUSR1 can interfere with
|
||||||
// SIGSEGV, see 4355769.
|
// SIGSEGV, see 4355769.
|
||||||
|
|
||||||
const int NANOSECS_PER_MILLISECS = 1000000;
|
|
||||||
|
|
||||||
int os::sleep(Thread* thread, jlong millis, bool interruptible) {
|
int os::sleep(Thread* thread, jlong millis, bool interruptible) {
|
||||||
assert(thread == Thread::current(), "thread consistency check");
|
assert(thread == Thread::current(), "thread consistency check");
|
||||||
|
|
||||||
@ -3283,7 +3280,7 @@ int os::sleep(Thread* thread, jlong millis, bool interruptible) {
|
|||||||
// not a guarantee() because JVM should not abort on kernel/glibc bugs
|
// not a guarantee() because JVM should not abort on kernel/glibc bugs
|
||||||
assert(!Linux::supports_monotonic_clock(), "time moving backwards");
|
assert(!Linux::supports_monotonic_clock(), "time moving backwards");
|
||||||
} else {
|
} else {
|
||||||
millis -= (newtime - prevtime) / NANOSECS_PER_MILLISECS;
|
millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(millis <= 0) {
|
if(millis <= 0) {
|
||||||
@ -3322,7 +3319,7 @@ int os::sleep(Thread* thread, jlong millis, bool interruptible) {
|
|||||||
// not a guarantee() because JVM should not abort on kernel/glibc bugs
|
// not a guarantee() because JVM should not abort on kernel/glibc bugs
|
||||||
assert(!Linux::supports_monotonic_clock(), "time moving backwards");
|
assert(!Linux::supports_monotonic_clock(), "time moving backwards");
|
||||||
} else {
|
} else {
|
||||||
millis -= (newtime - prevtime) / NANOSECS_PER_MILLISECS;
|
millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(millis <= 0) break ;
|
if(millis <= 0) break ;
|
||||||
@ -3924,7 +3921,7 @@ jlong os::Linux::fast_thread_cpu_time(clockid_t clockid) {
|
|||||||
int rc = os::Linux::clock_gettime(clockid, &tp);
|
int rc = os::Linux::clock_gettime(clockid, &tp);
|
||||||
assert(rc == 0, "clock_gettime is expected to return 0 code");
|
assert(rc == 0, "clock_gettime is expected to return 0 code");
|
||||||
|
|
||||||
return (tp.tv_sec * SEC_IN_NANOSECS) + tp.tv_nsec;
|
return (tp.tv_sec * NANOSECS_PER_SEC) + tp.tv_nsec;
|
||||||
}
|
}
|
||||||
|
|
||||||
/////
|
/////
|
||||||
@ -5165,9 +5162,6 @@ void os::PlatformEvent::unpark() {
|
|||||||
* is no need to track notifications.
|
* is no need to track notifications.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#define NANOSECS_PER_SEC 1000000000
|
|
||||||
#define NANOSECS_PER_MILLISEC 1000000
|
|
||||||
#define MAX_SECS 100000000
|
#define MAX_SECS 100000000
|
||||||
/*
|
/*
|
||||||
* This code is common to linux and solaris and will be moved to a
|
* This code is common to linux and solaris and will be moved to a
|
||||||
|
@ -1674,7 +1674,6 @@ void* os::thread_local_storage_at(int index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const int NANOSECS_PER_MILLISECS = 1000000;
|
|
||||||
// gethrtime can move backwards if read from one cpu and then a different cpu
|
// gethrtime can move backwards if read from one cpu and then a different cpu
|
||||||
// getTimeNanos is guaranteed to not move backward on Solaris
|
// getTimeNanos is guaranteed to not move backward on Solaris
|
||||||
// local spinloop created as faster for a CAS on an int than
|
// local spinloop created as faster for a CAS on an int than
|
||||||
@ -1803,7 +1802,7 @@ double os::elapsedVTime() {
|
|||||||
// getTimeMillis guaranteed to not move backwards on Solaris
|
// getTimeMillis guaranteed to not move backwards on Solaris
|
||||||
jlong getTimeMillis() {
|
jlong getTimeMillis() {
|
||||||
jlong nanotime = getTimeNanos();
|
jlong nanotime = getTimeNanos();
|
||||||
return (jlong)(nanotime / NANOSECS_PER_MILLISECS);
|
return (jlong)(nanotime / NANOSECS_PER_MILLISEC);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
|
// Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
|
||||||
@ -6064,10 +6063,7 @@ void os::PlatformEvent::unpark() {
|
|||||||
* is no need to track notifications.
|
* is no need to track notifications.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define NANOSECS_PER_SEC 1000000000
|
|
||||||
#define NANOSECS_PER_MILLISEC 1000000
|
|
||||||
#define MAX_SECS 100000000
|
#define MAX_SECS 100000000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This code is common to linux and solaris and will be moved to a
|
* This code is common to linux and solaris and will be moved to a
|
||||||
* common place in dolphin.
|
* common place in dolphin.
|
||||||
|
@ -821,17 +821,15 @@ jlong os::javaTimeMillis() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define NANOS_PER_SEC CONST64(1000000000)
|
|
||||||
#define NANOS_PER_MILLISEC 1000000
|
|
||||||
jlong os::javaTimeNanos() {
|
jlong os::javaTimeNanos() {
|
||||||
if (!has_performance_count) {
|
if (!has_performance_count) {
|
||||||
return javaTimeMillis() * NANOS_PER_MILLISEC; // the best we can do.
|
return javaTimeMillis() * NANOSECS_PER_MILLISEC; // the best we can do.
|
||||||
} else {
|
} else {
|
||||||
LARGE_INTEGER current_count;
|
LARGE_INTEGER current_count;
|
||||||
QueryPerformanceCounter(¤t_count);
|
QueryPerformanceCounter(¤t_count);
|
||||||
double current = as_long(current_count);
|
double current = as_long(current_count);
|
||||||
double freq = performance_frequency;
|
double freq = performance_frequency;
|
||||||
jlong time = (jlong)((current/freq) * NANOS_PER_SEC);
|
jlong time = (jlong)((current/freq) * NANOSECS_PER_SEC);
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -847,15 +845,15 @@ void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
|
|||||||
info_ptr->may_skip_forward = true;
|
info_ptr->may_skip_forward = true;
|
||||||
} else {
|
} else {
|
||||||
jlong freq = performance_frequency;
|
jlong freq = performance_frequency;
|
||||||
if (freq < NANOS_PER_SEC) {
|
if (freq < NANOSECS_PER_SEC) {
|
||||||
// the performance counter is 64 bits and we will
|
// the performance counter is 64 bits and we will
|
||||||
// be multiplying it -- so no wrap in 64 bits
|
// be multiplying it -- so no wrap in 64 bits
|
||||||
info_ptr->max_value = ALL_64_BITS;
|
info_ptr->max_value = ALL_64_BITS;
|
||||||
} else if (freq > NANOS_PER_SEC) {
|
} else if (freq > NANOSECS_PER_SEC) {
|
||||||
// use the max value the counter can reach to
|
// use the max value the counter can reach to
|
||||||
// determine the max value which could be returned
|
// determine the max value which could be returned
|
||||||
julong max_counter = (julong)ALL_64_BITS;
|
julong max_counter = (julong)ALL_64_BITS;
|
||||||
info_ptr->max_value = (jlong)(max_counter / (freq / NANOS_PER_SEC));
|
info_ptr->max_value = (jlong)(max_counter / (freq / NANOSECS_PER_SEC));
|
||||||
} else {
|
} else {
|
||||||
// the performance counter is 64 bits and we will
|
// the performance counter is 64 bits and we will
|
||||||
// be using it directly -- so no wrap in 64 bits
|
// be using it directly -- so no wrap in 64 bits
|
||||||
|
@ -672,15 +672,20 @@ void PSMarkSweep::mark_sweep_phase4() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
jlong PSMarkSweep::millis_since_last_gc() {
|
jlong PSMarkSweep::millis_since_last_gc() {
|
||||||
jlong ret_val = os::javaTimeMillis() - _time_of_last_gc;
|
// We need a monotonically non-deccreasing time in ms but
|
||||||
|
// os::javaTimeMillis() does not guarantee monotonicity.
|
||||||
|
jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
|
||||||
|
jlong ret_val = now - _time_of_last_gc;
|
||||||
// XXX See note in genCollectedHeap::millis_since_last_gc().
|
// XXX See note in genCollectedHeap::millis_since_last_gc().
|
||||||
if (ret_val < 0) {
|
if (ret_val < 0) {
|
||||||
NOT_PRODUCT(warning("time warp: %d", ret_val);)
|
NOT_PRODUCT(warning("time warp: "INT64_FORMAT, ret_val);)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PSMarkSweep::reset_millis_since_last_gc() {
|
void PSMarkSweep::reset_millis_since_last_gc() {
|
||||||
_time_of_last_gc = os::javaTimeMillis();
|
// We need a monotonically non-deccreasing time in ms but
|
||||||
|
// os::javaTimeMillis() does not guarantee monotonicity.
|
||||||
|
_time_of_last_gc = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
|
||||||
}
|
}
|
||||||
|
@ -3398,17 +3398,22 @@ PSParallelCompact::move_and_update(ParCompactionManager* cm, SpaceId space_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
jlong PSParallelCompact::millis_since_last_gc() {
|
jlong PSParallelCompact::millis_since_last_gc() {
|
||||||
jlong ret_val = os::javaTimeMillis() - _time_of_last_gc;
|
// We need a monotonically non-deccreasing time in ms but
|
||||||
|
// os::javaTimeMillis() does not guarantee monotonicity.
|
||||||
|
jlong now = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
|
||||||
|
jlong ret_val = now - _time_of_last_gc;
|
||||||
// XXX See note in genCollectedHeap::millis_since_last_gc().
|
// XXX See note in genCollectedHeap::millis_since_last_gc().
|
||||||
if (ret_val < 0) {
|
if (ret_val < 0) {
|
||||||
NOT_PRODUCT(warning("time warp: %d", ret_val);)
|
NOT_PRODUCT(warning("time warp: "INT64_FORMAT, ret_val);)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PSParallelCompact::reset_millis_since_last_gc() {
|
void PSParallelCompact::reset_millis_since_last_gc() {
|
||||||
_time_of_last_gc = os::javaTimeMillis();
|
// We need a monotonically non-deccreasing time in ms but
|
||||||
|
// os::javaTimeMillis() does not guarantee monotonicity.
|
||||||
|
_time_of_last_gc = os::javaTimeNanos() / NANOSECS_PER_MILLISEC;
|
||||||
}
|
}
|
||||||
|
|
||||||
ParMarkBitMap::IterationStatus MoveAndUpdateClosure::copy_until_full()
|
ParMarkBitMap::IterationStatus MoveAndUpdateClosure::copy_until_full()
|
||||||
|
@ -1460,26 +1460,22 @@ class GenTimeOfLastGCClosure: public GenCollectedHeap::GenClosure {
|
|||||||
};
|
};
|
||||||
|
|
||||||
jlong GenCollectedHeap::millis_since_last_gc() {
|
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);
|
GenTimeOfLastGCClosure tolgc_cl(now);
|
||||||
// iterate over generations getting the oldest
|
// iterate over generations getting the oldest
|
||||||
// time that a generation was collected
|
// time that a generation was collected
|
||||||
generation_iterate(&tolgc_cl, false);
|
generation_iterate(&tolgc_cl, false);
|
||||||
tolgc_cl.do_generation(perm_gen());
|
tolgc_cl.do_generation(perm_gen());
|
||||||
// XXX Despite the assert above, since javaTimeMillis()
|
|
||||||
// doesnot guarantee monotonically increasing return
|
// javaTimeNanos() is guaranteed to be monotonically non-decreasing
|
||||||
// values (note, i didn't say "strictly monotonic"),
|
// provided the underlying platform provides such a time source
|
||||||
// we need to guard against getting back a time
|
// (and it is bug free). So we still have to guard against getting
|
||||||
// later than now. This should be fixed by basing
|
// back a time later than 'now'.
|
||||||
// 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
|
|
||||||
jlong retVal = now - tolgc_cl.time();
|
jlong retVal = now - tolgc_cl.time();
|
||||||
if (retVal < 0) {
|
if (retVal < 0) {
|
||||||
NOT_PRODUCT(warning("time warp: %d", retVal);)
|
NOT_PRODUCT(warning("time warp: "INT64_FORMAT, retVal);)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return retVal;
|
return retVal;
|
||||||
|
@ -413,10 +413,13 @@ class Generation: public CHeapObj {
|
|||||||
// Time (in ms) when we were last collected or now if a collection is
|
// Time (in ms) when we were last collected or now if a collection is
|
||||||
// in progress.
|
// in progress.
|
||||||
virtual jlong time_of_last_gc(jlong now) {
|
virtual jlong time_of_last_gc(jlong now) {
|
||||||
// XXX See note in genCollectedHeap::millis_since_last_gc()
|
// Both _time_of_last_gc and now are set using a time source
|
||||||
|
// that guarantees monotonically non-decreasing values provided
|
||||||
|
// the underlying platform provides such a source. So we still
|
||||||
|
// have to guard against non-monotonicity.
|
||||||
NOT_PRODUCT(
|
NOT_PRODUCT(
|
||||||
if (now < _time_of_last_gc) {
|
if (now < _time_of_last_gc) {
|
||||||
warning("time warp: %d to %d", _time_of_last_gc, now);
|
warning("time warp: "INT64_FORMAT" to "INT64_FORMAT, _time_of_last_gc, now);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
return _time_of_last_gc;
|
return _time_of_last_gc;
|
||||||
|
@ -43,7 +43,9 @@ void referenceProcessor_init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ReferenceProcessor::init_statics() {
|
void ReferenceProcessor::init_statics() {
|
||||||
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;
|
||||||
|
|
||||||
// Initialize the soft ref timestamp clock.
|
// Initialize the soft ref timestamp clock.
|
||||||
_soft_ref_timestamp_clock = now;
|
_soft_ref_timestamp_clock = now;
|
||||||
@ -151,7 +153,10 @@ void ReferenceProcessor::weak_oops_do(OopClosure* f) {
|
|||||||
void ReferenceProcessor::update_soft_ref_master_clock() {
|
void ReferenceProcessor::update_soft_ref_master_clock() {
|
||||||
// Update (advance) the soft ref master clock field. This must be done
|
// Update (advance) the soft ref master clock field. This must be done
|
||||||
// after processing the soft ref list.
|
// after processing the soft ref list.
|
||||||
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;
|
||||||
jlong soft_ref_clock = java_lang_ref_SoftReference::clock();
|
jlong soft_ref_clock = java_lang_ref_SoftReference::clock();
|
||||||
assert(soft_ref_clock == _soft_ref_timestamp_clock, "soft ref clocks out of sync");
|
assert(soft_ref_clock == _soft_ref_timestamp_clock, "soft ref clocks out of sync");
|
||||||
|
|
||||||
@ -161,10 +166,11 @@ void ReferenceProcessor::update_soft_ref_master_clock() {
|
|||||||
_soft_ref_timestamp_clock, now);
|
_soft_ref_timestamp_clock, now);
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
// In product mode, protect ourselves from system time being adjusted
|
// The values of now and _soft_ref_timestamp_clock are set using
|
||||||
// externally and going backward; see note in the implementation of
|
// javaTimeNanos(), which is guaranteed to be monotonically
|
||||||
// GenCollectedHeap::time_since_last_gc() for the right way to fix
|
// non-decreasing provided the underlying platform provides such
|
||||||
// this uniformly throughout the VM; see bug-id 4741166. XXX
|
// a time source (and it is bug free).
|
||||||
|
// In product mode, however, protect ourselves from non-monotonicty.
|
||||||
if (now > _soft_ref_timestamp_clock) {
|
if (now > _soft_ref_timestamp_clock) {
|
||||||
_soft_ref_timestamp_clock = now;
|
_soft_ref_timestamp_clock = now;
|
||||||
java_lang_ref_SoftReference::set_clock(now);
|
java_lang_ref_SoftReference::set_clock(now);
|
||||||
|
@ -175,6 +175,9 @@ const int MILLIUNITS = 1000; // milli units per base unit
|
|||||||
const int MICROUNITS = 1000000; // micro units per base unit
|
const int MICROUNITS = 1000000; // micro units per base unit
|
||||||
const int NANOUNITS = 1000000000; // nano units per base unit
|
const int NANOUNITS = 1000000000; // nano units per base unit
|
||||||
|
|
||||||
|
const jlong NANOSECS_PER_SEC = CONST64(1000000000);
|
||||||
|
const jint NANOSECS_PER_MILLISEC = 1000000;
|
||||||
|
|
||||||
inline const char* proper_unit_for_byte_size(size_t s) {
|
inline const char* proper_unit_for_byte_size(size_t s) {
|
||||||
if (s >= 10*M) {
|
if (s >= 10*M) {
|
||||||
return "M";
|
return "M";
|
||||||
|
Loading…
x
Reference in New Issue
Block a user