Mercurial > hg > truffle
diff src/os/bsd/vm/os_bsd.cpp @ 14909:4ca6dc0799b6
Backout jdk9 merge
author | Gilles Duboscq <duboscq@ssw.jku.at> |
---|---|
date | Tue, 01 Apr 2014 13:57:07 +0200 |
parents | d8041d695d19 |
children | b1911c1e44c8 |
line wrap: on
line diff
--- a/src/os/bsd/vm/os_bsd.cpp Tue Apr 01 14:09:03 2014 +0200 +++ b/src/os/bsd/vm/os_bsd.cpp Tue Apr 01 13:57:07 2014 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2013, 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 @@ -219,7 +219,7 @@ static char cpu_arch[] = "amd64"; #elif defined(ARM) static char cpu_arch[] = "arm"; -#elif defined(PPC32) +#elif defined(PPC) static char cpu_arch[] = "ppc"; #elif defined(SPARC) # ifdef _LP64 @@ -994,7 +994,7 @@ jlong os::javaTimeNanos() { - if (os::supports_monotonic_clock()) { + if (Bsd::supports_monotonic_clock()) { struct timespec tp; int status = Bsd::clock_gettime(CLOCK_MONOTONIC, &tp); assert(status == 0, "gettime error"); @@ -1010,7 +1010,7 @@ } void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { - if (os::supports_monotonic_clock()) { + if (Bsd::supports_monotonic_clock()) { info_ptr->max_value = ALL_64_BITS; // CLOCK_MONOTONIC - amount of time since some arbitrary point in the past @@ -1557,17 +1557,6 @@ } #endif /* !__APPLE__ */ -void* os::get_default_process_handle() { -#ifdef __APPLE__ - // MacOS X needs to use RTLD_FIRST instead of RTLD_LAZY - // to avoid finding unexpected symbols on second (or later) - // loads of a library. - return (void*)::dlopen(NULL, RTLD_FIRST); -#else - return (void*)::dlopen(NULL, RTLD_LAZY); -#endif -} - // XXX: Do we need a lock around this as per Linux? void* os::dll_lookup(void* handle, const char* name) { return dlsym(handle, name); @@ -1677,12 +1666,58 @@ st->cr(); } +// Taken from /usr/include/bits/siginfo.h Supposed to be architecture specific +// but they're the same for all the bsd arch that we support +// and they're the same for solaris but there's no common place to put this. +const char *ill_names[] = { "ILL0", "ILL_ILLOPC", "ILL_ILLOPN", "ILL_ILLADR", + "ILL_ILLTRP", "ILL_PRVOPC", "ILL_PRVREG", + "ILL_COPROC", "ILL_BADSTK" }; + +const char *fpe_names[] = { "FPE0", "FPE_INTDIV", "FPE_INTOVF", "FPE_FLTDIV", + "FPE_FLTOVF", "FPE_FLTUND", "FPE_FLTRES", + "FPE_FLTINV", "FPE_FLTSUB", "FPE_FLTDEN" }; + +const char *segv_names[] = { "SEGV0", "SEGV_MAPERR", "SEGV_ACCERR" }; + +const char *bus_names[] = { "BUS0", "BUS_ADRALN", "BUS_ADRERR", "BUS_OBJERR" }; + void os::print_siginfo(outputStream* st, void* siginfo) { - const siginfo_t* si = (const siginfo_t*)siginfo; - - os::Posix::print_siginfo_brief(st, si); - - if (si && (si->si_signo == SIGBUS || si->si_signo == SIGSEGV) && + st->print("siginfo:"); + + const int buflen = 100; + char buf[buflen]; + siginfo_t *si = (siginfo_t*)siginfo; + st->print("si_signo=%s: ", os::exception_name(si->si_signo, buf, buflen)); + if (si->si_errno != 0 && strerror_r(si->si_errno, buf, buflen) == 0) { + st->print("si_errno=%s", buf); + } else { + st->print("si_errno=%d", si->si_errno); + } + const int c = si->si_code; + assert(c > 0, "unexpected si_code"); + switch (si->si_signo) { + case SIGILL: + st->print(", si_code=%d (%s)", c, c > 8 ? "" : ill_names[c]); + st->print(", si_addr=" PTR_FORMAT, si->si_addr); + break; + case SIGFPE: + st->print(", si_code=%d (%s)", c, c > 9 ? "" : fpe_names[c]); + st->print(", si_addr=" PTR_FORMAT, si->si_addr); + break; + case SIGSEGV: + st->print(", si_code=%d (%s)", c, c > 2 ? "" : segv_names[c]); + st->print(", si_addr=" PTR_FORMAT, si->si_addr); + break; + case SIGBUS: + st->print(", si_code=%d (%s)", c, c > 3 ? "" : bus_names[c]); + st->print(", si_addr=" PTR_FORMAT, si->si_addr); + break; + default: + st->print(", si_code=%d", si->si_code); + // no si_addr + } + + if ((si->si_signo == SIGBUS || si->si_signo == SIGSEGV) && UseSharedSpaces) { FileMapInfo* mapinfo = FileMapInfo::current_info(); if (mapinfo->is_in_shared_space(si->si_addr)) { @@ -1742,14 +1777,12 @@ if (rp == NULL) return; - if (Arguments::sun_java_launcher_is_altjvm()) { - // Support for the java launcher's '-XXaltjvm=<path>' option. Typical - // value for buf is "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so" - // or "<JAVA_HOME>/jre/lib/<vmtype>/libjvm.dylib". If "/jre/lib/" - // appears at the right place in the string, then assume we are - // installed in a JDK and we're done. Otherwise, check for a - // JAVA_HOME environment variable and construct a path to the JVM - // being overridden. + if (Arguments::created_by_gamma_launcher()) { + // Support for the gamma launcher. Typical value for buf is + // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm". If "/jre/lib/" appears at + // the right place in the string, then assume we are installed in a JDK and + // we're done. Otherwise, check for a JAVA_HOME environment variable and + // construct a path to the JVM being overridden. const char *p = buf + strlen(buf) - 1; for (int count = 0; p > buf && count < 5; ++count) { @@ -1788,7 +1821,7 @@ jrelib_p = buf + len; snprintf(jrelib_p, buflen-len, "/%s", COMPILER_VARIANT); if (0 != access(buf, F_OK)) { - snprintf(jrelib_p, buflen-len, "%s", ""); + snprintf(jrelib_p, buflen-len, ""); } // If the path exists within JAVA_HOME, add the JVM library name @@ -2513,21 +2546,88 @@ RESTARTABLE_RETURN_INT(::read(fd, buf, nBytes)); } -void os::naked_short_sleep(jlong ms) { - struct timespec req; - - assert(ms < 1000, "Un-interruptable sleep, short time use only"); - req.tv_sec = 0; - if (ms > 0) { - req.tv_nsec = (ms % 1000) * 1000000; +// TODO-FIXME: reconcile Solaris' os::sleep with the bsd variation. +// Solaris uses poll(), bsd 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(!Bsd::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(!Bsd::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 ; } - else { - req.tv_nsec = 1; - } - - nanosleep(&req, NULL); - - return; +} + +int os::naked_sleep() { + // %% make the sleep time an integer flag. for now use 1 millisec. + return os::sleep(Thread::current(), 1, false); } // Sleep forever; naked call to OS-specific sleep; use with CAUTION @@ -2908,6 +3008,50 @@ 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) @@ -3248,8 +3392,7 @@ st->print("[%s]", get_signal_handler_name(handler, buf, buflen)); } - st->print(", sa_mask[0]="); - os::Posix::print_signal_set_short(st, &sa.sa_mask); + st->print(", sa_mask[0]=" PTR32_FORMAT, *(uint32_t*)&sa.sa_mask); address rh = VMError::get_resetted_sighandler(sig); // May be, handler was resetted by VMError? @@ -3258,8 +3401,7 @@ sa.sa_flags = VMError::get_resetted_sigflags(sig) & SIGNIFICANT_SIGNAL_MASK; } - st->print(", sa_flags="); - os::Posix::print_sa_flags(st, sa.sa_flags); + st->print(", sa_flags=" PTR32_FORMAT, sa.sa_flags); // Check: is it our handler? if(handler == CAST_FROM_FN_PTR(address, (sa_sigaction_t)signalHandler) ||