8246112: Remove build-time and run-time checks for clock_gettime and CLOCK_MONOTONIC
Reviewed-by: ihse, erikj, gziemski, hseigel
This commit is contained in:
parent
19b6f61bd2
commit
6f2be9c608
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -605,25 +605,6 @@ AC_DEFUN([FLAGS_SETUP_CFLAGS_HELPER],
|
||||
fi
|
||||
fi
|
||||
|
||||
# Optional POSIX functionality needed by the JVM
|
||||
#
|
||||
# Check if clock_gettime is available and in which library. This indicates
|
||||
# availability of CLOCK_MONOTONIC for hotspot. But we don't need to link, so
|
||||
# don't let it update LIBS.
|
||||
save_LIBS="$LIBS"
|
||||
AC_SEARCH_LIBS(clock_gettime, rt, [HAS_CLOCK_GETTIME=true], [])
|
||||
if test "x$LIBS" = "x-lrt "; then
|
||||
CLOCK_GETTIME_IN_LIBRT=true
|
||||
fi
|
||||
LIBS="$save_LIBS"
|
||||
|
||||
if test "x$HAS_CLOCK_GETTIME" = "xtrue"; then
|
||||
OS_CFLAGS_JVM="$OS_CFLAGS_JVM -DSUPPORTS_CLOCK_MONOTONIC"
|
||||
if test "x$CLOCK_GETTIME_IN_LIBRT" = "xtrue"; then
|
||||
OS_CFLAGS_JVM="$OS_CFLAGS_JVM -DNEEDS_LIBRT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Extra flags needed when building optional static versions of certain
|
||||
# JDK libraries.
|
||||
STATIC_LIBS_CFLAGS="-DSTATIC_BUILD=1"
|
||||
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
# Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
@ -108,6 +108,13 @@ AC_DEFUN([FLAGS_SETUP_LDFLAGS_HELPER],
|
||||
OS_LDFLAGS_JVM_ONLY="-Wl,-rpath,@loader_path/. -Wl,-rpath,@loader_path/.."
|
||||
OS_LDFLAGS="-mmacosx-version-min=$MACOSX_VERSION_MIN"
|
||||
fi
|
||||
if test "x$OPENJDK_TARGET_OS" = xlinux; then
|
||||
# Hotspot needs to link librt to get the clock_* functions.
|
||||
# But once our supported minimum build and runtime platform
|
||||
# has glibc 2.17, this can be removed as the functions are
|
||||
# in libc.
|
||||
OS_LDFLAGS_JVM_ONLY="-lrt"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Setup debug level-dependent LDFLAGS
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2020 SAP SE. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
@ -959,21 +959,6 @@ double os::elapsedVTime() {
|
||||
}
|
||||
}
|
||||
|
||||
jlong os::javaTimeMillis() {
|
||||
timeval time;
|
||||
int status = gettimeofday(&time, NULL);
|
||||
assert(status != -1, "aix error at gettimeofday()");
|
||||
return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000);
|
||||
}
|
||||
|
||||
void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {
|
||||
timeval time;
|
||||
int status = gettimeofday(&time, NULL);
|
||||
assert(status != -1, "aix error at gettimeofday()");
|
||||
seconds = jlong(time.tv_sec);
|
||||
nanos = jlong(time.tv_usec) * 1000;
|
||||
}
|
||||
|
||||
// We use mread_real_time here.
|
||||
// On AIX: If the CPU has a time register, the result will be RTC_POWER and
|
||||
// it has to be converted to real time. AIX documentations suggests to do
|
||||
@ -3290,4 +3275,3 @@ bool os::supports_map_sync() {
|
||||
}
|
||||
|
||||
void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) {}
|
||||
|
||||
|
@ -107,11 +107,6 @@ inline struct hostent* os::get_host_by_name(char* name) {
|
||||
return ::gethostbyname(name);
|
||||
}
|
||||
|
||||
inline bool os::supports_monotonic_clock() {
|
||||
// mread_real_time() is monotonic on AIX (see os::javaTimeNanos() comments)
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void os::exit(int num) {
|
||||
::exit(num);
|
||||
}
|
||||
|
@ -123,8 +123,6 @@ julong os::Bsd::_physical_memory = 0;
|
||||
#ifdef __APPLE__
|
||||
mach_timebase_info_data_t os::Bsd::_timebase_info = {0, 0};
|
||||
volatile uint64_t os::Bsd::_max_abstime = 0;
|
||||
#else
|
||||
int (*os::Bsd::_clock_gettime)(clockid_t, struct timespec *) = NULL;
|
||||
#endif
|
||||
pthread_t os::Bsd::_main_thread;
|
||||
int os::Bsd::_page_size = -1;
|
||||
@ -789,40 +787,13 @@ double os::elapsedVTime() {
|
||||
return elapsedTime();
|
||||
}
|
||||
|
||||
jlong os::javaTimeMillis() {
|
||||
timeval time;
|
||||
int status = gettimeofday(&time, NULL);
|
||||
assert(status != -1, "bsd error");
|
||||
return jlong(time.tv_sec) * 1000 + jlong(time.tv_usec / 1000);
|
||||
}
|
||||
|
||||
void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {
|
||||
timeval time;
|
||||
int status = gettimeofday(&time, NULL);
|
||||
assert(status != -1, "bsd error");
|
||||
seconds = jlong(time.tv_sec);
|
||||
nanos = jlong(time.tv_usec) * 1000;
|
||||
}
|
||||
|
||||
#ifndef __APPLE__
|
||||
#ifndef CLOCK_MONOTONIC
|
||||
#define CLOCK_MONOTONIC (1)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __APPLE__
|
||||
void os::Bsd::clock_init() {
|
||||
mach_timebase_info(&_timebase_info);
|
||||
}
|
||||
#else
|
||||
void os::Bsd::clock_init() {
|
||||
struct timespec res;
|
||||
struct timespec tp;
|
||||
if (::clock_getres(CLOCK_MONOTONIC, &res) == 0 &&
|
||||
::clock_gettime(CLOCK_MONOTONIC, &tp) == 0) {
|
||||
// yes, monotonic clock is supported
|
||||
_clock_gettime = ::clock_gettime;
|
||||
}
|
||||
// Nothing to do
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -854,45 +825,15 @@ jlong os::javaTimeNanos() {
|
||||
return (prev == obsv) ? now : obsv;
|
||||
}
|
||||
|
||||
#else // __APPLE__
|
||||
|
||||
jlong os::javaTimeNanos() {
|
||||
if (os::supports_monotonic_clock()) {
|
||||
struct timespec tp;
|
||||
int status = Bsd::_clock_gettime(CLOCK_MONOTONIC, &tp);
|
||||
assert(status == 0, "gettime error");
|
||||
jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec);
|
||||
return result;
|
||||
} else {
|
||||
timeval time;
|
||||
int status = gettimeofday(&time, NULL);
|
||||
assert(status != -1, "bsd error");
|
||||
jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec);
|
||||
return 1000 * usecs;
|
||||
}
|
||||
void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
|
||||
info_ptr->max_value = ALL_64_BITS;
|
||||
info_ptr->may_skip_backward = false; // not subject to resetting or drifting
|
||||
info_ptr->may_skip_forward = false; // not subject to resetting or drifting
|
||||
info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time
|
||||
}
|
||||
|
||||
#endif // __APPLE__
|
||||
|
||||
void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
|
||||
if (os::supports_monotonic_clock()) {
|
||||
info_ptr->max_value = ALL_64_BITS;
|
||||
|
||||
// CLOCK_MONOTONIC - amount of time since some arbitrary point in the past
|
||||
info_ptr->may_skip_backward = false; // not subject to resetting or drifting
|
||||
info_ptr->may_skip_forward = false; // not subject to resetting or drifting
|
||||
} else {
|
||||
// gettimeofday - based on time in seconds since the Epoch thus does not wrap
|
||||
info_ptr->max_value = ALL_64_BITS;
|
||||
|
||||
// gettimeofday is a real time clock so it skips
|
||||
info_ptr->may_skip_backward = true;
|
||||
info_ptr->may_skip_forward = true;
|
||||
}
|
||||
|
||||
info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time
|
||||
}
|
||||
|
||||
// Return the real, user, and system times in seconds from an
|
||||
// arbitrary fixed point in the past.
|
||||
bool os::getTimesSecs(double* process_real_time,
|
||||
@ -2812,4 +2753,3 @@ bool os::start_debugging(char *buf, int buflen) {
|
||||
}
|
||||
|
||||
void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) {}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -37,8 +37,6 @@ class Bsd {
|
||||
// mach_absolute_time
|
||||
static mach_timebase_info_data_t _timebase_info;
|
||||
static volatile uint64_t _max_abstime;
|
||||
#else
|
||||
static int (*_clock_gettime)(clockid_t, struct timespec *);
|
||||
#endif
|
||||
|
||||
static GrowableArray<int>* _cpu_to_node;
|
||||
|
@ -109,14 +109,6 @@ inline struct hostent* os::get_host_by_name(char* name) {
|
||||
return ::gethostbyname(name);
|
||||
}
|
||||
|
||||
inline bool os::supports_monotonic_clock() {
|
||||
#ifdef __APPLE__
|
||||
return true;
|
||||
#else
|
||||
return Bsd::_clock_gettime != NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void os::exit(int num) {
|
||||
::exit(num);
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -56,12 +56,13 @@ class CPUPerformanceInterface::CPUPerformance : public CHeapObj<mtInternal> {
|
||||
int _active_processor_count;
|
||||
|
||||
bool now_in_nanos(long* resultp) {
|
||||
timeval current_time;
|
||||
if (gettimeofday(¤t_time, NULL) != 0) {
|
||||
// Error getting current time
|
||||
struct timespec tp;
|
||||
int status = clock_gettime(CLOCK_REALTIME, &tp);
|
||||
assert(status == 0, "clock_gettime error: %s", os::strerror(errno));
|
||||
if (status != 0) {
|
||||
return false;
|
||||
}
|
||||
*resultp = current_time.tv_sec * NANOS_PER_SEC + 1000L * current_time.tv_usec;
|
||||
*resultp = tp.tv_sec * NANOS_PER_SEC + tp.tv_nsec;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1268,10 +1268,6 @@ void os::Linux::capture_initial_stack(size_t max_size) {
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// time support
|
||||
|
||||
#ifndef SUPPORTS_CLOCK_MONOTONIC
|
||||
#error "Build platform doesn't support clock_gettime and related functionality"
|
||||
#endif
|
||||
|
||||
// Time since start-up in seconds to a fine granularity.
|
||||
// Used by VMSelfDestructTimer and the MemProfiler.
|
||||
double os::elapsedTime() {
|
||||
@ -1300,38 +1296,6 @@ double os::elapsedVTime() {
|
||||
}
|
||||
}
|
||||
|
||||
jlong os::javaTimeMillis() {
|
||||
if (os::Posix::supports_clock_gettime()) {
|
||||
struct timespec ts;
|
||||
int status = os::Posix::clock_gettime(CLOCK_REALTIME, &ts);
|
||||
assert_status(status == 0, status, "gettime error");
|
||||
return jlong(ts.tv_sec) * MILLIUNITS +
|
||||
jlong(ts.tv_nsec) / NANOUNITS_PER_MILLIUNIT;
|
||||
} else {
|
||||
timeval time;
|
||||
int status = gettimeofday(&time, NULL);
|
||||
assert(status != -1, "linux error");
|
||||
return jlong(time.tv_sec) * MILLIUNITS +
|
||||
jlong(time.tv_usec) / (MICROUNITS / MILLIUNITS);
|
||||
}
|
||||
}
|
||||
|
||||
void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {
|
||||
if (os::Posix::supports_clock_gettime()) {
|
||||
struct timespec ts;
|
||||
int status = os::Posix::clock_gettime(CLOCK_REALTIME, &ts);
|
||||
assert_status(status == 0, status, "gettime error");
|
||||
seconds = jlong(ts.tv_sec);
|
||||
nanos = jlong(ts.tv_nsec);
|
||||
} else {
|
||||
timeval time;
|
||||
int status = gettimeofday(&time, NULL);
|
||||
assert(status != -1, "linux error");
|
||||
seconds = jlong(time.tv_sec);
|
||||
nanos = jlong(time.tv_usec) * (NANOUNITS / MICROUNITS);
|
||||
}
|
||||
}
|
||||
|
||||
void os::Linux::fast_thread_clock_init() {
|
||||
if (!UseLinuxPosixThreadCPUClocks) {
|
||||
return;
|
||||
@ -1352,47 +1316,12 @@ void os::Linux::fast_thread_clock_init() {
|
||||
|
||||
if (pthread_getcpuclockid_func &&
|
||||
pthread_getcpuclockid_func(_main_thread, &clockid) == 0 &&
|
||||
os::Posix::clock_getres(clockid, &tp) == 0 && tp.tv_sec == 0) {
|
||||
clock_getres(clockid, &tp) == 0 && tp.tv_sec == 0) {
|
||||
_supports_fast_thread_cpu_time = true;
|
||||
_pthread_getcpuclockid = pthread_getcpuclockid_func;
|
||||
}
|
||||
}
|
||||
|
||||
jlong os::javaTimeNanos() {
|
||||
if (os::supports_monotonic_clock()) {
|
||||
struct timespec tp;
|
||||
int status = os::Posix::clock_gettime(CLOCK_MONOTONIC, &tp);
|
||||
assert(status == 0, "gettime error");
|
||||
jlong result = jlong(tp.tv_sec) * (1000 * 1000 * 1000) + jlong(tp.tv_nsec);
|
||||
return result;
|
||||
} else {
|
||||
timeval time;
|
||||
int status = gettimeofday(&time, NULL);
|
||||
assert(status != -1, "linux error");
|
||||
jlong usecs = jlong(time.tv_sec) * (1000 * 1000) + jlong(time.tv_usec);
|
||||
return 1000 * usecs;
|
||||
}
|
||||
}
|
||||
|
||||
void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
|
||||
if (os::supports_monotonic_clock()) {
|
||||
info_ptr->max_value = ALL_64_BITS;
|
||||
|
||||
// CLOCK_MONOTONIC - amount of time since some arbitrary point in the past
|
||||
info_ptr->may_skip_backward = false; // not subject to resetting or drifting
|
||||
info_ptr->may_skip_forward = false; // not subject to resetting or drifting
|
||||
} else {
|
||||
// gettimeofday - based on time in seconds since the Epoch thus does not wrap
|
||||
info_ptr->max_value = ALL_64_BITS;
|
||||
|
||||
// gettimeofday is a real time clock so it skips
|
||||
info_ptr->may_skip_backward = true;
|
||||
info_ptr->may_skip_forward = true;
|
||||
}
|
||||
|
||||
info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time
|
||||
}
|
||||
|
||||
// Return the real, user, and system times in seconds from an
|
||||
// arbitrary fixed point in the past.
|
||||
bool os::getTimesSecs(double* process_real_time,
|
||||
@ -4344,9 +4273,8 @@ OSReturn os::get_native_priority(const Thread* const thread,
|
||||
|
||||
jlong os::Linux::fast_thread_cpu_time(clockid_t clockid) {
|
||||
struct timespec tp;
|
||||
int rc = os::Posix::clock_gettime(clockid, &tp);
|
||||
assert(rc == 0, "clock_gettime is expected to return 0 code");
|
||||
|
||||
int status = clock_gettime(clockid, &tp);
|
||||
assert(status == 0, "clock_gettime error: %s", os::strerror(errno));
|
||||
return (tp.tv_sec * NANOSECS_PER_SEC) + tp.tv_nsec;
|
||||
}
|
||||
|
||||
@ -4454,12 +4382,6 @@ void os::init(void) {
|
||||
os::Posix::init();
|
||||
|
||||
initial_time_count = javaTimeNanos();
|
||||
|
||||
// Always warn if no monotonic clock available
|
||||
if (!os::Posix::supports_monotonic_clock()) {
|
||||
warning("No monotonic clock was available - timed services may " \
|
||||
"be adversely affected if the time-of-day clock changes");
|
||||
}
|
||||
}
|
||||
|
||||
// To install functions for atexit system call
|
||||
|
@ -101,10 +101,6 @@ inline struct hostent* os::get_host_by_name(char* name) {
|
||||
return ::gethostbyname(name);
|
||||
}
|
||||
|
||||
inline bool os::supports_monotonic_clock() {
|
||||
return os::Posix::supports_monotonic_clock();
|
||||
}
|
||||
|
||||
inline void os::exit(int num) {
|
||||
::exit(num);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
*/
|
||||
|
||||
#include "jvm.h"
|
||||
#include "jvmtifiles/jvmti.h"
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "os_posix.inline.hpp"
|
||||
@ -1116,23 +1117,6 @@ static void pthread_init_common(void) {
|
||||
os::PlatformMutex::init();
|
||||
}
|
||||
|
||||
// Not all POSIX types and API's are available on all notionally "posix"
|
||||
// platforms. If we have build-time support then we will check for actual
|
||||
// runtime support via dlopen/dlsym lookup. This allows for running on an
|
||||
// older OS version compared to the build platform. But if there is no
|
||||
// build time support then there cannot be any runtime support as we do not
|
||||
// know what the runtime types would be (for example clockid_t might be an
|
||||
// int or int64_t).
|
||||
//
|
||||
#ifdef SUPPORTS_CLOCK_MONOTONIC
|
||||
|
||||
// This means we have clockid_t, clock_gettime et al and CLOCK_MONOTONIC
|
||||
|
||||
int (*os::Posix::_clock_gettime)(clockid_t, struct timespec *) = NULL;
|
||||
int (*os::Posix::_clock_getres)(clockid_t, struct timespec *) = NULL;
|
||||
|
||||
bool os::Posix::_supports_monotonic_clock = false;
|
||||
|
||||
static int (*_pthread_condattr_setclock)(pthread_condattr_t *, clockid_t) = NULL;
|
||||
|
||||
static bool _use_clock_monotonic_condattr = false;
|
||||
@ -1144,44 +1128,7 @@ void os::Posix::init(void) {
|
||||
// NOTE: no logging available when this is called. Put logging
|
||||
// statements in init_2().
|
||||
|
||||
// 1. Check for CLOCK_MONOTONIC support.
|
||||
|
||||
void* handle = NULL;
|
||||
|
||||
// For older linux we need librt, for other OS we can find
|
||||
// this function in regular libc.
|
||||
#ifdef NEEDS_LIBRT
|
||||
// We do dlopen's in this particular order due to bug in linux
|
||||
// dynamic loader (see 6348968) leading to crash on exit.
|
||||
handle = dlopen("librt.so.1", RTLD_LAZY);
|
||||
if (handle == NULL) {
|
||||
handle = dlopen("librt.so", RTLD_LAZY);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (handle == NULL) {
|
||||
handle = RTLD_DEFAULT;
|
||||
}
|
||||
|
||||
int (*clock_getres_func)(clockid_t, struct timespec*) =
|
||||
(int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_getres");
|
||||
int (*clock_gettime_func)(clockid_t, struct timespec*) =
|
||||
(int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_gettime");
|
||||
if (clock_getres_func != NULL && clock_gettime_func != NULL) {
|
||||
_clock_gettime = clock_gettime_func;
|
||||
_clock_getres = clock_getres_func;
|
||||
// We assume that if both clock_gettime and clock_getres support
|
||||
// CLOCK_MONOTONIC then the OS provides true high-res monotonic clock.
|
||||
struct timespec res;
|
||||
struct timespec tp;
|
||||
if (clock_getres_func(CLOCK_MONOTONIC, &res) == 0 &&
|
||||
clock_gettime_func(CLOCK_MONOTONIC, &tp) == 0) {
|
||||
// Yes, monotonic clock is supported.
|
||||
_supports_monotonic_clock = true;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Check for pthread_condattr_setclock support.
|
||||
// Check for pthread_condattr_setclock support.
|
||||
|
||||
// libpthread is already loaded.
|
||||
int (*condattr_setclock_func)(pthread_condattr_t*, clockid_t) =
|
||||
@ -1196,7 +1143,7 @@ void os::Posix::init(void) {
|
||||
pthread_init_common();
|
||||
|
||||
int status;
|
||||
if (_pthread_condattr_setclock != NULL && _clock_gettime != NULL) {
|
||||
if (_pthread_condattr_setclock != NULL) {
|
||||
if ((status = _pthread_condattr_setclock(_condAttr, CLOCK_MONOTONIC)) != 0) {
|
||||
if (status == EINVAL) {
|
||||
_use_clock_monotonic_condattr = false;
|
||||
@ -1212,28 +1159,13 @@ void os::Posix::init(void) {
|
||||
}
|
||||
|
||||
void os::Posix::init_2(void) {
|
||||
log_info(os)("Use of CLOCK_MONOTONIC is%s supported",
|
||||
(_clock_gettime != NULL ? "" : " not"));
|
||||
log_info(os)("Use of CLOCK_MONOTONIC is supported");
|
||||
log_info(os)("Use of pthread_condattr_setclock is%s supported",
|
||||
(_pthread_condattr_setclock != NULL ? "" : " not"));
|
||||
log_info(os)("Relative timed-wait using pthread_cond_timedwait is associated with %s",
|
||||
_use_clock_monotonic_condattr ? "CLOCK_MONOTONIC" : "the default clock");
|
||||
}
|
||||
|
||||
#else // !SUPPORTS_CLOCK_MONOTONIC
|
||||
|
||||
void os::Posix::init(void) {
|
||||
pthread_init_common();
|
||||
}
|
||||
|
||||
void os::Posix::init_2(void) {
|
||||
log_info(os)("Use of CLOCK_MONOTONIC is not supported");
|
||||
log_info(os)("Use of pthread_condattr_setclock is not supported");
|
||||
log_info(os)("Relative timed-wait using pthread_cond_timedwait is associated with the default clock");
|
||||
}
|
||||
|
||||
#endif // SUPPORTS_CLOCK_MONOTONIC
|
||||
|
||||
// Utility to convert the given timeout to an absolute timespec
|
||||
// (based on the appropriate clock) to use with pthread_cond_timewait,
|
||||
// and sem_timedwait().
|
||||
@ -1285,7 +1217,6 @@ static void calc_rel_time(timespec* abstime, jlong timeout, jlong now_sec,
|
||||
|
||||
// Unpack the given deadline in milliseconds since the epoch, into the given timespec.
|
||||
// The current time in seconds is also passed in to enforce an upper bound as discussed above.
|
||||
// This is only used with gettimeofday, when clock_gettime is not available.
|
||||
static void unpack_abs_time(timespec* abstime, jlong deadline, jlong now_sec) {
|
||||
time_t max_secs = now_sec + MAX_SECS;
|
||||
|
||||
@ -1320,39 +1251,22 @@ static void to_abstime(timespec* abstime, jlong timeout,
|
||||
timeout = 0;
|
||||
}
|
||||
|
||||
#ifdef SUPPORTS_CLOCK_MONOTONIC
|
||||
|
||||
clockid_t clock = CLOCK_MONOTONIC;
|
||||
// need to ensure we have a runtime check for clock_gettime support
|
||||
if (!isAbsolute && os::Posix::supports_monotonic_clock()) {
|
||||
if (!_use_clock_monotonic_condattr || isRealtime) {
|
||||
clock = CLOCK_REALTIME;
|
||||
}
|
||||
struct timespec now;
|
||||
int status = os::Posix::clock_gettime(clock, &now);
|
||||
assert_status(status == 0, status, "clock_gettime");
|
||||
calc_rel_time(abstime, timeout, now.tv_sec, now.tv_nsec, NANOUNITS);
|
||||
DEBUG_ONLY(max_secs += now.tv_sec;)
|
||||
} else {
|
||||
|
||||
#else
|
||||
|
||||
{ // Match the block scope.
|
||||
|
||||
#endif // SUPPORTS_CLOCK_MONOTONIC
|
||||
|
||||
// Time-of-day clock is all we can reliably use.
|
||||
struct timeval now;
|
||||
int status = gettimeofday(&now, NULL);
|
||||
assert_status(status == 0, errno, "gettimeofday");
|
||||
if (isAbsolute) {
|
||||
unpack_abs_time(abstime, timeout, now.tv_sec);
|
||||
} else {
|
||||
calc_rel_time(abstime, timeout, now.tv_sec, now.tv_usec, MICROUNITS);
|
||||
}
|
||||
DEBUG_ONLY(max_secs += now.tv_sec;)
|
||||
if (isAbsolute || (!_use_clock_monotonic_condattr || isRealtime)) {
|
||||
clock = CLOCK_REALTIME;
|
||||
}
|
||||
|
||||
struct timespec now;
|
||||
int status = clock_gettime(clock, &now);
|
||||
assert(status == 0, "clock_gettime error: %s", os::strerror(errno));
|
||||
|
||||
if (!isAbsolute) {
|
||||
calc_rel_time(abstime, timeout, now.tv_sec, now.tv_nsec, NANOUNITS);
|
||||
} else {
|
||||
unpack_abs_time(abstime, timeout, now.tv_sec);
|
||||
}
|
||||
DEBUG_ONLY(max_secs += now.tv_sec;)
|
||||
|
||||
assert(abstime->tv_sec >= 0, "tv_sec < 0");
|
||||
assert(abstime->tv_sec <= max_secs, "tv_sec > max_secs");
|
||||
assert(abstime->tv_nsec >= 0, "tv_nsec < 0");
|
||||
@ -1367,6 +1281,51 @@ void os::Posix::to_RTC_abstime(timespec* abstime, int64_t millis) {
|
||||
true /* use real-time clock */);
|
||||
}
|
||||
|
||||
// Common (partly) shared time functions
|
||||
|
||||
jlong os::javaTimeMillis() {
|
||||
struct timespec ts;
|
||||
int status = clock_gettime(CLOCK_REALTIME, &ts);
|
||||
assert(status == 0, "clock_gettime error: %s", os::strerror(errno));
|
||||
return jlong(ts.tv_sec) * MILLIUNITS +
|
||||
jlong(ts.tv_nsec) / NANOUNITS_PER_MILLIUNIT;
|
||||
}
|
||||
|
||||
void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {
|
||||
struct timespec ts;
|
||||
int status = clock_gettime(CLOCK_REALTIME, &ts);
|
||||
assert(status == 0, "clock_gettime error: %s", os::strerror(errno));
|
||||
seconds = jlong(ts.tv_sec);
|
||||
nanos = jlong(ts.tv_nsec);
|
||||
}
|
||||
|
||||
// macOS and AIX have platform specific implementations for javaTimeNanos()
|
||||
// using native clock/timer access APIs. These have historically worked well
|
||||
// for those platforms, but it may be possible for them to switch to the
|
||||
// generic clock_gettime mechanism in the future.
|
||||
#if !defined(__APPLE__) && !defined(AIX)
|
||||
|
||||
jlong os::javaTimeNanos() {
|
||||
struct timespec tp;
|
||||
int status = clock_gettime(CLOCK_MONOTONIC, &tp);
|
||||
assert(status == 0, "clock_gettime error: %s", os::strerror(errno));
|
||||
jlong result = jlong(tp.tv_sec) * NANOSECS_PER_SEC + jlong(tp.tv_nsec);
|
||||
return result;
|
||||
}
|
||||
|
||||
// for timer info max values which include all bits
|
||||
#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
|
||||
|
||||
void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
|
||||
// CLOCK_MONOTONIC - amount of time since some arbitrary point in the past
|
||||
info_ptr->max_value = ALL_64_BITS;
|
||||
info_ptr->may_skip_backward = false; // not subject to resetting or drifting
|
||||
info_ptr->may_skip_forward = false; // not subject to resetting or drifting
|
||||
info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time
|
||||
}
|
||||
|
||||
#endif // ! APPLE && !AIX
|
||||
|
||||
// Shared pthread_mutex/cond based PlatformEvent implementation.
|
||||
// Not currently usable by Solaris.
|
||||
|
||||
|
@ -92,23 +92,6 @@ public:
|
||||
static address ucontext_get_pc(const ucontext_t* ctx);
|
||||
static void ucontext_set_pc(ucontext_t* ctx, address pc);
|
||||
|
||||
#ifdef SUPPORTS_CLOCK_MONOTONIC
|
||||
|
||||
private:
|
||||
static bool _supports_monotonic_clock;
|
||||
// These need to be members so we can access them from inline functions
|
||||
static int (*_clock_gettime)(clockid_t, struct timespec *);
|
||||
static int (*_clock_getres)(clockid_t, struct timespec *);
|
||||
public:
|
||||
static bool supports_monotonic_clock();
|
||||
static bool supports_clock_gettime();
|
||||
static int clock_gettime(clockid_t clock_id, struct timespec *tp);
|
||||
static int clock_getres(clockid_t clock_id, struct timespec *tp);
|
||||
#else
|
||||
static bool supports_monotonic_clock() { return false; }
|
||||
static bool supports_clock_gettime() { return false; }
|
||||
#endif
|
||||
|
||||
static void to_RTC_abstime(timespec* abstime, int64_t millis);
|
||||
|
||||
static bool handle_stack_overflow(JavaThread* thread, address addr, address pc,
|
||||
|
@ -46,28 +46,6 @@ inline int os::close(int fd) {
|
||||
return ::close(fd);
|
||||
}
|
||||
|
||||
#ifdef SUPPORTS_CLOCK_MONOTONIC
|
||||
|
||||
// Exported clock functionality
|
||||
|
||||
inline bool os::Posix::supports_monotonic_clock() {
|
||||
return _supports_monotonic_clock;
|
||||
}
|
||||
|
||||
inline bool os::Posix::supports_clock_gettime() {
|
||||
return _clock_gettime != NULL;
|
||||
}
|
||||
|
||||
inline int os::Posix::clock_gettime(clockid_t clock_id, struct timespec *tp) {
|
||||
return _clock_gettime != NULL ? _clock_gettime(clock_id, tp) : -1;
|
||||
}
|
||||
|
||||
inline int os::Posix::clock_getres(clockid_t clock_id, struct timespec *tp) {
|
||||
return _clock_getres != NULL ? _clock_getres(clock_id, tp) : -1;
|
||||
}
|
||||
|
||||
#endif // SUPPORTS_CLOCK_MONOTONIC
|
||||
|
||||
// Platform Mutex/Monitor implementation
|
||||
|
||||
inline void os::PlatformMutex::lock() {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -71,10 +71,6 @@ inline int os::close(int fd) {
|
||||
return ::close(fd);
|
||||
}
|
||||
|
||||
inline bool os::supports_monotonic_clock() {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void os::exit(int num) {
|
||||
win32::exit_process_or_thread(win32::EPT_PROCESS, num);
|
||||
}
|
||||
|
@ -190,7 +190,6 @@ class os: AllStatic {
|
||||
static void javaTimeNanos_info(jvmtiTimerInfo *info_ptr);
|
||||
static void javaTimeSystemUTC(jlong &seconds, jlong &nanos);
|
||||
static void run_periodic_checks();
|
||||
static bool supports_monotonic_clock();
|
||||
|
||||
// Returns the elapsed time in seconds since the vm started.
|
||||
static double elapsedTime();
|
||||
|
@ -3128,7 +3128,7 @@ bool JavaThread::sleep(jlong millis) {
|
||||
if (newtime - prevtime < 0) {
|
||||
// time moving backwards, should only happen if no monotonic clock
|
||||
// not a guarantee() because JVM should not abort on kernel/glibc bugs
|
||||
assert(!os::supports_monotonic_clock(),
|
||||
assert(false,
|
||||
"unexpected time moving backwards detected in JavaThread::sleep()");
|
||||
} else {
|
||||
millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
|
||||
|
Loading…
x
Reference in New Issue
Block a user