src/os/linux/vm/os_linux.cpp
Print this page
*** 1449,1459 ****
_pthread_getcpuclockid = pthread_getcpuclockid_func;
}
}
jlong os::javaTimeNanos() {
! if (Linux::supports_monotonic_clock()) {
struct timespec tp;
int status = Linux::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;
--- 1449,1459 ----
_pthread_getcpuclockid = pthread_getcpuclockid_func;
}
}
jlong os::javaTimeNanos() {
! if (os::supports_monotonic_clock()) {
struct timespec tp;
int status = Linux::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;
*** 1465,1475 ****
return 1000 * usecs;
}
}
void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
! if (Linux::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
--- 1465,1475 ----
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
*** 3793,3881 ****
size_t os::read(int fd, void *buf, unsigned int nBytes) {
return ::read(fd, buf, nBytes);
}
- // TODO-FIXME: reconcile Solaris' os::sleep with the linux variation.
- // Solaris uses poll(), linux uses park().
- // Poll() is likely a better choice, assuming that Thread.interrupt()
- // generates a SIGUSRx signal. Note that SIGUSR1 can interfere with
- // SIGSEGV, see 4355769.
-
- int os::sleep(Thread* thread, jlong millis, bool interruptible) {
- assert(thread == Thread::current(), "thread consistency check");
-
- ParkEvent * const slp = thread->_SleepEvent ;
- slp->reset() ;
- OrderAccess::fence() ;
-
- if (interruptible) {
- jlong prevtime = javaTimeNanos();
-
- for (;;) {
- if (os::is_interrupted(thread, true)) {
- return OS_INTRPT;
- }
-
- jlong newtime = javaTimeNanos();
-
- 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(!Linux::supports_monotonic_clock(), "time moving backwards");
- } else {
- millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
- }
-
- if(millis <= 0) {
- return OS_OK;
- }
-
- prevtime = newtime;
-
- {
- assert(thread->is_Java_thread(), "sanity check");
- JavaThread *jt = (JavaThread *) thread;
- ThreadBlockInVM tbivm(jt);
- OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */);
-
- jt->set_suspend_equivalent();
- // cleared by handle_special_suspend_equivalent_condition() or
- // java_suspend_self() via check_and_wait_while_suspended()
-
- slp->park(millis);
-
- // were we externally suspended while we were waiting?
- jt->check_and_wait_while_suspended();
- }
- }
- } else {
- OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
- jlong prevtime = javaTimeNanos();
-
- for (;;) {
- // It'd be nice to avoid the back-to-back javaTimeNanos() calls on
- // the 1st iteration ...
- jlong newtime = javaTimeNanos();
-
- 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(!Linux::supports_monotonic_clock(), "time moving backwards");
- } else {
- millis -= (newtime - prevtime) / NANOSECS_PER_MILLISEC;
- }
-
- if(millis <= 0) break ;
-
- prevtime = newtime;
- slp->park(millis);
- }
- return OS_OK ;
- }
- }
-
//
// Short sleep, direct OS call.
//
// Note: certain versions of Linux CFS scheduler (since 2.6.23) do not guarantee
// sched_yield(2) will actually give up the CPU:
--- 3793,3802 ----
*** 4224,4277 ****
}
guarantee(osthread->sr.is_running(), "Must be running!");
}
- ////////////////////////////////////////////////////////////////////////////////
- // interrupt support
-
- void os::interrupt(Thread* thread) {
- assert(Thread::current() == thread || Threads_lock->owned_by_self(),
- "possibility of dangling Thread pointer");
-
- OSThread* osthread = thread->osthread();
-
- if (!osthread->interrupted()) {
- osthread->set_interrupted(true);
- // More than one thread can get here with the same value of osthread,
- // resulting in multiple notifications. We do, however, want the store
- // to interrupted() to be visible to other threads before we execute unpark().
- OrderAccess::fence();
- ParkEvent * const slp = thread->_SleepEvent ;
- if (slp != NULL) slp->unpark() ;
- }
-
- // For JSR166. Unpark even if interrupt status already was set
- if (thread->is_Java_thread())
- ((JavaThread*)thread)->parker()->unpark();
-
- ParkEvent * ev = thread->_ParkEvent ;
- if (ev != NULL) ev->unpark() ;
-
- }
-
- bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
- assert(Thread::current() == thread || Threads_lock->owned_by_self(),
- "possibility of dangling Thread pointer");
-
- OSThread* osthread = thread->osthread();
-
- bool interrupted = osthread->interrupted();
-
- if (interrupted && clear_interrupted) {
- osthread->set_interrupted(false);
- // consider thread->_SleepEvent->reset() ... optional optimization
- }
-
- return interrupted;
- }
-
///////////////////////////////////////////////////////////////////////////////////
// signal handling (except suspend/resume)
// This routine may be used by user applications as a "hook" to catch signals.
// The user-defined signal handler must pass unrecognized signals to this
--- 4145,4154 ----
*** 4785,4795 ****
pthread_condattr_t* _condattr = os::Linux::condAttr();
if ((status = pthread_condattr_init(_condattr)) != 0) {
fatal(err_msg("pthread_condattr_init: %s", strerror(status)));
}
// Only set the clock if CLOCK_MONOTONIC is available
! if (Linux::supports_monotonic_clock()) {
if ((status = pthread_condattr_setclock(_condattr, CLOCK_MONOTONIC)) != 0) {
if (status == EINVAL) {
warning("Unable to use monotonic clock with relative timed-waits" \
" - changes to the time-of-day clock may have adverse affects");
} else {
--- 4662,4672 ----
pthread_condattr_t* _condattr = os::Linux::condAttr();
if ((status = pthread_condattr_init(_condattr)) != 0) {
fatal(err_msg("pthread_condattr_init: %s", strerror(status)));
}
// Only set the clock if CLOCK_MONOTONIC is available
! if (os::supports_monotonic_clock()) {
if ((status = pthread_condattr_setclock(_condattr, CLOCK_MONOTONIC)) != 0) {
if (status == EINVAL) {
warning("Unable to use monotonic clock with relative timed-waits" \
" - changes to the time-of-day clock may have adverse affects");
} else {
*** 5616,5626 ****
millis %= 1000;
if (seconds > 50000000) { // see man cond_timedwait(3T)
seconds = 50000000;
}
! if (os::Linux::supports_monotonic_clock()) {
struct timespec now;
int status = os::Linux::clock_gettime(CLOCK_MONOTONIC, &now);
assert_status(status == 0, status, "clock_gettime");
abstime->tv_sec = now.tv_sec + seconds;
long nanos = now.tv_nsec + millis * NANOSECS_PER_MILLISEC;
--- 5493,5503 ----
millis %= 1000;
if (seconds > 50000000) { // see man cond_timedwait(3T)
seconds = 50000000;
}
! if (os::supports_monotonic_clock()) {
struct timespec now;
int status = os::Linux::clock_gettime(CLOCK_MONOTONIC, &now);
assert_status(status == 0, status, "clock_gettime");
abstime->tv_sec = now.tv_sec + seconds;
long nanos = now.tv_nsec + millis * NANOSECS_PER_MILLISEC;
*** 5833,5843 ****
static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) {
assert (time > 0, "convertTime");
time_t max_secs = 0;
! if (!os::Linux::supports_monotonic_clock() || isAbsolute) {
struct timeval now;
int status = gettimeofday(&now, NULL);
assert(status == 0, "gettimeofday");
max_secs = now.tv_sec + MAX_SECS;
--- 5710,5720 ----
static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) {
assert (time > 0, "convertTime");
time_t max_secs = 0;
! if (!os::supports_monotonic_clock() || isAbsolute) {
struct timeval now;
int status = gettimeofday(&now, NULL);
assert(status == 0, "gettimeofday");
max_secs = now.tv_sec + MAX_SECS;