Path: blob/master/src/hotspot/os/bsd/os_bsd.cpp
64440 views
/*1* Copyright (c) 1999, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324// no precompiled headers25#include "jvm.h"26#include "classfile/vmSymbols.hpp"27#include "code/icBuffer.hpp"28#include "code/vtableStubs.hpp"29#include "compiler/compileBroker.hpp"30#include "compiler/disassembler.hpp"31#include "interpreter/interpreter.hpp"32#include "jvmtifiles/jvmti.h"33#include "logging/log.hpp"34#include "logging/logStream.hpp"35#include "memory/allocation.inline.hpp"36#include "oops/oop.inline.hpp"37#include "os_bsd.inline.hpp"38#include "os_posix.inline.hpp"39#include "os_share_bsd.hpp"40#include "prims/jniFastGetField.hpp"41#include "prims/jvm_misc.hpp"42#include "runtime/arguments.hpp"43#include "runtime/atomic.hpp"44#include "runtime/globals.hpp"45#include "runtime/globals_extension.hpp"46#include "runtime/interfaceSupport.inline.hpp"47#include "runtime/java.hpp"48#include "runtime/javaCalls.hpp"49#include "runtime/mutexLocker.hpp"50#include "runtime/objectMonitor.hpp"51#include "runtime/osThread.hpp"52#include "runtime/perfMemory.hpp"53#include "runtime/semaphore.hpp"54#include "runtime/sharedRuntime.hpp"55#include "runtime/statSampler.hpp"56#include "runtime/stubRoutines.hpp"57#include "runtime/thread.inline.hpp"58#include "runtime/threadCritical.hpp"59#include "runtime/timer.hpp"60#include "services/attachListener.hpp"61#include "services/memTracker.hpp"62#include "services/runtimeService.hpp"63#include "signals_posix.hpp"64#include "utilities/align.hpp"65#include "utilities/decoder.hpp"66#include "utilities/defaultStream.hpp"67#include "utilities/events.hpp"68#include "utilities/growableArray.hpp"69#include "utilities/vmError.hpp"7071// put OS-includes here72# include <dlfcn.h>73# include <errno.h>74# include <fcntl.h>75# include <inttypes.h>76# include <poll.h>77# include <pthread.h>78# include <pwd.h>79# include <signal.h>80# include <stdint.h>81# include <stdio.h>82# include <string.h>83# include <sys/ioctl.h>84# include <sys/mman.h>85# include <sys/param.h>86# include <sys/resource.h>87# include <sys/socket.h>88# include <sys/stat.h>89# include <sys/syscall.h>90# include <sys/sysctl.h>91# include <sys/time.h>92# include <sys/times.h>93# include <sys/types.h>94# include <time.h>95# include <unistd.h>9697#if defined(__FreeBSD__) || defined(__NetBSD__)98#include <elf.h>99#endif100101#ifdef __APPLE__102#include <mach-o/dyld.h>103#endif104105#ifndef MAP_ANONYMOUS106#define MAP_ANONYMOUS MAP_ANON107#endif108109#define MAX_PATH (2 * K)110111// for timer info max values which include all bits112#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)113114////////////////////////////////////////////////////////////////////////////////115// global variables116julong os::Bsd::_physical_memory = 0;117118#ifdef __APPLE__119mach_timebase_info_data_t os::Bsd::_timebase_info = {0, 0};120volatile uint64_t os::Bsd::_max_abstime = 0;121#endif122pthread_t os::Bsd::_main_thread;123int os::Bsd::_page_size = -1;124125static jlong initial_time_count=0;126127static int clock_tics_per_sec = 100;128129#if defined(__APPLE__) && defined(__x86_64__)130static const int processor_id_unassigned = -1;131static const int processor_id_assigning = -2;132static const int processor_id_map_size = 256;133static volatile int processor_id_map[processor_id_map_size];134static volatile int processor_id_next = 0;135#endif136137////////////////////////////////////////////////////////////////////////////////138// utility functions139140julong os::available_memory() {141return Bsd::available_memory();142}143144// available here means free145julong os::Bsd::available_memory() {146uint64_t available = physical_memory() >> 2;147#ifdef __APPLE__148mach_msg_type_number_t count = HOST_VM_INFO64_COUNT;149vm_statistics64_data_t vmstat;150kern_return_t kerr = host_statistics64(mach_host_self(), HOST_VM_INFO64,151(host_info64_t)&vmstat, &count);152assert(kerr == KERN_SUCCESS,153"host_statistics64 failed - check mach_host_self() and count");154if (kerr == KERN_SUCCESS) {155available = vmstat.free_count * os::vm_page_size();156}157#endif158return available;159}160161// for more info see :162// https://man.openbsd.org/sysctl.2163void os::Bsd::print_uptime_info(outputStream* st) {164struct timeval boottime;165size_t len = sizeof(boottime);166int mib[2];167mib[0] = CTL_KERN;168mib[1] = KERN_BOOTTIME;169170if (sysctl(mib, 2, &boottime, &len, NULL, 0) >= 0) {171time_t bootsec = boottime.tv_sec;172time_t currsec = time(NULL);173os::print_dhm(st, "OS uptime:", (long) difftime(currsec, bootsec));174}175}176177julong os::physical_memory() {178return Bsd::physical_memory();179}180181// Return true if user is running as root.182183bool os::have_special_privileges() {184static bool init = false;185static bool privileges = false;186if (!init) {187privileges = (getuid() != geteuid()) || (getgid() != getegid());188init = true;189}190return privileges;191}192193194195// Cpu architecture string196#if defined(ZERO)197static char cpu_arch[] = ZERO_LIBARCH;198#elif defined(IA64)199static char cpu_arch[] = "ia64";200#elif defined(IA32)201static char cpu_arch[] = "i386";202#elif defined(AMD64)203static char cpu_arch[] = "amd64";204#elif defined(ARM)205static char cpu_arch[] = "arm";206#elif defined(AARCH64)207static char cpu_arch[] = "aarch64";208#elif defined(PPC32)209static char cpu_arch[] = "ppc";210#else211#error Add appropriate cpu_arch setting212#endif213214// Compiler variant215#ifdef COMPILER2216#define COMPILER_VARIANT "server"217#else218#define COMPILER_VARIANT "client"219#endif220221222void os::Bsd::initialize_system_info() {223int mib[2];224size_t len;225int cpu_val;226julong mem_val;227228// get processors count via hw.ncpus sysctl229mib[0] = CTL_HW;230mib[1] = HW_NCPU;231len = sizeof(cpu_val);232if (sysctl(mib, 2, &cpu_val, &len, NULL, 0) != -1 && cpu_val >= 1) {233assert(len == sizeof(cpu_val), "unexpected data size");234set_processor_count(cpu_val);235} else {236set_processor_count(1); // fallback237}238239#if defined(__APPLE__) && defined(__x86_64__)240// initialize processor id map241for (int i = 0; i < processor_id_map_size; i++) {242processor_id_map[i] = processor_id_unassigned;243}244#endif245246// get physical memory via hw.memsize sysctl (hw.memsize is used247// since it returns a 64 bit value)248mib[0] = CTL_HW;249250#if defined (HW_MEMSIZE) // Apple251mib[1] = HW_MEMSIZE;252#elif defined(HW_PHYSMEM) // Most of BSD253mib[1] = HW_PHYSMEM;254#elif defined(HW_REALMEM) // Old FreeBSD255mib[1] = HW_REALMEM;256#else257#error No ways to get physmem258#endif259260len = sizeof(mem_val);261if (sysctl(mib, 2, &mem_val, &len, NULL, 0) != -1) {262assert(len == sizeof(mem_val), "unexpected data size");263_physical_memory = mem_val;264} else {265_physical_memory = 256 * 1024 * 1024; // fallback (XXXBSD?)266}267268#ifdef __OpenBSD__269{270// limit _physical_memory memory view on OpenBSD since271// datasize rlimit restricts us anyway.272struct rlimit limits;273getrlimit(RLIMIT_DATA, &limits);274_physical_memory = MIN2(_physical_memory, (julong)limits.rlim_cur);275}276#endif277}278279#ifdef __APPLE__280static const char *get_home() {281const char *home_dir = ::getenv("HOME");282if ((home_dir == NULL) || (*home_dir == '\0')) {283struct passwd *passwd_info = getpwuid(geteuid());284if (passwd_info != NULL) {285home_dir = passwd_info->pw_dir;286}287}288289return home_dir;290}291#endif292293void os::init_system_properties_values() {294// The next steps are taken in the product version:295//296// Obtain the JAVA_HOME value from the location of libjvm.so.297// This library should be located at:298// <JAVA_HOME>/jre/lib/<arch>/{client|server}/libjvm.so.299//300// If "/jre/lib/" appears at the right place in the path, then we301// assume libjvm.so is installed in a JDK and we use this path.302//303// Otherwise exit with message: "Could not create the Java virtual machine."304//305// The following extra steps are taken in the debugging version:306//307// If "/jre/lib/" does NOT appear at the right place in the path308// instead of exit check for $JAVA_HOME environment variable.309//310// If it is defined and we are able to locate $JAVA_HOME/jre/lib/<arch>,311// then we append a fake suffix "hotspot/libjvm.so" to this path so312// it looks like libjvm.so is installed there313// <JAVA_HOME>/jre/lib/<arch>/hotspot/libjvm.so.314//315// Otherwise exit.316//317// Important note: if the location of libjvm.so changes this318// code needs to be changed accordingly.319320// See ld(1):321// The linker uses the following search paths to locate required322// shared libraries:323// 1: ...324// ...325// 7: The default directories, normally /lib and /usr/lib.326#ifndef DEFAULT_LIBPATH327#ifndef OVERRIDE_LIBPATH328#define DEFAULT_LIBPATH "/lib:/usr/lib"329#else330#define DEFAULT_LIBPATH OVERRIDE_LIBPATH331#endif332#endif333334// Base path of extensions installed on the system.335#define SYS_EXT_DIR "/usr/java/packages"336#define EXTENSIONS_DIR "/lib/ext"337338#ifndef __APPLE__339340// Buffer that fits several sprintfs.341// Note that the space for the colon and the trailing null are provided342// by the nulls included by the sizeof operator.343const size_t bufsize =344MAX2((size_t)MAXPATHLEN, // For dll_dir & friends.345(size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR) + sizeof(SYS_EXT_DIR) + sizeof(EXTENSIONS_DIR)); // extensions dir346char *buf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);347348// sysclasspath, java_home, dll_dir349{350char *pslash;351os::jvm_path(buf, bufsize);352353// Found the full path to libjvm.so.354// Now cut the path to <java_home>/jre if we can.355*(strrchr(buf, '/')) = '\0'; // Get rid of /libjvm.so.356pslash = strrchr(buf, '/');357if (pslash != NULL) {358*pslash = '\0'; // Get rid of /{client|server|hotspot}.359}360Arguments::set_dll_dir(buf);361362if (pslash != NULL) {363pslash = strrchr(buf, '/');364if (pslash != NULL) {365*pslash = '\0'; // Get rid of /<arch>.366pslash = strrchr(buf, '/');367if (pslash != NULL) {368*pslash = '\0'; // Get rid of /lib.369}370}371}372Arguments::set_java_home(buf);373if (!set_boot_path('/', ':')) {374vm_exit_during_initialization("Failed setting boot class path.", NULL);375}376}377378// Where to look for native libraries.379//380// Note: Due to a legacy implementation, most of the library path381// is set in the launcher. This was to accomodate linking restrictions382// on legacy Bsd implementations (which are no longer supported).383// Eventually, all the library path setting will be done here.384//385// However, to prevent the proliferation of improperly built native386// libraries, the new path component /usr/java/packages is added here.387// Eventually, all the library path setting will be done here.388{389// Get the user setting of LD_LIBRARY_PATH, and prepended it. It390// should always exist (until the legacy problem cited above is391// addressed).392const char *v = ::getenv("LD_LIBRARY_PATH");393const char *v_colon = ":";394if (v == NULL) { v = ""; v_colon = ""; }395// That's +1 for the colon and +1 for the trailing '\0'.396char *ld_library_path = NEW_C_HEAP_ARRAY(char,397strlen(v) + 1 +398sizeof(SYS_EXT_DIR) + sizeof("/lib/") + strlen(cpu_arch) + sizeof(DEFAULT_LIBPATH) + 1,399mtInternal);400sprintf(ld_library_path, "%s%s" SYS_EXT_DIR "/lib/%s:" DEFAULT_LIBPATH, v, v_colon, cpu_arch);401Arguments::set_library_path(ld_library_path);402FREE_C_HEAP_ARRAY(char, ld_library_path);403}404405// Extensions directories.406sprintf(buf, "%s" EXTENSIONS_DIR ":" SYS_EXT_DIR EXTENSIONS_DIR, Arguments::get_java_home());407Arguments::set_ext_dirs(buf);408409FREE_C_HEAP_ARRAY(char, buf);410411#else // __APPLE__412413#define SYS_EXTENSIONS_DIR "/Library/Java/Extensions"414#define SYS_EXTENSIONS_DIRS SYS_EXTENSIONS_DIR ":/Network" SYS_EXTENSIONS_DIR ":/System" SYS_EXTENSIONS_DIR ":/usr/lib/java"415416const char *user_home_dir = get_home();417// The null in SYS_EXTENSIONS_DIRS counts for the size of the colon after user_home_dir.418size_t system_ext_size = strlen(user_home_dir) + sizeof(SYS_EXTENSIONS_DIR) +419sizeof(SYS_EXTENSIONS_DIRS);420421// Buffer that fits several sprintfs.422// Note that the space for the colon and the trailing null are provided423// by the nulls included by the sizeof operator.424const size_t bufsize =425MAX2((size_t)MAXPATHLEN, // for dll_dir & friends.426(size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR) + system_ext_size); // extensions dir427char *buf = NEW_C_HEAP_ARRAY(char, bufsize, mtInternal);428429// sysclasspath, java_home, dll_dir430{431char *pslash;432os::jvm_path(buf, bufsize);433434// Found the full path to libjvm.so.435// Now cut the path to <java_home>/jre if we can.436*(strrchr(buf, '/')) = '\0'; // Get rid of /libjvm.so.437pslash = strrchr(buf, '/');438if (pslash != NULL) {439*pslash = '\0'; // Get rid of /{client|server|hotspot}.440}441#ifdef STATIC_BUILD442strcat(buf, "/lib");443#endif444445Arguments::set_dll_dir(buf);446447if (pslash != NULL) {448pslash = strrchr(buf, '/');449if (pslash != NULL) {450*pslash = '\0'; // Get rid of /lib.451}452}453Arguments::set_java_home(buf);454if (!set_boot_path('/', ':')) {455vm_exit_during_initialization("Failed setting boot class path.", NULL);456}457}458459// Where to look for native libraries.460//461// Note: Due to a legacy implementation, most of the library path462// is set in the launcher. This was to accomodate linking restrictions463// on legacy Bsd implementations (which are no longer supported).464// Eventually, all the library path setting will be done here.465//466// However, to prevent the proliferation of improperly built native467// libraries, the new path component /usr/java/packages is added here.468// Eventually, all the library path setting will be done here.469{470// Get the user setting of LD_LIBRARY_PATH, and prepended it. It471// should always exist (until the legacy problem cited above is472// addressed).473// Prepend the default path with the JAVA_LIBRARY_PATH so that the app launcher code474// can specify a directory inside an app wrapper475const char *l = ::getenv("JAVA_LIBRARY_PATH");476const char *l_colon = ":";477if (l == NULL) { l = ""; l_colon = ""; }478479const char *v = ::getenv("DYLD_LIBRARY_PATH");480const char *v_colon = ":";481if (v == NULL) { v = ""; v_colon = ""; }482483// Apple's Java6 has "." at the beginning of java.library.path.484// OpenJDK on Windows has "." at the end of java.library.path.485// OpenJDK on Linux and Solaris don't have "." in java.library.path486// at all. To ease the transition from Apple's Java6 to OpenJDK7,487// "." is appended to the end of java.library.path. Yes, this488// could cause a change in behavior, but Apple's Java6 behavior489// can be achieved by putting "." at the beginning of the490// JAVA_LIBRARY_PATH environment variable.491char *ld_library_path = NEW_C_HEAP_ARRAY(char,492strlen(v) + 1 + strlen(l) + 1 +493system_ext_size + 3,494mtInternal);495sprintf(ld_library_path, "%s%s%s%s%s" SYS_EXTENSIONS_DIR ":" SYS_EXTENSIONS_DIRS ":.",496v, v_colon, l, l_colon, user_home_dir);497Arguments::set_library_path(ld_library_path);498FREE_C_HEAP_ARRAY(char, ld_library_path);499}500501// Extensions directories.502//503// Note that the space for the colon and the trailing null are provided504// by the nulls included by the sizeof operator (so actually one byte more505// than necessary is allocated).506sprintf(buf, "%s" SYS_EXTENSIONS_DIR ":%s" EXTENSIONS_DIR ":" SYS_EXTENSIONS_DIRS,507user_home_dir, Arguments::get_java_home());508Arguments::set_ext_dirs(buf);509510FREE_C_HEAP_ARRAY(char, buf);511512#undef SYS_EXTENSIONS_DIR513#undef SYS_EXTENSIONS_DIRS514515#endif // __APPLE__516517#undef SYS_EXT_DIR518#undef EXTENSIONS_DIR519}520521////////////////////////////////////////////////////////////////////////////////522// breakpoint support523524void os::breakpoint() {525BREAKPOINT;526}527528extern "C" void breakpoint() {529// use debugger to set breakpoint here530}531532//////////////////////////////////////////////////////////////////////////////533// create new thread534535#ifdef __APPLE__536// library handle for calling objc_registerThreadWithCollector()537// without static linking to the libobjc library538#define OBJC_LIB "/usr/lib/libobjc.dylib"539#define OBJC_GCREGISTER "objc_registerThreadWithCollector"540typedef void (*objc_registerThreadWithCollector_t)();541extern "C" objc_registerThreadWithCollector_t objc_registerThreadWithCollectorFunction;542objc_registerThreadWithCollector_t objc_registerThreadWithCollectorFunction = NULL;543#endif544545// Thread start routine for all newly created threads546static void *thread_native_entry(Thread *thread) {547548thread->record_stack_base_and_size();549thread->initialize_thread_current();550551OSThread* osthread = thread->osthread();552Monitor* sync = osthread->startThread_lock();553554osthread->set_thread_id(os::Bsd::gettid());555556#ifdef __APPLE__557// Store unique OS X thread id used by SA558osthread->set_unique_thread_id();559#endif560561// initialize signal mask for this thread562PosixSignals::hotspot_sigmask(thread);563564// initialize floating point control register565os::Bsd::init_thread_fpu_state();566567#ifdef __APPLE__568// register thread with objc gc569if (objc_registerThreadWithCollectorFunction != NULL) {570objc_registerThreadWithCollectorFunction();571}572#endif573574// handshaking with parent thread575{576MutexLocker ml(sync, Mutex::_no_safepoint_check_flag);577578// notify parent thread579osthread->set_state(INITIALIZED);580sync->notify_all();581582// wait until os::start_thread()583while (osthread->get_state() == INITIALIZED) {584sync->wait_without_safepoint_check();585}586}587588log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",589os::current_thread_id(), (uintx) pthread_self());590591// call one more level start routine592thread->call_run();593594// Note: at this point the thread object may already have deleted itself.595// Prevent dereferencing it from here on out.596thread = NULL;597598log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",599os::current_thread_id(), (uintx) pthread_self());600601return 0;602}603604bool os::create_thread(Thread* thread, ThreadType thr_type,605size_t req_stack_size) {606assert(thread->osthread() == NULL, "caller responsible");607608// Allocate the OSThread object609OSThread* osthread = new OSThread(NULL, NULL);610if (osthread == NULL) {611return false;612}613614// set the correct thread state615osthread->set_thread_type(thr_type);616617// Initial state is ALLOCATED but not INITIALIZED618osthread->set_state(ALLOCATED);619620thread->set_osthread(osthread);621622// init thread attributes623pthread_attr_t attr;624pthread_attr_init(&attr);625pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);626627// calculate stack size if it's not specified by caller628size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size);629int status = pthread_attr_setstacksize(&attr, stack_size);630assert_status(status == 0, status, "pthread_attr_setstacksize");631632ThreadState state;633634{635636ResourceMark rm;637pthread_t tid;638int ret = 0;639int limit = 3;640do {641ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);642} while (ret == EAGAIN && limit-- > 0);643644char buf[64];645if (ret == 0) {646log_info(os, thread)("Thread \"%s\" started (pthread id: " UINTX_FORMAT ", attributes: %s). ",647thread->name(), (uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));648} else {649log_warning(os, thread)("Failed to start thread \"%s\" - pthread_create failed (%s) for attributes: %s.",650thread->name(), os::errno_name(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));651// Log some OS information which might explain why creating the thread failed.652log_info(os, thread)("Number of threads approx. running in the VM: %d", Threads::number_of_threads());653LogStream st(Log(os, thread)::info());654os::Posix::print_rlimit_info(&st);655os::print_memory_info(&st);656}657658pthread_attr_destroy(&attr);659660if (ret != 0) {661// Need to clean up stuff we've allocated so far662thread->set_osthread(NULL);663delete osthread;664return false;665}666667// Store pthread info into the OSThread668osthread->set_pthread_id(tid);669670// Wait until child thread is either initialized or aborted671{672Monitor* sync_with_child = osthread->startThread_lock();673MutexLocker ml(sync_with_child, Mutex::_no_safepoint_check_flag);674while ((state = osthread->get_state()) == ALLOCATED) {675sync_with_child->wait_without_safepoint_check();676}677}678679}680681// The thread is returned suspended (in state INITIALIZED),682// and is started higher up in the call chain683assert(state == INITIALIZED, "race condition");684return true;685}686687/////////////////////////////////////////////////////////////////////////////688// attach existing thread689690// bootstrap the main thread691bool os::create_main_thread(JavaThread* thread) {692assert(os::Bsd::_main_thread == pthread_self(), "should be called inside main thread");693return create_attached_thread(thread);694}695696bool os::create_attached_thread(JavaThread* thread) {697#ifdef ASSERT698thread->verify_not_published();699#endif700701// Allocate the OSThread object702OSThread* osthread = new OSThread(NULL, NULL);703704if (osthread == NULL) {705return false;706}707708osthread->set_thread_id(os::Bsd::gettid());709710#ifdef __APPLE__711// Store unique OS X thread id used by SA712osthread->set_unique_thread_id();713#endif714715// Store pthread info into the OSThread716osthread->set_pthread_id(::pthread_self());717718// initialize floating point control register719os::Bsd::init_thread_fpu_state();720721// Initial thread state is RUNNABLE722osthread->set_state(RUNNABLE);723724thread->set_osthread(osthread);725726// initialize signal mask for this thread727// and save the caller's signal mask728PosixSignals::hotspot_sigmask(thread);729730log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",731os::current_thread_id(), (uintx) pthread_self());732733return true;734}735736void os::pd_start_thread(Thread* thread) {737OSThread * osthread = thread->osthread();738assert(osthread->get_state() != INITIALIZED, "just checking");739Monitor* sync_with_child = osthread->startThread_lock();740MutexLocker ml(sync_with_child, Mutex::_no_safepoint_check_flag);741sync_with_child->notify();742}743744// Free Bsd resources related to the OSThread745void os::free_thread(OSThread* osthread) {746assert(osthread != NULL, "osthread not set");747748// We are told to free resources of the argument thread,749// but we can only really operate on the current thread.750assert(Thread::current()->osthread() == osthread,751"os::free_thread but not current thread");752753// Restore caller's signal mask754sigset_t sigmask = osthread->caller_sigmask();755pthread_sigmask(SIG_SETMASK, &sigmask, NULL);756757delete osthread;758}759760////////////////////////////////////////////////////////////////////////////////761// time support762763// Time since start-up in seconds to a fine granularity.764double os::elapsedTime() {765return ((double)os::elapsed_counter()) / os::elapsed_frequency();766}767768jlong os::elapsed_counter() {769return javaTimeNanos() - initial_time_count;770}771772jlong os::elapsed_frequency() {773return NANOSECS_PER_SEC; // nanosecond resolution774}775776bool os::supports_vtime() { return true; }777778double os::elapsedVTime() {779// better than nothing, but not much780return elapsedTime();781}782783#ifdef __APPLE__784void os::Bsd::clock_init() {785mach_timebase_info(&_timebase_info);786}787#else788void os::Bsd::clock_init() {789// Nothing to do790}791#endif792793794795#ifdef __APPLE__796static bool rwxChecked, rwxAvailable;797#endif798bool os::Bsd::isRWXJITAvailable() {799#ifdef __APPLE__800if (!rwxChecked) {801rwxChecked = true;802const int flags = MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS | MAP_JIT;803char* addr = (char*)::mmap(0, getpagesize(), PROT_NONE, flags, -1, 0);804rwxAvailable = addr != MAP_FAILED;805if (rwxAvailable) {806::munmap(addr, getpagesize());807}808}809return rwxAvailable;810#else811return true;812#endif813}814815#ifdef __APPLE__816817jlong os::javaTimeNanos() {818const uint64_t tm = mach_absolute_time();819const uint64_t now = (tm * Bsd::_timebase_info.numer) / Bsd::_timebase_info.denom;820const uint64_t prev = Bsd::_max_abstime;821if (now <= prev) {822return prev; // same or retrograde time;823}824const uint64_t obsv = Atomic::cmpxchg(&Bsd::_max_abstime, prev, now);825assert(obsv >= prev, "invariant"); // Monotonicity826// If the CAS succeeded then we're done and return "now".827// If the CAS failed and the observed value "obsv" is >= now then828// we should return "obsv". If the CAS failed and now > obsv > prv then829// some other thread raced this thread and installed a new value, in which case830// we could either (a) retry the entire operation, (b) retry trying to install now831// or (c) just return obsv. We use (c). No loop is required although in some cases832// we might discard a higher "now" value in deference to a slightly lower but freshly833// installed obsv value. That's entirely benign -- it admits no new orderings compared834// to (a) or (b) -- and greatly reduces coherence traffic.835// We might also condition (c) on the magnitude of the delta between obsv and now.836// Avoiding excessive CAS operations to hot RW locations is critical.837// See https://blogs.oracle.com/dave/entry/cas_and_cache_trivia_invalidate838return (prev == obsv) ? now : obsv;839}840841void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {842info_ptr->max_value = ALL_64_BITS;843info_ptr->may_skip_backward = false; // not subject to resetting or drifting844info_ptr->may_skip_forward = false; // not subject to resetting or drifting845info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time846}847848#endif // __APPLE__849850// Return the real, user, and system times in seconds from an851// arbitrary fixed point in the past.852bool os::getTimesSecs(double* process_real_time,853double* process_user_time,854double* process_system_time) {855struct tms ticks;856clock_t real_ticks = times(&ticks);857858if (real_ticks == (clock_t) (-1)) {859return false;860} else {861double ticks_per_second = (double) clock_tics_per_sec;862*process_user_time = ((double) ticks.tms_utime) / ticks_per_second;863*process_system_time = ((double) ticks.tms_stime) / ticks_per_second;864*process_real_time = ((double) real_ticks) / ticks_per_second;865866return true;867}868}869870871char * os::local_time_string(char *buf, size_t buflen) {872struct tm t;873time_t long_time;874time(&long_time);875localtime_r(&long_time, &t);876jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",877t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,878t.tm_hour, t.tm_min, t.tm_sec);879return buf;880}881882struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {883return localtime_r(clock, res);884}885886// Information of current thread in variety of formats887pid_t os::Bsd::gettid() {888int retval = -1;889890#ifdef __APPLE__ // XNU kernel891mach_port_t port = mach_thread_self();892guarantee(MACH_PORT_VALID(port), "just checking");893mach_port_deallocate(mach_task_self(), port);894return (pid_t)port;895896#else897#ifdef __FreeBSD__898retval = syscall(SYS_thr_self);899#else900#ifdef __OpenBSD__901retval = syscall(SYS_getthrid);902#else903#ifdef __NetBSD__904retval = (pid_t) syscall(SYS__lwp_self);905#endif906#endif907#endif908#endif909910if (retval == -1) {911return getpid();912}913}914915intx os::current_thread_id() {916#ifdef __APPLE__917return (intx)os::Bsd::gettid();918#else919return (intx)::pthread_self();920#endif921}922923int os::current_process_id() {924return (int)(getpid());925}926927// DLL functions928929const char* os::dll_file_extension() { return JNI_LIB_SUFFIX; }930931static int local_dladdr(const void* addr, Dl_info* info) {932#ifdef __APPLE__933if (addr == (void*)-1) {934// dladdr() in macOS12/Monterey returns success for -1, but that addr935// value should not be allowed to work to avoid confusion.936return 0;937}938#endif939return dladdr(addr, info);940}941942// This must be hard coded because it's the system's temporary943// directory not the java application's temp directory, ala java.io.tmpdir.944#ifdef __APPLE__945// macosx has a secure per-user temporary directory946char temp_path_storage[PATH_MAX];947const char* os::get_temp_directory() {948static char *temp_path = NULL;949if (temp_path == NULL) {950int pathSize = confstr(_CS_DARWIN_USER_TEMP_DIR, temp_path_storage, PATH_MAX);951if (pathSize == 0 || pathSize > PATH_MAX) {952strlcpy(temp_path_storage, "/tmp/", sizeof(temp_path_storage));953}954temp_path = temp_path_storage;955}956return temp_path;957}958#else // __APPLE__959const char* os::get_temp_directory() { return "/tmp"; }960#endif // __APPLE__961962// check if addr is inside libjvm.so963bool os::address_is_in_vm(address addr) {964static address libjvm_base_addr;965Dl_info dlinfo;966967if (libjvm_base_addr == NULL) {968if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) {969libjvm_base_addr = (address)dlinfo.dli_fbase;970}971assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm");972}973974if (dladdr((void *)addr, &dlinfo) != 0) {975if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true;976}977978return false;979}980981bool os::dll_address_to_function_name(address addr, char *buf,982int buflen, int *offset,983bool demangle) {984// buf is not optional, but offset is optional985assert(buf != NULL, "sanity check");986987Dl_info dlinfo;988989if (local_dladdr((void*)addr, &dlinfo) != 0) {990// see if we have a matching symbol991if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) {992if (!(demangle && Decoder::demangle(dlinfo.dli_sname, buf, buflen))) {993jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);994}995if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;996return true;997}998999#ifndef __APPLE__1000// The 6-parameter Decoder::decode() function is not implemented on macOS.1001// The Mach-O binary format does not contain a "list of files" with address1002// ranges like ELF. That makes sense since Mach-O can contain binaries for1003// than one instruction set so there can be more than one address range for1004// each "file".10051006// no matching symbol so try for just file info1007if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {1008if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),1009buf, buflen, offset, dlinfo.dli_fname, demangle)) {1010return true;1011}1012}10131014#else // __APPLE__1015#define MACH_MAXSYMLEN 25610161017char localbuf[MACH_MAXSYMLEN];1018// Handle non-dynamic manually:1019if (dlinfo.dli_fbase != NULL &&1020Decoder::decode(addr, localbuf, MACH_MAXSYMLEN, offset,1021dlinfo.dli_fbase)) {1022if (!(demangle && Decoder::demangle(localbuf, buf, buflen))) {1023jio_snprintf(buf, buflen, "%s", localbuf);1024}1025return true;1026}10271028#undef MACH_MAXSYMLEN1029#endif // __APPLE__1030}1031buf[0] = '\0';1032if (offset != NULL) *offset = -1;1033return false;1034}10351036// ported from solaris version1037bool os::dll_address_to_library_name(address addr, char* buf,1038int buflen, int* offset) {1039// buf is not optional, but offset is optional1040assert(buf != NULL, "sanity check");10411042Dl_info dlinfo;10431044if (local_dladdr((void*)addr, &dlinfo) != 0) {1045if (dlinfo.dli_fname != NULL) {1046jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);1047}1048if (dlinfo.dli_fbase != NULL && offset != NULL) {1049*offset = addr - (address)dlinfo.dli_fbase;1050}1051return true;1052}10531054buf[0] = '\0';1055if (offset) *offset = -1;1056return false;1057}10581059// Loads .dll/.so and1060// in case of error it checks if .dll/.so was built for the1061// same architecture as Hotspot is running on10621063#ifdef __APPLE__1064void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {1065#ifdef STATIC_BUILD1066return os::get_default_process_handle();1067#else1068log_info(os)("attempting shared library load of %s", filename);10691070void * result= ::dlopen(filename, RTLD_LAZY);1071if (result != NULL) {1072Events::log_dll_message(NULL, "Loaded shared library %s", filename);1073// Successful loading1074log_info(os)("shared library load of %s was successful", filename);1075return result;1076}10771078const char* error_report = ::dlerror();1079if (error_report == NULL) {1080error_report = "dlerror returned no error description";1081}1082if (ebuf != NULL && ebuflen > 0) {1083// Read system error message into ebuf1084::strncpy(ebuf, error_report, ebuflen-1);1085ebuf[ebuflen-1]='\0';1086}1087Events::log_dll_message(NULL, "Loading shared library %s failed, %s", filename, error_report);1088log_info(os)("shared library load of %s failed, %s", filename, error_report);10891090return NULL;1091#endif // STATIC_BUILD1092}1093#else1094void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {1095#ifdef STATIC_BUILD1096return os::get_default_process_handle();1097#else1098log_info(os)("attempting shared library load of %s", filename);1099void * result= ::dlopen(filename, RTLD_LAZY);1100if (result != NULL) {1101Events::log_dll_message(NULL, "Loaded shared library %s", filename);1102// Successful loading1103log_info(os)("shared library load of %s was successful", filename);1104return result;1105}11061107Elf32_Ehdr elf_head;11081109const char* const error_report = ::dlerror();1110if (error_report == NULL) {1111error_report = "dlerror returned no error description";1112}1113if (ebuf != NULL && ebuflen > 0) {1114// Read system error message into ebuf1115::strncpy(ebuf, error_report, ebuflen-1);1116ebuf[ebuflen-1]='\0';1117}1118Events::log_dll_message(NULL, "Loading shared library %s failed, %s", filename, error_report);1119log_info(os)("shared library load of %s failed, %s", filename, error_report);11201121int diag_msg_max_length=ebuflen-strlen(ebuf);1122char* diag_msg_buf=ebuf+strlen(ebuf);11231124if (diag_msg_max_length==0) {1125// No more space in ebuf for additional diagnostics message1126return NULL;1127}112811291130int file_descriptor= ::open(filename, O_RDONLY | O_NONBLOCK);11311132if (file_descriptor < 0) {1133// Can't open library, report dlerror() message1134return NULL;1135}11361137bool failed_to_read_elf_head=1138(sizeof(elf_head)!=1139(::read(file_descriptor, &elf_head,sizeof(elf_head))));11401141::close(file_descriptor);1142if (failed_to_read_elf_head) {1143// file i/o error - report dlerror() msg1144return NULL;1145}11461147typedef struct {1148Elf32_Half code; // Actual value as defined in elf.h1149Elf32_Half compat_class; // Compatibility of archs at VM's sense1150char elf_class; // 32 or 64 bit1151char endianess; // MSB or LSB1152char* name; // String representation1153} arch_t;11541155#ifndef EM_4861156#define EM_486 6 /* Intel 80486 */1157#endif11581159#ifndef EM_MIPS_RS3_LE1160#define EM_MIPS_RS3_LE 10 /* MIPS */1161#endif11621163#ifndef EM_PPC641164#define EM_PPC64 21 /* PowerPC64 */1165#endif11661167#ifndef EM_S3901168#define EM_S390 22 /* IBM System/390 */1169#endif11701171#ifndef EM_IA_641172#define EM_IA_64 50 /* HP/Intel IA-64 */1173#endif11741175#ifndef EM_X86_641176#define EM_X86_64 62 /* AMD x86-64 */1177#endif11781179static const arch_t arch_array[]={1180{EM_386, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},1181{EM_486, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},1182{EM_IA_64, EM_IA_64, ELFCLASS64, ELFDATA2LSB, (char*)"IA 64"},1183{EM_X86_64, EM_X86_64, ELFCLASS64, ELFDATA2LSB, (char*)"AMD 64"},1184{EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"},1185{EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"},1186{EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"},1187{EM_S390, EM_S390, ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"},1188{EM_ALPHA, EM_ALPHA, ELFCLASS64, ELFDATA2LSB, (char*)"Alpha"},1189{EM_MIPS_RS3_LE, EM_MIPS_RS3_LE, ELFCLASS32, ELFDATA2LSB, (char*)"MIPSel"},1190{EM_MIPS, EM_MIPS, ELFCLASS32, ELFDATA2MSB, (char*)"MIPS"},1191{EM_PARISC, EM_PARISC, ELFCLASS32, ELFDATA2MSB, (char*)"PARISC"},1192{EM_68K, EM_68K, ELFCLASS32, ELFDATA2MSB, (char*)"M68k"}1193};11941195#if (defined IA32)1196static Elf32_Half running_arch_code=EM_386;1197#elif (defined AMD64)1198static Elf32_Half running_arch_code=EM_X86_64;1199#elif (defined IA64)1200static Elf32_Half running_arch_code=EM_IA_64;1201#elif (defined __powerpc64__)1202static Elf32_Half running_arch_code=EM_PPC64;1203#elif (defined __powerpc__)1204static Elf32_Half running_arch_code=EM_PPC;1205#elif (defined ARM)1206static Elf32_Half running_arch_code=EM_ARM;1207#elif (defined S390)1208static Elf32_Half running_arch_code=EM_S390;1209#elif (defined ALPHA)1210static Elf32_Half running_arch_code=EM_ALPHA;1211#elif (defined MIPSEL)1212static Elf32_Half running_arch_code=EM_MIPS_RS3_LE;1213#elif (defined PARISC)1214static Elf32_Half running_arch_code=EM_PARISC;1215#elif (defined MIPS)1216static Elf32_Half running_arch_code=EM_MIPS;1217#elif (defined M68K)1218static Elf32_Half running_arch_code=EM_68K;1219#else1220#error Method os::dll_load requires that one of following is defined:\1221IA32, AMD64, IA64, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K1222#endif12231224// Identify compatability class for VM's architecture and library's architecture1225// Obtain string descriptions for architectures12261227arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL};1228int running_arch_index=-1;12291230for (unsigned int i=0; i < ARRAY_SIZE(arch_array); i++) {1231if (running_arch_code == arch_array[i].code) {1232running_arch_index = i;1233}1234if (lib_arch.code == arch_array[i].code) {1235lib_arch.compat_class = arch_array[i].compat_class;1236lib_arch.name = arch_array[i].name;1237}1238}12391240assert(running_arch_index != -1,1241"Didn't find running architecture code (running_arch_code) in arch_array");1242if (running_arch_index == -1) {1243// Even though running architecture detection failed1244// we may still continue with reporting dlerror() message1245return NULL;1246}12471248if (lib_arch.endianess != arch_array[running_arch_index].endianess) {1249::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)");1250return NULL;1251}12521253#ifndef S3901254if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {1255::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)");1256return NULL;1257}1258#endif // !S39012591260if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) {1261if (lib_arch.name!=NULL) {1262::snprintf(diag_msg_buf, diag_msg_max_length-1,1263" (Possible cause: can't load %s-bit .so on a %s-bit platform)",1264lib_arch.name, arch_array[running_arch_index].name);1265} else {1266::snprintf(diag_msg_buf, diag_msg_max_length-1,1267" (Possible cause: can't load this .so (machine code=0x%x) on a %s-bit platform)",1268lib_arch.code,1269arch_array[running_arch_index].name);1270}1271}12721273return NULL;1274#endif // STATIC_BUILD1275}1276#endif // !__APPLE__12771278int _print_dll_info_cb(const char * name, address base_address, address top_address, void * param) {1279outputStream * out = (outputStream *) param;1280out->print_cr(INTPTR_FORMAT " \t%s", (intptr_t)base_address, name);1281return 0;1282}12831284void os::print_dll_info(outputStream *st) {1285st->print_cr("Dynamic libraries:");1286if (get_loaded_modules_info(_print_dll_info_cb, (void *)st)) {1287st->print_cr("Error: Cannot print dynamic libraries.");1288}1289}12901291int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) {1292#ifdef RTLD_DI_LINKMAP1293Dl_info dli;1294void *handle;1295Link_map *map;1296Link_map *p;12971298if (dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli) == 0 ||1299dli.dli_fname == NULL) {1300return 1;1301}1302handle = dlopen(dli.dli_fname, RTLD_LAZY);1303if (handle == NULL) {1304return 1;1305}1306dlinfo(handle, RTLD_DI_LINKMAP, &map);1307if (map == NULL) {1308dlclose(handle);1309return 1;1310}13111312while (map->l_prev != NULL)1313map = map->l_prev;13141315while (map != NULL) {1316// Value for top_address is returned as 0 since we don't have any information about module size1317if (callback(map->l_name, (address)map->l_addr, (address)0, param)) {1318dlclose(handle);1319return 1;1320}1321map = map->l_next;1322}13231324dlclose(handle);1325#elif defined(__APPLE__)1326for (uint32_t i = 1; i < _dyld_image_count(); i++) {1327// Value for top_address is returned as 0 since we don't have any information about module size1328if (callback(_dyld_get_image_name(i), (address)_dyld_get_image_header(i), (address)0, param)) {1329return 1;1330}1331}1332return 0;1333#else1334return 1;1335#endif1336}13371338void os::get_summary_os_info(char* buf, size_t buflen) {1339// These buffers are small because we want this to be brief1340// and not use a lot of stack while generating the hs_err file.1341char os[100];1342size_t size = sizeof(os);1343int mib_kern[] = { CTL_KERN, KERN_OSTYPE };1344if (sysctl(mib_kern, 2, os, &size, NULL, 0) < 0) {1345#ifdef __APPLE__1346strncpy(os, "Darwin", sizeof(os));1347#elif __OpenBSD__1348strncpy(os, "OpenBSD", sizeof(os));1349#else1350strncpy(os, "BSD", sizeof(os));1351#endif1352}13531354char release[100];1355size = sizeof(release);1356int mib_release[] = { CTL_KERN, KERN_OSRELEASE };1357if (sysctl(mib_release, 2, release, &size, NULL, 0) < 0) {1358// if error, leave blank1359strncpy(release, "", sizeof(release));1360}13611362#ifdef __APPLE__1363char osproductversion[100];1364size_t sz = sizeof(osproductversion);1365int ret = sysctlbyname("kern.osproductversion", osproductversion, &sz, NULL, 0);1366if (ret == 0) {1367char build[100];1368size = sizeof(build);1369int mib_build[] = { CTL_KERN, KERN_OSVERSION };1370if (sysctl(mib_build, 2, build, &size, NULL, 0) < 0) {1371snprintf(buf, buflen, "%s %s, macOS %s", os, release, osproductversion);1372} else {1373snprintf(buf, buflen, "%s %s, macOS %s (%s)", os, release, osproductversion, build);1374}1375} else1376#endif1377snprintf(buf, buflen, "%s %s", os, release);1378}13791380void os::print_os_info_brief(outputStream* st) {1381os::Posix::print_uname_info(st);1382}13831384void os::print_os_info(outputStream* st) {1385st->print_cr("OS:");13861387os::Posix::print_uname_info(st);13881389os::Bsd::print_uptime_info(st);13901391os::Posix::print_rlimit_info(st);13921393os::Posix::print_load_average(st);13941395VM_Version::print_platform_virtualization_info(st);1396}13971398void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) {1399// Nothing to do for now.1400}14011402void os::get_summary_cpu_info(char* buf, size_t buflen) {1403unsigned int mhz;1404size_t size = sizeof(mhz);1405int mib[] = { CTL_HW, HW_CPU_FREQ };1406if (sysctl(mib, 2, &mhz, &size, NULL, 0) < 0) {1407mhz = 1; // looks like an error but can be divided by1408} else {1409mhz /= 1000000; // reported in millions1410}14111412char model[100];1413size = sizeof(model);1414int mib_model[] = { CTL_HW, HW_MODEL };1415if (sysctl(mib_model, 2, model, &size, NULL, 0) < 0) {1416strncpy(model, cpu_arch, sizeof(model));1417}14181419char machine[100];1420size = sizeof(machine);1421int mib_machine[] = { CTL_HW, HW_MACHINE };1422if (sysctl(mib_machine, 2, machine, &size, NULL, 0) < 0) {1423strncpy(machine, "", sizeof(machine));1424}14251426#if defined(__APPLE__) && !defined(ZERO)1427if (VM_Version::is_cpu_emulated()) {1428snprintf(buf, buflen, "\"%s\" %s (EMULATED) %d MHz", model, machine, mhz);1429} else {1430NOT_AARCH64(snprintf(buf, buflen, "\"%s\" %s %d MHz", model, machine, mhz));1431// aarch64 CPU doesn't report its speed1432AARCH64_ONLY(snprintf(buf, buflen, "\"%s\" %s", model, machine));1433}1434#else1435snprintf(buf, buflen, "\"%s\" %s %d MHz", model, machine, mhz);1436#endif1437}14381439void os::print_memory_info(outputStream* st) {1440xsw_usage swap_usage;1441size_t size = sizeof(swap_usage);14421443st->print("Memory:");1444st->print(" %dk page", os::vm_page_size()>>10);14451446st->print(", physical " UINT64_FORMAT "k",1447os::physical_memory() >> 10);1448st->print("(" UINT64_FORMAT "k free)",1449os::available_memory() >> 10);14501451if((sysctlbyname("vm.swapusage", &swap_usage, &size, NULL, 0) == 0) || (errno == ENOMEM)) {1452if (size >= offset_of(xsw_usage, xsu_used)) {1453st->print(", swap " UINT64_FORMAT "k",1454((julong) swap_usage.xsu_total) >> 10);1455st->print("(" UINT64_FORMAT "k free)",1456((julong) swap_usage.xsu_avail) >> 10);1457}1458}14591460st->cr();1461}14621463static char saved_jvm_path[MAXPATHLEN] = {0};14641465// Find the full path to the current module, libjvm1466void os::jvm_path(char *buf, jint buflen) {1467// Error checking.1468if (buflen < MAXPATHLEN) {1469assert(false, "must use a large-enough buffer");1470buf[0] = '\0';1471return;1472}1473// Lazy resolve the path to current module.1474if (saved_jvm_path[0] != 0) {1475strcpy(buf, saved_jvm_path);1476return;1477}14781479char dli_fname[MAXPATHLEN];1480dli_fname[0] = '\0';1481bool ret = dll_address_to_library_name(1482CAST_FROM_FN_PTR(address, os::jvm_path),1483dli_fname, sizeof(dli_fname), NULL);1484assert(ret, "cannot locate libjvm");1485char *rp = NULL;1486if (ret && dli_fname[0] != '\0') {1487rp = os::Posix::realpath(dli_fname, buf, buflen);1488}1489if (rp == NULL) {1490return;1491}14921493if (Arguments::sun_java_launcher_is_altjvm()) {1494// Support for the java launcher's '-XXaltjvm=<path>' option. Typical1495// value for buf is "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so"1496// or "<JAVA_HOME>/jre/lib/<vmtype>/libjvm.dylib". If "/jre/lib/"1497// appears at the right place in the string, then assume we are1498// installed in a JDK and we're done. Otherwise, check for a1499// JAVA_HOME environment variable and construct a path to the JVM1500// being overridden.15011502const char *p = buf + strlen(buf) - 1;1503for (int count = 0; p > buf && count < 5; ++count) {1504for (--p; p > buf && *p != '/'; --p)1505/* empty */ ;1506}15071508if (strncmp(p, "/jre/lib/", 9) != 0) {1509// Look for JAVA_HOME in the environment.1510char* java_home_var = ::getenv("JAVA_HOME");1511if (java_home_var != NULL && java_home_var[0] != 0) {1512char* jrelib_p;1513int len;15141515// Check the current module name "libjvm"1516p = strrchr(buf, '/');1517assert(strstr(p, "/libjvm") == p, "invalid library name");15181519rp = os::Posix::realpath(java_home_var, buf, buflen);1520if (rp == NULL) {1521return;1522}15231524// determine if this is a legacy image or modules image1525// modules image doesn't have "jre" subdirectory1526len = strlen(buf);1527assert(len < buflen, "Ran out of buffer space");1528jrelib_p = buf + len;15291530// Add the appropriate library subdir1531snprintf(jrelib_p, buflen-len, "/jre/lib");1532if (0 != access(buf, F_OK)) {1533snprintf(jrelib_p, buflen-len, "/lib");1534}15351536// Add the appropriate client or server subdir1537len = strlen(buf);1538jrelib_p = buf + len;1539snprintf(jrelib_p, buflen-len, "/%s", COMPILER_VARIANT);1540if (0 != access(buf, F_OK)) {1541snprintf(jrelib_p, buflen-len, "%s", "");1542}15431544// If the path exists within JAVA_HOME, add the JVM library name1545// to complete the path to JVM being overridden. Otherwise fallback1546// to the path to the current library.1547if (0 == access(buf, F_OK)) {1548// Use current module name "libjvm"1549len = strlen(buf);1550snprintf(buf + len, buflen-len, "/libjvm%s", JNI_LIB_SUFFIX);1551} else {1552// Fall back to path of current library1553rp = os::Posix::realpath(dli_fname, buf, buflen);1554if (rp == NULL) {1555return;1556}1557}1558}1559}1560}15611562strncpy(saved_jvm_path, buf, MAXPATHLEN);1563saved_jvm_path[MAXPATHLEN - 1] = '\0';1564}15651566void os::print_jni_name_prefix_on(outputStream* st, int args_size) {1567// no prefix required, not even "_"1568}15691570void os::print_jni_name_suffix_on(outputStream* st, int args_size) {1571// no suffix required1572}15731574////////////////////////////////////////////////////////////////////////////////1575// Virtual Memory15761577int os::vm_page_size() {1578// Seems redundant as all get out1579assert(os::Bsd::page_size() != -1, "must call os::init");1580return os::Bsd::page_size();1581}15821583// Solaris allocates memory by pages.1584int os::vm_allocation_granularity() {1585assert(os::Bsd::page_size() != -1, "must call os::init");1586return os::Bsd::page_size();1587}15881589static void warn_fail_commit_memory(char* addr, size_t size, bool exec,1590int err) {1591warning("INFO: os::commit_memory(" INTPTR_FORMAT ", " SIZE_FORMAT1592", %d) failed; error='%s' (errno=%d)", (intptr_t)addr, size, exec,1593os::errno_name(err), err);1594}15951596// NOTE: Bsd kernel does not really reserve the pages for us.1597// All it does is to check if there are enough free pages1598// left at the time of mmap(). This could be a potential1599// problem.1600bool os::pd_commit_memory(char* addr, size_t size, bool exec) {1601int prot = exec&&os::Bsd::isRWXJITAvailable() ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;1602#if defined(__OpenBSD__)1603// XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD1604Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot);1605if (::mprotect(addr, size, prot) == 0) {1606return true;1607}1608#elif defined(__APPLE__)1609if (exec) {1610// Do not replace MAP_JIT mappings, see JDK-82349301611if (::mprotect(addr, size, prot) == 0) {1612return true;1613}1614} else {1615uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,1616MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);1617if (res != (uintptr_t) MAP_FAILED) {1618return true;1619}1620}1621#else1622uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,1623MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);1624if (res != (uintptr_t) MAP_FAILED) {1625return true;1626}1627#endif16281629// Warn about any commit errors we see in non-product builds just1630// in case mmap() doesn't work as described on the man page.1631NOT_PRODUCT(warn_fail_commit_memory(addr, size, exec, errno);)16321633return false;1634}16351636bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,1637bool exec) {1638// alignment_hint is ignored on this OS1639return pd_commit_memory(addr, size, exec);1640}16411642void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,1643const char* mesg) {1644assert(mesg != NULL, "mesg must be specified");1645if (!pd_commit_memory(addr, size, exec)) {1646// add extra info in product mode for vm_exit_out_of_memory():1647PRODUCT_ONLY(warn_fail_commit_memory(addr, size, exec, errno);)1648vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "%s", mesg);1649}1650}16511652void os::pd_commit_memory_or_exit(char* addr, size_t size,1653size_t alignment_hint, bool exec,1654const char* mesg) {1655// alignment_hint is ignored on this OS1656pd_commit_memory_or_exit(addr, size, exec, mesg);1657}16581659void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {1660}16611662void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) {1663::madvise(addr, bytes, MADV_DONTNEED);1664}16651666void os::numa_make_global(char *addr, size_t bytes) {1667}16681669void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) {1670}16711672bool os::numa_topology_changed() { return false; }16731674size_t os::numa_get_groups_num() {1675return 1;1676}16771678int os::numa_get_group_id() {1679return 0;1680}16811682size_t os::numa_get_leaf_groups(int *ids, size_t size) {1683if (size > 0) {1684ids[0] = 0;1685return 1;1686}1687return 0;1688}16891690int os::numa_get_group_id_for_address(const void* address) {1691return 0;1692}16931694bool os::get_page_info(char *start, page_info* info) {1695return false;1696}16971698char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) {1699return end;1700}170117021703bool os::pd_uncommit_memory(char* addr, size_t size, bool exec) {1704#if defined(__OpenBSD__)1705// XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD1706Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with PROT_NONE", p2i(addr), p2i(addr+size));1707return ::mprotect(addr, size, PROT_NONE) == 0;1708#elif defined(__APPLE__)1709if (exec) {1710if (::madvise(addr, size, MADV_FREE) != 0) {1711return false;1712}1713return ::mprotect(addr, size, PROT_NONE) == 0;1714} else {1715uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE,1716MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0);1717return res != (uintptr_t) MAP_FAILED;1718}1719#else1720uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE,1721MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0);1722return res != (uintptr_t) MAP_FAILED;1723#endif1724}17251726bool os::pd_create_stack_guard_pages(char* addr, size_t size) {1727return os::commit_memory(addr, size, !ExecMem);1728}17291730// If this is a growable mapping, remove the guard pages entirely by1731// munmap()ping them. If not, just call uncommit_memory().1732bool os::remove_stack_guard_pages(char* addr, size_t size) {1733return os::uncommit_memory(addr, size);1734}17351736// 'requested_addr' is only treated as a hint, the return value may or1737// may not start from the requested address. Unlike Bsd mmap(), this1738// function returns NULL to indicate failure.1739static char* anon_mmap(char* requested_addr, size_t bytes, bool exec) {1740// MAP_FIXED is intentionally left out, to leave existing mappings intact.1741const int flags = MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS1742MACOS_ONLY(| (exec && os::Bsd::isRWXJITAvailable() ? MAP_JIT : 0));17431744// Map reserved/uncommitted pages PROT_NONE so we fail early if we1745// touch an uncommitted page. Otherwise, the read/write might1746// succeed if we have enough swap space to back the physical page.1747char* addr = (char*)::mmap(requested_addr, bytes, PROT_NONE, flags, -1, 0);17481749return addr == MAP_FAILED ? NULL : addr;1750}17511752static int anon_munmap(char * addr, size_t size) {1753return ::munmap(addr, size) == 0;1754}17551756char* os::pd_reserve_memory(size_t bytes, bool exec) {1757return anon_mmap(NULL /* addr */, bytes, exec);1758}17591760bool os::pd_release_memory(char* addr, size_t size) {1761return anon_munmap(addr, size);1762}17631764static bool bsd_mprotect(char* addr, size_t size, int prot) {1765// Bsd wants the mprotect address argument to be page aligned.1766char* bottom = (char*)align_down((intptr_t)addr, os::Bsd::page_size());17671768// According to SUSv3, mprotect() should only be used with mappings1769// established by mmap(), and mmap() always maps whole pages. Unaligned1770// 'addr' likely indicates problem in the VM (e.g. trying to change1771// protection of malloc'ed or statically allocated memory). Check the1772// caller if you hit this assert.1773assert(addr == bottom, "sanity check");17741775size = align_up(pointer_delta(addr, bottom, 1) + size, os::Bsd::page_size());1776Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(bottom), p2i(bottom+size), prot);1777return ::mprotect(bottom, size, prot) == 0;1778}17791780// Set protections specified1781bool os::protect_memory(char* addr, size_t bytes, ProtType prot,1782bool is_committed) {1783unsigned int p = 0;1784switch (prot) {1785case MEM_PROT_NONE: p = PROT_NONE; break;1786case MEM_PROT_READ: p = PROT_READ; break;1787case MEM_PROT_RW: p = PROT_READ|PROT_WRITE; break;1788case MEM_PROT_RWX: p = PROT_READ|PROT_WRITE|PROT_EXEC; break;1789default:1790ShouldNotReachHere();1791}1792// is_committed is unused.1793return bsd_mprotect(addr, bytes, p);1794}17951796bool os::guard_memory(char* addr, size_t size) {1797return bsd_mprotect(addr, size, PROT_NONE);1798}17991800bool os::unguard_memory(char* addr, size_t size) {1801return bsd_mprotect(addr, size, PROT_READ|PROT_WRITE);1802}18031804bool os::Bsd::hugetlbfs_sanity_check(bool warn, size_t page_size) {1805return false;1806}18071808// Large page support18091810static size_t _large_page_size = 0;18111812void os::large_page_init() {1813}181418151816char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, size_t page_size, char* req_addr, bool exec) {1817fatal("os::reserve_memory_special should not be called on BSD.");1818return NULL;1819}18201821bool os::pd_release_memory_special(char* base, size_t bytes) {1822fatal("os::release_memory_special should not be called on BSD.");1823return false;1824}18251826size_t os::large_page_size() {1827return _large_page_size;1828}18291830bool os::can_commit_large_page_memory() {1831// Does not matter, we do not support huge pages.1832return false;1833}18341835bool os::can_execute_large_page_memory() {1836// Does not matter, we do not support huge pages.1837return false;1838}18391840char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) {1841assert(file_desc >= 0, "file_desc is not valid");1842char* result = pd_attempt_reserve_memory_at(requested_addr, bytes, !ExecMem);1843if (result != NULL) {1844if (replace_existing_mapping_with_file_mapping(result, bytes, file_desc) == NULL) {1845vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));1846}1847}1848return result;1849}18501851// Reserve memory at an arbitrary address, only if that area is1852// available (and not reserved for something else).18531854char* os::pd_attempt_reserve_memory_at(char* requested_addr, size_t bytes, bool exec) {1855// Assert only that the size is a multiple of the page size, since1856// that's all that mmap requires, and since that's all we really know1857// about at this low abstraction level. If we need higher alignment,1858// we can either pass an alignment to this method or verify alignment1859// in one of the methods further up the call chain. See bug 5044738.1860assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block");18611862// Repeatedly allocate blocks until the block is allocated at the1863// right spot.18641865// Bsd mmap allows caller to pass an address as hint; give it a try first,1866// if kernel honors the hint then we can return immediately.1867char * addr = anon_mmap(requested_addr, bytes, exec);1868if (addr == requested_addr) {1869return requested_addr;1870}18711872if (addr != NULL) {1873// mmap() is successful but it fails to reserve at the requested address1874anon_munmap(addr, bytes);1875}18761877return NULL;1878}18791880// Used to convert frequent JVM_Yield() to nops1881bool os::dont_yield() {1882return DontYieldALot;1883}18841885void os::naked_yield() {1886sched_yield();1887}18881889////////////////////////////////////////////////////////////////////////////////1890// thread priority support18911892// Note: Normal Bsd applications are run with SCHED_OTHER policy. SCHED_OTHER1893// only supports dynamic priority, static priority must be zero. For real-time1894// applications, Bsd supports SCHED_RR which allows static priority (1-99).1895// However, for large multi-threaded applications, SCHED_RR is not only slower1896// than SCHED_OTHER, but also very unstable (my volano tests hang hard 4 out1897// of 5 runs - Sep 2005).1898//1899// The following code actually changes the niceness of kernel-thread/LWP. It1900// has an assumption that setpriority() only modifies one kernel-thread/LWP,1901// not the entire user process, and user level threads are 1:1 mapped to kernel1902// threads. It has always been the case, but could change in the future. For1903// this reason, the code should not be used as default (ThreadPriorityPolicy=0).1904// It is only used when ThreadPriorityPolicy=1 and may require system level permission1905// (e.g., root privilege or CAP_SYS_NICE capability).19061907#if !defined(__APPLE__)1908int os::java_to_os_priority[CriticalPriority + 1] = {190919, // 0 Entry should never be used191019110, // 1 MinPriority19123, // 219136, // 31914191510, // 4191615, // 5 NormPriority191718, // 61918191921, // 7192025, // 8192128, // 9 NearMaxPriority1922192331, // 10 MaxPriority1924192531 // 11 CriticalPriority1926};1927#else1928// Using Mach high-level priority assignments1929int os::java_to_os_priority[CriticalPriority + 1] = {19300, // 0 Entry should never be used (MINPRI_USER)1931193227, // 1 MinPriority193328, // 2193429, // 31935193630, // 4193731, // 5 NormPriority (BASEPRI_DEFAULT)193832, // 61939194033, // 7194134, // 8194235, // 9 NearMaxPriority1943194436, // 10 MaxPriority1945194636 // 11 CriticalPriority1947};1948#endif19491950static int prio_init() {1951if (ThreadPriorityPolicy == 1) {1952if (geteuid() != 0) {1953if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy) && !FLAG_IS_JIMAGE_RESOURCE(ThreadPriorityPolicy)) {1954warning("-XX:ThreadPriorityPolicy=1 may require system level permission, " \1955"e.g., being the root user. If the necessary permission is not " \1956"possessed, changes to priority will be silently ignored.");1957}1958}1959}1960if (UseCriticalJavaThreadPriority) {1961os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority];1962}1963return 0;1964}19651966OSReturn os::set_native_priority(Thread* thread, int newpri) {1967if (!UseThreadPriorities || ThreadPriorityPolicy == 0) return OS_OK;19681969#ifdef __OpenBSD__1970// OpenBSD pthread_setprio starves low priority threads1971return OS_OK;1972#elif defined(__FreeBSD__)1973int ret = pthread_setprio(thread->osthread()->pthread_id(), newpri);1974return (ret == 0) ? OS_OK : OS_ERR;1975#elif defined(__APPLE__) || defined(__NetBSD__)1976struct sched_param sp;1977int policy;19781979if (pthread_getschedparam(thread->osthread()->pthread_id(), &policy, &sp) != 0) {1980return OS_ERR;1981}19821983sp.sched_priority = newpri;1984if (pthread_setschedparam(thread->osthread()->pthread_id(), policy, &sp) != 0) {1985return OS_ERR;1986}19871988return OS_OK;1989#else1990int ret = setpriority(PRIO_PROCESS, thread->osthread()->thread_id(), newpri);1991return (ret == 0) ? OS_OK : OS_ERR;1992#endif1993}19941995OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {1996if (!UseThreadPriorities || ThreadPriorityPolicy == 0) {1997*priority_ptr = java_to_os_priority[NormPriority];1998return OS_OK;1999}20002001errno = 0;2002#if defined(__OpenBSD__) || defined(__FreeBSD__)2003*priority_ptr = pthread_getprio(thread->osthread()->pthread_id());2004#elif defined(__APPLE__) || defined(__NetBSD__)2005int policy;2006struct sched_param sp;20072008int res = pthread_getschedparam(thread->osthread()->pthread_id(), &policy, &sp);2009if (res != 0) {2010*priority_ptr = -1;2011return OS_ERR;2012} else {2013*priority_ptr = sp.sched_priority;2014return OS_OK;2015}2016#else2017*priority_ptr = getpriority(PRIO_PROCESS, thread->osthread()->thread_id());2018#endif2019return (*priority_ptr != -1 || errno == 0 ? OS_OK : OS_ERR);2020}20212022extern void report_error(char* file_name, int line_no, char* title,2023char* format, ...);20242025// this is called _before_ the most of global arguments have been parsed2026void os::init(void) {2027char dummy; // used to get a guess on initial stack address20282029clock_tics_per_sec = CLK_TCK;20302031Bsd::set_page_size(getpagesize());2032if (Bsd::page_size() == -1) {2033fatal("os_bsd.cpp: os::init: sysconf failed (%s)", os::strerror(errno));2034}2035_page_sizes.add(Bsd::page_size());20362037Bsd::initialize_system_info();20382039// _main_thread points to the thread that created/loaded the JVM.2040Bsd::_main_thread = pthread_self();20412042Bsd::clock_init();2043initial_time_count = javaTimeNanos();20442045os::Posix::init();2046}20472048// To install functions for atexit system call2049extern "C" {2050static void perfMemory_exit_helper() {2051perfMemory_exit();2052}2053}20542055// this is called _after_ the global arguments have been parsed2056jint os::init_2(void) {20572058// This could be set after os::Posix::init() but all platforms2059// have to set it the same so we have to mirror Solaris.2060DEBUG_ONLY(os::set_mutex_init_done();)20612062os::Posix::init_2();20632064if (PosixSignals::init() == JNI_ERR) {2065return JNI_ERR;2066}20672068// Check and sets minimum stack sizes against command line options2069if (Posix::set_minimum_stack_sizes() == JNI_ERR) {2070return JNI_ERR;2071}20722073// Not supported.2074FLAG_SET_ERGO(UseNUMA, false);2075FLAG_SET_ERGO(UseNUMAInterleaving, false);20762077if (MaxFDLimit) {2078// set the number of file descriptors to max. print out error2079// if getrlimit/setrlimit fails but continue regardless.2080struct rlimit nbr_files;2081int status = getrlimit(RLIMIT_NOFILE, &nbr_files);2082if (status != 0) {2083log_info(os)("os::init_2 getrlimit failed: %s", os::strerror(errno));2084} else {2085nbr_files.rlim_cur = nbr_files.rlim_max;20862087#ifdef __APPLE__2088// Darwin returns RLIM_INFINITY for rlim_max, but fails with EINVAL if2089// you attempt to use RLIM_INFINITY. As per setrlimit(2), OPEN_MAX must2090// be used instead2091nbr_files.rlim_cur = MIN(OPEN_MAX, nbr_files.rlim_cur);2092#endif20932094status = setrlimit(RLIMIT_NOFILE, &nbr_files);2095if (status != 0) {2096log_info(os)("os::init_2 setrlimit failed: %s", os::strerror(errno));2097}2098}2099}21002101// at-exit methods are called in the reverse order of their registration.2102// atexit functions are called on return from main or as a result of a2103// call to exit(3C). There can be only 32 of these functions registered2104// and atexit() does not set errno.21052106if (PerfAllowAtExitRegistration) {2107// only register atexit functions if PerfAllowAtExitRegistration is set.2108// atexit functions can be delayed until process exit time, which2109// can be problematic for embedded VM situations. Embedded VMs should2110// call DestroyJavaVM() to assure that VM resources are released.21112112// note: perfMemory_exit_helper atexit function may be removed in2113// the future if the appropriate cleanup code can be added to the2114// VM_Exit VMOperation's doit method.2115if (atexit(perfMemory_exit_helper) != 0) {2116warning("os::init_2 atexit(perfMemory_exit_helper) failed");2117}2118}21192120// initialize thread priority policy2121prio_init();21222123#ifdef __APPLE__2124// dynamically link to objective c gc registration2125void *handleLibObjc = dlopen(OBJC_LIB, RTLD_LAZY);2126if (handleLibObjc != NULL) {2127objc_registerThreadWithCollectorFunction = (objc_registerThreadWithCollector_t) dlsym(handleLibObjc, OBJC_GCREGISTER);2128}2129#endif21302131return JNI_OK;2132}21332134int os::active_processor_count() {2135// User has overridden the number of active processors2136if (ActiveProcessorCount > 0) {2137log_trace(os)("active_processor_count: "2138"active processor count set by user : %d",2139ActiveProcessorCount);2140return ActiveProcessorCount;2141}21422143return _processor_count;2144}21452146uint os::processor_id() {2147#if defined(__APPLE__) && defined(__x86_64__)2148// Get the initial APIC id and return the associated processor id. The initial APIC2149// id is limited to 8-bits, which means we can have at most 256 unique APIC ids. If2150// the system has more processors (or the initial APIC ids are discontiguous) the2151// APIC id will be truncated and more than one processor will potentially share the2152// same processor id. This is not optimal, but unlikely to happen in practice. Should2153// this become a real problem we could switch to using x2APIC ids, which are 32-bit2154// wide. However, note that x2APIC is Intel-specific, and the wider number space2155// would require a more complicated mapping approach.2156uint eax = 0x1;2157uint ebx;2158uint ecx = 0;2159uint edx;21602161__asm__ ("cpuid\n\t" : "+a" (eax), "+b" (ebx), "+c" (ecx), "+d" (edx) : );21622163uint apic_id = (ebx >> 24) & (processor_id_map_size - 1);2164int processor_id = Atomic::load(&processor_id_map[apic_id]);21652166while (processor_id < 0) {2167// Assign processor id to APIC id2168processor_id = Atomic::cmpxchg(&processor_id_map[apic_id], processor_id_unassigned, processor_id_assigning);2169if (processor_id == processor_id_unassigned) {2170processor_id = Atomic::fetch_and_add(&processor_id_next, 1) % os::processor_count();2171Atomic::store(&processor_id_map[apic_id], processor_id);2172}2173}21742175assert(processor_id >= 0 && processor_id < os::processor_count(), "invalid processor id");21762177return (uint)processor_id;2178#else // defined(__APPLE__) && defined(__x86_64__)2179// Return 0 until we find a good way to get the current processor id on2180// the platform. Returning 0 is safe, since there is always at least one2181// processor, but might not be optimal for performance in some cases.2182return 0;2183#endif2184}21852186void os::set_native_thread_name(const char *name) {2187#if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_52188// This is only supported in Snow Leopard and beyond2189if (name != NULL) {2190// Add a "Java: " prefix to the name2191char buf[MAXTHREADNAMESIZE];2192snprintf(buf, sizeof(buf), "Java: %s", name);2193pthread_setname_np(buf);2194}2195#endif2196}21972198bool os::bind_to_processor(uint processor_id) {2199// Not yet implemented.2200return false;2201}22022203////////////////////////////////////////////////////////////////////////////////2204// debug support22052206bool os::find(address addr, outputStream* st) {2207Dl_info dlinfo;2208memset(&dlinfo, 0, sizeof(dlinfo));2209if (dladdr(addr, &dlinfo) != 0) {2210st->print(INTPTR_FORMAT ": ", (intptr_t)addr);2211if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) {2212st->print("%s+%#x", dlinfo.dli_sname,2213(uint)((uintptr_t)addr - (uintptr_t)dlinfo.dli_saddr));2214} else if (dlinfo.dli_fbase != NULL) {2215st->print("<offset %#x>", (uint)((uintptr_t)addr - (uintptr_t)dlinfo.dli_fbase));2216} else {2217st->print("<absolute address>");2218}2219if (dlinfo.dli_fname != NULL) {2220st->print(" in %s", dlinfo.dli_fname);2221}2222if (dlinfo.dli_fbase != NULL) {2223st->print(" at " INTPTR_FORMAT, (intptr_t)dlinfo.dli_fbase);2224}2225st->cr();22262227if (Verbose) {2228// decode some bytes around the PC2229address begin = clamp_address_in_page(addr-40, addr, os::vm_page_size());2230address end = clamp_address_in_page(addr+40, addr, os::vm_page_size());2231address lowest = (address) dlinfo.dli_sname;2232if (!lowest) lowest = (address) dlinfo.dli_fbase;2233if (begin < lowest) begin = lowest;2234Dl_info dlinfo2;2235if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr2236&& end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) {2237end = (address) dlinfo2.dli_saddr;2238}2239Disassembler::decode(begin, end, st);2240}2241return true;2242}2243return false;2244}22452246////////////////////////////////////////////////////////////////////////////////2247// misc22482249// This does not do anything on Bsd. This is basically a hook for being2250// able to use structured exception handling (thread-local exception filters)2251// on, e.g., Win32.2252void os::os_exception_wrapper(java_call_t f, JavaValue* value,2253const methodHandle& method, JavaCallArguments* args,2254JavaThread* thread) {2255f(value, method, args, thread);2256}22572258void os::print_statistics() {2259}22602261bool os::message_box(const char* title, const char* message) {2262int i;2263fdStream err(defaultStream::error_fd());2264for (i = 0; i < 78; i++) err.print_raw("=");2265err.cr();2266err.print_raw_cr(title);2267for (i = 0; i < 78; i++) err.print_raw("-");2268err.cr();2269err.print_raw_cr(message);2270for (i = 0; i < 78; i++) err.print_raw("=");2271err.cr();22722273char buf[16];2274// Prevent process from exiting upon "read error" without consuming all CPU2275while (::read(0, buf, sizeof(buf)) <= 0) { ::sleep(100); }22762277return buf[0] == 'y' || buf[0] == 'Y';2278}22792280static inline struct timespec get_mtime(const char* filename) {2281struct stat st;2282int ret = os::stat(filename, &st);2283assert(ret == 0, "failed to stat() file '%s': %s", filename, os::strerror(errno));2284#ifdef __APPLE__2285return st.st_mtimespec;2286#else2287return st.st_mtim;2288#endif2289}22902291int os::compare_file_modified_times(const char* file1, const char* file2) {2292struct timespec filetime1 = get_mtime(file1);2293struct timespec filetime2 = get_mtime(file2);2294int diff = filetime1.tv_sec - filetime2.tv_sec;2295if (diff == 0) {2296return filetime1.tv_nsec - filetime2.tv_nsec;2297}2298return diff;2299}23002301// This code originates from JDK's sysOpen and open64_w2302// from src/solaris/hpi/src/system_md.c23032304int os::open(const char *path, int oflag, int mode) {2305if (strlen(path) > MAX_PATH - 1) {2306errno = ENAMETOOLONG;2307return -1;2308}2309int fd;23102311fd = ::open(path, oflag, mode);2312if (fd == -1) return -1;23132314// If the open succeeded, the file might still be a directory2315{2316struct stat buf;2317int ret = ::fstat(fd, &buf);2318int st_mode = buf.st_mode;23192320if (ret != -1) {2321if ((st_mode & S_IFMT) == S_IFDIR) {2322errno = EISDIR;2323::close(fd);2324return -1;2325}2326} else {2327::close(fd);2328return -1;2329}2330}23312332// All file descriptors that are opened in the JVM and not2333// specifically destined for a subprocess should have the2334// close-on-exec flag set. If we don't set it, then careless 3rd2335// party native code might fork and exec without closing all2336// appropriate file descriptors (e.g. as we do in closeDescriptors in2337// UNIXProcess.c), and this in turn might:2338//2339// - cause end-of-file to fail to be detected on some file2340// descriptors, resulting in mysterious hangs, or2341//2342// - might cause an fopen in the subprocess to fail on a system2343// suffering from bug 1085341.2344//2345// (Yes, the default setting of the close-on-exec flag is a Unix2346// design flaw)2347//2348// See:2349// 1085341: 32-bit stdio routines should support file descriptors >2552350// 4843136: (process) pipe file descriptor from Runtime.exec not being closed2351// 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 92352//2353#ifdef FD_CLOEXEC2354{2355int flags = ::fcntl(fd, F_GETFD);2356if (flags != -1) {2357::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);2358}2359}2360#endif23612362return fd;2363}236423652366// create binary file, rewriting existing file if required2367int os::create_binary_file(const char* path, bool rewrite_existing) {2368int oflags = O_WRONLY | O_CREAT;2369oflags |= rewrite_existing ? O_TRUNC : O_EXCL;2370return ::open(path, oflags, S_IREAD | S_IWRITE);2371}23722373// return current position of file pointer2374jlong os::current_file_offset(int fd) {2375return (jlong)::lseek(fd, (off_t)0, SEEK_CUR);2376}23772378// move file pointer to the specified offset2379jlong os::seek_to_file_offset(int fd, jlong offset) {2380return (jlong)::lseek(fd, (off_t)offset, SEEK_SET);2381}23822383// This code originates from JDK's sysAvailable2384// from src/solaris/hpi/src/native_threads/src/sys_api_td.c23852386int os::available(int fd, jlong *bytes) {2387jlong cur, end;2388int mode;2389struct stat buf;23902391if (::fstat(fd, &buf) >= 0) {2392mode = buf.st_mode;2393if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {2394int n;2395if (::ioctl(fd, FIONREAD, &n) >= 0) {2396*bytes = n;2397return 1;2398}2399}2400}2401if ((cur = ::lseek(fd, 0L, SEEK_CUR)) == -1) {2402return 0;2403} else if ((end = ::lseek(fd, 0L, SEEK_END)) == -1) {2404return 0;2405} else if (::lseek(fd, cur, SEEK_SET) == -1) {2406return 0;2407}2408*bytes = end - cur;2409return 1;2410}24112412// Map a block of memory.2413char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,2414char *addr, size_t bytes, bool read_only,2415bool allow_exec) {2416int prot;2417int flags;24182419if (read_only) {2420prot = PROT_READ;2421flags = MAP_SHARED;2422} else {2423prot = PROT_READ | PROT_WRITE;2424flags = MAP_PRIVATE;2425}24262427if (allow_exec) {2428prot |= PROT_EXEC;2429}24302431if (addr != NULL) {2432flags |= MAP_FIXED;2433}24342435char* mapped_address = (char*)mmap(addr, (size_t)bytes, prot, flags,2436fd, file_offset);2437if (mapped_address == MAP_FAILED) {2438return NULL;2439}2440return mapped_address;2441}244224432444// Remap a block of memory.2445char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset,2446char *addr, size_t bytes, bool read_only,2447bool allow_exec) {2448// same as map_memory() on this OS2449return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only,2450allow_exec);2451}245224532454// Unmap a block of memory.2455bool os::pd_unmap_memory(char* addr, size_t bytes) {2456return munmap(addr, bytes) == 0;2457}24582459// current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)2460// are used by JVM M&M and JVMTI to get user+sys or user CPU time2461// of a thread.2462//2463// current_thread_cpu_time() and thread_cpu_time(Thread*) returns2464// the fast estimate available on the platform.24652466jlong os::current_thread_cpu_time() {2467#ifdef __APPLE__2468return os::thread_cpu_time(Thread::current(), true /* user + sys */);2469#else2470Unimplemented();2471return 0;2472#endif2473}24742475jlong os::thread_cpu_time(Thread* thread) {2476#ifdef __APPLE__2477return os::thread_cpu_time(thread, true /* user + sys */);2478#else2479Unimplemented();2480return 0;2481#endif2482}24832484jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {2485#ifdef __APPLE__2486return os::thread_cpu_time(Thread::current(), user_sys_cpu_time);2487#else2488Unimplemented();2489return 0;2490#endif2491}24922493jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {2494#ifdef __APPLE__2495struct thread_basic_info tinfo;2496mach_msg_type_number_t tcount = THREAD_INFO_MAX;2497kern_return_t kr;2498thread_t mach_thread;24992500mach_thread = thread->osthread()->thread_id();2501kr = thread_info(mach_thread, THREAD_BASIC_INFO, (thread_info_t)&tinfo, &tcount);2502if (kr != KERN_SUCCESS) {2503return -1;2504}25052506if (user_sys_cpu_time) {2507jlong nanos;2508nanos = ((jlong) tinfo.system_time.seconds + tinfo.user_time.seconds) * (jlong)1000000000;2509nanos += ((jlong) tinfo.system_time.microseconds + (jlong) tinfo.user_time.microseconds) * (jlong)1000;2510return nanos;2511} else {2512return ((jlong)tinfo.user_time.seconds * 1000000000) + ((jlong)tinfo.user_time.microseconds * (jlong)1000);2513}2514#else2515Unimplemented();2516return 0;2517#endif2518}251925202521void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {2522info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits2523info_ptr->may_skip_backward = false; // elapsed time not wall time2524info_ptr->may_skip_forward = false; // elapsed time not wall time2525info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned2526}25272528void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {2529info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits2530info_ptr->may_skip_backward = false; // elapsed time not wall time2531info_ptr->may_skip_forward = false; // elapsed time not wall time2532info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned2533}25342535bool os::is_thread_cpu_time_supported() {2536#ifdef __APPLE__2537return true;2538#else2539return false;2540#endif2541}25422543// System loadavg support. Returns -1 if load average cannot be obtained.2544// Bsd doesn't yet have a (official) notion of processor sets,2545// so just return the system wide load average.2546int os::loadavg(double loadavg[], int nelem) {2547return ::getloadavg(loadavg, nelem);2548}25492550void os::pause() {2551char filename[MAX_PATH];2552if (PauseAtStartupFile && PauseAtStartupFile[0]) {2553jio_snprintf(filename, MAX_PATH, "%s", PauseAtStartupFile);2554} else {2555jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());2556}25572558int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);2559if (fd != -1) {2560struct stat buf;2561::close(fd);2562while (::stat(filename, &buf) == 0) {2563(void)::poll(NULL, 0, 100);2564}2565} else {2566jio_fprintf(stderr,2567"Could not open pause file '%s', continuing immediately.\n", filename);2568}2569}25702571// Get the kern.corefile setting, or otherwise the default path to the core file2572// Returns the length of the string2573int os::get_core_path(char* buffer, size_t bufferSize) {2574int n = 0;2575#ifdef __APPLE__2576char coreinfo[MAX_PATH];2577size_t sz = sizeof(coreinfo);2578int ret = sysctlbyname("kern.corefile", coreinfo, &sz, NULL, 0);2579if (ret == 0) {2580char *pid_pos = strstr(coreinfo, "%P");2581// skip over the "%P" to preserve any optional custom user pattern2582const char* tail = (pid_pos != NULL) ? (pid_pos + 2) : "";25832584if (pid_pos != NULL) {2585*pid_pos = '\0';2586n = jio_snprintf(buffer, bufferSize, "%s%d%s", coreinfo, os::current_process_id(), tail);2587} else {2588n = jio_snprintf(buffer, bufferSize, "%s", coreinfo);2589}2590} else2591#endif2592{2593n = jio_snprintf(buffer, bufferSize, "/cores/core.%d", os::current_process_id());2594}2595// Truncate if theoretical string was longer than bufferSize2596n = MIN2(n, (int)bufferSize);25972598return n;2599}26002601bool os::supports_map_sync() {2602return false;2603}26042605bool os::start_debugging(char *buf, int buflen) {2606int len = (int)strlen(buf);2607char *p = &buf[len];26082609jio_snprintf(p, buflen-len,2610"\n\n"2611"Do you want to debug the problem?\n\n"2612"To debug, run 'gdb /proc/%d/exe %d'; then switch to thread " INTX_FORMAT " (" INTPTR_FORMAT ")\n"2613"Enter 'yes' to launch gdb automatically (PATH must include gdb)\n"2614"Otherwise, press RETURN to abort...",2615os::current_process_id(), os::current_process_id(),2616os::current_thread_id(), os::current_thread_id());26172618bool yes = os::message_box("Unexpected Error", buf);26192620if (yes) {2621// yes, user asked VM to launch debugger2622jio_snprintf(buf, sizeof(buf), "gdb /proc/%d/exe %d",2623os::current_process_id(), os::current_process_id());26242625os::fork_and_exec(buf);2626yes = false;2627}2628return yes;2629}26302631void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) {}263226332634