< prev index next >

src/os/aix/vm/os_aix.cpp

Print this page
rev 9449 : 8143125-Further Developments for AIX

*** 34,43 **** --- 34,44 ---- #include "code/icBuffer.hpp" #include "code/vtableStubs.hpp" #include "compiler/compileBroker.hpp" #include "interpreter/interpreter.hpp" #include "jvm_aix.h" + #include "libo4.hpp" #include "libperfstat_aix.hpp" #include "loadlib_aix.hpp" #include "memory/allocation.inline.hpp" #include "memory/filemap.hpp" #include "misc_aix.hpp"
*** 71,80 **** --- 72,82 ---- #include "runtime/vm_version.hpp" #include "services/attachListener.hpp" #include "services/runtimeService.hpp" #include "utilities/decoder.hpp" #include "utilities/defaultStream.hpp" + #define PV_8_Compat 0x308000 /* Power PC 8 */ #include "utilities/events.hpp" #include "utilities/growableArray.hpp" #include "utilities/vmError.hpp" // put OS-includes here (sorted alphabetically)
*** 106,134 **** #include <sys/types.h> #include <sys/utsname.h> #include <sys/vminfo.h> #include <sys/wait.h> ! // If RUSAGE_THREAD for getrusage() has not been defined, do it here. The code calling ! // getrusage() is prepared to handle the associated failure. ! #ifndef RUSAGE_THREAD ! #define RUSAGE_THREAD (1) /* only the calling thread */ ! #endif ! ! // PPC port ! static const uintx Use64KPagesThreshold = 1*M; ! static const uintx MaxExpectedDataSegmentSize = SIZE_4G*2; - // Add missing declarations (should be in procinfo.h but isn't until AIX 6.1). #if !defined(_AIXVERSION_610) ! extern "C" { ! int getthrds64(pid_t ProcessIdentifier, ! struct thrdentry64* ThreadBuffer, ! int ThreadSize, ! tid64_t* IndexPointer, ! int Count); ! } #endif #define MAX_PATH (2 * K) // for timer info max values which include all bits --- 108,125 ---- #include <sys/types.h> #include <sys/utsname.h> #include <sys/vminfo.h> #include <sys/wait.h> ! // Missing prototypes for various system APIs. ! extern "C" ! int mread_real_time(timebasestruct_t *t, size_t size_of_timebasestruct_t); #if !defined(_AIXVERSION_610) ! extern "C" int getthrds64(pid_t, struct thrdentry64*, int, tid64_t*, int); ! extern "C" int getprocs64(procentry64*, int, fdsinfo*, int, pid_t*, int); ! extern "C" int getargs (procsinfo*, int, char*, int); #endif #define MAX_PATH (2 * K) // for timer info max values which include all bits
*** 148,169 **** // Typedefs for stackslots, stack pointers, pointers to op codes. typedef unsigned long stackslot_t; typedef stackslot_t* stackptr_t; - // Excerpts from systemcfg.h definitions newer than AIX 5.3. - #ifndef PV_7 - #define PV_7 0x200000 /* Power PC 7 */ - #define PV_7_Compat 0x208000 /* Power PC 7 */ - #endif - #ifndef PV_8 - #define PV_8 0x300000 /* Power PC 8 */ - #define PV_8_Compat 0x308000 /* Power PC 8 */ - #endif - // Query dimensions of the stack of the calling thread. static bool query_stack_dimensions(address* p_stack_base, size_t* p_stack_size); // Function to check a given stack pointer against given stack limits. inline bool is_valid_stackpointer(stackptr_t sp, stackptr_t stack_base, size_t stack_size) { if (((uintptr_t)sp) & 0x7) { return false; --- 139,151 ---- // Typedefs for stackslots, stack pointers, pointers to op codes. typedef unsigned long stackslot_t; typedef stackslot_t* stackptr_t; // Query dimensions of the stack of the calling thread. static bool query_stack_dimensions(address* p_stack_base, size_t* p_stack_size); + static address resolve_function_descriptor_to_code_pointer(address p); // Function to check a given stack pointer against given stack limits. inline bool is_valid_stackpointer(stackptr_t sp, stackptr_t stack_base, size_t stack_size) { if (((uintptr_t)sp) & 0x7) { return false;
*** 183,193 **** return false; } if (((uintptr_t)p) & 0x3) { return false; } ! if (!LoadedLibraries::find_for_text_address(p, NULL)) { return false; } return true; } --- 165,175 ---- return false; } if (((uintptr_t)p) & 0x3) { return false; } ! if (LoadedLibraries::find_for_text_address(p, NULL) == NULL) { return false; } return true; }
*** 201,235 **** address sp; \ sp = os::current_stack_pointer(); \ CHECK_STACK_PTR(sp, stack_base, stack_size); \ } //////////////////////////////////////////////////////////////////////////////// // global variables (for a description see os_aix.hpp) julong os::Aix::_physical_memory = 0; pthread_t os::Aix::_main_thread = ((pthread_t)0); int os::Aix::_page_size = -1; int os::Aix::_on_pase = -1; int os::Aix::_os_version = -1; int os::Aix::_stack_page_size = -1; int os::Aix::_xpg_sus_mode = -1; int os::Aix::_extshm = -1; - int os::Aix::_logical_cpus = -1; //////////////////////////////////////////////////////////////////////////////// // local variables - static int g_multipage_error = -1; // error analysis for multipage initialization static jlong initial_time_count = 0; static int clock_tics_per_sec = 100; static sigset_t check_signal_done; // For diagnostics to print a message once (see run_periodic_checks) static bool check_signals = true; - static pid_t _initial_pid = 0; static int SR_signum = SIGUSR2; // Signal used to suspend/resume a thread (must be > SIGSEGV, see 4355769) static sigset_t SR_sigset; // This describes the state of multipage support of the underlying // OS. Note that this is of no interest to the outsize world and // therefore should not be defined in AIX class. // // AIX supports four different page sizes - 4K, 64K, 16MB, 16GB. The --- 183,230 ---- address sp; \ sp = os::current_stack_pointer(); \ CHECK_STACK_PTR(sp, stack_base, stack_size); \ } + static void vmembk_print_on(outputStream* os); + //////////////////////////////////////////////////////////////////////////////// // global variables (for a description see os_aix.hpp) julong os::Aix::_physical_memory = 0; + pthread_t os::Aix::_main_thread = ((pthread_t)0); int os::Aix::_page_size = -1; + + // -1 = uninitialized, 0 if AIX, 1 if OS/400 pase int os::Aix::_on_pase = -1; + + // -1 = uninitialized, otherwise os version in the form 0xMMmm - MM:major, mm:minor + // E.g. 0x0601 for AIX 6.1 or 0x0504 for OS/400 V5R4 int os::Aix::_os_version = -1; + int os::Aix::_stack_page_size = -1; + + // -1 = uninitialized, 0 - no, 1 - yes int os::Aix::_xpg_sus_mode = -1; + + // -1 = uninitialized, 0 - no, 1 - yes int os::Aix::_extshm = -1; //////////////////////////////////////////////////////////////////////////////// // local variables static jlong initial_time_count = 0; static int clock_tics_per_sec = 100; static sigset_t check_signal_done; // For diagnostics to print a message once (see run_periodic_checks) static bool check_signals = true; static int SR_signum = SIGUSR2; // Signal used to suspend/resume a thread (must be > SIGSEGV, see 4355769) static sigset_t SR_sigset; + // Process break recorded at startup. + static address g_brk_at_startup = NULL; + // This describes the state of multipage support of the underlying // OS. Note that this is of no interest to the outsize world and // therefore should not be defined in AIX class. // // AIX supports four different page sizes - 4K, 64K, 16MB, 16GB. The
*** 276,302 **** // growing which may result in a malloc OOM even though there is // enough memory. The problem only arises if we shmat() or mmap() at // a specific wish address, e.g. to place the heap in a // compressed-oops-friendly way. static bool is_close_to_brk(address a) { ! address a1 = (address) sbrk(0); ! if (a >= a1 && a < (a1 + MaxExpectedDataSegmentSize)) { return true; } return false; } julong os::available_memory() { return Aix::available_memory(); } julong os::Aix::available_memory() { os::Aix::meminfo_t mi; if (os::Aix::get_meminfo(&mi)) { return mi.real_free; } else { ! return 0xFFFFFFFFFFFFFFFFLL; } } julong os::physical_memory() { return Aix::physical_memory(); --- 271,302 ---- // growing which may result in a malloc OOM even though there is // enough memory. The problem only arises if we shmat() or mmap() at // a specific wish address, e.g. to place the heap in a // compressed-oops-friendly way. static bool is_close_to_brk(address a) { ! assert0(g_brk_at_startup != NULL); ! if (a >= g_brk_at_startup && ! a < (g_brk_at_startup + MaxExpectedDataSegmentSize)) { return true; } return false; } julong os::available_memory() { return Aix::available_memory(); } julong os::Aix::available_memory() { + // Avoid expensive API call here, as returned value will always be null. + if (os::Aix::on_pase()) { + return 0x0LL; + } os::Aix::meminfo_t mi; if (os::Aix::get_meminfo(&mi)) { return mi.real_free; } else { ! return ULONG_MAX; } } julong os::physical_memory() { return Aix::physical_memory();
*** 330,348 **** char* p = addr; for (int i = 0; i < numFullDisclaimsNeeded; i ++) { if (::disclaim(p, maxDisclaimSize, DISCLAIM_ZEROMEM) != 0) { ! trc("Cannot disclaim %p - %p (errno %d)\n", p, p + maxDisclaimSize, errno); return false; } p += maxDisclaimSize; } if (lastDisclaimSize > 0) { if (::disclaim(p, lastDisclaimSize, DISCLAIM_ZEROMEM) != 0) { ! trc("Cannot disclaim %p - %p (errno %d)\n", p, p + lastDisclaimSize, errno); return false; } } return true; --- 330,348 ---- char* p = addr; for (int i = 0; i < numFullDisclaimsNeeded; i ++) { if (::disclaim(p, maxDisclaimSize, DISCLAIM_ZEROMEM) != 0) { ! trcVerbose("Cannot disclaim %p - %p (errno %d)\n", p, p + maxDisclaimSize, errno); return false; } p += maxDisclaimSize; } if (lastDisclaimSize > 0) { if (::disclaim(p, lastDisclaimSize, DISCLAIM_ZEROMEM) != 0) { ! trcVerbose("Cannot disclaim %p - %p (errno %d)\n", p, p + lastDisclaimSize, errno); return false; } } return true;
*** 355,383 **** static char cpu_arch[] = "ppc64"; #else #error Add appropriate cpu_arch setting #endif // Given an address, returns the size of the page backing that address. size_t os::Aix::query_pagesize(void* addr) { vm_page_info pi; pi.addr = (uint64_t)addr; ! if (::vmgetinfo(&pi, VM_PAGE_INFO, sizeof(pi)) == 0) { return pi.pagesize; } else { - fprintf(stderr, "vmgetinfo failed to retrieve page size for address %p (errno %d).\n", addr, errno); assert(false, "vmgetinfo failed to retrieve page size"); return SIZE_4K; } - - } - - // Returns the kernel thread id of the currently running thread. - pid_t os::Aix::gettid() { - return (pid_t) thread_self(); } void os::Aix::initialize_system_info() { // Get the number of online(logical) cpus instead of configured. --- 355,388 ---- static char cpu_arch[] = "ppc64"; #else #error Add appropriate cpu_arch setting #endif + // Wrap the function "vmgetinfo" which is not available on older OS releases. + static int checked_vmgetinfo(void *out, int command, int arg) { + if (os::Aix::on_pase() && os::Aix::os_version() < 0x0601) { + guarantee(false, "cannot call vmgetinfo on AS/400 older than V6R1"); + } + return ::vmgetinfo(out, command, arg); + } // Given an address, returns the size of the page backing that address. size_t os::Aix::query_pagesize(void* addr) { + if (os::Aix::on_pase() && os::Aix::os_version() < 0x0601) { + // AS/400 older than V6R1: no vmgetinfo here, default to 4K + return SIZE_4K; + } + vm_page_info pi; pi.addr = (uint64_t)addr; ! if (checked_vmgetinfo(&pi, VM_PAGE_INFO, sizeof(pi)) == 0) { return pi.pagesize; } else { assert(false, "vmgetinfo failed to retrieve page size"); return SIZE_4K; } } void os::Aix::initialize_system_info() { // Get the number of online(logical) cpus instead of configured.
*** 385,395 **** assert(_processor_count > 0, "_processor_count must be > 0"); // Retrieve total physical storage. os::Aix::meminfo_t mi; if (!os::Aix::get_meminfo(&mi)) { - fprintf(stderr, "os::Aix::get_meminfo failed.\n"); fflush(stderr); assert(false, "os::Aix::get_meminfo failed."); } _physical_memory = (julong) mi.real_total; } --- 390,399 ----
*** 398,408 **** switch (pagesize) { case SIZE_4K : return "4K"; case SIZE_64K: return "64K"; case SIZE_16M: return "16M"; case SIZE_16G: return "16G"; - case -1: return "not set"; default: assert(false, "surprise"); return "??"; } } --- 402,411 ----
*** 429,438 **** --- 432,443 ---- g_multipage_support.datapsize = os::Aix::query_pagesize(p); ::free(p); } // Query default shm page size (LDR_CNTRL SHMPSIZE). + // Note that this is pure curiosity. We do not rely on default page size but set + // our own page size after allocated. { const int shmid = ::shmget(IPC_PRIVATE, 1, IPC_CREAT | S_IRUSR | S_IWUSR); guarantee(shmid != -1, "shmget failed"); void* p = ::shmat(shmid, NULL, 0); ::shmctl(shmid, IPC_RMID, NULL);
*** 445,485 **** // thread (because primordial thread's stack may have different page size than // pthread thread stacks). Running a VM on the primordial thread won't work for a // number of reasons so we may just as well guarantee it here. guarantee0(!os::Aix::is_primordial_thread()); ! // Query pthread stack page size. { int dummy = 0; g_multipage_support.pthr_stack_pagesize = os::Aix::query_pagesize(&dummy); } // Query default text page size (LDR_CNTRL TEXTPSIZE). - /* PPC port: so far unused. { address any_function = ! (address) resolve_function_descriptor_to_code_pointer((address)describe_pagesize); g_multipage_support.textpsize = os::Aix::query_pagesize(any_function); } - */ // Now probe for support of 64K pages and 16M pages. // Before OS/400 V6R1, there is no support for pages other than 4K. if (os::Aix::on_pase_V5R4_or_older()) { ! Unimplemented(); goto query_multipage_support_end; } // Now check which page sizes the OS claims it supports, and of those, which actually can be used. { const int MAX_PAGE_SIZES = 4; psize_t sizes[MAX_PAGE_SIZES]; ! const int num_psizes = ::vmgetinfo(sizes, VMINFO_GETPSIZES, MAX_PAGE_SIZES); if (num_psizes == -1) { ! trc("vmgetinfo(VMINFO_GETPSIZES) failed (errno: %d)\n", errno); ! trc("disabling multipage support.\n"); g_multipage_support.error = ERROR_MP_VMGETINFO_FAILED; goto query_multipage_support_end; } guarantee(num_psizes > 0, "vmgetinfo(.., VMINFO_GETPSIZES, ...) failed."); assert(num_psizes <= MAX_PAGE_SIZES, "Surprise! more than 4 page sizes?"); --- 450,490 ---- // thread (because primordial thread's stack may have different page size than // pthread thread stacks). Running a VM on the primordial thread won't work for a // number of reasons so we may just as well guarantee it here. guarantee0(!os::Aix::is_primordial_thread()); ! // Query pthread stack page size. Should be the same as data page size because ! // pthread stacks are allocated from C-Heap. { int dummy = 0; g_multipage_support.pthr_stack_pagesize = os::Aix::query_pagesize(&dummy); } // Query default text page size (LDR_CNTRL TEXTPSIZE). { address any_function = ! resolve_function_descriptor_to_code_pointer((address)describe_pagesize); g_multipage_support.textpsize = os::Aix::query_pagesize(any_function); } // Now probe for support of 64K pages and 16M pages. // Before OS/400 V6R1, there is no support for pages other than 4K. if (os::Aix::on_pase_V5R4_or_older()) { ! trcVerbose("OS/400 < V6R1 - no large page support."); ! g_multipage_support.error = ERROR_MP_OS_TOO_OLD; goto query_multipage_support_end; } // Now check which page sizes the OS claims it supports, and of those, which actually can be used. { const int MAX_PAGE_SIZES = 4; psize_t sizes[MAX_PAGE_SIZES]; ! const int num_psizes = checked_vmgetinfo(sizes, VMINFO_GETPSIZES, MAX_PAGE_SIZES); if (num_psizes == -1) { ! trcVerbose("vmgetinfo(VMINFO_GETPSIZES) failed (errno: %d)", errno); ! trcVerbose("disabling multipage support."); g_multipage_support.error = ERROR_MP_VMGETINFO_FAILED; goto query_multipage_support_end; } guarantee(num_psizes > 0, "vmgetinfo(.., VMINFO_GETPSIZES, ...) failed."); assert(num_psizes <= MAX_PAGE_SIZES, "Surprise! more than 4 page sizes?");
*** 503,514 **** struct shmid_ds shm_buf = { 0 }; shm_buf.shm_pagesize = pagesize; if (::shmctl(shmid, SHM_PAGESIZE, &shm_buf) != 0) { const int en = errno; ::shmctl(shmid, IPC_RMID, NULL); // As early as possible! ! // PPC port trcVerbose("shmctl(SHM_PAGESIZE) failed with %s", ! // PPC port MiscUtils::describe_errno(en)); } else { // Attach and double check pageisze. void* p = ::shmat(shmid, NULL, 0); ::shmctl(shmid, IPC_RMID, NULL); // As early as possible! guarantee0(p != (void*) -1); // Should always work. --- 508,519 ---- struct shmid_ds shm_buf = { 0 }; shm_buf.shm_pagesize = pagesize; if (::shmctl(shmid, SHM_PAGESIZE, &shm_buf) != 0) { const int en = errno; ::shmctl(shmid, IPC_RMID, NULL); // As early as possible! ! trcVerbose("shmctl(SHM_PAGESIZE) failed with %s", ! MiscUtils::describe_errno(en)); } else { // Attach and double check pageisze. void* p = ::shmat(shmid, NULL, 0); ::shmctl(shmid, IPC_RMID, NULL); // As early as possible! guarantee0(p != (void*) -1); // Should always work.
*** 530,568 **** } // end: check which pages can be used for shared memory query_multipage_support_end: ! trcVerbose("base page size (sysconf _SC_PAGESIZE): %s\n", describe_pagesize(g_multipage_support.pagesize)); ! trcVerbose("Data page size (C-Heap, bss, etc): %s\n", describe_pagesize(g_multipage_support.datapsize)); ! trcVerbose("Text page size: %s\n", describe_pagesize(g_multipage_support.textpsize)); ! trcVerbose("Thread stack page size (pthread): %s\n", describe_pagesize(g_multipage_support.pthr_stack_pagesize)); ! trcVerbose("Default shared memory page size: %s\n", describe_pagesize(g_multipage_support.shmpsize)); ! trcVerbose("Can use 64K pages dynamically with shared meory: %s\n", (g_multipage_support.can_use_64K_pages ? "yes" :"no")); ! trcVerbose("Can use 16M pages dynamically with shared memory: %s\n", (g_multipage_support.can_use_16M_pages ? "yes" :"no")); ! trcVerbose("Multipage error details: %d\n", g_multipage_support.error); // sanity checks assert0(g_multipage_support.pagesize == SIZE_4K); assert0(g_multipage_support.datapsize == SIZE_4K || g_multipage_support.datapsize == SIZE_64K); ! // PPC port: so far unused.assert0(g_multipage_support.textpsize == SIZE_4K || g_multipage_support.textpsize == SIZE_64K); assert0(g_multipage_support.pthr_stack_pagesize == g_multipage_support.datapsize); assert0(g_multipage_support.shmpsize == SIZE_4K || g_multipage_support.shmpsize == SIZE_64K); ! } // end os::Aix::query_multipage_support() void os::init_system_properties_values() { ! #define DEFAULT_LIBPATH "/usr/lib:/lib" #define EXTENSIONS_DIR "/lib/ext" // Buffer that fits several sprintfs. // Note that the space for the trailing null is provided // by the nulls included by the sizeof operator. --- 535,573 ---- } // end: check which pages can be used for shared memory query_multipage_support_end: ! trcVerbose("base page size (sysconf _SC_PAGESIZE): %s", describe_pagesize(g_multipage_support.pagesize)); ! trcVerbose("Data page size (C-Heap, bss, etc): %s", describe_pagesize(g_multipage_support.datapsize)); ! trcVerbose("Text page size: %s", describe_pagesize(g_multipage_support.textpsize)); ! trcVerbose("Thread stack page size (pthread): %s", describe_pagesize(g_multipage_support.pthr_stack_pagesize)); ! trcVerbose("Default shared memory page size: %s", describe_pagesize(g_multipage_support.shmpsize)); ! trcVerbose("Can use 64K pages dynamically with shared meory: %s", (g_multipage_support.can_use_64K_pages ? "yes" :"no")); ! trcVerbose("Can use 16M pages dynamically with shared memory: %s", (g_multipage_support.can_use_16M_pages ? "yes" :"no")); ! trcVerbose("Multipage error details: %d", g_multipage_support.error); // sanity checks assert0(g_multipage_support.pagesize == SIZE_4K); assert0(g_multipage_support.datapsize == SIZE_4K || g_multipage_support.datapsize == SIZE_64K); ! assert0(g_multipage_support.textpsize == SIZE_4K || g_multipage_support.textpsize == SIZE_64K); assert0(g_multipage_support.pthr_stack_pagesize == g_multipage_support.datapsize); assert0(g_multipage_support.shmpsize == SIZE_4K || g_multipage_support.shmpsize == SIZE_64K); ! } void os::init_system_properties_values() { ! #define DEFAULT_LIBPATH "/lib:/usr/lib" #define EXTENSIONS_DIR "/lib/ext" // Buffer that fits several sprintfs. // Note that the space for the trailing null is provided // by the nulls included by the sizeof operator.
*** 576,586 **** char *pslash; os::jvm_path(buf, bufsize); // Found the full path to libjvm.so. // Now cut the path to <java_home>/jre if we can. ! *(strrchr(buf, '/')) = '\0'; // Get rid of /libjvm.so. pslash = strrchr(buf, '/'); if (pslash != NULL) { *pslash = '\0'; // Get rid of /{client|server|hotspot}. } Arguments::set_dll_dir(buf); --- 581,594 ---- char *pslash; os::jvm_path(buf, bufsize); // Found the full path to libjvm.so. // Now cut the path to <java_home>/jre if we can. ! pslash = strrchr(buf, '/'); ! if (pslash != NULL) { ! *pslash = '\0'; // Get rid of /libjvm.so. ! } pslash = strrchr(buf, '/'); if (pslash != NULL) { *pslash = '\0'; // Get rid of /{client|server|hotspot}. } Arguments::set_dll_dir(buf);
*** 751,762 **** assert(pmi, "get_meminfo: invalid parameter"); memset(pmi, 0, sizeof(meminfo_t)); if (os::Aix::on_pase()) { ! Unimplemented(); return false; } else { // On AIX, I use the (dynamically loaded) perfstat library to retrieve memory statistics --- 759,783 ---- assert(pmi, "get_meminfo: invalid parameter"); memset(pmi, 0, sizeof(meminfo_t)); if (os::Aix::on_pase()) { + // On PASE, use the libo4 porting library. ! unsigned long long virt_total = 0; ! unsigned long long real_total = 0; ! unsigned long long real_free = 0; ! unsigned long long pgsp_total = 0; ! unsigned long long pgsp_free = 0; ! if (libo4::get_memory_info(&virt_total, &real_total, &real_free, &pgsp_total, &pgsp_free)) { ! pmi->virt_total = virt_total; ! pmi->real_total = real_total; ! pmi->real_free = real_free; ! pmi->pgsp_total = pgsp_total; ! pmi->pgsp_free = pgsp_free; ! return true; ! } return false; } else { // On AIX, I use the (dynamically loaded) perfstat library to retrieve memory statistics
*** 796,880 **** return true; } } // end os::Aix::get_meminfo - // Retrieve global cpu information. - // Returns false if something went wrong; - // the content of pci is undefined in this case. - bool os::Aix::get_cpuinfo(cpuinfo_t* pci) { - assert(pci, "get_cpuinfo: invalid parameter"); - memset(pci, 0, sizeof(cpuinfo_t)); - - perfstat_cpu_total_t psct; - memset (&psct, '\0', sizeof(psct)); - - if (-1 == libperfstat::perfstat_cpu_total(NULL, &psct, sizeof(perfstat_cpu_total_t), 1)) { - fprintf(stderr, "perfstat_cpu_total() failed (errno=%d)\n", errno); - assert(0, "perfstat_cpu_total() failed"); - return false; - } - - // global cpu information - strcpy (pci->description, psct.description); - pci->processorHZ = psct.processorHZ; - pci->ncpus = psct.ncpus; - os::Aix::_logical_cpus = psct.ncpus; - for (int i = 0; i < 3; i++) { - pci->loadavg[i] = (double) psct.loadavg[i] / (1 << SBITS); - } - - // get the processor version from _system_configuration - switch (_system_configuration.version) { - case PV_8: - strcpy(pci->version, "Power PC 8"); - break; - case PV_7: - strcpy(pci->version, "Power PC 7"); - break; - case PV_6_1: - strcpy(pci->version, "Power PC 6 DD1.x"); - break; - case PV_6: - strcpy(pci->version, "Power PC 6"); - break; - case PV_5: - strcpy(pci->version, "Power PC 5"); - break; - case PV_5_2: - strcpy(pci->version, "Power PC 5_2"); - break; - case PV_5_3: - strcpy(pci->version, "Power PC 5_3"); - break; - case PV_5_Compat: - strcpy(pci->version, "PV_5_Compat"); - break; - case PV_6_Compat: - strcpy(pci->version, "PV_6_Compat"); - break; - case PV_7_Compat: - strcpy(pci->version, "PV_7_Compat"); - break; - case PV_8_Compat: - strcpy(pci->version, "PV_8_Compat"); - break; - default: - strcpy(pci->version, "unknown"); - } - - return true; - - } //end os::Aix::get_cpuinfo - - ////////////////////////////////////////////////////////////////////////////// - // detecting pthread library - - void os::Aix::libpthread_init() { - return; - } - ////////////////////////////////////////////////////////////////////////////// // create new thread // Thread start routine for all newly created threads static void *java_start(Thread *thread) { --- 817,826 ----
*** 887,896 **** --- 833,862 ---- query_stack_dimensions(&base, &size); thread->set_stack_base(base); thread->set_stack_size(size); } + const pthread_t pthread_id = ::pthread_self(); + const tid_t kernel_thread_id = ::thread_self(); + + trcVerbose("newborn Thread : pthread-id %u, ktid " UINT64_FORMAT + ", stack %p ... %p, stacksize 0x%IX (%IB)", + pthread_id, kernel_thread_id, + thread->stack_base() - thread->stack_size(), + thread->stack_base(), + thread->stack_size(), + thread->stack_size()); + + // Normally, pthread stacks on AIX live in the data segment (are allocated with malloc() + // by the pthread library). In rare cases, this may not be the case, e.g. when third-party + // tools hook pthread_create(). In this case, we may run into problems establishing + // guard pages on those stacks, because the stacks may reside in memory which is not + // protectable (shmated). + if (thread->stack_base() > ::sbrk(0)) { + fprintf(stderr, "Thread " UINT64_FORMAT ": stack not in data segment.", (uint64_t) pthread_id); + } + // Do some sanity checks. CHECK_CURRENT_STACK_PTR(thread->stack_base(), thread->stack_size()); // Try to randomize the cache line index of hot stack frames. // This helps when threads of the same stack traces evict each other's
*** 904,935 **** ThreadLocalStorage::set_thread(thread); OSThread* osthread = thread->osthread(); ! // thread_id is kernel thread id (similar to Solaris LWP id) ! osthread->set_thread_id(os::Aix::gettid()); ! // initialize signal mask for this thread os::Aix::hotspot_sigmask(thread); ! // initialize floating point control register os::Aix::init_thread_fpu_state(); assert(osthread->get_state() == RUNNABLE, "invalid os thread state"); ! // call one more level start routine thread->run(); return 0; } bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) { - // We want the whole function to be synchronized. - ThreadCritical cs; - assert(thread->osthread() == NULL, "caller responsible"); // Allocate the OSThread object OSThread* osthread = new OSThread(NULL, NULL); if (osthread == NULL) { --- 870,901 ---- ThreadLocalStorage::set_thread(thread); OSThread* osthread = thread->osthread(); ! // Thread_id is pthread id. ! osthread->set_thread_id(pthread_id); ! // Initialize signal mask for this thread. os::Aix::hotspot_sigmask(thread); ! // Initialize floating point control register. os::Aix::init_thread_fpu_state(); assert(osthread->get_state() == RUNNABLE, "invalid os thread state"); ! // Call one more level start routine. thread->run(); + trcVerbose("Thread finished : pthread-id %u, ktid " UINT64_FORMAT ".", + pthread_id, kernel_thread_id); + return 0; } bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) { assert(thread->osthread() == NULL, "caller responsible"); // Allocate the OSThread object OSThread* osthread = new OSThread(NULL, NULL); if (osthread == NULL) {
*** 990,1012 **** int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread); pthread_attr_destroy(&attr); if (ret == 0) { ! // PPC port traceOsMisc(("Created New Thread : pthread-id %u", tid)); } else { if (PrintMiscellaneous && (Verbose || WizardMode)) { perror("pthread_create()"); } // Need to clean up stuff we've allocated so far thread->set_osthread(NULL); delete osthread; return false; } ! // Store pthread info into the OSThread ! osthread->set_pthread_id(tid); return true; } ///////////////////////////////////////////////////////////////////////////// --- 956,984 ---- int ret = pthread_create(&tid, &attr, (void* (*)(void*)) java_start, thread); pthread_attr_destroy(&attr); if (ret == 0) { ! trcVerbose("Created New Thread : pthread-id %u", tid); } else { + if (os::Aix::on_pase()) { + // QIBM_MULTI_THREADED=Y is needed when the launcher is started on iSeries + // using QSH. Otherwise pthread_create fails with errno=11. + trcVerbose("(Please make sure you set the environment variable " + "QIBM_MULTI_THREADED=Y before running this program.)"); + } if (PrintMiscellaneous && (Verbose || WizardMode)) { perror("pthread_create()"); } // Need to clean up stuff we've allocated so far thread->set_osthread(NULL); delete osthread; return false; } ! // OSThread::thread_id is the pthread id. ! osthread->set_thread_id(tid); return true; } /////////////////////////////////////////////////////////////////////////////
*** 1028,1040 **** if (osthread == NULL) { return false; } ! // Store pthread info into the OSThread ! osthread->set_thread_id(os::Aix::gettid()); ! osthread->set_pthread_id(::pthread_self()); // initialize floating point control register os::Aix::init_thread_fpu_state(); // some sanity checks --- 1000,1021 ---- if (osthread == NULL) { return false; } ! const pthread_t pthread_id = ::pthread_self(); ! const tid_t kernel_thread_id = ::thread_self(); ! ! trcVerbose("attaching Thread : pthread-id %u, ktid " UINT64_FORMAT ", stack %p ... %p, stacksize 0x%IX (%IB)", ! pthread_id, kernel_thread_id, ! thread->stack_base() - thread->stack_size(), ! thread->stack_base(), ! thread->stack_size(), ! thread->stack_size()); ! ! // OSThread::thread_id is the pthread id. ! osthread->set_thread_id(pthread_id); // initialize floating point control register os::Aix::init_thread_fpu_state(); // some sanity checks
*** 1150,1170 **** assert(status != -1, "aix error at gettimeofday()"); seconds = jlong(time.tv_sec); nanos = jlong(time.tv_usec) * 1000; } - - // We need to manually declare mread_real_time, - // because IBM didn't provide a prototype in time.h. - // (they probably only ever tested in C, not C++) - extern "C" - int mread_real_time(timebasestruct_t *t, size_t size_of_timebasestruct_t); - jlong os::javaTimeNanos() { if (os::Aix::on_pase()) { ! Unimplemented(); ! return 0; } else { // On AIX use the precision of processors real time clock // or time base registers. timebasestruct_t time; int rc; --- 1131,1149 ---- assert(status != -1, "aix error at gettimeofday()"); seconds = jlong(time.tv_sec); nanos = jlong(time.tv_usec) * 1000; } jlong os::javaTimeNanos() { if (os::Aix::on_pase()) { ! ! timeval time; ! int status = gettimeofday(&time, NULL); ! assert(status != -1, "PASE error at gettimeofday()"); ! jlong usecs = jlong((unsigned long long) time.tv_sec * (1000 * 1000) + time.tv_usec); ! return 1000 * usecs; ! } else { // On AIX use the precision of processors real time clock // or time base registers. timebasestruct_t time; int rc;
*** 1289,1314 **** ::strncpy(buf, s, n); buf[n] = '\0'; return n; } ! intx os::current_thread_id() { return (intx)pthread_self(); } int os::current_process_id() { ! ! // This implementation returns a unique pid, the pid of the ! // launcher thread that starts the vm 'process'. ! ! // Under POSIX, getpid() returns the same pid as the ! // launcher thread rather than a unique pid per thread. ! // Use gettid() if you want the old pre NPTL behaviour. ! ! // if you are looking for the result of a call to getpid() that ! // returns a unique pid for the calling thread, then look at the ! // OSThread::thread_id() method in osThread_linux.hpp file ! ! return (int)(_initial_pid ? _initial_pid : getpid()); } // DLL functions const char* os::dll_file_extension() { return ".so"; } --- 1268,1283 ---- ::strncpy(buf, s, n); buf[n] = '\0'; return n; } ! intx os::current_thread_id() { ! return (intx)pthread_self(); ! } int os::current_process_id() { ! return getpid(); } // DLL functions const char* os::dll_file_extension() { return ".so"; }
*** 1341,1350 **** --- 1310,1322 ---- snprintf(buffer, buflen, "lib%s.so", fname); retval = true; } else if (strchr(pname, *os::path_separator()) != NULL) { int n; char** pelements = split_path(pname, &n); + if (pelements == NULL) { + return false; + } for (int i = 0; i < n; i++) { // Really shouldn't be NULL, but check can't hurt if (pelements[i] == NULL || strlen(pelements[i]) == 0) { continue; // skip the empty path values }
*** 1578,1654 **** st->print("load average:"); double loadavg[3] = {-1.L, -1.L, -1.L}; os::loadavg(loadavg, 3); st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]); st->cr(); } void os::print_memory_info(outputStream* st) { st->print_cr("Memory:"); ! st->print_cr(" default page size: %s", describe_pagesize(os::vm_page_size())); ! st->print_cr(" default stack page size: %s", describe_pagesize(os::vm_page_size())); st->print_cr(" Default shared memory page size: %s", describe_pagesize(g_multipage_support.shmpsize)); st->print_cr(" Can use 64K pages dynamically with shared meory: %s", (g_multipage_support.can_use_64K_pages ? "yes" :"no")); st->print_cr(" Can use 16M pages dynamically with shared memory: %s", (g_multipage_support.can_use_16M_pages ? "yes" :"no")); ! if (g_multipage_error != 0) { ! st->print_cr(" multipage error: %d", g_multipage_error); ! } // print out LDR_CNTRL because it affects the default page sizes const char* const ldr_cntrl = ::getenv("LDR_CNTRL"); st->print_cr(" LDR_CNTRL=%s.", ldr_cntrl ? ldr_cntrl : "<unset>"); const char* const extshm = ::getenv("EXTSHM"); st->print_cr(" EXTSHM=%s.", extshm ? extshm : "<unset>"); if ( (strcmp(extshm, "on") == 0) || (strcmp(extshm, "ON") == 0) ) { st->print_cr(" *** Unsupported! Please remove EXTSHM from your environment! ***"); } ! // Call os::Aix::get_meminfo() to retrieve memory statistics. os::Aix::meminfo_t mi; if (os::Aix::get_meminfo(&mi)) { char buffer[256]; if (os::Aix::on_aix()) { ! jio_snprintf(buffer, sizeof(buffer), ! " physical total : %llu\n" ! " physical free : %llu\n" ! " swap total : %llu\n" ! " swap free : %llu\n", ! mi.real_total, ! mi.real_free, ! mi.pgsp_total, ! mi.pgsp_free); ! } else { ! Unimplemented(); } st->print_raw(buffer); - } else { - st->print_cr(" (no more information available)"); } } // Get a string for the cpuinfo that is a summary of the cpu type void os::get_summary_cpu_info(char* buf, size_t buflen) { // This looks good ! os::Aix::cpuinfo_t ci; ! if (os::Aix::get_cpuinfo(&ci)) { strncpy(buf, ci.version, buflen); } else { strncpy(buf, "AIX", buflen); } } void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) { } void os::print_siginfo(outputStream* st, void* siginfo) { - // Use common posix version. os::Posix::print_siginfo_brief(st, (const siginfo_t*) siginfo); st->cr(); } static void print_signal_handler(outputStream* st, int sig, --- 1550,1667 ---- st->print("load average:"); double loadavg[3] = {-1.L, -1.L, -1.L}; os::loadavg(loadavg, 3); st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]); st->cr(); + + // print wpar info + libperfstat::wparinfo_t wi; + if (libperfstat::get_wparinfo(&wi)) { + st->print_cr("wpar info"); + st->print_cr("name: %s", wi.name); + st->print_cr("id: %d", wi.wpar_id); + st->print_cr("type: %s", (wi.app_wpar ? "application" : "system")); + } + + // print partition info + libperfstat::partitioninfo_t pi; + if (libperfstat::get_partitioninfo(&pi)) { + st->print_cr("partition info"); + st->print_cr(" name: %s", pi.name); + } + } void os::print_memory_info(outputStream* st) { st->print_cr("Memory:"); ! st->print_cr(" Base page size (sysconf _SC_PAGESIZE): %s", ! describe_pagesize(g_multipage_support.pagesize)); ! st->print_cr(" Data page size (C-Heap, bss, etc): %s", ! describe_pagesize(g_multipage_support.datapsize)); ! st->print_cr(" Text page size: %s", ! describe_pagesize(g_multipage_support.textpsize)); ! st->print_cr(" Thread stack page size (pthread): %s", ! describe_pagesize(g_multipage_support.pthr_stack_pagesize)); st->print_cr(" Default shared memory page size: %s", describe_pagesize(g_multipage_support.shmpsize)); st->print_cr(" Can use 64K pages dynamically with shared meory: %s", (g_multipage_support.can_use_64K_pages ? "yes" :"no")); st->print_cr(" Can use 16M pages dynamically with shared memory: %s", (g_multipage_support.can_use_16M_pages ? "yes" :"no")); ! st->print_cr(" Multipage error: %d", ! g_multipage_support.error); ! st->cr(); ! st->print_cr(" os::vm_page_size: %s", describe_pagesize(os::vm_page_size())); ! // not used in OpenJDK st->print_cr(" os::stack_page_size: %s", describe_pagesize(os::stack_page_size())); // print out LDR_CNTRL because it affects the default page sizes const char* const ldr_cntrl = ::getenv("LDR_CNTRL"); st->print_cr(" LDR_CNTRL=%s.", ldr_cntrl ? ldr_cntrl : "<unset>"); + // Print out EXTSHM because it is an unsupported setting. const char* const extshm = ::getenv("EXTSHM"); st->print_cr(" EXTSHM=%s.", extshm ? extshm : "<unset>"); if ( (strcmp(extshm, "on") == 0) || (strcmp(extshm, "ON") == 0) ) { st->print_cr(" *** Unsupported! Please remove EXTSHM from your environment! ***"); } ! // Print out AIXTHREAD_GUARDPAGES because it affects the size of pthread stacks. ! const char* const aixthread_guardpages = ::getenv("AIXTHREAD_GUARDPAGES"); ! st->print_cr(" AIXTHREAD_GUARDPAGES=%s.", ! aixthread_guardpages ? aixthread_guardpages : "<unset>"); ! os::Aix::meminfo_t mi; if (os::Aix::get_meminfo(&mi)) { char buffer[256]; if (os::Aix::on_aix()) { ! st->print_cr("physical total : " SIZE_FORMAT, mi.real_total); ! st->print_cr("physical free : " SIZE_FORMAT, mi.real_free); ! st->print_cr("swap total : " SIZE_FORMAT, mi.pgsp_total); ! st->print_cr("swap free : " SIZE_FORMAT, mi.pgsp_free); ! } else { ! // PASE - Numbers are result of QWCRSSTS; they mean: ! // real_total: Sum of all system pools ! // real_free: always 0 ! // pgsp_total: we take the size of the system ASP ! // pgsp_free: size of system ASP times percentage of system ASP unused ! st->print_cr("physical total : " SIZE_FORMAT, mi.real_total); ! st->print_cr("system asp total : " SIZE_FORMAT, mi.pgsp_total); ! st->print_cr("%% system asp used : " SIZE_FORMAT, ! mi.pgsp_total ? (100.0f * (mi.pgsp_total - mi.pgsp_free) / mi.pgsp_total) : -1.0f); } st->print_raw(buffer); } + st->cr(); + + // Print segments allocated with os::reserve_memory. + st->print_cr("internal virtual memory regions used by vm:"); + vmembk_print_on(st); } // Get a string for the cpuinfo that is a summary of the cpu type void os::get_summary_cpu_info(char* buf, size_t buflen) { // This looks good ! libperfstat::cpuinfo_t ci; ! if (libperfstat::get_cpuinfo(&ci)) { strncpy(buf, ci.version, buflen); } else { strncpy(buf, "AIX", buflen); } } void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) { + st->print("CPU:"); + st->print("total %d", os::processor_count()); + // It's not safe to query number of active processors after crash. + // st->print("(active %d)", os::active_processor_count()); + st->print(" %s", VM_Version::cpu_features()); + st->cr(); } void os::print_siginfo(outputStream* st, void* siginfo) { os::Posix::print_siginfo_brief(st, (const siginfo_t*) siginfo); st->cr(); } static void print_signal_handler(outputStream* st, int sig,
*** 1783,1807 **** } // a counter for each possible signal value static volatile jint pending_signals[NSIG+1] = { 0 }; ! // Linux(POSIX) specific hand shaking semaphore. static sem_t sig_sem; void os::signal_init_pd() { // Initialize signal structures ::memset((void*)pending_signals, 0, sizeof(pending_signals)); // Initialize signal semaphore ! int rc = ::sem_init(&sig_sem, 0, 0); ! guarantee(rc != -1, "sem_init failed"); } void os::signal_notify(int sig) { Atomic::inc(&pending_signals[sig]); ! ::sem_post(&sig_sem); } static int check_pending_signals(bool wait) { Atomic::store(0, &sigint_count); for (;;) { --- 1796,1874 ---- } // a counter for each possible signal value static volatile jint pending_signals[NSIG+1] = { 0 }; ! // Wrapper functions for: sem_init(), sem_post(), sem_wait() ! // On AIX, we use sem_init(), sem_post(), sem_wait() ! // On Pase, we need to use msem_lock() and msem_unlock(), because Posix Semaphores ! // do not seem to work at all on PASE (unimplemented, will cause SIGILL). ! // Note that just using msem_.. APIs for both PASE and AIX is not an option either, as ! // on AIX, msem_..() calls are suspected of causing problems. static sem_t sig_sem; + static msemaphore* p_sig_msem = 0; + + static void local_sem_init() { + if (os::Aix::on_aix()) { + int rc = ::sem_init(&sig_sem, 0, 0); + guarantee(rc != -1, "sem_init failed"); + } else { + // Memory semaphores must live in shared mem. + guarantee0(p_sig_msem == NULL); + p_sig_msem = (msemaphore*)os::reserve_memory(sizeof(msemaphore), NULL); + guarantee(p_sig_msem, "Cannot allocate memory for memory semaphore"); + guarantee(::msem_init(p_sig_msem, 0) == p_sig_msem, "msem_init failed"); + } + } + + static void local_sem_post() { + static bool warn_only_once = false; + if (os::Aix::on_aix()) { + int rc = ::sem_post(&sig_sem); + if (rc == -1 && !warn_only_once) { + trcVerbose("sem_post failed (errno = %d, %s)", errno, strerror(errno)); + warn_only_once = true; + } + } else { + guarantee0(p_sig_msem != NULL); + int rc = ::msem_unlock(p_sig_msem, 0); + if (rc == -1 && !warn_only_once) { + trcVerbose("msem_unlock failed (errno = %d, %s)", errno, strerror(errno)); + warn_only_once = true; + } + } + } + + static void local_sem_wait() { + static bool warn_only_once = false; + if (os::Aix::on_aix()) { + int rc = ::sem_wait(&sig_sem); + if (rc == -1 && !warn_only_once) { + trcVerbose("sem_wait failed (errno = %d, %s)", errno, strerror(errno)); + warn_only_once = true; + } + } else { + guarantee0(p_sig_msem != NULL); // must init before use + int rc = ::msem_lock(p_sig_msem, 0); + if (rc == -1 && !warn_only_once) { + trcVerbose("msem_lock failed (errno = %d, %s)", errno, strerror(errno)); + warn_only_once = true; + } + } + } void os::signal_init_pd() { // Initialize signal structures ::memset((void*)pending_signals, 0, sizeof(pending_signals)); // Initialize signal semaphore ! local_sem_init(); } void os::signal_notify(int sig) { Atomic::inc(&pending_signals[sig]); ! local_sem_post(); } static int check_pending_signals(bool wait) { Atomic::store(0, &sigint_count); for (;;) {
*** 1820,1841 **** bool threadIsSuspended; do { thread->set_suspend_equivalent(); // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() ! ::sem_wait(&sig_sem); // were we externally suspended while we were waiting? threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); if (threadIsSuspended) { // // The semaphore has been incremented, but while we were waiting // another thread suspended us. We don't want to continue running // while suspended because that would surprise the thread that // suspended us. // ! ::sem_post(&sig_sem); thread->java_suspend_self(); } } while (threadIsSuspended); } --- 1887,1909 ---- bool threadIsSuspended; do { thread->set_suspend_equivalent(); // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() ! local_sem_wait(); // were we externally suspended while we were waiting? threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); if (threadIsSuspended) { // // The semaphore has been incremented, but while we were waiting // another thread suspended us. We don't want to continue running // while suspended because that would surprise the thread that // suspended us. // ! ! local_sem_post(); thread->java_suspend_self(); } } while (threadIsSuspended); }
*** 1884,1899 **** // also check that range is fully page aligned to the page size if the block. void assert_is_valid_subrange(char* p, size_t s) const { if (!contains_range(p, s)) { fprintf(stderr, "[" PTR_FORMAT " - " PTR_FORMAT "] is not a sub " "range of [" PTR_FORMAT " - " PTR_FORMAT "].\n", ! p, p + s - 1, addr, addr + size - 1); guarantee0(false); } if (!is_aligned_to(p, pagesize) || !is_aligned_to(p + s, pagesize)) { fprintf(stderr, "range [" PTR_FORMAT " - " PTR_FORMAT "] is not" ! " aligned to pagesize (%s)\n", p, p + s); guarantee0(false); } } }; --- 1952,1967 ---- // also check that range is fully page aligned to the page size if the block. void assert_is_valid_subrange(char* p, size_t s) const { if (!contains_range(p, s)) { fprintf(stderr, "[" PTR_FORMAT " - " PTR_FORMAT "] is not a sub " "range of [" PTR_FORMAT " - " PTR_FORMAT "].\n", ! p, p + s, addr, addr + size); guarantee0(false); } if (!is_aligned_to(p, pagesize) || !is_aligned_to(p + s, pagesize)) { fprintf(stderr, "range [" PTR_FORMAT " - " PTR_FORMAT "] is not" ! " aligned to pagesize (%lu)\n", p, p + s, (unsigned long) pagesize); guarantee0(false); } } };
*** 1986,1996 **** const size_t size = align_size_up(bytes, SIZE_64K); // Reserve the shared segment. int shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | S_IRUSR | S_IWUSR); if (shmid == -1) { ! trc("shmget(.., " UINTX_FORMAT ", ..) failed (errno: %d).", size, errno); return NULL; } // Important note: // It is very important that we, upon leaving this function, do not leave a shm segment alive. --- 2054,2064 ---- const size_t size = align_size_up(bytes, SIZE_64K); // Reserve the shared segment. int shmid = shmget(IPC_PRIVATE, size, IPC_CREAT | S_IRUSR | S_IWUSR); if (shmid == -1) { ! trcVerbose("shmget(.., " UINTX_FORMAT ", ..) failed (errno: %d).", size, errno); return NULL; } // Important note: // It is very important that we, upon leaving this function, do not leave a shm segment alive.
*** 2015,2025 **** char* const addr = (char*) shmat(shmid, requested_addr, SHM_RND); const int errno_shmat = errno; // (A) Right after shmat and before handing shmat errors delete the shm segment. if (::shmctl(shmid, IPC_RMID, NULL) == -1) { ! trc("shmctl(%u, IPC_RMID) failed (%d)\n", shmid, errno); assert(false, "failed to remove shared memory segment!"); } // Handle shmat error. If we failed to attach, just return. if (addr == (char*)-1) { --- 2083,2093 ---- char* const addr = (char*) shmat(shmid, requested_addr, SHM_RND); const int errno_shmat = errno; // (A) Right after shmat and before handing shmat errors delete the shm segment. if (::shmctl(shmid, IPC_RMID, NULL) == -1) { ! trcVerbose("shmctl(%u, IPC_RMID) failed (%d)\n", shmid, errno); assert(false, "failed to remove shared memory segment!"); } // Handle shmat error. If we failed to attach, just return. if (addr == (char*)-1) {
*** 2080,2089 **** --- 2148,2159 ---- return false; } return true; } + //////////////////////////////// mmap-based routines ///////////////////////////////// + // Reserve memory via mmap. // If <requested_addr> is given, an attempt is made to attach at the given address. // Failing that, memory is allocated at any address. // If <alignment_hint> is given and <requested_addr> is NULL, an attempt is made to // allocate at an address aligned with the given alignment. Failing that, memory
*** 2225,2237 **** } return rc; } - // End: shared memory bookkeeping - //////////////////////////////////////////////////////////////////////////////////////////////////// - int os::vm_page_size() { // Seems redundant as all get out. assert(os::Aix::page_size() != -1, "must call os::init"); return os::Aix::page_size(); } --- 2295,2304 ----
*** 2265,2279 **** assert0(is_aligned_to(addr, os::vm_page_size())); assert0(is_aligned_to(size, os::vm_page_size())); vmembk_t* const vmi = vmembk_find(addr); ! assert0(vmi); vmi->assert_is_valid_subrange(addr, size); trcVerbose("commit_memory [" PTR_FORMAT " - " PTR_FORMAT "].", addr, addr + size - 1); return true; } bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint, bool exec) { return pd_commit_memory(addr, size, exec); --- 2332,2353 ---- assert0(is_aligned_to(addr, os::vm_page_size())); assert0(is_aligned_to(size, os::vm_page_size())); vmembk_t* const vmi = vmembk_find(addr); ! guarantee0(vmi); vmi->assert_is_valid_subrange(addr, size); trcVerbose("commit_memory [" PTR_FORMAT " - " PTR_FORMAT "].", addr, addr + size - 1); + if (UseExplicitCommit) { + // AIX commits memory on touch. So, touch all pages to be committed. + for (char* p = addr; p < (addr + size); p += SIZE_4K) { + *p = '\0'; + } + } + return true; } bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint, bool exec) { return pd_commit_memory(addr, size, exec);
*** 2290,2300 **** assert0(is_aligned_to(addr, os::vm_page_size())); assert0(is_aligned_to(size, os::vm_page_size())); // Dynamically do different things for mmap/shmat. const vmembk_t* const vmi = vmembk_find(addr); ! assert0(vmi); vmi->assert_is_valid_subrange(addr, size); if (vmi->type == VMEM_SHMATED) { return uncommit_shmated_memory(addr, size); } else { --- 2364,2374 ---- assert0(is_aligned_to(addr, os::vm_page_size())); assert0(is_aligned_to(size, os::vm_page_size())); // Dynamically do different things for mmap/shmat. const vmembk_t* const vmi = vmembk_find(addr); ! guarantee0(vmi); vmi->assert_is_valid_subrange(addr, size); if (vmi->type == VMEM_SHMATED) { return uncommit_shmated_memory(addr, size); } else {
*** 2388,2398 **** bool os::pd_release_memory(char* addr, size_t size) { // Dynamically do different things for mmap/shmat. vmembk_t* const vmi = vmembk_find(addr); ! assert0(vmi); // Always round to os::vm_page_size(), which may be larger than 4K. size = align_size_up(size, os::vm_page_size()); addr = (char *)align_ptr_up(addr, os::vm_page_size()); --- 2462,2472 ---- bool os::pd_release_memory(char* addr, size_t size) { // Dynamically do different things for mmap/shmat. vmembk_t* const vmi = vmembk_find(addr); ! guarantee0(vmi); // Always round to os::vm_page_size(), which may be larger than 4K. size = align_size_up(size, os::vm_page_size()); addr = (char *)align_ptr_up(addr, os::vm_page_size());
*** 2464,2478 **** if (prot & PROT_READ) { rc = !read_protected; } else { rc = read_protected; } } } - if (!rc) { - assert(false, "mprotect failed."); } return rc; } // Set protections specified bool os::protect_memory(char* addr, size_t size, ProtType prot, bool is_committed) { --- 2538,2572 ---- if (prot & PROT_READ) { rc = !read_protected; } else { rc = read_protected; } + + if (!rc) { + if (os::Aix::on_pase()) { + // There is an issue on older PASE systems where mprotect() will return success but the + // memory will not be protected. + // This has nothing to do with the problem of using mproect() on SPEC1170 incompatible + // machines; we only see it rarely, when using mprotect() to protect the guard page of + // a stack. It is an OS error. + // + // A valid strategy is just to try again. This usually works. :-/ + + MiscUtils::sleep_ms(1); + if (::mprotect(addr, size, prot) == 0) { + const bool read_protected_2 = + (SafeFetch32((int*)addr, 0x12345678) == 0x12345678 && + SafeFetch32((int*)addr, 0x76543210) == 0x76543210) ? true : false; + rc = true; + } } } } + } + + assert(rc == true, "mprotect failed."); + return rc; } // Set protections specified bool os::protect_memory(char* addr, size_t size, ProtType prot, bool is_committed) {
*** 2505,2518 **** void os::large_page_init() { return; // Nothing to do. See query_multipage_support and friends. } char* os::reserve_memory_special(size_t bytes, size_t alignment, char* req_addr, bool exec) { ! // "exec" is passed in but not used. Creating the shared image for ! // the code cache doesn't have an SHM_X executable permission to check. ! Unimplemented(); ! return 0; } bool os::release_memory_special(char* base, size_t bytes) { // Detaching the SHM segment will also delete it, see reserve_memory_special(). Unimplemented(); --- 2599,2613 ---- void os::large_page_init() { return; // Nothing to do. See query_multipage_support and friends. } char* os::reserve_memory_special(size_t bytes, size_t alignment, char* req_addr, bool exec) { ! // reserve_memory_special() is used to allocate large paged memory. On AIX, we implement ! // 64k paged memory reservation using the normal memory allocation paths (os::reserve_memory()), ! // so this is not needed. ! assert(false, "should not be called on AIX"); ! return NULL; } bool os::release_memory_special(char* base, size_t bytes) { // Detaching the SHM segment will also delete it, see reserve_memory_special(). Unimplemented();
*** 2960,2970 **** --- 3055,3067 ---- // Never leave program error signals blocked; // on all our platforms they would bring down the process immediately when // getting raised while being blocked. unblock_program_error_signals(); + int orig_errno = errno; // Preserve errno value over signal handler. JVM_handle_aix_signal(sig, info, uc, true); + errno = orig_errno; } // This boolean allows users to forward their own non-matching signals // to JVM_handle_aix_signal, harmlessly. bool os::Aix::signal_handlers_are_installed = false;
*** 3082,3092 **** sigaction(sig, (struct sigaction*)NULL, &oldAct); void* oldhand = oldAct.sa_sigaction ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction) : CAST_FROM_FN_PTR(void*, oldAct.sa_handler); - // Renamed 'signalHandler' to avoid collision with other shared libs. if (oldhand != CAST_FROM_FN_PTR(void*, SIG_DFL) && oldhand != CAST_FROM_FN_PTR(void*, SIG_IGN) && oldhand != CAST_FROM_FN_PTR(void*, (sa_sigaction_t)javaSignalHandler)) { if (AllowUserSignalHandlers || !set_installed) { // Do not overwrite; user takes responsibility to forward to us. --- 3179,3188 ----
*** 3106,3116 **** sigfillset(&(sigAct.sa_mask)); if (!set_installed) { sigAct.sa_handler = SIG_DFL; sigAct.sa_flags = SA_RESTART; } else { - // Renamed 'signalHandler' to avoid collision with other shared libs. sigAct.sa_sigaction = javaSignalHandler; sigAct.sa_flags = SA_SIGINFO|SA_RESTART; } // Save flags, which are set by ours assert(sig > 0 && sig < NSIG, "vm signal out of expected range"); --- 3202,3211 ----
*** 3298,3308 **** address jvmHandler = NULL; struct sigaction act; if (os_sigaction == NULL) { // only trust the default sigaction, in case it has been interposed ! os_sigaction = (os_sigaction_t)dlsym(RTLD_DEFAULT, "sigaction"); if (os_sigaction == NULL) return; } os_sigaction(sig, (struct sigaction*)NULL, &act); --- 3393,3403 ---- address jvmHandler = NULL; struct sigaction act; if (os_sigaction == NULL) { // only trust the default sigaction, in case it has been interposed ! os_sigaction = CAST_TO_FN_PTR(os_sigaction_t, dlsym(RTLD_DEFAULT, "sigaction")); if (os_sigaction == NULL) return; } os_sigaction(sig, (struct sigaction*)NULL, &act);
*** 3315,3325 **** case SIGBUS: case SIGFPE: case SIGPIPE: case SIGILL: case SIGXFSZ: - // Renamed 'signalHandler' to avoid collision with other shared libs. jvmHandler = CAST_FROM_FN_PTR(address, (sa_sigaction_t)javaSignalHandler); break; case SHUTDOWN1_SIGNAL: case SHUTDOWN2_SIGNAL: --- 3410,3419 ----
*** 3387,3404 **** void os::init(void) { // This is basic, we want to know if that ever changes. // (Shared memory boundary is supposed to be a 256M aligned.) assert(SHMLBA == ((uint64_t)0x10000000ULL)/*256M*/, "unexpected"); // First off, we need to know whether we run on AIX or PASE, and // the OS level we run on. os::Aix::initialize_os_info(); // Scan environment (SPEC1170 behaviour, etc). os::Aix::scan_environment(); ! // Check which pages are supported by AIX. query_multipage_support(); // Act like we only have one page size by eliminating corner cases which // we did not support very well anyway. // We have two input conditions: --- 3481,3502 ---- void os::init(void) { // This is basic, we want to know if that ever changes. // (Shared memory boundary is supposed to be a 256M aligned.) assert(SHMLBA == ((uint64_t)0x10000000ULL)/*256M*/, "unexpected"); + // Record process break at startup. + g_brk_at_startup = (address) ::sbrk(0); + assert(g_brk_at_startup != (address) -1, "sbrk failed"); + // First off, we need to know whether we run on AIX or PASE, and // the OS level we run on. os::Aix::initialize_os_info(); // Scan environment (SPEC1170 behaviour, etc). os::Aix::scan_environment(); ! // Probe multipage support. query_multipage_support(); // Act like we only have one page size by eliminating corner cases which // we did not support very well anyway. // We have two input conditions:
*** 3463,3475 **** Aix::_stack_page_size = Aix::_page_size; // For now UseLargePages is just ignored. FLAG_SET_ERGO(bool, UseLargePages, false); _page_sizes[0] = 0; // debug trace ! trcVerbose("os::vm_page_size %s\n", describe_pagesize(os::vm_page_size())); // Next, we need to initialize libo4 and libperfstat libraries. if (os::Aix::on_pase()) { os::Aix::initialize_libo4(); } else { --- 3561,3574 ---- Aix::_stack_page_size = Aix::_page_size; // For now UseLargePages is just ignored. FLAG_SET_ERGO(bool, UseLargePages, false); _page_sizes[0] = 0; + _large_page_size = -1; // debug trace ! trcVerbose("os::vm_page_size %s", describe_pagesize(os::vm_page_size())); // Next, we need to initialize libo4 and libperfstat libraries. if (os::Aix::on_pase()) { os::Aix::initialize_libo4(); } else {
*** 3483,3494 **** // Now initialze basic system properties. Note that for some of the values we // need libperfstat etc. os::Aix::initialize_system_info(); - _initial_pid = getpid(); - clock_tics_per_sec = sysconf(_SC_CLK_TCK); init_random(1234567); ThreadCritical::initialize(); --- 3582,3591 ----
*** 3509,3523 **** --- 3606,3630 ---- } // This is called _after_ the global arguments have been parsed. jint os::init_2(void) { + if (os::Aix::on_pase()) { + trcVerbose("Running on PASE."); + } else { + trcVerbose("Running on AIX (not PASE)."); + } + trcVerbose("processor count: %d", os::_processor_count); trcVerbose("physical memory: %lu", Aix::_physical_memory); // Initially build up the loaded dll map. LoadedLibraries::reload(); + if (Verbose) { + trcVerbose("Loaded Libraries: "); + LoadedLibraries::print(tty); + } const int page_size = Aix::page_size(); const int map_size = page_size; address map_address = (address) MAP_FAILED;
*** 3551,3564 **** // fail if the address is already mapped. map_address = (address) ::mmap(address_wishes[i] - (ssize_t)page_size, map_size, prot, flags | MAP_FIXED, -1, 0); ! if (Verbose) { ! fprintf(stderr, "SafePoint Polling Page address: %p (wish) => %p\n", address_wishes[i], map_address + (ssize_t)page_size); - } if (map_address + (ssize_t)page_size == address_wishes[i]) { // Map succeeded and map_address is at wished address, exit loop. break; } --- 3658,3669 ---- // fail if the address is already mapped. map_address = (address) ::mmap(address_wishes[i] - (ssize_t)page_size, map_size, prot, flags | MAP_FIXED, -1, 0); ! trcVerbose("SafePoint Polling Page address: %p (wish) => %p", address_wishes[i], map_address + (ssize_t)page_size); if (map_address + (ssize_t)page_size == address_wishes[i]) { // Map succeeded and map_address is at wished address, exit loop. break; }
*** 3581,3595 **** if (!UseMembar) { address mem_serialize_page = (address) ::mmap(NULL, Aix::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); guarantee(mem_serialize_page != NULL, "mmap Failed for memory serialize page"); os::set_memory_serialize_page(mem_serialize_page); ! #ifndef PRODUCT ! if (Verbose && PrintMiscellaneous) { ! tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); ! } ! #endif } // initialize suspend/resume support - must do this before signal_sets_init() if (SR_initialize() != 0) { perror("SR_initialize failed"); --- 3686,3698 ---- if (!UseMembar) { address mem_serialize_page = (address) ::mmap(NULL, Aix::page_size(), PROT_READ | PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); guarantee(mem_serialize_page != NULL, "mmap Failed for memory serialize page"); os::set_memory_serialize_page(mem_serialize_page); ! trcVerbose("Memory Serialize Page address: %p - %p, size %IX (%IB)", ! mem_serialize_page, mem_serialize_page + Aix::page_size(), ! Aix::page_size(), Aix::page_size()); } // initialize suspend/resume support - must do this before signal_sets_init() if (SR_initialize() != 0) { perror("SR_initialize failed");
*** 3622,3632 **** // Make the stack size a multiple of the page size so that // the yellow/red zones can be guarded. // Note that this can be 0, if no default stacksize was set. JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes, vm_page_size())); ! Aix::libpthread_init(); if (MaxFDLimit) { // Set the number of file descriptors to max. print out error // if getrlimit/setrlimit fails but continue regardless. struct rlimit nbr_files; --- 3725,3738 ---- // Make the stack size a multiple of the page size so that // the yellow/red zones can be guarded. // Note that this can be 0, if no default stacksize was set. JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes, vm_page_size())); ! if (UseNUMA) { ! UseNUMA = false; ! warning("NUMA optimizations are not available on this OS."); ! } if (MaxFDLimit) { // Set the number of file descriptors to max. print out error // if getrlimit/setrlimit fails but continue regardless. struct rlimit nbr_files;
*** 3644,3654 **** } } if (PerfAllowAtExitRegistration) { // Only register atexit functions if PerfAllowAtExitRegistration is set. ! // Atexit functions can be delayed until process exit time, which // can be problematic for embedded VM situations. Embedded VMs should // call DestroyJavaVM() to assure that VM resources are released. // Note: perfMemory_exit_helper atexit function may be removed in // the future if the appropriate cleanup code can be added to the --- 3750,3760 ---- } } if (PerfAllowAtExitRegistration) { // Only register atexit functions if PerfAllowAtExitRegistration is set. ! // At exit functions can be delayed until process exit time, which // can be problematic for embedded VM situations. Embedded VMs should // call DestroyJavaVM() to assure that VM resources are released. // Note: perfMemory_exit_helper atexit function may be removed in // the future if the appropriate cleanup code can be added to the
*** 3744,3763 **** } //////////////////////////////////////////////////////////////////////////////// // debug support - static address same_page(address x, address y) { - intptr_t page_bits = -os::vm_page_size(); - if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits)) - return x; - else if (x > y) - return (address)(intptr_t(y) | ~page_bits) + 1; - else - return (address)(intptr_t(y) & page_bits); - } - bool os::find(address addr, outputStream* st) { st->print(PTR_FORMAT ": ", addr); loaded_module_t lm; --- 3850,3859 ----
*** 4117,4144 **** // System loadavg support. Returns -1 if load average cannot be obtained. // For now just return the system wide load average (no processor sets). int os::loadavg(double values[], int nelem) { - // Implemented using libperfstat on AIX. - guarantee(nelem >= 0 && nelem <= 3, "argument error"); guarantee(values, "argument error"); if (os::Aix::on_pase()) { ! Unimplemented(); return -1; } else { // AIX: use libperfstat ! // ! // See also: ! // http://publib.boulder.ibm.com/infocenter/pseries/v5r3/index.jsp?topic=/com.ibm.aix.basetechref/doc/basetrf1/perfstat_cputot.htm ! // /usr/include/libperfstat.h: ! ! // Use the already AIX version independent get_cpuinfo. ! os::Aix::cpuinfo_t ci; ! if (os::Aix::get_cpuinfo(&ci)) { for (int i = 0; i < nelem; i++) { values[i] = ci.loadavg[i]; } } else { return -1; --- 4213,4244 ---- // System loadavg support. Returns -1 if load average cannot be obtained. // For now just return the system wide load average (no processor sets). int os::loadavg(double values[], int nelem) { guarantee(nelem >= 0 && nelem <= 3, "argument error"); guarantee(values, "argument error"); if (os::Aix::on_pase()) { ! ! // AS/400 PASE: use libo4 porting library ! double v[3] = { 0.0, 0.0, 0.0 }; ! ! if (libo4::get_load_avg(v, v + 1, v + 2)) { ! for (int i = 0; i < nelem; i ++) { ! values[i] = v[i]; ! } ! return nelem; ! } else { return -1; + } + } else { + // AIX: use libperfstat ! libperfstat::cpuinfo_t ci; ! if (libperfstat::get_cpuinfo(&ci)) { for (int i = 0; i < nelem; i++) { values[i] = ci.loadavg[i]; } } else { return -1;
*** 4184,4194 **** struct utsname uts; memset(&uts, 0, sizeof(uts)); strcpy(uts.sysname, "?"); if (::uname(&uts) == -1) { ! trc("uname failed (%d)", errno); guarantee(0, "Could not determine whether we run on AIX or PASE"); } else { trcVerbose("uname says: sysname \"%s\" version \"%s\" release \"%s\" " "node \"%s\" machine \"%s\"\n", uts.sysname, uts.version, uts.release, uts.nodename, uts.machine); --- 4284,4294 ---- struct utsname uts; memset(&uts, 0, sizeof(uts)); strcpy(uts.sysname, "?"); if (::uname(&uts) == -1) { ! trcVerbose("uname failed (%d)", errno); guarantee(0, "Could not determine whether we run on AIX or PASE"); } else { trcVerbose("uname says: sysname \"%s\" version \"%s\" release \"%s\" " "node \"%s\" machine \"%s\"\n", uts.sysname, uts.version, uts.release, uts.nodename, uts.machine);
*** 4196,4214 **** assert(major > 0, "invalid OS version"); const int minor = atoi(uts.release); assert(minor > 0, "invalid OS release"); _os_version = (major << 8) | minor; if (strcmp(uts.sysname, "OS400") == 0) { ! Unimplemented(); } else if (strcmp(uts.sysname, "AIX") == 0) { // We run on AIX. We do not support versions older than AIX 5.3. _on_pase = 0; if (_os_version < 0x0503) { ! trc("AIX release older than AIX 5.3 not supported."); assert(false, "AIX release too old."); } else { ! trcVerbose("We run on AIX %d.%d\n", major, minor); } } else { assert(false, "unknown OS"); } } --- 4296,4321 ---- assert(major > 0, "invalid OS version"); const int minor = atoi(uts.release); assert(minor > 0, "invalid OS release"); _os_version = (major << 8) | minor; if (strcmp(uts.sysname, "OS400") == 0) { ! // We run on AS/400 PASE. We do not support versions older than V5R4M0. ! _on_pase = 1; ! if (_os_version < 0x0504) { ! trcVerbose("OS/400 releases older than V5R4M0 not supported."); ! assert(false, "OS/400 release too old."); ! } else { ! trcVerbose("We run on OS/400 (pase) V%dR%d", major, minor); ! } } else if (strcmp(uts.sysname, "AIX") == 0) { // We run on AIX. We do not support versions older than AIX 5.3. _on_pase = 0; if (_os_version < 0x0503) { ! trcVerbose("AIX release older than AIX 5.3 not supported."); assert(false, "AIX release too old."); } else { ! trcVerbose("We run on AIX %d.%d", major, minor); } } else { assert(false, "unknown OS"); } }
*** 4230,4245 **** // shared memory cannot be change dynamically, effectivly preventing // large pages from working. // This switch was needed on AIX 32bit, but on AIX 64bit the general // recommendation is (in OSS notes) to switch it off. p = ::getenv("EXTSHM"); ! if (Verbose) { ! fprintf(stderr, "EXTSHM=%s.\n", p ? p : "<unset>"); ! } if (p && strcasecmp(p, "ON") == 0) { - fprintf(stderr, "Unsupported setting: EXTSHM=ON. Large Page support will be disabled.\n"); _extshm = 1; } else { _extshm = 0; } // SPEC1170 behaviour: will change the behaviour of a number of POSIX APIs. --- 4337,4357 ---- // shared memory cannot be change dynamically, effectivly preventing // large pages from working. // This switch was needed on AIX 32bit, but on AIX 64bit the general // recommendation is (in OSS notes) to switch it off. p = ::getenv("EXTSHM"); ! trcVerbose("EXTSHM=%s.", p ? p : "<unset>"); if (p && strcasecmp(p, "ON") == 0) { _extshm = 1; + trcVerbose("*** Unsupported mode! Please remove EXTSHM from your environment! ***"); + if (!AllowExtshm) { + // We allow under certain conditions the user to continue. However, we want this + // to be a fatal error by default. On certain AIX systems, leaving EXTSHM=ON means + // that the VM is not able to allocate 64k pages for the heap. + // We do not want to run with reduced performance. + vm_exit_during_initialization("EXTSHM is ON. Please remove EXTSHM from your environment."); + } } else { _extshm = 0; } // SPEC1170 behaviour: will change the behaviour of a number of POSIX APIs.
*** 4252,4299 **** // exec() ? before loading the libjvm ? ....) p = ::getenv("XPG_SUS_ENV"); trcVerbose("XPG_SUS_ENV=%s.", p ? p : "<unset>"); if (p && strcmp(p, "ON") == 0) { _xpg_sus_mode = 1; ! trc("Unsupported setting: XPG_SUS_ENV=ON"); // This is not supported. Worst of all, it changes behaviour of mmap MAP_FIXED to // clobber address ranges. If we ever want to support that, we have to do some // testing first. guarantee(false, "XPG_SUS_ENV=ON not supported"); } else { _xpg_sus_mode = 0; } ! // Switch off AIX internal (pthread) guard pages. This has ! // immediate effect for any pthread_create calls which follow. p = ::getenv("AIXTHREAD_GUARDPAGES"); trcVerbose("AIXTHREAD_GUARDPAGES=%s.", p ? p : "<unset>"); - rc = ::putenv("AIXTHREAD_GUARDPAGES=0"); - guarantee(rc == 0, ""); } // end: os::Aix::scan_environment() ! // PASE: initialize the libo4 library (AS400 PASE porting library). void os::Aix::initialize_libo4() { ! Unimplemented(); } ! // AIX: initialize the libperfstat library (we load this dynamically ! // because it is only available on AIX. void os::Aix::initialize_libperfstat() { - assert(os::Aix::on_aix(), "AIX only"); - if (!libperfstat::init()) { ! trc("libperfstat initialization failed."); assert(false, "libperfstat initialization failed"); } else { ! if (Verbose) { ! fprintf(stderr, "libperfstat initialized.\n"); ! } } ! } // end: os::Aix::initialize_libperfstat ///////////////////////////////////////////////////////////////////////////// // thread stack // Function to query the current stack size using pthread_getthrds_np. --- 4364,4422 ---- // exec() ? before loading the libjvm ? ....) p = ::getenv("XPG_SUS_ENV"); trcVerbose("XPG_SUS_ENV=%s.", p ? p : "<unset>"); if (p && strcmp(p, "ON") == 0) { _xpg_sus_mode = 1; ! trcVerbose("Unsupported setting: XPG_SUS_ENV=ON"); // This is not supported. Worst of all, it changes behaviour of mmap MAP_FIXED to // clobber address ranges. If we ever want to support that, we have to do some // testing first. guarantee(false, "XPG_SUS_ENV=ON not supported"); } else { _xpg_sus_mode = 0; } ! if (os::Aix::on_pase()) { ! p = ::getenv("QIBM_MULTI_THREADED"); ! trcVerbose("QIBM_MULTI_THREADED=%s.", p ? p : "<unset>"); ! } ! ! p = ::getenv("LDR_CNTRL"); ! trcVerbose("LDR_CNTRL=%s.", p ? p : "<unset>"); ! if (os::Aix::on_pase() && os::Aix::os_version() == 0x0701) { ! if (p && ::strstr(p, "TEXTPSIZE")) { ! trcVerbose("*** WARNING - LDR_CNTRL contains TEXTPSIZE. " ! "you may experience hangs or crashes on OS/400 V7R1."); ! } ! } ! p = ::getenv("AIXTHREAD_GUARDPAGES"); trcVerbose("AIXTHREAD_GUARDPAGES=%s.", p ? p : "<unset>"); } // end: os::Aix::scan_environment() ! // PASE: initialize the libo4 library (PASE porting library). void os::Aix::initialize_libo4() { ! guarantee(os::Aix::on_pase(), "OS/400 only."); ! if (!libo4::init()) { ! trcVerbose("libo4 initialization failed."); ! assert(false, "libo4 initialization failed"); ! } else { ! trcVerbose("libo4 initialized."); ! } } ! // AIX: initialize the libperfstat library. void os::Aix::initialize_libperfstat() { assert(os::Aix::on_aix(), "AIX only"); if (!libperfstat::init()) { ! trcVerbose("libperfstat initialization failed."); assert(false, "libperfstat initialization failed"); } else { ! trcVerbose("libperfstat initialized."); } ! } ///////////////////////////////////////////////////////////////////////////// // thread stack // Function to query the current stack size using pthread_getthrds_np.
< prev index next >