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;