Path: blob/master/src/hotspot/os/aix/os_aix.cpp
40930 views
/*1* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.2* Copyright (c) 2012, 2020 SAP SE. All rights reserved.3* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.4*5* This code is free software; you can redistribute it and/or modify it6* under the terms of the GNU General Public License version 2 only, as7* published by the Free Software Foundation.8*9* This code is distributed in the hope that it will be useful, but WITHOUT10* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or11* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License12* version 2 for more details (a copy is included in the LICENSE file that13* accompanied this code).14*15* You should have received a copy of the GNU General Public License version16* 2 along with this work; if not, write to the Free Software Foundation,17* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.18*19* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA20* or visit www.oracle.com if you need additional information or have any21* questions.22*23*/2425// According to the AIX OS doc #pragma alloca must be used26// with C++ compiler before referencing the function alloca()27#pragma alloca2829// no precompiled headers30#include "jvm.h"31#include "classfile/vmSymbols.hpp"32#include "code/icBuffer.hpp"33#include "code/vtableStubs.hpp"34#include "compiler/compileBroker.hpp"35#include "interpreter/interpreter.hpp"36#include "jvmtifiles/jvmti.h"37#include "logging/log.hpp"38#include "logging/logStream.hpp"39#include "libo4.hpp"40#include "libperfstat_aix.hpp"41#include "libodm_aix.hpp"42#include "loadlib_aix.hpp"43#include "memory/allocation.inline.hpp"44#include "misc_aix.hpp"45#include "oops/oop.inline.hpp"46#include "os_aix.inline.hpp"47#include "os_share_aix.hpp"48#include "porting_aix.hpp"49#include "prims/jniFastGetField.hpp"50#include "prims/jvm_misc.hpp"51#include "runtime/arguments.hpp"52#include "runtime/atomic.hpp"53#include "runtime/globals.hpp"54#include "runtime/globals_extension.hpp"55#include "runtime/interfaceSupport.inline.hpp"56#include "runtime/java.hpp"57#include "runtime/javaCalls.hpp"58#include "runtime/mutexLocker.hpp"59#include "runtime/objectMonitor.hpp"60#include "runtime/os.hpp"61#include "runtime/osThread.hpp"62#include "runtime/perfMemory.hpp"63#include "runtime/safefetch.inline.hpp"64#include "runtime/sharedRuntime.hpp"65#include "runtime/statSampler.hpp"66#include "runtime/thread.inline.hpp"67#include "runtime/threadCritical.hpp"68#include "runtime/timer.hpp"69#include "runtime/vm_version.hpp"70#include "services/attachListener.hpp"71#include "services/runtimeService.hpp"72#include "signals_posix.hpp"73#include "utilities/align.hpp"74#include "utilities/decoder.hpp"75#include "utilities/defaultStream.hpp"76#include "utilities/events.hpp"77#include "utilities/growableArray.hpp"78#include "utilities/vmError.hpp"7980// put OS-includes here (sorted alphabetically)81#include <errno.h>82#include <fcntl.h>83#include <inttypes.h>84#include <poll.h>85#include <procinfo.h>86#include <pthread.h>87#include <pwd.h>88#include <semaphore.h>89#include <signal.h>90#include <stdint.h>91#include <stdio.h>92#include <string.h>93#include <unistd.h>94#include <sys/ioctl.h>95#include <sys/ipc.h>96#include <sys/mman.h>97#include <sys/resource.h>98#include <sys/select.h>99#include <sys/shm.h>100#include <sys/socket.h>101#include <sys/stat.h>102#include <sys/sysinfo.h>103#include <sys/systemcfg.h>104#include <sys/time.h>105#include <sys/times.h>106#include <sys/types.h>107#include <sys/utsname.h>108#include <sys/vminfo.h>109110// Missing prototypes for various system APIs.111extern "C"112int mread_real_time(timebasestruct_t *t, size_t size_of_timebasestruct_t);113114#if !defined(_AIXVERSION_610)115extern "C" int getthrds64(pid_t, struct thrdentry64*, int, tid64_t*, int);116extern "C" int getprocs64(procentry64*, int, fdsinfo*, int, pid_t*, int);117extern "C" int getargs(procsinfo*, int, char*, int);118#endif119120#define MAX_PATH (2 * K)121122// for timer info max values which include all bits123#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)124// for multipage initialization error analysis (in 'g_multipage_error')125#define ERROR_MP_OS_TOO_OLD 100126#define ERROR_MP_EXTSHM_ACTIVE 101127#define ERROR_MP_VMGETINFO_FAILED 102128#define ERROR_MP_VMGETINFO_CLAIMS_NO_SUPPORT_FOR_64K 103129130// excerpts from systemcfg.h that might be missing on older os levels131#ifndef PV_7132#define PV_7 0x200000 /* Power PC 7 */133#endif134#ifndef PV_7_Compat135#define PV_7_Compat 0x208000 /* Power PC 7 */136#endif137#ifndef PV_8138#define PV_8 0x300000 /* Power PC 8 */139#endif140#ifndef PV_8_Compat141#define PV_8_Compat 0x308000 /* Power PC 8 */142#endif143#ifndef PV_9144#define PV_9 0x400000 /* Power PC 9 */145#endif146#ifndef PV_9_Compat147#define PV_9_Compat 0x408000 /* Power PC 9 */148#endif149150151static address resolve_function_descriptor_to_code_pointer(address p);152153static void vmembk_print_on(outputStream* os);154155////////////////////////////////////////////////////////////////////////////////156// global variables (for a description see os_aix.hpp)157158julong os::Aix::_physical_memory = 0;159160pthread_t os::Aix::_main_thread = ((pthread_t)0);161int os::Aix::_page_size = -1;162163// -1 = uninitialized, 0 if AIX, 1 if OS/400 pase164int os::Aix::_on_pase = -1;165166// 0 = uninitialized, otherwise 32 bit number:167// 0xVVRRTTSS168// VV - major version169// RR - minor version170// TT - tech level, if known, 0 otherwise171// SS - service pack, if known, 0 otherwise172uint32_t os::Aix::_os_version = 0;173174// -1 = uninitialized, 0 - no, 1 - yes175int os::Aix::_xpg_sus_mode = -1;176177// -1 = uninitialized, 0 - no, 1 - yes178int os::Aix::_extshm = -1;179180////////////////////////////////////////////////////////////////////////////////181// local variables182183static volatile jlong max_real_time = 0;184static jlong initial_time_count = 0;185static int clock_tics_per_sec = 100;186187// Process break recorded at startup.188static address g_brk_at_startup = NULL;189190// This describes the state of multipage support of the underlying191// OS. Note that this is of no interest to the outsize world and192// therefore should not be defined in AIX class.193//194// AIX supports four different page sizes - 4K, 64K, 16MB, 16GB. The195// latter two (16M "large" resp. 16G "huge" pages) require special196// setup and are normally not available.197//198// AIX supports multiple page sizes per process, for:199// - Stack (of the primordial thread, so not relevant for us)200// - Data - data, bss, heap, for us also pthread stacks201// - Text - text code202// - shared memory203//204// Default page sizes can be set via linker options (-bdatapsize, -bstacksize, ...)205// and via environment variable LDR_CNTRL (DATAPSIZE, STACKPSIZE, ...).206//207// For shared memory, page size can be set dynamically via208// shmctl(). Different shared memory regions can have different page209// sizes.210//211// More information can be found at AIBM info center:212// http://publib.boulder.ibm.com/infocenter/aix/v6r1/index.jsp?topic=/com.ibm.aix.prftungd/doc/prftungd/multiple_page_size_app_support.htm213//214static struct {215size_t pagesize; // sysconf _SC_PAGESIZE (4K)216size_t datapsize; // default data page size (LDR_CNTRL DATAPSIZE)217size_t shmpsize; // default shared memory page size (LDR_CNTRL SHMPSIZE)218size_t pthr_stack_pagesize; // stack page size of pthread threads219size_t textpsize; // default text page size (LDR_CNTRL STACKPSIZE)220bool can_use_64K_pages; // True if we can alloc 64K pages dynamically with Sys V shm.221bool can_use_16M_pages; // True if we can alloc 16M pages dynamically with Sys V shm.222int error; // Error describing if something went wrong at multipage init.223} g_multipage_support = {224(size_t) -1,225(size_t) -1,226(size_t) -1,227(size_t) -1,228(size_t) -1,229false, false,2300231};232233// We must not accidentally allocate memory close to the BRK - even if234// that would work - because then we prevent the BRK segment from235// growing which may result in a malloc OOM even though there is236// enough memory. The problem only arises if we shmat() or mmap() at237// a specific wish address, e.g. to place the heap in a238// compressed-oops-friendly way.239static bool is_close_to_brk(address a) {240assert0(g_brk_at_startup != NULL);241if (a >= g_brk_at_startup &&242a < (g_brk_at_startup + MaxExpectedDataSegmentSize)) {243return true;244}245return false;246}247248julong os::available_memory() {249return Aix::available_memory();250}251252julong os::Aix::available_memory() {253// Avoid expensive API call here, as returned value will always be null.254if (os::Aix::on_pase()) {255return 0x0LL;256}257os::Aix::meminfo_t mi;258if (os::Aix::get_meminfo(&mi)) {259return mi.real_free;260} else {261return ULONG_MAX;262}263}264265julong os::physical_memory() {266return Aix::physical_memory();267}268269// Return true if user is running as root.270271bool os::have_special_privileges() {272static bool init = false;273static bool privileges = false;274if (!init) {275privileges = (getuid() != geteuid()) || (getgid() != getegid());276init = true;277}278return privileges;279}280281// Helper function, emulates disclaim64 using multiple 32bit disclaims282// because we cannot use disclaim64() on AS/400 and old AIX releases.283static bool my_disclaim64(char* addr, size_t size) {284285if (size == 0) {286return true;287}288289// Maximum size 32bit disclaim() accepts. (Theoretically 4GB, but I just do not trust that.)290const unsigned int maxDisclaimSize = 0x40000000;291292const unsigned int numFullDisclaimsNeeded = (size / maxDisclaimSize);293const unsigned int lastDisclaimSize = (size % maxDisclaimSize);294295char* p = addr;296297for (int i = 0; i < numFullDisclaimsNeeded; i ++) {298if (::disclaim(p, maxDisclaimSize, DISCLAIM_ZEROMEM) != 0) {299trcVerbose("Cannot disclaim %p - %p (errno %d)\n", p, p + maxDisclaimSize, errno);300return false;301}302p += maxDisclaimSize;303}304305if (lastDisclaimSize > 0) {306if (::disclaim(p, lastDisclaimSize, DISCLAIM_ZEROMEM) != 0) {307trcVerbose("Cannot disclaim %p - %p (errno %d)\n", p, p + lastDisclaimSize, errno);308return false;309}310}311312return true;313}314315// Cpu architecture string316#if defined(PPC32)317static char cpu_arch[] = "ppc";318#elif defined(PPC64)319static char cpu_arch[] = "ppc64";320#else321#error Add appropriate cpu_arch setting322#endif323324// Wrap the function "vmgetinfo" which is not available on older OS releases.325static int checked_vmgetinfo(void *out, int command, int arg) {326if (os::Aix::on_pase() && os::Aix::os_version_short() < 0x0601) {327guarantee(false, "cannot call vmgetinfo on AS/400 older than V6R1");328}329return ::vmgetinfo(out, command, arg);330}331332// Given an address, returns the size of the page backing that address.333size_t os::Aix::query_pagesize(void* addr) {334335if (os::Aix::on_pase() && os::Aix::os_version_short() < 0x0601) {336// AS/400 older than V6R1: no vmgetinfo here, default to 4K337return 4*K;338}339340vm_page_info pi;341pi.addr = (uint64_t)addr;342if (checked_vmgetinfo(&pi, VM_PAGE_INFO, sizeof(pi)) == 0) {343return pi.pagesize;344} else {345assert(false, "vmgetinfo failed to retrieve page size");346return 4*K;347}348}349350void os::Aix::initialize_system_info() {351352// Get the number of online(logical) cpus instead of configured.353os::_processor_count = sysconf(_SC_NPROCESSORS_ONLN);354assert(_processor_count > 0, "_processor_count must be > 0");355356// Retrieve total physical storage.357os::Aix::meminfo_t mi;358if (!os::Aix::get_meminfo(&mi)) {359assert(false, "os::Aix::get_meminfo failed.");360}361_physical_memory = (julong) mi.real_total;362}363364// Helper function for tracing page sizes.365static const char* describe_pagesize(size_t pagesize) {366switch (pagesize) {367case 4*K : return "4K";368case 64*K: return "64K";369case 16*M: return "16M";370case 16*G: return "16G";371default:372assert(false, "surprise");373return "??";374}375}376377// Probe OS for multipage support.378// Will fill the global g_multipage_support structure.379// Must be called before calling os::large_page_init().380static void query_multipage_support() {381382guarantee(g_multipage_support.pagesize == -1,383"do not call twice");384385g_multipage_support.pagesize = ::sysconf(_SC_PAGESIZE);386387// This really would surprise me.388assert(g_multipage_support.pagesize == 4*K, "surprise!");389390// Query default data page size (default page size for C-Heap, pthread stacks and .bss).391// Default data page size is defined either by linker options (-bdatapsize)392// or by environment variable LDR_CNTRL (suboption DATAPSIZE). If none is given,393// default should be 4K.394{395void* p = ::malloc(16*M);396g_multipage_support.datapsize = os::Aix::query_pagesize(p);397::free(p);398}399400// Query default shm page size (LDR_CNTRL SHMPSIZE).401// Note that this is pure curiosity. We do not rely on default page size but set402// our own page size after allocated.403{404const int shmid = ::shmget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR | S_IWUSR);405guarantee(shmid != -1, "shmget failed");406void* p = ::shmat(shmid, NULL, 0);407::shmctl(shmid, IPC_RMID, NULL);408guarantee(p != (void*) -1, "shmat failed");409g_multipage_support.shmpsize = os::Aix::query_pagesize(p);410::shmdt(p);411}412413// Before querying the stack page size, make sure we are not running as primordial414// thread (because primordial thread's stack may have different page size than415// pthread thread stacks). Running a VM on the primordial thread won't work for a416// number of reasons so we may just as well guarantee it here.417guarantee0(!os::is_primordial_thread());418419// Query pthread stack page size. Should be the same as data page size because420// pthread stacks are allocated from C-Heap.421{422int dummy = 0;423g_multipage_support.pthr_stack_pagesize = os::Aix::query_pagesize(&dummy);424}425426// Query default text page size (LDR_CNTRL TEXTPSIZE).427{428address any_function =429resolve_function_descriptor_to_code_pointer((address)describe_pagesize);430g_multipage_support.textpsize = os::Aix::query_pagesize(any_function);431}432433// Now probe for support of 64K pages and 16M pages.434435// Before OS/400 V6R1, there is no support for pages other than 4K.436if (os::Aix::on_pase_V5R4_or_older()) {437trcVerbose("OS/400 < V6R1 - no large page support.");438g_multipage_support.error = ERROR_MP_OS_TOO_OLD;439goto query_multipage_support_end;440}441442// Now check which page sizes the OS claims it supports, and of those, which actually can be used.443{444const int MAX_PAGE_SIZES = 4;445psize_t sizes[MAX_PAGE_SIZES];446const int num_psizes = checked_vmgetinfo(sizes, VMINFO_GETPSIZES, MAX_PAGE_SIZES);447if (num_psizes == -1) {448trcVerbose("vmgetinfo(VMINFO_GETPSIZES) failed (errno: %d)", errno);449trcVerbose("disabling multipage support.");450g_multipage_support.error = ERROR_MP_VMGETINFO_FAILED;451goto query_multipage_support_end;452}453guarantee(num_psizes > 0, "vmgetinfo(.., VMINFO_GETPSIZES, ...) failed.");454assert(num_psizes <= MAX_PAGE_SIZES, "Surprise! more than 4 page sizes?");455trcVerbose("vmgetinfo(.., VMINFO_GETPSIZES, ...) returns %d supported page sizes: ", num_psizes);456for (int i = 0; i < num_psizes; i ++) {457trcVerbose(" %s ", describe_pagesize(sizes[i]));458}459460// Can we use 64K, 16M pages?461for (int i = 0; i < num_psizes; i ++) {462const size_t pagesize = sizes[i];463if (pagesize != 64*K && pagesize != 16*M) {464continue;465}466bool can_use = false;467trcVerbose("Probing support for %s pages...", describe_pagesize(pagesize));468const int shmid = ::shmget(IPC_PRIVATE, pagesize,469IPC_CREAT | S_IRUSR | S_IWUSR);470guarantee0(shmid != -1); // Should always work.471// Try to set pagesize.472struct shmid_ds shm_buf = { 0 };473shm_buf.shm_pagesize = pagesize;474if (::shmctl(shmid, SHM_PAGESIZE, &shm_buf) != 0) {475const int en = errno;476::shmctl(shmid, IPC_RMID, NULL); // As early as possible!477trcVerbose("shmctl(SHM_PAGESIZE) failed with errno=%d", errno);478} else {479// Attach and double check pageisze.480void* p = ::shmat(shmid, NULL, 0);481::shmctl(shmid, IPC_RMID, NULL); // As early as possible!482guarantee0(p != (void*) -1); // Should always work.483const size_t real_pagesize = os::Aix::query_pagesize(p);484if (real_pagesize != pagesize) {485trcVerbose("real page size (" SIZE_FORMAT_HEX ") differs.", real_pagesize);486} else {487can_use = true;488}489::shmdt(p);490}491trcVerbose("Can use: %s", (can_use ? "yes" : "no"));492if (pagesize == 64*K) {493g_multipage_support.can_use_64K_pages = can_use;494} else if (pagesize == 16*M) {495g_multipage_support.can_use_16M_pages = can_use;496}497}498499} // end: check which pages can be used for shared memory500501query_multipage_support_end:502503trcVerbose("base page size (sysconf _SC_PAGESIZE): %s",504describe_pagesize(g_multipage_support.pagesize));505trcVerbose("Data page size (C-Heap, bss, etc): %s",506describe_pagesize(g_multipage_support.datapsize));507trcVerbose("Text page size: %s",508describe_pagesize(g_multipage_support.textpsize));509trcVerbose("Thread stack page size (pthread): %s",510describe_pagesize(g_multipage_support.pthr_stack_pagesize));511trcVerbose("Default shared memory page size: %s",512describe_pagesize(g_multipage_support.shmpsize));513trcVerbose("Can use 64K pages dynamically with shared memory: %s",514(g_multipage_support.can_use_64K_pages ? "yes" :"no"));515trcVerbose("Can use 16M pages dynamically with shared memory: %s",516(g_multipage_support.can_use_16M_pages ? "yes" :"no"));517trcVerbose("Multipage error details: %d",518g_multipage_support.error);519520// sanity checks521assert0(g_multipage_support.pagesize == 4*K);522assert0(g_multipage_support.datapsize == 4*K || g_multipage_support.datapsize == 64*K);523assert0(g_multipage_support.textpsize == 4*K || g_multipage_support.textpsize == 64*K);524assert0(g_multipage_support.pthr_stack_pagesize == g_multipage_support.datapsize);525assert0(g_multipage_support.shmpsize == 4*K || g_multipage_support.shmpsize == 64*K);526527}528529void os::init_system_properties_values() {530531#ifndef OVERRIDE_LIBPATH532#define DEFAULT_LIBPATH "/lib:/usr/lib"533#else534#define DEFAULT_LIBPATH OVERRIDE_LIBPATH535#endif536#define EXTENSIONS_DIR "/lib/ext"537538// Buffer that fits several sprintfs.539// Note that the space for the trailing null is provided540// by the nulls included by the sizeof operator.541const size_t bufsize =542MAX2((size_t)MAXPATHLEN, // For dll_dir & friends.543(size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR)); // extensions dir544char *buf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);545546// sysclasspath, java_home, dll_dir547{548char *pslash;549os::jvm_path(buf, bufsize);550551// Found the full path to libjvm.so.552// Now cut the path to <java_home>/jre if we can.553pslash = strrchr(buf, '/');554if (pslash != NULL) {555*pslash = '\0'; // Get rid of /libjvm.so.556}557pslash = strrchr(buf, '/');558if (pslash != NULL) {559*pslash = '\0'; // Get rid of /{client|server|hotspot}.560}561Arguments::set_dll_dir(buf);562563if (pslash != NULL) {564pslash = strrchr(buf, '/');565if (pslash != NULL) {566*pslash = '\0'; // Get rid of /lib.567}568}569Arguments::set_java_home(buf);570if (!set_boot_path('/', ':')) {571vm_exit_during_initialization("Failed setting boot class path.", NULL);572}573}574575// Where to look for native libraries.576577// On Aix we get the user setting of LIBPATH.578// Eventually, all the library path setting will be done here.579// Get the user setting of LIBPATH.580const char *v = ::getenv("LIBPATH");581const char *v_colon = ":";582if (v == NULL) { v = ""; v_colon = ""; }583584// Concatenate user and invariant part of ld_library_path.585// That's +1 for the colon and +1 for the trailing '\0'.586char *ld_library_path = NEW_C_HEAP_ARRAY(char, strlen(v) + 1 + sizeof(DEFAULT_LIBPATH) + 1, mtInternal);587sprintf(ld_library_path, "%s%s" DEFAULT_LIBPATH, v, v_colon);588Arguments::set_library_path(ld_library_path);589FREE_C_HEAP_ARRAY(char, ld_library_path);590591// Extensions directories.592sprintf(buf, "%s" EXTENSIONS_DIR, Arguments::get_java_home());593Arguments::set_ext_dirs(buf);594595FREE_C_HEAP_ARRAY(char, buf);596597#undef DEFAULT_LIBPATH598#undef EXTENSIONS_DIR599}600601////////////////////////////////////////////////////////////////////////////////602// breakpoint support603604void os::breakpoint() {605BREAKPOINT;606}607608extern "C" void breakpoint() {609// use debugger to set breakpoint here610}611612// retrieve memory information.613// Returns false if something went wrong;614// content of pmi undefined in this case.615bool os::Aix::get_meminfo(meminfo_t* pmi) {616617assert(pmi, "get_meminfo: invalid parameter");618619memset(pmi, 0, sizeof(meminfo_t));620621if (os::Aix::on_pase()) {622// On PASE, use the libo4 porting library.623624unsigned long long virt_total = 0;625unsigned long long real_total = 0;626unsigned long long real_free = 0;627unsigned long long pgsp_total = 0;628unsigned long long pgsp_free = 0;629if (libo4::get_memory_info(&virt_total, &real_total, &real_free, &pgsp_total, &pgsp_free)) {630pmi->virt_total = virt_total;631pmi->real_total = real_total;632pmi->real_free = real_free;633pmi->pgsp_total = pgsp_total;634pmi->pgsp_free = pgsp_free;635return true;636}637return false;638639} else {640641// On AIX, I use the (dynamically loaded) perfstat library to retrieve memory statistics642// See:643// http://publib.boulder.ibm.com/infocenter/systems/index.jsp644// ?topic=/com.ibm.aix.basetechref/doc/basetrf1/perfstat_memtot.htm645// http://publib.boulder.ibm.com/infocenter/systems/index.jsp646// ?topic=/com.ibm.aix.files/doc/aixfiles/libperfstat.h.htm647648perfstat_memory_total_t psmt;649memset (&psmt, '\0', sizeof(psmt));650const int rc = libperfstat::perfstat_memory_total(NULL, &psmt, sizeof(psmt), 1);651if (rc == -1) {652trcVerbose("perfstat_memory_total() failed (errno=%d)", errno);653assert(0, "perfstat_memory_total() failed");654return false;655}656657assert(rc == 1, "perfstat_memory_total() - weird return code");658659// excerpt from660// http://publib.boulder.ibm.com/infocenter/systems/index.jsp661// ?topic=/com.ibm.aix.files/doc/aixfiles/libperfstat.h.htm662// The fields of perfstat_memory_total_t:663// u_longlong_t virt_total Total virtual memory (in 4 KB pages).664// u_longlong_t real_total Total real memory (in 4 KB pages).665// u_longlong_t real_free Free real memory (in 4 KB pages).666// u_longlong_t pgsp_total Total paging space (in 4 KB pages).667// u_longlong_t pgsp_free Free paging space (in 4 KB pages).668669pmi->virt_total = psmt.virt_total * 4096;670pmi->real_total = psmt.real_total * 4096;671pmi->real_free = psmt.real_free * 4096;672pmi->pgsp_total = psmt.pgsp_total * 4096;673pmi->pgsp_free = psmt.pgsp_free * 4096;674675return true;676677}678} // end os::Aix::get_meminfo679680//////////////////////////////////////////////////////////////////////////////681// create new thread682683// Thread start routine for all newly created threads684static void *thread_native_entry(Thread *thread) {685686thread->record_stack_base_and_size();687688const pthread_t pthread_id = ::pthread_self();689const tid_t kernel_thread_id = ::thread_self();690691LogTarget(Info, os, thread) lt;692if (lt.is_enabled()) {693address low_address = thread->stack_end();694address high_address = thread->stack_base();695lt.print("Thread is alive (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT696", stack [" PTR_FORMAT " - " PTR_FORMAT " (" SIZE_FORMAT "k using %uk pages)).",697os::current_thread_id(), (uintx) kernel_thread_id, low_address, high_address,698(high_address - low_address) / K, os::Aix::query_pagesize(low_address) / K);699}700701// Normally, pthread stacks on AIX live in the data segment (are allocated with malloc()702// by the pthread library). In rare cases, this may not be the case, e.g. when third-party703// tools hook pthread_create(). In this case, we may run into problems establishing704// guard pages on those stacks, because the stacks may reside in memory which is not705// protectable (shmated).706if (thread->stack_base() > ::sbrk(0)) {707log_warning(os, thread)("Thread stack not in data segment.");708}709710// Try to randomize the cache line index of hot stack frames.711// This helps when threads of the same stack traces evict each other's712// cache lines. The threads can be either from the same JVM instance, or713// from different JVM instances. The benefit is especially true for714// processors with hyperthreading technology.715716static int counter = 0;717int pid = os::current_process_id();718alloca(((pid ^ counter++) & 7) * 128);719720thread->initialize_thread_current();721722OSThread* osthread = thread->osthread();723724// Thread_id is pthread id.725osthread->set_thread_id(pthread_id);726727// .. but keep kernel thread id too for diagnostics728osthread->set_kernel_thread_id(kernel_thread_id);729730// Initialize signal mask for this thread.731PosixSignals::hotspot_sigmask(thread);732733// Initialize floating point control register.734os::Aix::init_thread_fpu_state();735736assert(osthread->get_state() == RUNNABLE, "invalid os thread state");737738// Call one more level start routine.739thread->call_run();740741// Note: at this point the thread object may already have deleted itself.742// Prevent dereferencing it from here on out.743thread = NULL;744745log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT ").",746os::current_thread_id(), (uintx) kernel_thread_id);747748return 0;749}750751bool os::create_thread(Thread* thread, ThreadType thr_type,752size_t req_stack_size) {753754assert(thread->osthread() == NULL, "caller responsible");755756// Allocate the OSThread object.757OSThread* osthread = new OSThread(NULL, NULL);758if (osthread == NULL) {759return false;760}761762// Set the correct thread state.763osthread->set_thread_type(thr_type);764765// Initial state is ALLOCATED but not INITIALIZED766osthread->set_state(ALLOCATED);767768thread->set_osthread(osthread);769770// Init thread attributes.771pthread_attr_t attr;772pthread_attr_init(&attr);773guarantee(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) == 0, "???");774775// Make sure we run in 1:1 kernel-user-thread mode.776if (os::Aix::on_aix()) {777guarantee(pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM) == 0, "???");778guarantee(pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED) == 0, "???");779}780781// Start in suspended state, and in os::thread_start, wake the thread up.782guarantee(pthread_attr_setsuspendstate_np(&attr, PTHREAD_CREATE_SUSPENDED_NP) == 0, "???");783784// Calculate stack size if it's not specified by caller.785size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size);786787// JDK-8187028: It was observed that on some configurations (4K backed thread stacks)788// the real thread stack size may be smaller than the requested stack size, by as much as 64K.789// This very much looks like a pthread lib error. As a workaround, increase the stack size790// by 64K for small thread stacks (arbitrarily choosen to be < 4MB)791if (stack_size < 4096 * K) {792stack_size += 64 * K;793}794795// On Aix, pthread_attr_setstacksize fails with huge values and leaves the796// thread size in attr unchanged. If this is the minimal stack size as set797// by pthread_attr_init this leads to crashes after thread creation. E.g. the798// guard pages might not fit on the tiny stack created.799int ret = pthread_attr_setstacksize(&attr, stack_size);800if (ret != 0) {801log_warning(os, thread)("The %sthread stack size specified is invalid: " SIZE_FORMAT "k",802(thr_type == compiler_thread) ? "compiler " : ((thr_type == java_thread) ? "" : "VM "),803stack_size / K);804thread->set_osthread(NULL);805delete osthread;806return false;807}808809// Save some cycles and a page by disabling OS guard pages where we have our own810// VM guard pages (in java threads). For other threads, keep system default guard811// pages in place.812if (thr_type == java_thread || thr_type == compiler_thread) {813ret = pthread_attr_setguardsize(&attr, 0);814}815816pthread_t tid = 0;817if (ret == 0) {818ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);819}820821if (ret == 0) {822char buf[64];823log_info(os, thread)("Thread started (pthread id: " UINTX_FORMAT ", attributes: %s). ",824(uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));825} else {826char buf[64];827log_warning(os, thread)("Failed to start thread - pthread_create failed (%d=%s) for attributes: %s.",828ret, os::errno_name(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));829// Log some OS information which might explain why creating the thread failed.830log_info(os, thread)("Number of threads approx. running in the VM: %d", Threads::number_of_threads());831LogStream st(Log(os, thread)::info());832os::Posix::print_rlimit_info(&st);833os::print_memory_info(&st);834}835836pthread_attr_destroy(&attr);837838if (ret != 0) {839// Need to clean up stuff we've allocated so far.840thread->set_osthread(NULL);841delete osthread;842return false;843}844845// OSThread::thread_id is the pthread id.846osthread->set_thread_id(tid);847848return true;849}850851/////////////////////////////////////////////////////////////////////////////852// attach existing thread853854// bootstrap the main thread855bool os::create_main_thread(JavaThread* thread) {856assert(os::Aix::_main_thread == pthread_self(), "should be called inside main thread");857return create_attached_thread(thread);858}859860bool os::create_attached_thread(JavaThread* thread) {861#ifdef ASSERT862thread->verify_not_published();863#endif864865// Allocate the OSThread object866OSThread* osthread = new OSThread(NULL, NULL);867868if (osthread == NULL) {869return false;870}871872const pthread_t pthread_id = ::pthread_self();873const tid_t kernel_thread_id = ::thread_self();874875// OSThread::thread_id is the pthread id.876osthread->set_thread_id(pthread_id);877878// .. but keep kernel thread id too for diagnostics879osthread->set_kernel_thread_id(kernel_thread_id);880881// initialize floating point control register882os::Aix::init_thread_fpu_state();883884// Initial thread state is RUNNABLE885osthread->set_state(RUNNABLE);886887thread->set_osthread(osthread);888889if (UseNUMA) {890int lgrp_id = os::numa_get_group_id();891if (lgrp_id != -1) {892thread->set_lgrp_id(lgrp_id);893}894}895896// initialize signal mask for this thread897// and save the caller's signal mask898PosixSignals::hotspot_sigmask(thread);899900log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", kernel thread id: " UINTX_FORMAT ").",901os::current_thread_id(), (uintx) kernel_thread_id);902903return true;904}905906void os::pd_start_thread(Thread* thread) {907int status = pthread_continue_np(thread->osthread()->pthread_id());908assert(status == 0, "thr_continue failed");909}910911// Free OS resources related to the OSThread912void os::free_thread(OSThread* osthread) {913assert(osthread != NULL, "osthread not set");914915// We are told to free resources of the argument thread,916// but we can only really operate on the current thread.917assert(Thread::current()->osthread() == osthread,918"os::free_thread but not current thread");919920// Restore caller's signal mask921sigset_t sigmask = osthread->caller_sigmask();922pthread_sigmask(SIG_SETMASK, &sigmask, NULL);923924delete osthread;925}926927////////////////////////////////////////////////////////////////////////////////928// time support929930// Time since start-up in seconds to a fine granularity.931double os::elapsedTime() {932return ((double)os::elapsed_counter()) / os::elapsed_frequency(); // nanosecond resolution933}934935jlong os::elapsed_counter() {936return javaTimeNanos() - initial_time_count;937}938939jlong os::elapsed_frequency() {940return NANOSECS_PER_SEC; // nanosecond resolution941}942943bool os::supports_vtime() { return true; }944945double os::elapsedVTime() {946struct rusage usage;947int retval = getrusage(RUSAGE_THREAD, &usage);948if (retval == 0) {949return usage.ru_utime.tv_sec + usage.ru_stime.tv_sec + (usage.ru_utime.tv_usec + usage.ru_stime.tv_usec) / (1000.0 * 1000);950} else {951// better than nothing, but not much952return elapsedTime();953}954}955956// We use mread_real_time here.957// On AIX: If the CPU has a time register, the result will be RTC_POWER and958// it has to be converted to real time. AIX documentations suggests to do959// this unconditionally, so we do it.960//961// See: https://www.ibm.com/support/knowledgecenter/ssw_aix_61/com.ibm.aix.basetrf2/read_real_time.htm962//963// On PASE: mread_real_time will always return RTC_POWER_PC data, so no964// conversion is necessary. However, mread_real_time will not return965// monotonic results but merely matches read_real_time. So we need a tweak966// to ensure monotonic results.967//968// For PASE no public documentation exists, just word by IBM969jlong os::javaTimeNanos() {970timebasestruct_t time;971int rc = mread_real_time(&time, TIMEBASE_SZ);972if (os::Aix::on_pase()) {973assert(rc == RTC_POWER, "expected time format RTC_POWER from mread_real_time in PASE");974jlong now = jlong(time.tb_high) * NANOSECS_PER_SEC + jlong(time.tb_low);975jlong prev = max_real_time;976if (now <= prev) {977return prev; // same or retrograde time;978}979jlong obsv = Atomic::cmpxchg(&max_real_time, prev, now);980assert(obsv >= prev, "invariant"); // Monotonicity981// If the CAS succeeded then we're done and return "now".982// If the CAS failed and the observed value "obsv" is >= now then983// we should return "obsv". If the CAS failed and now > obsv > prv then984// some other thread raced this thread and installed a new value, in which case985// we could either (a) retry the entire operation, (b) retry trying to install now986// or (c) just return obsv. We use (c). No loop is required although in some cases987// we might discard a higher "now" value in deference to a slightly lower but freshly988// installed obsv value. That's entirely benign -- it admits no new orderings compared989// to (a) or (b) -- and greatly reduces coherence traffic.990// We might also condition (c) on the magnitude of the delta between obsv and now.991// Avoiding excessive CAS operations to hot RW locations is critical.992// See https://blogs.oracle.com/dave/entry/cas_and_cache_trivia_invalidate993return (prev == obsv) ? now : obsv;994} else {995if (rc != RTC_POWER) {996rc = time_base_to_time(&time, TIMEBASE_SZ);997assert(rc != -1, "error calling time_base_to_time()");998}999return jlong(time.tb_high) * NANOSECS_PER_SEC + jlong(time.tb_low);1000}1001}10021003void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {1004info_ptr->max_value = ALL_64_BITS;1005// mread_real_time() is monotonic (see 'os::javaTimeNanos()')1006info_ptr->may_skip_backward = false;1007info_ptr->may_skip_forward = false;1008info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time1009}10101011// Return the real, user, and system times in seconds from an1012// arbitrary fixed point in the past.1013bool os::getTimesSecs(double* process_real_time,1014double* process_user_time,1015double* process_system_time) {1016struct tms ticks;1017clock_t real_ticks = times(&ticks);10181019if (real_ticks == (clock_t) (-1)) {1020return false;1021} else {1022double ticks_per_second = (double) clock_tics_per_sec;1023*process_user_time = ((double) ticks.tms_utime) / ticks_per_second;1024*process_system_time = ((double) ticks.tms_stime) / ticks_per_second;1025*process_real_time = ((double) real_ticks) / ticks_per_second;10261027return true;1028}1029}10301031char * os::local_time_string(char *buf, size_t buflen) {1032struct tm t;1033time_t long_time;1034time(&long_time);1035localtime_r(&long_time, &t);1036jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",1037t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,1038t.tm_hour, t.tm_min, t.tm_sec);1039return buf;1040}10411042struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {1043return localtime_r(clock, res);1044}10451046intx os::current_thread_id() {1047return (intx)pthread_self();1048}10491050int os::current_process_id() {1051return getpid();1052}10531054// DLL functions10551056const char* os::dll_file_extension() { return ".so"; }10571058// This must be hard coded because it's the system's temporary1059// directory not the java application's temp directory, ala java.io.tmpdir.1060const char* os::get_temp_directory() { return "/tmp"; }10611062// Check if addr is inside libjvm.so.1063bool os::address_is_in_vm(address addr) {10641065// Input could be a real pc or a function pointer literal. The latter1066// would be a function descriptor residing in the data segment of a module.1067loaded_module_t lm;1068if (LoadedLibraries::find_for_text_address(addr, &lm) != NULL) {1069return lm.is_in_vm;1070} else if (LoadedLibraries::find_for_data_address(addr, &lm) != NULL) {1071return lm.is_in_vm;1072} else {1073return false;1074}10751076}10771078// Resolve an AIX function descriptor literal to a code pointer.1079// If the input is a valid code pointer to a text segment of a loaded module,1080// it is returned unchanged.1081// If the input is a valid AIX function descriptor, it is resolved to the1082// code entry point.1083// If the input is neither a valid function descriptor nor a valid code pointer,1084// NULL is returned.1085static address resolve_function_descriptor_to_code_pointer(address p) {10861087if (LoadedLibraries::find_for_text_address(p, NULL) != NULL) {1088// It is a real code pointer.1089return p;1090} else if (LoadedLibraries::find_for_data_address(p, NULL) != NULL) {1091// Pointer to data segment, potential function descriptor.1092address code_entry = (address)(((FunctionDescriptor*)p)->entry());1093if (LoadedLibraries::find_for_text_address(code_entry, NULL) != NULL) {1094// It is a function descriptor.1095return code_entry;1096}1097}10981099return NULL;1100}11011102bool os::dll_address_to_function_name(address addr, char *buf,1103int buflen, int *offset,1104bool demangle) {1105if (offset) {1106*offset = -1;1107}1108// Buf is not optional, but offset is optional.1109assert(buf != NULL, "sanity check");1110buf[0] = '\0';11111112// Resolve function ptr literals first.1113addr = resolve_function_descriptor_to_code_pointer(addr);1114if (!addr) {1115return false;1116}11171118return AixSymbols::get_function_name(addr, buf, buflen, offset, NULL, demangle);1119}11201121bool os::dll_address_to_library_name(address addr, char* buf,1122int buflen, int* offset) {1123if (offset) {1124*offset = -1;1125}1126// Buf is not optional, but offset is optional.1127assert(buf != NULL, "sanity check");1128buf[0] = '\0';11291130// Resolve function ptr literals first.1131addr = resolve_function_descriptor_to_code_pointer(addr);1132if (!addr) {1133return false;1134}11351136return AixSymbols::get_module_name(addr, buf, buflen);1137}11381139// Loads .dll/.so and in case of error it checks if .dll/.so was built1140// for the same architecture as Hotspot is running on.1141void *os::dll_load(const char *filename, char *ebuf, int ebuflen) {11421143log_info(os)("attempting shared library load of %s", filename);11441145if (ebuf && ebuflen > 0) {1146ebuf[0] = '\0';1147ebuf[ebuflen - 1] = '\0';1148}11491150if (!filename || strlen(filename) == 0) {1151::strncpy(ebuf, "dll_load: empty filename specified", ebuflen - 1);1152return NULL;1153}11541155// RTLD_LAZY is currently not implemented. The dl is loaded immediately with all its dependants.1156void * result= ::dlopen(filename, RTLD_LAZY);1157if (result != NULL) {1158Events::log(NULL, "Loaded shared library %s", filename);1159// Reload dll cache. Don't do this in signal handling.1160LoadedLibraries::reload();1161log_info(os)("shared library load of %s was successful", filename);1162return result;1163} else {1164// error analysis when dlopen fails1165const char* error_report = ::dlerror();1166if (error_report == NULL) {1167error_report = "dlerror returned no error description";1168}1169if (ebuf != NULL && ebuflen > 0) {1170snprintf(ebuf, ebuflen - 1, "%s, LIBPATH=%s, LD_LIBRARY_PATH=%s : %s",1171filename, ::getenv("LIBPATH"), ::getenv("LD_LIBRARY_PATH"), error_report);1172}1173Events::log(NULL, "Loading shared library %s failed, %s", filename, error_report);1174log_info(os)("shared library load of %s failed, %s", filename, error_report);1175}1176return NULL;1177}11781179void* os::dll_lookup(void* handle, const char* name) {1180void* res = dlsym(handle, name);1181return res;1182}11831184void* os::get_default_process_handle() {1185return (void*)::dlopen(NULL, RTLD_LAZY);1186}11871188void os::print_dll_info(outputStream *st) {1189st->print_cr("Dynamic libraries:");1190LoadedLibraries::print(st);1191}11921193void os::get_summary_os_info(char* buf, size_t buflen) {1194// There might be something more readable than uname results for AIX.1195struct utsname name;1196uname(&name);1197snprintf(buf, buflen, "%s %s", name.release, name.version);1198}11991200int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) {1201// Not yet implemented.1202return 0;1203}12041205void os::print_os_info_brief(outputStream* st) {1206uint32_t ver = os::Aix::os_version();1207st->print_cr("AIX kernel version %u.%u.%u.%u",1208(ver >> 24) & 0xFF, (ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF);12091210os::Posix::print_uname_info(st);12111212// Linux uses print_libversion_info(st); here.1213}12141215void os::print_os_info(outputStream* st) {1216st->print_cr("OS:");12171218os::Posix::print_uname_info(st);12191220uint32_t ver = os::Aix::os_version();1221st->print_cr("AIX kernel version %u.%u.%u.%u",1222(ver >> 24) & 0xFF, (ver >> 16) & 0xFF, (ver >> 8) & 0xFF, ver & 0xFF);12231224os::Posix::print_uptime_info(st);12251226os::Posix::print_rlimit_info(st);12271228os::Posix::print_load_average(st);12291230// _SC_THREAD_THREADS_MAX is the maximum number of threads within a process.1231long tmax = sysconf(_SC_THREAD_THREADS_MAX);1232st->print_cr("maximum #threads within a process:%ld", tmax);12331234// print wpar info1235libperfstat::wparinfo_t wi;1236if (libperfstat::get_wparinfo(&wi)) {1237st->print_cr("wpar info");1238st->print_cr("name: %s", wi.name);1239st->print_cr("id: %d", wi.wpar_id);1240st->print_cr("type: %s", (wi.app_wpar ? "application" : "system"));1241}12421243VM_Version::print_platform_virtualization_info(st);1244}12451246void os::print_memory_info(outputStream* st) {12471248st->print_cr("Memory:");12491250st->print_cr(" Base page size (sysconf _SC_PAGESIZE): %s",1251describe_pagesize(g_multipage_support.pagesize));1252st->print_cr(" Data page size (C-Heap, bss, etc): %s",1253describe_pagesize(g_multipage_support.datapsize));1254st->print_cr(" Text page size: %s",1255describe_pagesize(g_multipage_support.textpsize));1256st->print_cr(" Thread stack page size (pthread): %s",1257describe_pagesize(g_multipage_support.pthr_stack_pagesize));1258st->print_cr(" Default shared memory page size: %s",1259describe_pagesize(g_multipage_support.shmpsize));1260st->print_cr(" Can use 64K pages dynamically with shared memory: %s",1261(g_multipage_support.can_use_64K_pages ? "yes" :"no"));1262st->print_cr(" Can use 16M pages dynamically with shared memory: %s",1263(g_multipage_support.can_use_16M_pages ? "yes" :"no"));1264st->print_cr(" Multipage error: %d",1265g_multipage_support.error);1266st->cr();1267st->print_cr(" os::vm_page_size: %s", describe_pagesize(os::vm_page_size()));12681269// print out LDR_CNTRL because it affects the default page sizes1270const char* const ldr_cntrl = ::getenv("LDR_CNTRL");1271st->print_cr(" LDR_CNTRL=%s.", ldr_cntrl ? ldr_cntrl : "<unset>");12721273// Print out EXTSHM because it is an unsupported setting.1274const char* const extshm = ::getenv("EXTSHM");1275st->print_cr(" EXTSHM=%s.", extshm ? extshm : "<unset>");1276if ( (strcmp(extshm, "on") == 0) || (strcmp(extshm, "ON") == 0) ) {1277st->print_cr(" *** Unsupported! Please remove EXTSHM from your environment! ***");1278}12791280// Print out AIXTHREAD_GUARDPAGES because it affects the size of pthread stacks.1281const char* const aixthread_guardpages = ::getenv("AIXTHREAD_GUARDPAGES");1282st->print_cr(" AIXTHREAD_GUARDPAGES=%s.",1283aixthread_guardpages ? aixthread_guardpages : "<unset>");1284st->cr();12851286os::Aix::meminfo_t mi;1287if (os::Aix::get_meminfo(&mi)) {1288if (os::Aix::on_aix()) {1289st->print_cr("physical total : " SIZE_FORMAT, mi.real_total);1290st->print_cr("physical free : " SIZE_FORMAT, mi.real_free);1291st->print_cr("swap total : " SIZE_FORMAT, mi.pgsp_total);1292st->print_cr("swap free : " SIZE_FORMAT, mi.pgsp_free);1293} else {1294// PASE - Numbers are result of QWCRSSTS; they mean:1295// real_total: Sum of all system pools1296// real_free: always 01297// pgsp_total: we take the size of the system ASP1298// pgsp_free: size of system ASP times percentage of system ASP unused1299st->print_cr("physical total : " SIZE_FORMAT, mi.real_total);1300st->print_cr("system asp total : " SIZE_FORMAT, mi.pgsp_total);1301st->print_cr("%% system asp used : %.2f",1302mi.pgsp_total ? (100.0f * (mi.pgsp_total - mi.pgsp_free) / mi.pgsp_total) : -1.0f);1303}1304}1305st->cr();13061307// Print program break.1308st->print_cr("Program break at VM startup: " PTR_FORMAT ".", p2i(g_brk_at_startup));1309address brk_now = (address)::sbrk(0);1310if (brk_now != (address)-1) {1311st->print_cr("Program break now : " PTR_FORMAT " (distance: " SIZE_FORMAT "k).",1312p2i(brk_now), (size_t)((brk_now - g_brk_at_startup) / K));1313}1314st->print_cr("MaxExpectedDataSegmentSize : " SIZE_FORMAT "k.", MaxExpectedDataSegmentSize / K);1315st->cr();13161317// Print segments allocated with os::reserve_memory.1318st->print_cr("internal virtual memory regions used by vm:");1319vmembk_print_on(st);1320}13211322// Get a string for the cpuinfo that is a summary of the cpu type1323void os::get_summary_cpu_info(char* buf, size_t buflen) {1324// read _system_configuration.version1325switch (_system_configuration.version) {1326case PV_9:1327strncpy(buf, "Power PC 9", buflen);1328break;1329case PV_8:1330strncpy(buf, "Power PC 8", buflen);1331break;1332case PV_7:1333strncpy(buf, "Power PC 7", buflen);1334break;1335case PV_6_1:1336strncpy(buf, "Power PC 6 DD1.x", buflen);1337break;1338case PV_6:1339strncpy(buf, "Power PC 6", buflen);1340break;1341case PV_5:1342strncpy(buf, "Power PC 5", buflen);1343break;1344case PV_5_2:1345strncpy(buf, "Power PC 5_2", buflen);1346break;1347case PV_5_3:1348strncpy(buf, "Power PC 5_3", buflen);1349break;1350case PV_5_Compat:1351strncpy(buf, "PV_5_Compat", buflen);1352break;1353case PV_6_Compat:1354strncpy(buf, "PV_6_Compat", buflen);1355break;1356case PV_7_Compat:1357strncpy(buf, "PV_7_Compat", buflen);1358break;1359case PV_8_Compat:1360strncpy(buf, "PV_8_Compat", buflen);1361break;1362case PV_9_Compat:1363strncpy(buf, "PV_9_Compat", buflen);1364break;1365default:1366strncpy(buf, "unknown", buflen);1367}1368}13691370void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) {1371// Nothing to do beyond of what os::print_cpu_info() does.1372}13731374static char saved_jvm_path[MAXPATHLEN] = {0};13751376// Find the full path to the current module, libjvm.so.1377void os::jvm_path(char *buf, jint buflen) {1378// Error checking.1379if (buflen < MAXPATHLEN) {1380assert(false, "must use a large-enough buffer");1381buf[0] = '\0';1382return;1383}1384// Lazy resolve the path to current module.1385if (saved_jvm_path[0] != 0) {1386strcpy(buf, saved_jvm_path);1387return;1388}13891390Dl_info dlinfo;1391int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo);1392assert(ret != 0, "cannot locate libjvm");1393char* rp = os::Posix::realpath((char *)dlinfo.dli_fname, buf, buflen);1394assert(rp != NULL, "error in realpath(): maybe the 'path' argument is too long?");13951396if (Arguments::sun_java_launcher_is_altjvm()) {1397// Support for the java launcher's '-XXaltjvm=<path>' option. Typical1398// value for buf is "<JAVA_HOME>/jre/lib/<vmtype>/libjvm.so".1399// If "/jre/lib/" appears at the right place in the string, then1400// assume we are installed in a JDK and we're done. Otherwise, check1401// for a JAVA_HOME environment variable and fix up the path so it1402// looks like libjvm.so is installed there (append a fake suffix1403// hotspot/libjvm.so).1404const char *p = buf + strlen(buf) - 1;1405for (int count = 0; p > buf && count < 4; ++count) {1406for (--p; p > buf && *p != '/'; --p)1407/* empty */ ;1408}14091410if (strncmp(p, "/jre/lib/", 9) != 0) {1411// Look for JAVA_HOME in the environment.1412char* java_home_var = ::getenv("JAVA_HOME");1413if (java_home_var != NULL && java_home_var[0] != 0) {1414char* jrelib_p;1415int len;14161417// Check the current module name "libjvm.so".1418p = strrchr(buf, '/');1419if (p == NULL) {1420return;1421}1422assert(strstr(p, "/libjvm") == p, "invalid library name");14231424rp = os::Posix::realpath(java_home_var, buf, buflen);1425if (rp == NULL) {1426return;1427}14281429// determine if this is a legacy image or modules image1430// modules image doesn't have "jre" subdirectory1431len = strlen(buf);1432assert(len < buflen, "Ran out of buffer room");1433jrelib_p = buf + len;1434snprintf(jrelib_p, buflen-len, "/jre/lib");1435if (0 != access(buf, F_OK)) {1436snprintf(jrelib_p, buflen-len, "/lib");1437}14381439if (0 == access(buf, F_OK)) {1440// Use current module name "libjvm.so"1441len = strlen(buf);1442snprintf(buf + len, buflen-len, "/hotspot/libjvm.so");1443} else {1444// Go back to path of .so1445rp = os::Posix::realpath((char *)dlinfo.dli_fname, buf, buflen);1446if (rp == NULL) {1447return;1448}1449}1450}1451}1452}14531454strncpy(saved_jvm_path, buf, sizeof(saved_jvm_path));1455saved_jvm_path[sizeof(saved_jvm_path) - 1] = '\0';1456}14571458void os::print_jni_name_prefix_on(outputStream* st, int args_size) {1459// no prefix required, not even "_"1460}14611462void os::print_jni_name_suffix_on(outputStream* st, int args_size) {1463// no suffix required1464}14651466////////////////////////////////////////////////////////////////////////////////1467// Virtual Memory14681469// We need to keep small simple bookkeeping for os::reserve_memory and friends.14701471#define VMEM_MAPPED 11472#define VMEM_SHMATED 214731474struct vmembk_t {1475int type; // 1 - mmap, 2 - shmat1476char* addr;1477size_t size; // Real size, may be larger than usersize.1478size_t pagesize; // page size of area1479vmembk_t* next;14801481bool contains_addr(char* p) const {1482return p >= addr && p < (addr + size);1483}14841485bool contains_range(char* p, size_t s) const {1486return contains_addr(p) && contains_addr(p + s - 1);1487}14881489void print_on(outputStream* os) const {1490os->print("[" PTR_FORMAT " - " PTR_FORMAT "] (" UINTX_FORMAT1491" bytes, %d %s pages), %s",1492addr, addr + size - 1, size, size / pagesize, describe_pagesize(pagesize),1493(type == VMEM_SHMATED ? "shmat" : "mmap")1494);1495}14961497// Check that range is a sub range of memory block (or equal to memory block);1498// also check that range is fully page aligned to the page size if the block.1499void assert_is_valid_subrange(char* p, size_t s) const {1500if (!contains_range(p, s)) {1501trcVerbose("[" PTR_FORMAT " - " PTR_FORMAT "] is not a sub "1502"range of [" PTR_FORMAT " - " PTR_FORMAT "].",1503p2i(p), p2i(p + s), p2i(addr), p2i(addr + size));1504guarantee0(false);1505}1506if (!is_aligned_to(p, pagesize) || !is_aligned_to(p + s, pagesize)) {1507trcVerbose("range [" PTR_FORMAT " - " PTR_FORMAT "] is not"1508" aligned to pagesize (%lu)", p2i(p), p2i(p + s), (unsigned long) pagesize);1509guarantee0(false);1510}1511}1512};15131514static struct {1515vmembk_t* first;1516MiscUtils::CritSect cs;1517} vmem;15181519static void vmembk_add(char* addr, size_t size, size_t pagesize, int type) {1520vmembk_t* p = (vmembk_t*) ::malloc(sizeof(vmembk_t));1521assert0(p);1522if (p) {1523MiscUtils::AutoCritSect lck(&vmem.cs);1524p->addr = addr; p->size = size;1525p->pagesize = pagesize;1526p->type = type;1527p->next = vmem.first;1528vmem.first = p;1529}1530}15311532static vmembk_t* vmembk_find(char* addr) {1533MiscUtils::AutoCritSect lck(&vmem.cs);1534for (vmembk_t* p = vmem.first; p; p = p->next) {1535if (p->addr <= addr && (p->addr + p->size) > addr) {1536return p;1537}1538}1539return NULL;1540}15411542static void vmembk_remove(vmembk_t* p0) {1543MiscUtils::AutoCritSect lck(&vmem.cs);1544assert0(p0);1545assert0(vmem.first); // List should not be empty.1546for (vmembk_t** pp = &(vmem.first); *pp; pp = &((*pp)->next)) {1547if (*pp == p0) {1548*pp = p0->next;1549::free(p0);1550return;1551}1552}1553assert0(false); // Not found?1554}15551556static void vmembk_print_on(outputStream* os) {1557MiscUtils::AutoCritSect lck(&vmem.cs);1558for (vmembk_t* vmi = vmem.first; vmi; vmi = vmi->next) {1559vmi->print_on(os);1560os->cr();1561}1562}15631564// Reserve and attach a section of System V memory.1565// If <requested_addr> is not NULL, function will attempt to attach the memory at the given1566// address. Failing that, it will attach the memory anywhere.1567// If <requested_addr> is NULL, function will attach the memory anywhere.1568static char* reserve_shmated_memory (size_t bytes, char* requested_addr) {15691570trcVerbose("reserve_shmated_memory " UINTX_FORMAT " bytes, wishaddress "1571PTR_FORMAT "...", bytes, p2i(requested_addr));15721573// We must prevent anyone from attaching too close to the1574// BRK because that may cause malloc OOM.1575if (requested_addr != NULL && is_close_to_brk((address)requested_addr)) {1576trcVerbose("Wish address " PTR_FORMAT " is too close to the BRK segment.", p2i(requested_addr));1577// Since we treat an attach to the wrong address as an error later anyway,1578// we return NULL here1579return NULL;1580}15811582// For old AS/400's (V5R4 and older) we should not even be here - System V shared memory is not1583// really supported (max size 4GB), so reserve_mmapped_memory should have been used instead.1584if (os::Aix::on_pase_V5R4_or_older()) {1585ShouldNotReachHere();1586}15871588// Align size of shm up to 64K to avoid errors if we later try to change the page size.1589const size_t size = align_up(bytes, 64*K);15901591// Reserve the shared segment.1592int shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | S_IRUSR | S_IWUSR);1593if (shmid == -1) {1594trcVerbose("shmget(.., " UINTX_FORMAT ", ..) failed (errno: %d).", size, errno);1595return NULL;1596}15971598// Important note:1599// It is very important that we, upon leaving this function, do not leave a shm segment alive.1600// We must right after attaching it remove it from the system. System V shm segments are global and1601// survive the process.1602// So, from here on: Do not assert, do not return, until we have called shmctl(IPC_RMID) (A).16031604struct shmid_ds shmbuf;1605memset(&shmbuf, 0, sizeof(shmbuf));1606shmbuf.shm_pagesize = 64*K;1607if (shmctl(shmid, SHM_PAGESIZE, &shmbuf) != 0) {1608trcVerbose("Failed to set page size (need " UINTX_FORMAT " 64K pages) - shmctl failed with %d.",1609size / (64*K), errno);1610// I want to know if this ever happens.1611assert(false, "failed to set page size for shmat");1612}16131614// Now attach the shared segment.1615// Note that I attach with SHM_RND - which means that the requested address is rounded down, if1616// needed, to the next lowest segment boundary. Otherwise the attach would fail if the address1617// were not a segment boundary.1618char* const addr = (char*) shmat(shmid, requested_addr, SHM_RND);1619const int errno_shmat = errno;16201621// (A) Right after shmat and before handing shmat errors delete the shm segment.1622if (::shmctl(shmid, IPC_RMID, NULL) == -1) {1623trcVerbose("shmctl(%u, IPC_RMID) failed (%d)\n", shmid, errno);1624assert(false, "failed to remove shared memory segment!");1625}16261627// Handle shmat error. If we failed to attach, just return.1628if (addr == (char*)-1) {1629trcVerbose("Failed to attach segment at " PTR_FORMAT " (%d).", p2i(requested_addr), errno_shmat);1630return NULL;1631}16321633// Just for info: query the real page size. In case setting the page size did not1634// work (see above), the system may have given us something other then 4K (LDR_CNTRL).1635const size_t real_pagesize = os::Aix::query_pagesize(addr);1636if (real_pagesize != shmbuf.shm_pagesize) {1637trcVerbose("pagesize is, surprisingly, " SIZE_FORMAT, real_pagesize);1638}16391640if (addr) {1641trcVerbose("shm-allocated " PTR_FORMAT " .. " PTR_FORMAT " (" UINTX_FORMAT " bytes, " UINTX_FORMAT " %s pages)",1642p2i(addr), p2i(addr + size - 1), size, size/real_pagesize, describe_pagesize(real_pagesize));1643} else {1644if (requested_addr != NULL) {1645trcVerbose("failed to shm-allocate " UINTX_FORMAT " bytes at with address " PTR_FORMAT ".", size, p2i(requested_addr));1646} else {1647trcVerbose("failed to shm-allocate " UINTX_FORMAT " bytes at any address.", size);1648}1649}16501651// book-keeping1652vmembk_add(addr, size, real_pagesize, VMEM_SHMATED);1653assert0(is_aligned_to(addr, os::vm_page_size()));16541655return addr;1656}16571658static bool release_shmated_memory(char* addr, size_t size) {16591660trcVerbose("release_shmated_memory [" PTR_FORMAT " - " PTR_FORMAT "].",1661p2i(addr), p2i(addr + size - 1));16621663bool rc = false;16641665// TODO: is there a way to verify shm size without doing bookkeeping?1666if (::shmdt(addr) != 0) {1667trcVerbose("error (%d).", errno);1668} else {1669trcVerbose("ok.");1670rc = true;1671}1672return rc;1673}16741675static bool uncommit_shmated_memory(char* addr, size_t size) {1676trcVerbose("uncommit_shmated_memory [" PTR_FORMAT " - " PTR_FORMAT "].",1677p2i(addr), p2i(addr + size - 1));16781679const bool rc = my_disclaim64(addr, size);16801681if (!rc) {1682trcVerbose("my_disclaim64(" PTR_FORMAT ", " UINTX_FORMAT ") failed.\n", p2i(addr), size);1683return false;1684}1685return true;1686}16871688//////////////////////////////// mmap-based routines /////////////////////////////////16891690// Reserve memory via mmap.1691// If <requested_addr> is given, an attempt is made to attach at the given address.1692// Failing that, memory is allocated at any address.1693static char* reserve_mmaped_memory(size_t bytes, char* requested_addr) {1694trcVerbose("reserve_mmaped_memory " UINTX_FORMAT " bytes, wishaddress " PTR_FORMAT "...",1695bytes, p2i(requested_addr));16961697if (requested_addr && !is_aligned_to(requested_addr, os::vm_page_size()) != 0) {1698trcVerbose("Wish address " PTR_FORMAT " not aligned to page boundary.", p2i(requested_addr));1699return NULL;1700}17011702// We must prevent anyone from attaching too close to the1703// BRK because that may cause malloc OOM.1704if (requested_addr != NULL && is_close_to_brk((address)requested_addr)) {1705trcVerbose("Wish address " PTR_FORMAT " is too close to the BRK segment.", p2i(requested_addr));1706// Since we treat an attach to the wrong address as an error later anyway,1707// we return NULL here1708return NULL;1709}17101711// In 64K mode, we lie and claim the global page size (os::vm_page_size()) is 64K1712// (complicated story). This mostly works just fine since 64K is a multiple of the1713// actual 4K lowest page size. Only at a few seams light shines thru, e.g. when1714// calling mmap. mmap will return memory aligned to the lowest pages size - 4K -1715// so we must make sure - transparently - that the caller only ever sees 64K1716// aligned mapping start addresses.1717const size_t alignment = os::vm_page_size();17181719// Size shall always be a multiple of os::vm_page_size (esp. in 64K mode).1720const size_t size = align_up(bytes, os::vm_page_size());17211722// alignment: Allocate memory large enough to include an aligned range of the right size and1723// cut off the leading and trailing waste pages.1724assert0(alignment != 0 && is_aligned_to(alignment, os::vm_page_size())); // see above1725const size_t extra_size = size + alignment;17261727// Note: MAP_SHARED (instead of MAP_PRIVATE) needed to be able to1728// later use msync(MS_INVALIDATE) (see os::uncommit_memory).1729int flags = MAP_ANONYMOUS | MAP_SHARED;17301731// MAP_FIXED is needed to enforce requested_addr - manpage is vague about what1732// it means if wishaddress is given but MAP_FIXED is not set.1733//1734// Important! Behaviour differs depending on whether SPEC1170 mode is active or not.1735// SPEC1170 mode active: behaviour like POSIX, MAP_FIXED will clobber existing mappings.1736// SPEC1170 mode not active: behaviour, unlike POSIX, is that no existing mappings will1737// get clobbered.1738if (requested_addr != NULL) {1739if (!os::Aix::xpg_sus_mode()) { // not SPEC1170 Behaviour1740flags |= MAP_FIXED;1741}1742}17431744char* addr = (char*)::mmap(requested_addr, extra_size,1745PROT_READ|PROT_WRITE|PROT_EXEC, flags, -1, 0);17461747if (addr == MAP_FAILED) {1748trcVerbose("mmap(" PTR_FORMAT ", " UINTX_FORMAT ", ..) failed (%d)", p2i(requested_addr), size, errno);1749return NULL;1750} else if (requested_addr != NULL && addr != requested_addr) {1751trcVerbose("mmap(" PTR_FORMAT ", " UINTX_FORMAT ", ..) succeeded, but at a different address than requested (" PTR_FORMAT "), will unmap",1752p2i(requested_addr), size, p2i(addr));1753::munmap(addr, extra_size);1754return NULL;1755}17561757// Handle alignment.1758char* const addr_aligned = align_up(addr, alignment);1759const size_t waste_pre = addr_aligned - addr;1760char* const addr_aligned_end = addr_aligned + size;1761const size_t waste_post = extra_size - waste_pre - size;1762if (waste_pre > 0) {1763::munmap(addr, waste_pre);1764}1765if (waste_post > 0) {1766::munmap(addr_aligned_end, waste_post);1767}1768addr = addr_aligned;17691770trcVerbose("mmap-allocated " PTR_FORMAT " .. " PTR_FORMAT " (" UINTX_FORMAT " bytes)",1771p2i(addr), p2i(addr + bytes), bytes);17721773// bookkeeping1774vmembk_add(addr, size, 4*K, VMEM_MAPPED);17751776// Test alignment, see above.1777assert0(is_aligned_to(addr, os::vm_page_size()));17781779return addr;1780}17811782static bool release_mmaped_memory(char* addr, size_t size) {1783assert0(is_aligned_to(addr, os::vm_page_size()));1784assert0(is_aligned_to(size, os::vm_page_size()));17851786trcVerbose("release_mmaped_memory [" PTR_FORMAT " - " PTR_FORMAT "].",1787p2i(addr), p2i(addr + size - 1));1788bool rc = false;17891790if (::munmap(addr, size) != 0) {1791trcVerbose("failed (%d)\n", errno);1792rc = false;1793} else {1794trcVerbose("ok.");1795rc = true;1796}17971798return rc;1799}18001801static bool uncommit_mmaped_memory(char* addr, size_t size) {18021803assert0(is_aligned_to(addr, os::vm_page_size()));1804assert0(is_aligned_to(size, os::vm_page_size()));18051806trcVerbose("uncommit_mmaped_memory [" PTR_FORMAT " - " PTR_FORMAT "].",1807p2i(addr), p2i(addr + size - 1));1808bool rc = false;18091810// Uncommit mmap memory with msync MS_INVALIDATE.1811if (::msync(addr, size, MS_INVALIDATE) != 0) {1812trcVerbose("failed (%d)\n", errno);1813rc = false;1814} else {1815trcVerbose("ok.");1816rc = true;1817}18181819return rc;1820}18211822int os::vm_page_size() {1823// Seems redundant as all get out.1824assert(os::Aix::page_size() != -1, "must call os::init");1825return os::Aix::page_size();1826}18271828// Aix allocates memory by pages.1829int os::vm_allocation_granularity() {1830assert(os::Aix::page_size() != -1, "must call os::init");1831return os::Aix::page_size();1832}18331834#ifdef PRODUCT1835static void warn_fail_commit_memory(char* addr, size_t size, bool exec,1836int err) {1837warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT1838", %d) failed; error='%s' (errno=%d)", p2i(addr), size, exec,1839os::errno_name(err), err);1840}1841#endif18421843void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,1844const char* mesg) {1845assert(mesg != NULL, "mesg must be specified");1846if (!pd_commit_memory(addr, size, exec)) {1847// Add extra info in product mode for vm_exit_out_of_memory():1848PRODUCT_ONLY(warn_fail_commit_memory(addr, size, exec, errno);)1849vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "%s", mesg);1850}1851}18521853bool os::pd_commit_memory(char* addr, size_t size, bool exec) {18541855assert(is_aligned_to(addr, os::vm_page_size()),1856"addr " PTR_FORMAT " not aligned to vm_page_size (" PTR_FORMAT ")",1857p2i(addr), os::vm_page_size());1858assert(is_aligned_to(size, os::vm_page_size()),1859"size " PTR_FORMAT " not aligned to vm_page_size (" PTR_FORMAT ")",1860size, os::vm_page_size());18611862vmembk_t* const vmi = vmembk_find(addr);1863guarantee0(vmi);1864vmi->assert_is_valid_subrange(addr, size);18651866trcVerbose("commit_memory [" PTR_FORMAT " - " PTR_FORMAT "].", p2i(addr), p2i(addr + size - 1));18671868if (UseExplicitCommit) {1869// AIX commits memory on touch. So, touch all pages to be committed.1870for (char* p = addr; p < (addr + size); p += 4*K) {1871*p = '\0';1872}1873}18741875return true;1876}18771878bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint, bool exec) {1879return pd_commit_memory(addr, size, exec);1880}18811882void os::pd_commit_memory_or_exit(char* addr, size_t size,1883size_t alignment_hint, bool exec,1884const char* mesg) {1885// Alignment_hint is ignored on this OS.1886pd_commit_memory_or_exit(addr, size, exec, mesg);1887}18881889bool os::pd_uncommit_memory(char* addr, size_t size, bool exec) {1890assert(is_aligned_to(addr, os::vm_page_size()),1891"addr " PTR_FORMAT " not aligned to vm_page_size (" PTR_FORMAT ")",1892p2i(addr), os::vm_page_size());1893assert(is_aligned_to(size, os::vm_page_size()),1894"size " PTR_FORMAT " not aligned to vm_page_size (" PTR_FORMAT ")",1895size, os::vm_page_size());18961897// Dynamically do different things for mmap/shmat.1898const vmembk_t* const vmi = vmembk_find(addr);1899guarantee0(vmi);1900vmi->assert_is_valid_subrange(addr, size);19011902if (vmi->type == VMEM_SHMATED) {1903return uncommit_shmated_memory(addr, size);1904} else {1905return uncommit_mmaped_memory(addr, size);1906}1907}19081909bool os::pd_create_stack_guard_pages(char* addr, size_t size) {1910// Do not call this; no need to commit stack pages on AIX.1911ShouldNotReachHere();1912return true;1913}19141915bool os::remove_stack_guard_pages(char* addr, size_t size) {1916// Do not call this; no need to commit stack pages on AIX.1917ShouldNotReachHere();1918return true;1919}19201921void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {1922}19231924void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) {1925}19261927void os::numa_make_global(char *addr, size_t bytes) {1928}19291930void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) {1931}19321933bool os::numa_topology_changed() {1934return false;1935}19361937size_t os::numa_get_groups_num() {1938return 1;1939}19401941int os::numa_get_group_id() {1942return 0;1943}19441945size_t os::numa_get_leaf_groups(int *ids, size_t size) {1946if (size > 0) {1947ids[0] = 0;1948return 1;1949}1950return 0;1951}19521953int os::numa_get_group_id_for_address(const void* address) {1954return 0;1955}19561957bool os::get_page_info(char *start, page_info* info) {1958return false;1959}19601961char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) {1962return end;1963}19641965// Reserves and attaches a shared memory segment.1966char* os::pd_reserve_memory(size_t bytes, bool exec) {1967// Always round to os::vm_page_size(), which may be larger than 4K.1968bytes = align_up(bytes, os::vm_page_size());19691970// In 4K mode always use mmap.1971// In 64K mode allocate small sizes with mmap, large ones with 64K shmatted.1972if (os::vm_page_size() == 4*K) {1973return reserve_mmaped_memory(bytes, NULL /* requested_addr */);1974} else {1975if (bytes >= Use64KPagesThreshold) {1976return reserve_shmated_memory(bytes, NULL /* requested_addr */);1977} else {1978return reserve_mmaped_memory(bytes, NULL /* requested_addr */);1979}1980}1981}19821983bool os::pd_release_memory(char* addr, size_t size) {19841985// Dynamically do different things for mmap/shmat.1986vmembk_t* const vmi = vmembk_find(addr);1987guarantee0(vmi);1988vmi->assert_is_valid_subrange(addr, size);19891990// Always round to os::vm_page_size(), which may be larger than 4K.1991size = align_up(size, os::vm_page_size());1992addr = align_up(addr, os::vm_page_size());19931994bool rc = false;1995bool remove_bookkeeping = false;1996if (vmi->type == VMEM_SHMATED) {1997// For shmatted memory, we do:1998// - If user wants to release the whole range, release the memory (shmdt).1999// - If user only wants to release a partial range, uncommit (disclaim) that2000// range. That way, at least, we do not use memory anymore (bust still page2001// table space).2002if (addr == vmi->addr && size == vmi->size) {2003rc = release_shmated_memory(addr, size);2004remove_bookkeeping = true;2005} else {2006rc = uncommit_shmated_memory(addr, size);2007}2008} else {2009// In mmap-mode:2010// - If the user wants to release the full range, we do that and remove the mapping.2011// - If the user wants to release part of the range, we release that part, but need2012// to adjust bookkeeping.2013assert(is_aligned(size, 4 * K), "Sanity");2014rc = release_mmaped_memory(addr, size);2015if (addr == vmi->addr && size == vmi->size) {2016remove_bookkeeping = true;2017} else {2018if (addr == vmi->addr && size < vmi->size) {2019// Chopped from head2020vmi->addr += size;2021vmi->size -= size;2022} else if (addr + size == vmi->addr + vmi->size) {2023// Chopped from tail2024vmi->size -= size;2025} else {2026// releasing a mapping in the middle of the original mapping:2027// For now we forbid this, since this is an invalid scenario2028// (the bookkeeping is easy enough to fix if needed but there2029// is no use case for it; any occurrence is likely an error.2030ShouldNotReachHere();2031}2032}2033}20342035// update bookkeeping2036if (rc && remove_bookkeeping) {2037vmembk_remove(vmi);2038}20392040return rc;2041}20422043static bool checked_mprotect(char* addr, size_t size, int prot) {20442045// Little problem here: if SPEC1170 behaviour is off, mprotect() on AIX will2046// not tell me if protection failed when trying to protect an un-protectable range.2047//2048// This means if the memory was allocated using shmget/shmat, protection wont work2049// but mprotect will still return 0:2050//2051// See http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/mprotect.htm20522053Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot);2054bool rc = ::mprotect(addr, size, prot) == 0 ? true : false;20552056if (!rc) {2057const char* const s_errno = os::errno_name(errno);2058warning("mprotect(" PTR_FORMAT "-" PTR_FORMAT ", 0x%X) failed (%s).", addr, addr + size, prot, s_errno);2059return false;2060}20612062// mprotect success check2063//2064// Mprotect said it changed the protection but can I believe it?2065//2066// To be sure I need to check the protection afterwards. Try to2067// read from protected memory and check whether that causes a segfault.2068//2069if (!os::Aix::xpg_sus_mode()) {20702071if (CanUseSafeFetch32()) {20722073const bool read_protected =2074(SafeFetch32((int*)addr, 0x12345678) == 0x12345678 &&2075SafeFetch32((int*)addr, 0x76543210) == 0x76543210) ? true : false;20762077if (prot & PROT_READ) {2078rc = !read_protected;2079} else {2080rc = read_protected;2081}20822083if (!rc) {2084if (os::Aix::on_pase()) {2085// There is an issue on older PASE systems where mprotect() will return success but the2086// memory will not be protected.2087// This has nothing to do with the problem of using mproect() on SPEC1170 incompatible2088// machines; we only see it rarely, when using mprotect() to protect the guard page of2089// a stack. It is an OS error.2090//2091// A valid strategy is just to try again. This usually works. :-/20922093::usleep(1000);2094Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot);2095if (::mprotect(addr, size, prot) == 0) {2096const bool read_protected_2 =2097(SafeFetch32((int*)addr, 0x12345678) == 0x12345678 &&2098SafeFetch32((int*)addr, 0x76543210) == 0x76543210) ? true : false;2099rc = true;2100}2101}2102}2103}2104}21052106assert(rc == true, "mprotect failed.");21072108return rc;2109}21102111// Set protections specified2112bool os::protect_memory(char* addr, size_t size, ProtType prot, bool is_committed) {2113unsigned int p = 0;2114switch (prot) {2115case MEM_PROT_NONE: p = PROT_NONE; break;2116case MEM_PROT_READ: p = PROT_READ; break;2117case MEM_PROT_RW: p = PROT_READ|PROT_WRITE; break;2118case MEM_PROT_RWX: p = PROT_READ|PROT_WRITE|PROT_EXEC; break;2119default:2120ShouldNotReachHere();2121}2122// is_committed is unused.2123return checked_mprotect(addr, size, p);2124}21252126bool os::guard_memory(char* addr, size_t size) {2127return checked_mprotect(addr, size, PROT_NONE);2128}21292130bool os::unguard_memory(char* addr, size_t size) {2131return checked_mprotect(addr, size, PROT_READ|PROT_WRITE|PROT_EXEC);2132}21332134// Large page support21352136static size_t _large_page_size = 0;21372138// Enable large page support if OS allows that.2139void os::large_page_init() {2140return; // Nothing to do. See query_multipage_support and friends.2141}21422143char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, size_t page_size, char* req_addr, bool exec) {2144fatal("os::reserve_memory_special should not be called on AIX.");2145return NULL;2146}21472148bool os::pd_release_memory_special(char* base, size_t bytes) {2149fatal("os::release_memory_special should not be called on AIX.");2150return false;2151}21522153size_t os::large_page_size() {2154return _large_page_size;2155}21562157bool os::can_commit_large_page_memory() {2158// Does not matter, we do not support huge pages.2159return false;2160}21612162bool os::can_execute_large_page_memory() {2163// Does not matter, we do not support huge pages.2164return false;2165}21662167char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) {2168assert(file_desc >= 0, "file_desc is not valid");2169char* result = NULL;21702171// Always round to os::vm_page_size(), which may be larger than 4K.2172bytes = align_up(bytes, os::vm_page_size());2173result = reserve_mmaped_memory(bytes, requested_addr);21742175if (result != NULL) {2176if (replace_existing_mapping_with_file_mapping(result, bytes, file_desc) == NULL) {2177vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));2178}2179}2180return result;2181}21822183// Reserve memory at an arbitrary address, only if that area is2184// available (and not reserved for something else).2185char* os::pd_attempt_reserve_memory_at(char* requested_addr, size_t bytes, bool exec) {2186char* addr = NULL;21872188// Always round to os::vm_page_size(), which may be larger than 4K.2189bytes = align_up(bytes, os::vm_page_size());21902191// In 4K mode always use mmap.2192// In 64K mode allocate small sizes with mmap, large ones with 64K shmatted.2193if (os::vm_page_size() == 4*K) {2194return reserve_mmaped_memory(bytes, requested_addr);2195} else {2196if (bytes >= Use64KPagesThreshold) {2197return reserve_shmated_memory(bytes, requested_addr);2198} else {2199return reserve_mmaped_memory(bytes, requested_addr);2200}2201}22022203return addr;2204}22052206// Sleep forever; naked call to OS-specific sleep; use with CAUTION2207void os::infinite_sleep() {2208while (true) { // sleep forever ...2209::sleep(100); // ... 100 seconds at a time2210}2211}22122213// Used to convert frequent JVM_Yield() to nops2214bool os::dont_yield() {2215return DontYieldALot;2216}22172218void os::naked_yield() {2219sched_yield();2220}22212222////////////////////////////////////////////////////////////////////////////////2223// thread priority support22242225// From AIX manpage to pthread_setschedparam2226// (see: http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?2227// topic=/com.ibm.aix.basetechref/doc/basetrf1/pthread_setschedparam.htm):2228//2229// "If schedpolicy is SCHED_OTHER, then sched_priority must be in the2230// range from 40 to 80, where 40 is the least favored priority and 802231// is the most favored."2232//2233// (Actually, I doubt this even has an impact on AIX, as we do kernel2234// scheduling there; however, this still leaves iSeries.)2235//2236// We use the same values for AIX and PASE.2237int os::java_to_os_priority[CriticalPriority + 1] = {223854, // 0 Entry should never be used2239224055, // 1 MinPriority224155, // 2224256, // 32243224456, // 4224557, // 5 NormPriority224657, // 62247224858, // 7224958, // 8225059, // 9 NearMaxPriority2251225260, // 10 MaxPriority2253225460 // 11 CriticalPriority2255};22562257static int prio_init() {2258if (ThreadPriorityPolicy == 1) {2259if (geteuid() != 0) {2260if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy) && !FLAG_IS_JIMAGE_RESOURCE(ThreadPriorityPolicy)) {2261warning("-XX:ThreadPriorityPolicy=1 may require system level permission, " \2262"e.g., being the root user. If the necessary permission is not " \2263"possessed, changes to priority will be silently ignored.");2264}2265}2266}2267if (UseCriticalJavaThreadPriority) {2268os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority];2269}2270return 0;2271}22722273OSReturn os::set_native_priority(Thread* thread, int newpri) {2274if (!UseThreadPriorities || ThreadPriorityPolicy == 0) return OS_OK;2275pthread_t thr = thread->osthread()->pthread_id();2276int policy = SCHED_OTHER;2277struct sched_param param;2278param.sched_priority = newpri;2279int ret = pthread_setschedparam(thr, policy, ¶m);22802281if (ret != 0) {2282trcVerbose("Could not change priority for thread %d to %d (error %d, %s)",2283(int)thr, newpri, ret, os::errno_name(ret));2284}2285return (ret == 0) ? OS_OK : OS_ERR;2286}22872288OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {2289if (!UseThreadPriorities || ThreadPriorityPolicy == 0) {2290*priority_ptr = java_to_os_priority[NormPriority];2291return OS_OK;2292}2293pthread_t thr = thread->osthread()->pthread_id();2294int policy = SCHED_OTHER;2295struct sched_param param;2296int ret = pthread_getschedparam(thr, &policy, ¶m);2297*priority_ptr = param.sched_priority;22982299return (ret == 0) ? OS_OK : OS_ERR;2300}23012302// To install functions for atexit system call2303extern "C" {2304static void perfMemory_exit_helper() {2305perfMemory_exit();2306}2307}23082309// This is called _before_ the most of global arguments have been parsed.2310void os::init(void) {2311// This is basic, we want to know if that ever changes.2312// (Shared memory boundary is supposed to be a 256M aligned.)2313assert(SHMLBA == ((uint64_t)0x10000000ULL)/*256M*/, "unexpected");23142315// Record process break at startup.2316g_brk_at_startup = (address) ::sbrk(0);2317assert(g_brk_at_startup != (address) -1, "sbrk failed");23182319// First off, we need to know whether we run on AIX or PASE, and2320// the OS level we run on.2321os::Aix::initialize_os_info();23222323// Scan environment (SPEC1170 behaviour, etc).2324os::Aix::scan_environment();23252326// Probe multipage support.2327query_multipage_support();23282329// Act like we only have one page size by eliminating corner cases which2330// we did not support very well anyway.2331// We have two input conditions:2332// 1) Data segment page size. This is controlled by linker setting (datapsize) on the2333// launcher, and/or by LDR_CNTRL environment variable. The latter overrules the linker2334// setting.2335// Data segment page size is important for us because it defines the thread stack page2336// size, which is needed for guard page handling, stack banging etc.2337// 2) The ability to allocate 64k pages dynamically. If this is a given, java heap can2338// and should be allocated with 64k pages.2339//2340// So, we do the following:2341// LDR_CNTRL can_use_64K_pages_dynamically what we do remarks2342// 4K no 4K old systems (aix 5.2, as/400 v5r4) or new systems with AME activated2343// 4k yes 64k (treat 4k stacks as 64k) different loader than java and standard settings2344// 64k no --- AIX 5.2 ? ---2345// 64k yes 64k new systems and standard java loader (we set datapsize=64k when linking)23462347// We explicitly leave no option to change page size, because only upgrading would work,2348// not downgrading (if stack page size is 64k you cannot pretend its 4k).23492350if (g_multipage_support.datapsize == 4*K) {2351// datapsize = 4K. Data segment, thread stacks are 4K paged.2352if (g_multipage_support.can_use_64K_pages) {2353// .. but we are able to use 64K pages dynamically.2354// This would be typical for java launchers which are not linked2355// with datapsize=64K (like, any other launcher but our own).2356//2357// In this case it would be smart to allocate the java heap with 64K2358// to get the performance benefit, and to fake 64k pages for the2359// data segment (when dealing with thread stacks).2360//2361// However, leave a possibility to downgrade to 4K, using2362// -XX:-Use64KPages.2363if (Use64KPages) {2364trcVerbose("64K page mode (faked for data segment)");2365Aix::_page_size = 64*K;2366} else {2367trcVerbose("4K page mode (Use64KPages=off)");2368Aix::_page_size = 4*K;2369}2370} else {2371// .. and not able to allocate 64k pages dynamically. Here, just2372// fall back to 4K paged mode and use mmap for everything.2373trcVerbose("4K page mode");2374Aix::_page_size = 4*K;2375FLAG_SET_ERGO(Use64KPages, false);2376}2377} else {2378// datapsize = 64k. Data segment, thread stacks are 64k paged.2379// This normally means that we can allocate 64k pages dynamically.2380// (There is one special case where this may be false: EXTSHM=on.2381// but we decided to not support that mode).2382assert0(g_multipage_support.can_use_64K_pages);2383Aix::_page_size = 64*K;2384trcVerbose("64K page mode");2385FLAG_SET_ERGO(Use64KPages, true);2386}23872388// For now UseLargePages is just ignored.2389FLAG_SET_ERGO(UseLargePages, false);2390_page_sizes.add(Aix::_page_size);23912392// debug trace2393trcVerbose("os::vm_page_size %s", describe_pagesize(os::vm_page_size()));23942395// Next, we need to initialize libo4 and libperfstat libraries.2396if (os::Aix::on_pase()) {2397os::Aix::initialize_libo4();2398} else {2399os::Aix::initialize_libperfstat();2400}24012402// Reset the perfstat information provided by ODM.2403if (os::Aix::on_aix()) {2404libperfstat::perfstat_reset();2405}24062407// Now initialze basic system properties. Note that for some of the values we2408// need libperfstat etc.2409os::Aix::initialize_system_info();24102411clock_tics_per_sec = sysconf(_SC_CLK_TCK);24122413// _main_thread points to the thread that created/loaded the JVM.2414Aix::_main_thread = pthread_self();24152416initial_time_count = javaTimeNanos();24172418os::Posix::init();2419}24202421// This is called _after_ the global arguments have been parsed.2422jint os::init_2(void) {24232424// This could be set after os::Posix::init() but all platforms2425// have to set it the same so we have to mirror Solaris.2426DEBUG_ONLY(os::set_mutex_init_done();)24272428os::Posix::init_2();24292430if (os::Aix::on_pase()) {2431trcVerbose("Running on PASE.");2432} else {2433trcVerbose("Running on AIX (not PASE).");2434}24352436trcVerbose("processor count: %d", os::_processor_count);2437trcVerbose("physical memory: %lu", Aix::_physical_memory);24382439// Initially build up the loaded dll map.2440LoadedLibraries::reload();2441if (Verbose) {2442trcVerbose("Loaded Libraries: ");2443LoadedLibraries::print(tty);2444}24452446if (PosixSignals::init() == JNI_ERR) {2447return JNI_ERR;2448}24492450// Check and sets minimum stack sizes against command line options2451if (Posix::set_minimum_stack_sizes() == JNI_ERR) {2452return JNI_ERR;2453}24542455// Not supported.2456FLAG_SET_ERGO(UseNUMA, false);2457FLAG_SET_ERGO(UseNUMAInterleaving, false);24582459if (MaxFDLimit) {2460// Set the number of file descriptors to max. print out error2461// if getrlimit/setrlimit fails but continue regardless.2462struct rlimit nbr_files;2463int status = getrlimit(RLIMIT_NOFILE, &nbr_files);2464if (status != 0) {2465log_info(os)("os::init_2 getrlimit failed: %s", os::strerror(errno));2466} else {2467nbr_files.rlim_cur = nbr_files.rlim_max;2468status = setrlimit(RLIMIT_NOFILE, &nbr_files);2469if (status != 0) {2470log_info(os)("os::init_2 setrlimit failed: %s", os::strerror(errno));2471}2472}2473}24742475if (PerfAllowAtExitRegistration) {2476// Only register atexit functions if PerfAllowAtExitRegistration is set.2477// At exit functions can be delayed until process exit time, which2478// can be problematic for embedded VM situations. Embedded VMs should2479// call DestroyJavaVM() to assure that VM resources are released.24802481// Note: perfMemory_exit_helper atexit function may be removed in2482// the future if the appropriate cleanup code can be added to the2483// VM_Exit VMOperation's doit method.2484if (atexit(perfMemory_exit_helper) != 0) {2485warning("os::init_2 atexit(perfMemory_exit_helper) failed");2486}2487}24882489// initialize thread priority policy2490prio_init();24912492return JNI_OK;2493}24942495int os::active_processor_count() {2496// User has overridden the number of active processors2497if (ActiveProcessorCount > 0) {2498log_trace(os)("active_processor_count: "2499"active processor count set by user : %d",2500ActiveProcessorCount);2501return ActiveProcessorCount;2502}25032504int online_cpus = ::sysconf(_SC_NPROCESSORS_ONLN);2505assert(online_cpus > 0 && online_cpus <= processor_count(), "sanity check");2506return online_cpus;2507}25082509void os::set_native_thread_name(const char *name) {2510// Not yet implemented.2511return;2512}25132514bool os::bind_to_processor(uint processor_id) {2515// Not yet implemented.2516return false;2517}25182519////////////////////////////////////////////////////////////////////////////////2520// debug support25212522bool os::find(address addr, outputStream* st) {25232524st->print(PTR_FORMAT ": ", addr);25252526loaded_module_t lm;2527if (LoadedLibraries::find_for_text_address(addr, &lm) != NULL ||2528LoadedLibraries::find_for_data_address(addr, &lm) != NULL) {2529st->print_cr("%s", lm.path);2530return true;2531}25322533return false;2534}25352536////////////////////////////////////////////////////////////////////////////////2537// misc25382539// This does not do anything on Aix. This is basically a hook for being2540// able to use structured exception handling (thread-local exception filters)2541// on, e.g., Win32.2542void2543os::os_exception_wrapper(java_call_t f, JavaValue* value, const methodHandle& method,2544JavaCallArguments* args, JavaThread* thread) {2545f(value, method, args, thread);2546}25472548void os::print_statistics() {2549}25502551bool os::message_box(const char* title, const char* message) {2552int i;2553fdStream err(defaultStream::error_fd());2554for (i = 0; i < 78; i++) err.print_raw("=");2555err.cr();2556err.print_raw_cr(title);2557for (i = 0; i < 78; i++) err.print_raw("-");2558err.cr();2559err.print_raw_cr(message);2560for (i = 0; i < 78; i++) err.print_raw("=");2561err.cr();25622563char buf[16];2564// Prevent process from exiting upon "read error" without consuming all CPU2565while (::read(0, buf, sizeof(buf)) <= 0) { ::sleep(100); }25662567return buf[0] == 'y' || buf[0] == 'Y';2568}25692570// Is a (classpath) directory empty?2571bool os::dir_is_empty(const char* path) {2572DIR *dir = NULL;2573struct dirent *ptr;25742575dir = opendir(path);2576if (dir == NULL) return true;25772578/* Scan the directory */2579bool result = true;2580while (result && (ptr = readdir(dir)) != NULL) {2581if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) {2582result = false;2583}2584}2585closedir(dir);2586return result;2587}25882589// This code originates from JDK's sysOpen and open64_w2590// from src/solaris/hpi/src/system_md.c25912592int os::open(const char *path, int oflag, int mode) {25932594if (strlen(path) > MAX_PATH - 1) {2595errno = ENAMETOOLONG;2596return -1;2597}2598// AIX 7.X now supports O_CLOEXEC too, like modern Linux; but we have to be careful, see2599// IV90804: OPENING A FILE IN AFS WITH O_CLOEXEC FAILS WITH AN EINVAL ERROR APPLIES TO AIX 7100-04 17/04/14 PTF PECHANGE2600int oflag_with_o_cloexec = oflag | O_CLOEXEC;26012602int fd = ::open64(path, oflag_with_o_cloexec, mode);2603if (fd == -1) {2604// we might fail in the open call when O_CLOEXEC is set, so try again without (see IV90804)2605fd = ::open64(path, oflag, mode);2606if (fd == -1) {2607return -1;2608}2609}26102611// If the open succeeded, the file might still be a directory.2612{2613struct stat64 buf64;2614int ret = ::fstat64(fd, &buf64);2615int st_mode = buf64.st_mode;26162617if (ret != -1) {2618if ((st_mode & S_IFMT) == S_IFDIR) {2619errno = EISDIR;2620::close(fd);2621return -1;2622}2623} else {2624::close(fd);2625return -1;2626}2627}26282629// All file descriptors that are opened in the JVM and not2630// specifically destined for a subprocess should have the2631// close-on-exec flag set. If we don't set it, then careless 3rd2632// party native code might fork and exec without closing all2633// appropriate file descriptors (e.g. as we do in closeDescriptors in2634// UNIXProcess.c), and this in turn might:2635//2636// - cause end-of-file to fail to be detected on some file2637// descriptors, resulting in mysterious hangs, or2638//2639// - might cause an fopen in the subprocess to fail on a system2640// suffering from bug 1085341.26412642// Validate that the use of the O_CLOEXEC flag on open above worked.2643static sig_atomic_t O_CLOEXEC_is_known_to_work = 0;2644if (O_CLOEXEC_is_known_to_work == 0) {2645int flags = ::fcntl(fd, F_GETFD);2646if (flags != -1) {2647if ((flags & FD_CLOEXEC) != 0) {2648O_CLOEXEC_is_known_to_work = 1;2649} else { // it does not work2650::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);2651O_CLOEXEC_is_known_to_work = -1;2652}2653}2654} else if (O_CLOEXEC_is_known_to_work == -1) {2655int flags = ::fcntl(fd, F_GETFD);2656if (flags != -1) {2657::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);2658}2659}26602661return fd;2662}26632664// create binary file, rewriting existing file if required2665int os::create_binary_file(const char* path, bool rewrite_existing) {2666int oflags = O_WRONLY | O_CREAT;2667if (!rewrite_existing) {2668oflags |= O_EXCL;2669}2670return ::open64(path, oflags, S_IREAD | S_IWRITE);2671}26722673// return current position of file pointer2674jlong os::current_file_offset(int fd) {2675return (jlong)::lseek64(fd, (off64_t)0, SEEK_CUR);2676}26772678// move file pointer to the specified offset2679jlong os::seek_to_file_offset(int fd, jlong offset) {2680return (jlong)::lseek64(fd, (off64_t)offset, SEEK_SET);2681}26822683// This code originates from JDK's sysAvailable2684// from src/solaris/hpi/src/native_threads/src/sys_api_td.c26852686int os::available(int fd, jlong *bytes) {2687jlong cur, end;2688int mode;2689struct stat64 buf64;26902691if (::fstat64(fd, &buf64) >= 0) {2692mode = buf64.st_mode;2693if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {2694int n;2695if (::ioctl(fd, FIONREAD, &n) >= 0) {2696*bytes = n;2697return 1;2698}2699}2700}2701if ((cur = ::lseek64(fd, 0L, SEEK_CUR)) == -1) {2702return 0;2703} else if ((end = ::lseek64(fd, 0L, SEEK_END)) == -1) {2704return 0;2705} else if (::lseek64(fd, cur, SEEK_SET) == -1) {2706return 0;2707}2708*bytes = end - cur;2709return 1;2710}27112712// Map a block of memory.2713char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,2714char *addr, size_t bytes, bool read_only,2715bool allow_exec) {2716int prot;2717int flags = MAP_PRIVATE;27182719if (read_only) {2720prot = PROT_READ;2721flags = MAP_SHARED;2722} else {2723prot = PROT_READ | PROT_WRITE;2724flags = MAP_PRIVATE;2725}27262727if (allow_exec) {2728prot |= PROT_EXEC;2729}27302731if (addr != NULL) {2732flags |= MAP_FIXED;2733}27342735// Allow anonymous mappings if 'fd' is -1.2736if (fd == -1) {2737flags |= MAP_ANONYMOUS;2738}27392740char* mapped_address = (char*)::mmap(addr, (size_t)bytes, prot, flags,2741fd, file_offset);2742if (mapped_address == MAP_FAILED) {2743return NULL;2744}2745return mapped_address;2746}27472748// Remap a block of memory.2749char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset,2750char *addr, size_t bytes, bool read_only,2751bool allow_exec) {2752// same as map_memory() on this OS2753return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only,2754allow_exec);2755}27562757// Unmap a block of memory.2758bool os::pd_unmap_memory(char* addr, size_t bytes) {2759return munmap(addr, bytes) == 0;2760}27612762// current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)2763// are used by JVM M&M and JVMTI to get user+sys or user CPU time2764// of a thread.2765//2766// current_thread_cpu_time() and thread_cpu_time(Thread*) returns2767// the fast estimate available on the platform.27682769jlong os::current_thread_cpu_time() {2770// return user + sys since the cost is the same2771const jlong n = os::thread_cpu_time(Thread::current(), true /* user + sys */);2772assert(n >= 0, "negative CPU time");2773return n;2774}27752776jlong os::thread_cpu_time(Thread* thread) {2777// consistent with what current_thread_cpu_time() returns2778const jlong n = os::thread_cpu_time(thread, true /* user + sys */);2779assert(n >= 0, "negative CPU time");2780return n;2781}27822783jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {2784const jlong n = os::thread_cpu_time(Thread::current(), user_sys_cpu_time);2785assert(n >= 0, "negative CPU time");2786return n;2787}27882789static bool thread_cpu_time_unchecked(Thread* thread, jlong* p_sys_time, jlong* p_user_time) {2790bool error = false;27912792jlong sys_time = 0;2793jlong user_time = 0;27942795// Reimplemented using getthrds64().2796//2797// Works like this:2798// For the thread in question, get the kernel thread id. Then get the2799// kernel thread statistics using that id.2800//2801// This only works of course when no pthread scheduling is used,2802// i.e. there is a 1:1 relationship to kernel threads.2803// On AIX, see AIXTHREAD_SCOPE variable.28042805pthread_t pthtid = thread->osthread()->pthread_id();28062807// retrieve kernel thread id for the pthread:2808tid64_t tid = 0;2809struct __pthrdsinfo pinfo;2810// I just love those otherworldly IBM APIs which force me to hand down2811// dummy buffers for stuff I dont care for...2812char dummy[1];2813int dummy_size = sizeof(dummy);2814if (pthread_getthrds_np(&pthtid, PTHRDSINFO_QUERY_TID, &pinfo, sizeof(pinfo),2815dummy, &dummy_size) == 0) {2816tid = pinfo.__pi_tid;2817} else {2818tty->print_cr("pthread_getthrds_np failed.");2819error = true;2820}28212822// retrieve kernel timing info for that kernel thread2823if (!error) {2824struct thrdentry64 thrdentry;2825if (getthrds64(getpid(), &thrdentry, sizeof(thrdentry), &tid, 1) == 1) {2826sys_time = thrdentry.ti_ru.ru_stime.tv_sec * 1000000000LL + thrdentry.ti_ru.ru_stime.tv_usec * 1000LL;2827user_time = thrdentry.ti_ru.ru_utime.tv_sec * 1000000000LL + thrdentry.ti_ru.ru_utime.tv_usec * 1000LL;2828} else {2829tty->print_cr("pthread_getthrds_np failed.");2830error = true;2831}2832}28332834if (p_sys_time) {2835*p_sys_time = sys_time;2836}28372838if (p_user_time) {2839*p_user_time = user_time;2840}28412842if (error) {2843return false;2844}28452846return true;2847}28482849jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {2850jlong sys_time;2851jlong user_time;28522853if (!thread_cpu_time_unchecked(thread, &sys_time, &user_time)) {2854return -1;2855}28562857return user_sys_cpu_time ? sys_time + user_time : user_time;2858}28592860void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {2861info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits2862info_ptr->may_skip_backward = false; // elapsed time not wall time2863info_ptr->may_skip_forward = false; // elapsed time not wall time2864info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned2865}28662867void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {2868info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits2869info_ptr->may_skip_backward = false; // elapsed time not wall time2870info_ptr->may_skip_forward = false; // elapsed time not wall time2871info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned2872}28732874bool os::is_thread_cpu_time_supported() {2875return true;2876}28772878// System loadavg support. Returns -1 if load average cannot be obtained.2879// For now just return the system wide load average (no processor sets).2880int os::loadavg(double values[], int nelem) {28812882guarantee(nelem >= 0 && nelem <= 3, "argument error");2883guarantee(values, "argument error");28842885if (os::Aix::on_pase()) {28862887// AS/400 PASE: use libo4 porting library2888double v[3] = { 0.0, 0.0, 0.0 };28892890if (libo4::get_load_avg(v, v + 1, v + 2)) {2891for (int i = 0; i < nelem; i ++) {2892values[i] = v[i];2893}2894return nelem;2895} else {2896return -1;2897}28982899} else {29002901// AIX: use libperfstat2902libperfstat::cpuinfo_t ci;2903if (libperfstat::get_cpuinfo(&ci)) {2904for (int i = 0; i < nelem; i++) {2905values[i] = ci.loadavg[i];2906}2907} else {2908return -1;2909}2910return nelem;2911}2912}29132914void os::pause() {2915char filename[MAX_PATH];2916if (PauseAtStartupFile && PauseAtStartupFile[0]) {2917jio_snprintf(filename, MAX_PATH, "%s", PauseAtStartupFile);2918} else {2919jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());2920}29212922int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);2923if (fd != -1) {2924struct stat buf;2925::close(fd);2926while (::stat(filename, &buf) == 0) {2927(void)::poll(NULL, 0, 100);2928}2929} else {2930trcVerbose("Could not open pause file '%s', continuing immediately.", filename);2931}2932}29332934bool os::is_primordial_thread(void) {2935if (pthread_self() == (pthread_t)1) {2936return true;2937} else {2938return false;2939}2940}29412942// OS recognitions (PASE/AIX, OS level) call this before calling any2943// one of Aix::on_pase(), Aix::os_version() static2944void os::Aix::initialize_os_info() {29452946assert(_on_pase == -1 && _os_version == 0, "already called.");29472948struct utsname uts;2949memset(&uts, 0, sizeof(uts));2950strcpy(uts.sysname, "?");2951if (::uname(&uts) == -1) {2952trcVerbose("uname failed (%d)", errno);2953guarantee(0, "Could not determine whether we run on AIX or PASE");2954} else {2955trcVerbose("uname says: sysname \"%s\" version \"%s\" release \"%s\" "2956"node \"%s\" machine \"%s\"\n",2957uts.sysname, uts.version, uts.release, uts.nodename, uts.machine);2958const int major = atoi(uts.version);2959assert(major > 0, "invalid OS version");2960const int minor = atoi(uts.release);2961assert(minor > 0, "invalid OS release");2962_os_version = (major << 24) | (minor << 16);2963char ver_str[20] = {0};2964const char* name_str = "unknown OS";2965if (strcmp(uts.sysname, "OS400") == 0) {2966// We run on AS/400 PASE. We do not support versions older than V5R4M0.2967_on_pase = 1;2968if (os_version_short() < 0x0504) {2969trcVerbose("OS/400 releases older than V5R4M0 not supported.");2970assert(false, "OS/400 release too old.");2971}2972name_str = "OS/400 (pase)";2973jio_snprintf(ver_str, sizeof(ver_str), "%u.%u", major, minor);2974} else if (strcmp(uts.sysname, "AIX") == 0) {2975// We run on AIX. We do not support versions older than AIX 7.1.2976_on_pase = 0;2977// Determine detailed AIX version: Version, Release, Modification, Fix Level.2978odmWrapper::determine_os_kernel_version(&_os_version);2979if (os_version_short() < 0x0701) {2980trcVerbose("AIX releases older than AIX 7.1 are not supported.");2981assert(false, "AIX release too old.");2982}2983name_str = "AIX";2984jio_snprintf(ver_str, sizeof(ver_str), "%u.%u.%u.%u",2985major, minor, (_os_version >> 8) & 0xFF, _os_version & 0xFF);2986} else {2987assert(false, "%s", name_str);2988}2989trcVerbose("We run on %s %s", name_str, ver_str);2990}29912992guarantee(_on_pase != -1 && _os_version, "Could not determine AIX/OS400 release");2993} // end: os::Aix::initialize_os_info()29942995// Scan environment for important settings which might effect the VM.2996// Trace out settings. Warn about invalid settings and/or correct them.2997//2998// Must run after os::Aix::initialue_os_info().2999void os::Aix::scan_environment() {30003001char* p;3002int rc;30033004// Warn explicity if EXTSHM=ON is used. That switch changes how3005// System V shared memory behaves. One effect is that page size of3006// shared memory cannot be change dynamically, effectivly preventing3007// large pages from working.3008// This switch was needed on AIX 32bit, but on AIX 64bit the general3009// recommendation is (in OSS notes) to switch it off.3010p = ::getenv("EXTSHM");3011trcVerbose("EXTSHM=%s.", p ? p : "<unset>");3012if (p && strcasecmp(p, "ON") == 0) {3013_extshm = 1;3014trcVerbose("*** Unsupported mode! Please remove EXTSHM from your environment! ***");3015if (!AllowExtshm) {3016// We allow under certain conditions the user to continue. However, we want this3017// to be a fatal error by default. On certain AIX systems, leaving EXTSHM=ON means3018// that the VM is not able to allocate 64k pages for the heap.3019// We do not want to run with reduced performance.3020vm_exit_during_initialization("EXTSHM is ON. Please remove EXTSHM from your environment.");3021}3022} else {3023_extshm = 0;3024}30253026// SPEC1170 behaviour: will change the behaviour of a number of POSIX APIs.3027// Not tested, not supported.3028//3029// Note that it might be worth the trouble to test and to require it, if only to3030// get useful return codes for mprotect.3031//3032// Note: Setting XPG_SUS_ENV in the process is too late. Must be set earlier (before3033// exec() ? before loading the libjvm ? ....)3034p = ::getenv("XPG_SUS_ENV");3035trcVerbose("XPG_SUS_ENV=%s.", p ? p : "<unset>");3036if (p && strcmp(p, "ON") == 0) {3037_xpg_sus_mode = 1;3038trcVerbose("Unsupported setting: XPG_SUS_ENV=ON");3039// This is not supported. Worst of all, it changes behaviour of mmap MAP_FIXED to3040// clobber address ranges. If we ever want to support that, we have to do some3041// testing first.3042guarantee(false, "XPG_SUS_ENV=ON not supported");3043} else {3044_xpg_sus_mode = 0;3045}30463047if (os::Aix::on_pase()) {3048p = ::getenv("QIBM_MULTI_THREADED");3049trcVerbose("QIBM_MULTI_THREADED=%s.", p ? p : "<unset>");3050}30513052p = ::getenv("LDR_CNTRL");3053trcVerbose("LDR_CNTRL=%s.", p ? p : "<unset>");3054if (os::Aix::on_pase() && os::Aix::os_version_short() == 0x0701) {3055if (p && ::strstr(p, "TEXTPSIZE")) {3056trcVerbose("*** WARNING - LDR_CNTRL contains TEXTPSIZE. "3057"you may experience hangs or crashes on OS/400 V7R1.");3058}3059}30603061p = ::getenv("AIXTHREAD_GUARDPAGES");3062trcVerbose("AIXTHREAD_GUARDPAGES=%s.", p ? p : "<unset>");30633064} // end: os::Aix::scan_environment()30653066// PASE: initialize the libo4 library (PASE porting library).3067void os::Aix::initialize_libo4() {3068guarantee(os::Aix::on_pase(), "OS/400 only.");3069if (!libo4::init()) {3070trcVerbose("libo4 initialization failed.");3071assert(false, "libo4 initialization failed");3072} else {3073trcVerbose("libo4 initialized.");3074}3075}30763077// AIX: initialize the libperfstat library.3078void os::Aix::initialize_libperfstat() {3079assert(os::Aix::on_aix(), "AIX only");3080if (!libperfstat::init()) {3081trcVerbose("libperfstat initialization failed.");3082assert(false, "libperfstat initialization failed");3083} else {3084trcVerbose("libperfstat initialized.");3085}3086}30873088/////////////////////////////////////////////////////////////////////////////3089// thread stack30903091// Get the current stack base from the OS (actually, the pthread library).3092// Note: usually not page aligned.3093address os::current_stack_base() {3094AixMisc::stackbounds_t bounds;3095bool rc = AixMisc::query_stack_bounds_for_current_thread(&bounds);3096guarantee(rc, "Unable to retrieve stack bounds.");3097return bounds.base;3098}30993100// Get the current stack size from the OS (actually, the pthread library).3101// Returned size is such that (base - size) is always aligned to page size.3102size_t os::current_stack_size() {3103AixMisc::stackbounds_t bounds;3104bool rc = AixMisc::query_stack_bounds_for_current_thread(&bounds);3105guarantee(rc, "Unable to retrieve stack bounds.");3106// Align the returned stack size such that the stack low address3107// is aligned to page size (Note: base is usually not and we do not care).3108// We need to do this because caller code will assume stack low address is3109// page aligned and will place guard pages without checking.3110address low = bounds.base - bounds.size;3111address low_aligned = (address)align_up(low, os::vm_page_size());3112size_t s = bounds.base - low_aligned;3113return s;3114}31153116// Get the default path to the core file3117// Returns the length of the string3118int os::get_core_path(char* buffer, size_t bufferSize) {3119const char* p = get_current_directory(buffer, bufferSize);31203121if (p == NULL) {3122assert(p != NULL, "failed to get current directory");3123return 0;3124}31253126jio_snprintf(buffer, bufferSize, "%s/core or core.%d",3127p, current_process_id());31283129return strlen(buffer);3130}31313132bool os::start_debugging(char *buf, int buflen) {3133int len = (int)strlen(buf);3134char *p = &buf[len];31353136jio_snprintf(p, buflen -len,3137"\n\n"3138"Do you want to debug the problem?\n\n"3139"To debug, run 'dbx -a %d'; then switch to thread tid " INTX_FORMAT ", k-tid " INTX_FORMAT "\n"3140"Enter 'yes' to launch dbx automatically (PATH must include dbx)\n"3141"Otherwise, press RETURN to abort...",3142os::current_process_id(),3143os::current_thread_id(), thread_self());31443145bool yes = os::message_box("Unexpected Error", buf);31463147if (yes) {3148// yes, user asked VM to launch debugger3149jio_snprintf(buf, buflen, "dbx -a %d", os::current_process_id());31503151os::fork_and_exec(buf);3152yes = false;3153}3154return yes;3155}31563157static inline time_t get_mtime(const char* filename) {3158struct stat st;3159int ret = os::stat(filename, &st);3160assert(ret == 0, "failed to stat() file '%s': %s", filename, os::strerror(errno));3161return st.st_mtime;3162}31633164int os::compare_file_modified_times(const char* file1, const char* file2) {3165time_t t1 = get_mtime(file1);3166time_t t2 = get_mtime(file2);3167return t1 - t2;3168}31693170bool os::supports_map_sync() {3171return false;3172}31733174void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) {}317531763177