--- a/src/hotspot/os/aix/os_aix.cpp Thu Oct 17 20:27:44 2019 +0100
+++ b/src/hotspot/os/aix/os_aix.cpp Thu Oct 17 20:53:35 2019 +0100
@@ -132,18 +132,6 @@
#define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103
// excerpts from systemcfg.h that might be missing on older os levels
-#ifndef PV_5_Compat
- #define PV_5_Compat 0x0F8000 /* Power PC 5 */
-#endif
-#ifndef PV_6
- #define PV_6 0x100000 /* Power PC 6 */
-#endif
-#ifndef PV_6_1
- #define PV_6_1 0x100001 /* Power PC 6 DD1.x */
-#endif
-#ifndef PV_6_Compat
- #define PV_6_Compat 0x108000 /* Power PC 6 */
-#endif
#ifndef PV_7
#define PV_7 0x200000 /* Power PC 7 */
#endif
@@ -156,6 +144,13 @@
#ifndef PV_8_Compat
#define PV_8_Compat 0x308000 /* Power PC 8 */
#endif
+#ifndef PV_9
+ #define PV_9 0x400000 /* Power PC 9 */
+#endif
+#ifndef PV_9_Compat
+ #define PV_9_Compat 0x408000 /* Power PC 9 */
+#endif
+
static address resolve_function_descriptor_to_code_pointer(address p);
@@ -487,8 +482,7 @@
if (::shmctl(shmid, SHM_PAGESIZE, &shm_buf) != 0) {
const int en = errno;
::shmctl(shmid, IPC_RMID, NULL); // As early as possible!
- trcVerbose("shmctl(SHM_PAGESIZE) failed with errno=%n",
- errno);
+ trcVerbose("shmctl(SHM_PAGESIZE) failed with errno=%d", errno);
} else {
// Attach and double check pageisze.
void* p = ::shmat(shmid, NULL, 0);
@@ -496,7 +490,7 @@
guarantee0(p != (void*) -1); // Should always work.
const size_t real_pagesize = os::Aix::query_pagesize(p);
if (real_pagesize != pagesize) {
- trcVerbose("real page size (0x%llX) differs.", real_pagesize);
+ trcVerbose("real page size (" SIZE_FORMAT_HEX ") differs.", real_pagesize);
} else {
can_use = true;
}
@@ -524,7 +518,7 @@
describe_pagesize(g_multipage_support.pthr_stack_pagesize));
trcVerbose("Default shared memory page size: %s",
describe_pagesize(g_multipage_support.shmpsize));
- trcVerbose("Can use 64K pages dynamically with shared meory: %s",
+ trcVerbose("Can use 64K pages dynamically with shared memory: %s",
(g_multipage_support.can_use_64K_pages ? "yes" :"no"));
trcVerbose("Can use 16M pages dynamically with shared memory: %s",
(g_multipage_support.can_use_16M_pages ? "yes" :"no"));
@@ -555,7 +549,7 @@
const size_t bufsize =
MAX2((size_t)MAXPATHLEN, // For dll_dir & friends.
(size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR)); // extensions dir
- char *buf = (char *)NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
+ char *buf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);
// sysclasspath, java_home, dll_dir
{
@@ -597,7 +591,7 @@
// Concatenate user and invariant part of ld_library_path.
// That's +1 for the colon and +1 for the trailing '\0'.
- char *ld_library_path = (char *)NEW_C_HEAP_ARRAY(char, strlen(v) + 1 + sizeof(DEFAULT_LIBPATH) + 1, mtInternal);
+ char *ld_library_path = NEW_C_HEAP_ARRAY(char, strlen(v) + 1 + sizeof(DEFAULT_LIBPATH) + 1, mtInternal);
sprintf(ld_library_path, "%s%s" DEFAULT_LIBPATH, v, v_colon);
Arguments::set_library_path(ld_library_path);
FREE_C_HEAP_ARRAY(char, ld_library_path);
@@ -1028,22 +1022,18 @@
// Time since start-up in seconds to a fine granularity.
// Used by VMSelfDestructTimer and the MemProfiler.
double os::elapsedTime() {
- return (double)(os::elapsed_counter()) * 0.000001;
+ return ((double)os::elapsed_counter()) / os::elapsed_frequency(); // nanosecond resolution
}
jlong os::elapsed_counter() {
- timeval time;
- int status = gettimeofday(&time, NULL);
- return jlong(time.tv_sec) * 1000 * 1000 + jlong(time.tv_usec) - initial_time_count;
+ return javaTimeNanos() - initial_time_count;
}
jlong os::elapsed_frequency() {
- return (1000 * 1000);
+ return NANOSECS_PER_SEC; // nanosecond resolution
}
bool os::supports_vtime() { return true; }
-bool os::enable_vtime() { return false; }
-bool os::vtime_enabled() { return false; }
double os::elapsedVTime() {
struct rusage usage;
@@ -1206,8 +1196,15 @@
}
// Die immediately, no exit hook, no abort hook, no cleanup.
+// Dump a core file, if possible, for debugging.
void os::die() {
- ::abort();
+ if (TestUnresponsiveErrorHandler && !CreateCoredumpOnCrash) {
+ // For TimeoutInErrorHandlingTest.java, we just kill the VM
+ // and don't take the time to generate a core file.
+ os::signal_raise(SIGKILL);
+ } else {
+ ::abort();
+ }
}
intx os::current_thread_id() {
@@ -1307,6 +1304,8 @@
// for the same architecture as Hotspot is running on.
void *os::dll_load(const char *filename, char *ebuf, int ebuflen) {
+ log_info(os)("attempting shared library load of %s", filename);
+
if (ebuf && ebuflen > 0) {
ebuf[0] = '\0';
ebuf[ebuflen - 1] = '\0';
@@ -1320,16 +1319,23 @@
// RTLD_LAZY is currently not implemented. The dl is loaded immediately with all its dependants.
void * result= ::dlopen(filename, RTLD_LAZY);
if (result != NULL) {
+ Events::log(NULL, "Loaded shared library %s", filename);
// Reload dll cache. Don't do this in signal handling.
LoadedLibraries::reload();
+ log_info(os)("shared library load of %s was successful", filename);
return result;
} else {
// error analysis when dlopen fails
- const char* const error_report = ::dlerror();
- if (error_report && ebuf && ebuflen > 0) {
+ const char* error_report = ::dlerror();
+ if (error_report == NULL) {
+ error_report = "dlerror returned no error description";
+ }
+ if (ebuf != NULL && ebuflen > 0) {
snprintf(ebuf, ebuflen - 1, "%s, LIBPATH=%s, LD_LIBRARY_PATH=%s : %s",
filename, ::getenv("LIBPATH"), ::getenv("LD_LIBRARY_PATH"), error_report);
}
+ Events::log(NULL, "Loading shared library %s failed, %s", filename, error_report);
+ log_info(os)("shared library load of %s failed, %s", filename, error_report);
}
return NULL;
}
@@ -1373,15 +1379,7 @@
void os::print_os_info(outputStream* st) {
st->print("OS:");
- st->print("uname:");
- struct utsname name;
- uname(&name);
- st->print(name.sysname); st->print(" ");
- st->print(name.nodename); st->print(" ");
- st->print(name.release); st->print(" ");
- st->print(name.version); st->print(" ");
- st->print(name.machine);
- st->cr();
+ os::Posix::print_uname_info(st);
uint32_t ver = os::Aix::os_version();
st->print_cr("AIX kernel version %u.%u.%u.%u",
@@ -1389,16 +1387,12 @@
os::Posix::print_rlimit_info(st);
+ os::Posix::print_load_average(st);
+
// _SC_THREAD_THREADS_MAX is the maximum number of threads within a process.
long tmax = sysconf(_SC_THREAD_THREADS_MAX);
st->print_cr("maximum #threads within a process:%ld", tmax);
- // load average
- st->print("load average:");
- double loadavg[3] = {-1.L, -1.L, -1.L};
- os::loadavg(loadavg, 3);
- st->print_cr("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
-
// print wpar info
libperfstat::wparinfo_t wi;
if (libperfstat::get_wparinfo(&wi)) {
@@ -1425,7 +1419,7 @@
describe_pagesize(g_multipage_support.pthr_stack_pagesize));
st->print_cr(" Default shared memory page size: %s",
describe_pagesize(g_multipage_support.shmpsize));
- st->print_cr(" Can use 64K pages dynamically with shared meory: %s",
+ st->print_cr(" Can use 64K pages dynamically with shared memory: %s",
(g_multipage_support.can_use_64K_pages ? "yes" :"no"));
st->print_cr(" Can use 16M pages dynamically with shared memory: %s",
(g_multipage_support.can_use_16M_pages ? "yes" :"no"));
@@ -1491,6 +1485,9 @@
void os::get_summary_cpu_info(char* buf, size_t buflen) {
// read _system_configuration.version
switch (_system_configuration.version) {
+ case PV_9:
+ strncpy(buf, "Power PC 9", buflen);
+ break;
case PV_8:
strncpy(buf, "Power PC 8", buflen);
break;
@@ -1524,6 +1521,9 @@
case PV_8_Compat:
strncpy(buf, "PV_8_Compat", buflen);
break;
+ case PV_9_Compat:
+ strncpy(buf, "PV_9_Compat", buflen);
+ break;
default:
strncpy(buf, "unknown", buflen);
}
@@ -1650,16 +1650,8 @@
////////////////////////////////////////////////////////////////////////////////
// sun.misc.Signal support
-static volatile jint sigint_count = 0;
-
static void
UserHandler(int sig, void *siginfo, void *context) {
- // 4511530 - sem_post is serialized and handled by the manager thread. When
- // the program is interrupted by Ctrl-C, SIGINT is sent to every thread. We
- // don't want to flood the manager thread with sem_post requests.
- if (sig == SIGINT && Atomic::add(1, &sigint_count) > 1)
- return;
-
// Ctrl-C is pressed during error reporting, likely because the error
// handler fails to abort. Let VM die immediately.
if (sig == SIGINT && VMError::is_error_reported()) {
@@ -1799,7 +1791,6 @@
}
static int check_pending_signals() {
- Atomic::store(0, &sigint_count);
for (;;) {
for (int i = 0; i < NSIG + 1; i++) {
jint n = pending_signals[i];
@@ -1876,12 +1867,12 @@
if (!contains_range(p, s)) {
trcVerbose("[" PTR_FORMAT " - " PTR_FORMAT "] is not a sub "
"range of [" PTR_FORMAT " - " PTR_FORMAT "].",
- p, p + s, addr, addr + size);
+ p2i(p), p2i(p + s), p2i(addr), p2i(addr + size));
guarantee0(false);
}
if (!is_aligned_to(p, pagesize) || !is_aligned_to(p + s, pagesize)) {
trcVerbose("range [" PTR_FORMAT " - " PTR_FORMAT "] is not"
- " aligned to pagesize (%lu)", p, p + s, (unsigned long) pagesize);
+ " aligned to pagesize (%lu)", p2i(p), p2i(p + s), (unsigned long) pagesize);
guarantee0(false);
}
}
@@ -1952,7 +1943,7 @@
trcVerbose("reserve_shmated_memory " UINTX_FORMAT " bytes, wishaddress "
PTR_FORMAT ", alignment_hint " UINTX_FORMAT "...",
- bytes, requested_addr, alignment_hint);
+ bytes, p2i(requested_addr), alignment_hint);
// Either give me wish address or wish alignment but not both.
assert0(!(requested_addr != NULL && alignment_hint != 0));
@@ -1961,7 +1952,7 @@
// BRK because that may cause malloc OOM.
if (requested_addr != NULL && is_close_to_brk((address)requested_addr)) {
trcVerbose("Wish address " PTR_FORMAT " is too close to the BRK segment. "
- "Will attach anywhere.", requested_addr);
+ "Will attach anywhere.", p2i(requested_addr));
// Act like the OS refused to attach there.
requested_addr = NULL;
}
@@ -2013,7 +2004,7 @@
// Handle shmat error. If we failed to attach, just return.
if (addr == (char*)-1) {
- trcVerbose("Failed to attach segment at " PTR_FORMAT " (%d).", requested_addr, errno_shmat);
+ trcVerbose("Failed to attach segment at " PTR_FORMAT " (%d).", p2i(requested_addr), errno_shmat);
return NULL;
}
@@ -2021,15 +2012,15 @@
// work (see above), the system may have given us something other then 4K (LDR_CNTRL).
const size_t real_pagesize = os::Aix::query_pagesize(addr);
if (real_pagesize != shmbuf.shm_pagesize) {
- trcVerbose("pagesize is, surprisingly, %h.", real_pagesize);
+ trcVerbose("pagesize is, surprisingly, " SIZE_FORMAT, real_pagesize);
}
if (addr) {
trcVerbose("shm-allocated " PTR_FORMAT " .. " PTR_FORMAT " (" UINTX_FORMAT " bytes, " UINTX_FORMAT " %s pages)",
- addr, addr + size - 1, size, size/real_pagesize, describe_pagesize(real_pagesize));
+ p2i(addr), p2i(addr + size - 1), size, size/real_pagesize, describe_pagesize(real_pagesize));
} else {
if (requested_addr != NULL) {
- trcVerbose("failed to shm-allocate " UINTX_FORMAT " bytes at with address " PTR_FORMAT ".", size, requested_addr);
+ trcVerbose("failed to shm-allocate " UINTX_FORMAT " bytes at with address " PTR_FORMAT ".", size, p2i(requested_addr));
} else {
trcVerbose("failed to shm-allocate " UINTX_FORMAT " bytes at any address.", size);
}
@@ -2045,7 +2036,7 @@
static bool release_shmated_memory(char* addr, size_t size) {
trcVerbose("release_shmated_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
- addr, addr + size - 1);
+ p2i(addr), p2i(addr + size - 1));
bool rc = false;
@@ -2061,12 +2052,12 @@
static bool uncommit_shmated_memory(char* addr, size_t size) {
trcVerbose("uncommit_shmated_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
- addr, addr + size - 1);
+ p2i(addr), p2i(addr + size - 1));
const bool rc = my_disclaim64(addr, size);
if (!rc) {
- trcVerbose("my_disclaim64(" PTR_FORMAT ", " UINTX_FORMAT ") failed.\n", addr, size);
+ trcVerbose("my_disclaim64(" PTR_FORMAT ", " UINTX_FORMAT ") failed.\n", p2i(addr), size);
return false;
}
return true;
@@ -2083,11 +2074,11 @@
static char* reserve_mmaped_memory(size_t bytes, char* requested_addr, size_t alignment_hint) {
trcVerbose("reserve_mmaped_memory " UINTX_FORMAT " bytes, wishaddress " PTR_FORMAT ", "
"alignment_hint " UINTX_FORMAT "...",
- bytes, requested_addr, alignment_hint);
+ bytes, p2i(requested_addr), alignment_hint);
// If a wish address is given, but not aligned to 4K page boundary, mmap will fail.
if (requested_addr && !is_aligned_to(requested_addr, os::vm_page_size()) != 0) {
- trcVerbose("Wish address " PTR_FORMAT " not aligned to page boundary.", requested_addr);
+ trcVerbose("Wish address " PTR_FORMAT " not aligned to page boundary.", p2i(requested_addr));
return NULL;
}
@@ -2095,7 +2086,7 @@
// BRK because that may cause malloc OOM.
if (requested_addr != NULL && is_close_to_brk((address)requested_addr)) {
trcVerbose("Wish address " PTR_FORMAT " is too close to the BRK segment. "
- "Will attach anywhere.", requested_addr);
+ "Will attach anywhere.", p2i(requested_addr));
// Act like the OS refused to attach there.
requested_addr = NULL;
}
@@ -2142,7 +2133,7 @@
PROT_READ|PROT_WRITE|PROT_EXEC, flags, -1, 0);
if (addr == MAP_FAILED) {
- trcVerbose("mmap(" PTR_FORMAT ", " UINTX_FORMAT ", ..) failed (%d)", requested_addr, size, errno);
+ trcVerbose("mmap(" PTR_FORMAT ", " UINTX_FORMAT ", ..) failed (%d)", p2i(requested_addr), size, errno);
return NULL;
}
@@ -2161,10 +2152,10 @@
if (addr) {
trcVerbose("mmap-allocated " PTR_FORMAT " .. " PTR_FORMAT " (" UINTX_FORMAT " bytes)",
- addr, addr + bytes, bytes);
+ p2i(addr), p2i(addr + bytes), bytes);
} else {
if (requested_addr != NULL) {
- trcVerbose("failed to mmap-allocate " UINTX_FORMAT " bytes at wish address " PTR_FORMAT ".", bytes, requested_addr);
+ trcVerbose("failed to mmap-allocate " UINTX_FORMAT " bytes at wish address " PTR_FORMAT ".", bytes, p2i(requested_addr));
} else {
trcVerbose("failed to mmap-allocate " UINTX_FORMAT " bytes at any address.", bytes);
}
@@ -2184,7 +2175,7 @@
assert0(is_aligned_to(size, os::vm_page_size()));
trcVerbose("release_mmaped_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
- addr, addr + size - 1);
+ p2i(addr), p2i(addr + size - 1));
bool rc = false;
if (::munmap(addr, size) != 0) {
@@ -2204,7 +2195,7 @@
assert0(is_aligned_to(size, os::vm_page_size()));
trcVerbose("uncommit_mmaped_memory [" PTR_FORMAT " - " PTR_FORMAT "].",
- addr, addr + size - 1);
+ p2i(addr), p2i(addr + size - 1));
bool rc = false;
// Uncommit mmap memory with msync MS_INVALIDATE.
@@ -2235,7 +2226,7 @@
static void warn_fail_commit_memory(char* addr, size_t size, bool exec,
int err) {
warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
- ", %d) failed; error='%s' (errno=%d)", addr, size, exec,
+ ", %d) failed; error='%s' (errno=%d)", p2i(addr), size, exec,
os::errno_name(err), err);
}
#endif
@@ -2263,7 +2254,7 @@
guarantee0(vmi);
vmi->assert_is_valid_subrange(addr, size);
- trcVerbose("commit_memory [" PTR_FORMAT " - " PTR_FORMAT "].", addr, addr + size - 1);
+ trcVerbose("commit_memory [" PTR_FORMAT " - " PTR_FORMAT "].", p2i(addr), p2i(addr + size - 1));
if (UseExplicitCommit) {
// AIX commits memory on touch. So, touch all pages to be committed.
@@ -2650,8 +2641,24 @@
60 // 11 CriticalPriority
};
+static int prio_init() {
+ if (ThreadPriorityPolicy == 1) {
+ if (geteuid() != 0) {
+ if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy)) {
+ warning("-XX:ThreadPriorityPolicy=1 may require system level permission, " \
+ "e.g., being the root user. If the necessary permission is not " \
+ "possessed, changes to priority will be silently ignored.");
+ }
+ }
+ }
+ if (UseCriticalJavaThreadPriority) {
+ os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority];
+ }
+ return 0;
+}
+
OSReturn os::set_native_priority(Thread* thread, int newpri) {
- if (!UseThreadPriorities) return OS_OK;
+ if (!UseThreadPriorities || ThreadPriorityPolicy == 0) return OS_OK;
pthread_t thr = thread->osthread()->pthread_id();
int policy = SCHED_OTHER;
struct sched_param param;
@@ -2666,7 +2673,7 @@
}
OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {
- if (!UseThreadPriorities) {
+ if (!UseThreadPriorities || ThreadPriorityPolicy == 0) {
*priority_ptr = java_to_os_priority[NormPriority];
return OS_OK;
}
@@ -2763,7 +2770,7 @@
os::SuspendResume::State state = osthread->sr.suspended();
if (state == os::SuspendResume::SR_SUSPENDED) {
sigset_t suspend_set; // signals for sigsuspend()
-
+ sigemptyset(&suspend_set);
// get current set of blocked signals and unblock resume signal
pthread_sigmask(SIG_BLOCK, NULL, &suspend_set);
sigdelset(&suspend_set, SR_signum);
@@ -3049,6 +3056,7 @@
// try to honor the signal mask
sigset_t oset;
+ sigemptyset(&oset);
pthread_sigmask(SIG_SETMASK, &(actp->sa_mask), &oset);
// call into the chained handler
@@ -3059,7 +3067,7 @@
}
// restore the signal mask
- pthread_sigmask(SIG_SETMASK, &oset, 0);
+ pthread_sigmask(SIG_SETMASK, &oset, NULL);
}
// Tell jvm's signal handler the signal is taken care of.
return true;
@@ -3492,7 +3500,7 @@
// _main_thread points to the thread that created/loaded the JVM.
Aix::_main_thread = pthread_self();
- initial_time_count = os::elapsed_counter();
+ initial_time_count = javaTimeNanos();
os::Posix::init();
}
@@ -3575,6 +3583,9 @@
}
}
+ // initialize thread priority policy
+ prio_init();
+
return JNI_OK;
}
@@ -3612,11 +3623,6 @@
return;
}
-bool os::distribute_processes(uint length, uint* distribution) {
- // Not yet implemented.
- return false;
-}
-
bool os::bind_to_processor(uint processor_id) {
// Not yet implemented.
return false;
@@ -4016,7 +4022,7 @@
void os::pause() {
char filename[MAX_PATH];
if (PauseAtStartupFile && PauseAtStartupFile[0]) {
- jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
+ jio_snprintf(filename, MAX_PATH, "%s", PauseAtStartupFile);
} else {
jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
}
@@ -4063,7 +4069,7 @@
assert(minor > 0, "invalid OS release");
_os_version = (major << 24) | (minor << 16);
char ver_str[20] = {0};
- char *name_str = "unknown OS";
+ const char* name_str = "unknown OS";
if (strcmp(uts.sysname, "OS400") == 0) {
// We run on AS/400 PASE. We do not support versions older than V5R4M0.
_on_pase = 1;
@@ -4074,19 +4080,19 @@
name_str = "OS/400 (pase)";
jio_snprintf(ver_str, sizeof(ver_str), "%u.%u", major, minor);
} else if (strcmp(uts.sysname, "AIX") == 0) {
- // We run on AIX. We do not support versions older than AIX 5.3.
+ // We run on AIX. We do not support versions older than AIX 7.1.
_on_pase = 0;
// Determine detailed AIX version: Version, Release, Modification, Fix Level.
odmWrapper::determine_os_kernel_version(&_os_version);
- if (os_version_short() < 0x0503) {
- trcVerbose("AIX release older than AIX 5.3 not supported.");
+ if (os_version_short() < 0x0701) {
+ trcVerbose("AIX releases older than AIX 7.1 are not supported.");
assert(false, "AIX release too old.");
}
name_str = "AIX";
jio_snprintf(ver_str, sizeof(ver_str), "%u.%u.%u.%u",
major, minor, (_os_version >> 8) & 0xFF, _os_version & 0xFF);
} else {
- assert(false, name_str);
+ assert(false, "%s", name_str);
}
trcVerbose("We run on %s %s", name_str, ver_str);
}
@@ -4222,7 +4228,7 @@
// Unlike system(), this function can be called from signal handler. It
// doesn't block SIGINT et al.
int os::fork_and_exec(char* cmd, bool use_vfork_if_available) {
- char * argv[4] = {"sh", "-c", cmd, NULL};
+ char* argv[4] = { (char*)"sh", (char*)"-c", cmd, NULL};
pid_t pid = fork();
@@ -4332,3 +4338,7 @@
time_t t2 = get_mtime(file2);
return t1 - t2;
}
+
+bool os::supports_map_sync() {
+ return false;
+}