8211175: Remove temporary clock initialization duplication
Reviewed-by: rehn, mikael
This commit is contained in:
parent
07815d0139
commit
d1d1c16f8c
@ -137,7 +137,6 @@ julong os::Linux::_physical_memory = 0;
|
||||
address os::Linux::_initial_thread_stack_bottom = NULL;
|
||||
uintptr_t os::Linux::_initial_thread_stack_size = 0;
|
||||
|
||||
int (*os::Linux::_clock_gettime)(clockid_t, struct timespec *) = NULL;
|
||||
int (*os::Linux::_pthread_getcpuclockid)(pthread_t, clockid_t *) = NULL;
|
||||
int (*os::Linux::_pthread_setname_np)(pthread_t, const char*) = NULL;
|
||||
Mutex* os::Linux::_createThread_lock = NULL;
|
||||
@ -1173,6 +1172,10 @@ 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() {
|
||||
@ -1218,62 +1221,6 @@ void os::javaTimeSystemUTC(jlong &seconds, jlong &nanos) {
|
||||
nanos = jlong(time.tv_usec) * 1000;
|
||||
}
|
||||
|
||||
|
||||
#ifndef CLOCK_MONOTONIC
|
||||
#define CLOCK_MONOTONIC (1)
|
||||
#endif
|
||||
|
||||
void os::Linux::clock_init() {
|
||||
// we do dlopen's in this particular order due to bug in linux
|
||||
// dynamical loader (see 6348968) leading to crash on exit
|
||||
void* handle = dlopen("librt.so.1", RTLD_LAZY);
|
||||
if (handle == NULL) {
|
||||
handle = dlopen("librt.so", RTLD_LAZY);
|
||||
}
|
||||
|
||||
if (handle) {
|
||||
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 && clock_gettime_func) {
|
||||
// See if monotonic clock is supported by the kernel. Note that some
|
||||
// early implementations simply return kernel jiffies (updated every
|
||||
// 1/100 or 1/1000 second). It would be bad to use such a low res clock
|
||||
// for nano time (though the monotonic property is still nice to have).
|
||||
// It's fixed in newer kernels, however clock_getres() still returns
|
||||
// 1/HZ. We check if clock_getres() works, but will ignore its reported
|
||||
// resolution for now. Hopefully as people move to new kernels, this
|
||||
// won't be a problem.
|
||||
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
|
||||
_clock_gettime = clock_gettime_func;
|
||||
return;
|
||||
} else {
|
||||
// close librt if there is no monotonic clock
|
||||
dlclose(handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
warning("No monotonic clock was available - timed services may " \
|
||||
"be adversely affected if the time-of-day clock changes");
|
||||
}
|
||||
|
||||
#ifndef SYS_clock_getres
|
||||
#if defined(X86) || defined(PPC64) || defined(S390)
|
||||
#define SYS_clock_getres AMD64_ONLY(229) IA32_ONLY(266) PPC64_ONLY(247) S390_ONLY(261)
|
||||
#define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y)
|
||||
#else
|
||||
#warning "SYS_clock_getres not defined for this platform, disabling fast_thread_cpu_time"
|
||||
#define sys_clock_getres(x,y) -1
|
||||
#endif
|
||||
#else
|
||||
#define sys_clock_getres(x,y) ::syscall(SYS_clock_getres, x, y)
|
||||
#endif
|
||||
|
||||
void os::Linux::fast_thread_clock_init() {
|
||||
if (!UseLinuxPosixThreadCPUClocks) {
|
||||
return;
|
||||
@ -1284,17 +1231,17 @@ void os::Linux::fast_thread_clock_init() {
|
||||
(int(*)(pthread_t, clockid_t *)) dlsym(RTLD_DEFAULT, "pthread_getcpuclockid");
|
||||
|
||||
// Switch to using fast clocks for thread cpu time if
|
||||
// the sys_clock_getres() returns 0 error code.
|
||||
// the clock_getres() returns 0 error code.
|
||||
// Note, that some kernels may support the current thread
|
||||
// clock (CLOCK_THREAD_CPUTIME_ID) but not the clocks
|
||||
// returned by the pthread_getcpuclockid().
|
||||
// If the fast Posix clocks are supported then the sys_clock_getres()
|
||||
// If the fast Posix clocks are supported then the clock_getres()
|
||||
// must return at least tp.tv_sec == 0 which means a resolution
|
||||
// better than 1 sec. This is extra check for reliability.
|
||||
|
||||
if (pthread_getcpuclockid_func &&
|
||||
pthread_getcpuclockid_func(_main_thread, &clockid) == 0 &&
|
||||
sys_clock_getres(clockid, &tp) == 0 && tp.tv_sec == 0) {
|
||||
os::Posix::clock_getres(clockid, &tp) == 0 && tp.tv_sec == 0) {
|
||||
_supports_fast_thread_cpu_time = true;
|
||||
_pthread_getcpuclockid = pthread_getcpuclockid_func;
|
||||
}
|
||||
@ -1303,7 +1250,7 @@ void os::Linux::fast_thread_clock_init() {
|
||||
jlong os::javaTimeNanos() {
|
||||
if (os::supports_monotonic_clock()) {
|
||||
struct timespec tp;
|
||||
int status = Linux::clock_gettime(CLOCK_MONOTONIC, &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;
|
||||
@ -2482,7 +2429,7 @@ void* os::user_handler() {
|
||||
static struct timespec create_semaphore_timespec(unsigned int sec, int nsec) {
|
||||
struct timespec ts;
|
||||
// Semaphore's are always associated with CLOCK_REALTIME
|
||||
os::Linux::clock_gettime(CLOCK_REALTIME, &ts);
|
||||
os::Posix::clock_gettime(CLOCK_REALTIME, &ts);
|
||||
// see os_posix.cpp for discussion on overflow checking
|
||||
if (sec >= MAX_SECS) {
|
||||
ts.tv_sec += MAX_SECS;
|
||||
@ -4715,7 +4662,7 @@ void os::Linux::install_signal_handlers() {
|
||||
|
||||
jlong os::Linux::fast_thread_cpu_time(clockid_t clockid) {
|
||||
struct timespec tp;
|
||||
int rc = os::Linux::clock_gettime(clockid, &tp);
|
||||
int rc = os::Posix::clock_gettime(clockid, &tp);
|
||||
assert(rc == 0, "clock_gettime is expected to return 0 code");
|
||||
|
||||
return (tp.tv_sec * NANOSECS_PER_SEC) + tp.tv_nsec;
|
||||
@ -4987,14 +4934,19 @@ void os::init(void) {
|
||||
// _main_thread points to the thread that created/loaded the JVM.
|
||||
Linux::_main_thread = pthread_self();
|
||||
|
||||
Linux::clock_init();
|
||||
initial_time_count = javaTimeNanos();
|
||||
|
||||
// retrieve entry point for pthread_setname_np
|
||||
Linux::_pthread_setname_np =
|
||||
(int(*)(pthread_t, const char*))dlsym(RTLD_DEFAULT, "pthread_setname_np");
|
||||
|
||||
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
|
||||
|
@ -43,7 +43,6 @@ class Linux {
|
||||
|
||||
static void check_signal_handler(int sig);
|
||||
|
||||
static int (*_clock_gettime)(clockid_t, struct timespec *);
|
||||
static int (*_pthread_getcpuclockid)(pthread_t, clockid_t *);
|
||||
static int (*_pthread_setname_np)(pthread_t, const char*);
|
||||
|
||||
@ -190,16 +189,9 @@ class Linux {
|
||||
static bool manually_expand_stack(JavaThread * t, address addr);
|
||||
static int max_register_window_saves_before_flushing();
|
||||
|
||||
// Real-time clock functions
|
||||
static void clock_init(void);
|
||||
|
||||
// fast POSIX clocks support
|
||||
static void fast_thread_clock_init(void);
|
||||
|
||||
static int clock_gettime(clockid_t clock_id, struct timespec *tp) {
|
||||
return _clock_gettime ? _clock_gettime(clock_id, tp) : -1;
|
||||
}
|
||||
|
||||
static int pthread_getcpuclockid(pthread_t tid, clockid_t *clock_id) {
|
||||
return _pthread_getcpuclockid ? _pthread_getcpuclockid(tid, clock_id) : -1;
|
||||
}
|
||||
|
@ -141,7 +141,7 @@ inline struct hostent* os::get_host_by_name(char* name) {
|
||||
}
|
||||
|
||||
inline bool os::supports_monotonic_clock() {
|
||||
return Linux::_clock_gettime != NULL;
|
||||
return os::Posix::supports_monotonic_clock();
|
||||
}
|
||||
|
||||
inline void os::exit(int num) {
|
||||
|
@ -1609,10 +1609,25 @@ static void pthread_init_common(void) {
|
||||
// This means we have clockid_t, clock_gettime et al and CLOCK_MONOTONIC
|
||||
|
||||
static int (*_clock_gettime)(clockid_t, struct timespec *);
|
||||
static int (*_clock_getres)(clockid_t, struct timespec *);
|
||||
static int (*_pthread_condattr_setclock)(pthread_condattr_t *, clockid_t);
|
||||
|
||||
static bool _use_clock_monotonic_condattr;
|
||||
|
||||
// Exported clock functionality
|
||||
|
||||
int os::Posix::clock_gettime(clockid_t clock_id, struct timespec *tp) {
|
||||
return _clock_gettime != NULL ? _clock_gettime(clock_id, tp) : -1;
|
||||
}
|
||||
|
||||
int os::Posix::clock_getres(clockid_t clock_id, struct timespec *tp) {
|
||||
return _clock_getres != NULL ? _clock_getres(clock_id, tp) : -1;
|
||||
}
|
||||
|
||||
bool os::Posix::supports_monotonic_clock() {
|
||||
return _clock_gettime != NULL;
|
||||
}
|
||||
|
||||
// Determine what POSIX API's are present and do appropriate
|
||||
// configuration.
|
||||
void os::Posix::init(void) {
|
||||
@ -1620,8 +1635,6 @@ void os::Posix::init(void) {
|
||||
// NOTE: no logging available when this is called. Put logging
|
||||
// statements in init_2().
|
||||
|
||||
// Copied from os::Linux::clock_init(). The duplication is temporary.
|
||||
|
||||
// 1. Check for CLOCK_MONOTONIC support.
|
||||
|
||||
void* handle = NULL;
|
||||
@ -1642,6 +1655,7 @@ void os::Posix::init(void) {
|
||||
}
|
||||
|
||||
_clock_gettime = NULL;
|
||||
_clock_getres = NULL;
|
||||
|
||||
int (*clock_getres_func)(clockid_t, struct timespec*) =
|
||||
(int(*)(clockid_t, struct timespec*))dlsym(handle, "clock_getres");
|
||||
@ -1656,6 +1670,7 @@ void os::Posix::init(void) {
|
||||
clock_gettime_func(CLOCK_MONOTONIC, &tp) == 0) {
|
||||
// Yes, monotonic clock is supported.
|
||||
_clock_gettime = clock_gettime_func;
|
||||
_clock_getres = clock_getres_func;
|
||||
} else {
|
||||
#ifdef NEEDS_LIBRT
|
||||
// Close librt if there is no monotonic clock.
|
||||
|
@ -116,6 +116,18 @@ public:
|
||||
// Returns true if either given uid is effective uid and given gid is
|
||||
// effective gid, or if given uid is root.
|
||||
static bool matches_effective_uid_and_gid_or_root(uid_t uid, gid_t gid);
|
||||
|
||||
#ifdef SUPPORTS_CLOCK_MONOTONIC
|
||||
|
||||
static bool supports_monotonic_clock();
|
||||
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; }
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
// On POSIX platforms the signal handler is global so we just do the write.
|
||||
|
Loading…
x
Reference in New Issue
Block a user