Path: blob/master/src/hotspot/os/bsd/os_bsd.cpp
40949 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);454set_boot_path('/', ':');455}456457// Where to look for native libraries.458//459// Note: Due to a legacy implementation, most of the library path460// is set in the launcher. This was to accomodate linking restrictions461// on legacy Bsd implementations (which are no longer supported).462// Eventually, all the library path setting will be done here.463//464// However, to prevent the proliferation of improperly built native465// libraries, the new path component /usr/java/packages is added here.466// Eventually, all the library path setting will be done here.467{468// Get the user setting of LD_LIBRARY_PATH, and prepended it. It469// should always exist (until the legacy problem cited above is470// addressed).471// Prepend the default path with the JAVA_LIBRARY_PATH so that the app launcher code472// can specify a directory inside an app wrapper473const char *l = ::getenv("JAVA_LIBRARY_PATH");474const char *l_colon = ":";475if (l == NULL) { l = ""; l_colon = ""; }476477const char *v = ::getenv("DYLD_LIBRARY_PATH");478const char *v_colon = ":";479if (v == NULL) { v = ""; v_colon = ""; }480481// Apple's Java6 has "." at the beginning of java.library.path.482// OpenJDK on Windows has "." at the end of java.library.path.483// OpenJDK on Linux and Solaris don't have "." in java.library.path484// at all. To ease the transition from Apple's Java6 to OpenJDK7,485// "." is appended to the end of java.library.path. Yes, this486// could cause a change in behavior, but Apple's Java6 behavior487// can be achieved by putting "." at the beginning of the488// JAVA_LIBRARY_PATH environment variable.489char *ld_library_path = NEW_C_HEAP_ARRAY(char,490strlen(v) + 1 + strlen(l) + 1 +491system_ext_size + 3,492mtInternal);493sprintf(ld_library_path, "%s%s%s%s%s" SYS_EXTENSIONS_DIR ":" SYS_EXTENSIONS_DIRS ":.",494v, v_colon, l, l_colon, user_home_dir);495Arguments::set_library_path(ld_library_path);496FREE_C_HEAP_ARRAY(char, ld_library_path);497}498499// Extensions directories.500//501// Note that the space for the colon and the trailing null are provided502// by the nulls included by the sizeof operator (so actually one byte more503// than necessary is allocated).504sprintf(buf, "%s" SYS_EXTENSIONS_DIR ":%s" EXTENSIONS_DIR ":" SYS_EXTENSIONS_DIRS,505user_home_dir, Arguments::get_java_home());506Arguments::set_ext_dirs(buf);507508FREE_C_HEAP_ARRAY(char, buf);509510#undef SYS_EXTENSIONS_DIR511#undef SYS_EXTENSIONS_DIRS512513#endif // __APPLE__514515#undef SYS_EXT_DIR516#undef EXTENSIONS_DIR517}518519////////////////////////////////////////////////////////////////////////////////520// breakpoint support521522void os::breakpoint() {523BREAKPOINT;524}525526extern "C" void breakpoint() {527// use debugger to set breakpoint here528}529530//////////////////////////////////////////////////////////////////////////////531// create new thread532533#ifdef __APPLE__534// library handle for calling objc_registerThreadWithCollector()535// without static linking to the libobjc library536#define OBJC_LIB "/usr/lib/libobjc.dylib"537#define OBJC_GCREGISTER "objc_registerThreadWithCollector"538typedef void (*objc_registerThreadWithCollector_t)();539extern "C" objc_registerThreadWithCollector_t objc_registerThreadWithCollectorFunction;540objc_registerThreadWithCollector_t objc_registerThreadWithCollectorFunction = NULL;541#endif542543// Thread start routine for all newly created threads544static void *thread_native_entry(Thread *thread) {545546thread->record_stack_base_and_size();547thread->initialize_thread_current();548549OSThread* osthread = thread->osthread();550Monitor* sync = osthread->startThread_lock();551552osthread->set_thread_id(os::Bsd::gettid());553554log_info(os, thread)("Thread is alive (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",555os::current_thread_id(), (uintx) pthread_self());556557#ifdef __APPLE__558// Store unique OS X thread id used by SA559osthread->set_unique_thread_id();560#endif561562// initialize signal mask for this thread563PosixSignals::hotspot_sigmask(thread);564565// initialize floating point control register566os::Bsd::init_thread_fpu_state();567568#ifdef __APPLE__569// register thread with objc gc570if (objc_registerThreadWithCollectorFunction != NULL) {571objc_registerThreadWithCollectorFunction();572}573#endif574575// handshaking with parent thread576{577MutexLocker ml(sync, Mutex::_no_safepoint_check_flag);578579// notify parent thread580osthread->set_state(INITIALIZED);581sync->notify_all();582583// wait until os::start_thread()584while (osthread->get_state() == INITIALIZED) {585sync->wait_without_safepoint_check();586}587}588589// call one more level start routine590thread->call_run();591592// Note: at this point the thread object may already have deleted itself.593// Prevent dereferencing it from here on out.594thread = NULL;595596log_info(os, thread)("Thread finished (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",597os::current_thread_id(), (uintx) pthread_self());598599return 0;600}601602bool os::create_thread(Thread* thread, ThreadType thr_type,603size_t req_stack_size) {604assert(thread->osthread() == NULL, "caller responsible");605606// Allocate the OSThread object607OSThread* osthread = new OSThread(NULL, NULL);608if (osthread == NULL) {609return false;610}611612// set the correct thread state613osthread->set_thread_type(thr_type);614615// Initial state is ALLOCATED but not INITIALIZED616osthread->set_state(ALLOCATED);617618thread->set_osthread(osthread);619620// init thread attributes621pthread_attr_t attr;622pthread_attr_init(&attr);623pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);624625// calculate stack size if it's not specified by caller626size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size);627int status = pthread_attr_setstacksize(&attr, stack_size);628assert_status(status == 0, status, "pthread_attr_setstacksize");629630ThreadState state;631632{633pthread_t tid;634int ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);635636char buf[64];637if (ret == 0) {638log_info(os, thread)("Thread started (pthread id: " UINTX_FORMAT ", attributes: %s). ",639(uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));640} else {641log_warning(os, thread)("Failed to start thread - pthread_create failed (%s) for attributes: %s.",642os::errno_name(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));643// Log some OS information which might explain why creating the thread failed.644log_info(os, thread)("Number of threads approx. running in the VM: %d", Threads::number_of_threads());645LogStream st(Log(os, thread)::info());646os::Posix::print_rlimit_info(&st);647os::print_memory_info(&st);648}649650pthread_attr_destroy(&attr);651652if (ret != 0) {653// Need to clean up stuff we've allocated so far654thread->set_osthread(NULL);655delete osthread;656return false;657}658659// Store pthread info into the OSThread660osthread->set_pthread_id(tid);661662// Wait until child thread is either initialized or aborted663{664Monitor* sync_with_child = osthread->startThread_lock();665MutexLocker ml(sync_with_child, Mutex::_no_safepoint_check_flag);666while ((state = osthread->get_state()) == ALLOCATED) {667sync_with_child->wait_without_safepoint_check();668}669}670671}672673// The thread is returned suspended (in state INITIALIZED),674// and is started higher up in the call chain675assert(state == INITIALIZED, "race condition");676return true;677}678679/////////////////////////////////////////////////////////////////////////////680// attach existing thread681682// bootstrap the main thread683bool os::create_main_thread(JavaThread* thread) {684assert(os::Bsd::_main_thread == pthread_self(), "should be called inside main thread");685return create_attached_thread(thread);686}687688bool os::create_attached_thread(JavaThread* thread) {689#ifdef ASSERT690thread->verify_not_published();691#endif692693// Allocate the OSThread object694OSThread* osthread = new OSThread(NULL, NULL);695696if (osthread == NULL) {697return false;698}699700osthread->set_thread_id(os::Bsd::gettid());701702#ifdef __APPLE__703// Store unique OS X thread id used by SA704osthread->set_unique_thread_id();705#endif706707// Store pthread info into the OSThread708osthread->set_pthread_id(::pthread_self());709710// initialize floating point control register711os::Bsd::init_thread_fpu_state();712713// Initial thread state is RUNNABLE714osthread->set_state(RUNNABLE);715716thread->set_osthread(osthread);717718// initialize signal mask for this thread719// and save the caller's signal mask720PosixSignals::hotspot_sigmask(thread);721722log_info(os, thread)("Thread attached (tid: " UINTX_FORMAT ", pthread id: " UINTX_FORMAT ").",723os::current_thread_id(), (uintx) pthread_self());724725return true;726}727728void os::pd_start_thread(Thread* thread) {729OSThread * osthread = thread->osthread();730assert(osthread->get_state() != INITIALIZED, "just checking");731Monitor* sync_with_child = osthread->startThread_lock();732MutexLocker ml(sync_with_child, Mutex::_no_safepoint_check_flag);733sync_with_child->notify();734}735736// Free Bsd resources related to the OSThread737void os::free_thread(OSThread* osthread) {738assert(osthread != NULL, "osthread not set");739740// We are told to free resources of the argument thread,741// but we can only really operate on the current thread.742assert(Thread::current()->osthread() == osthread,743"os::free_thread but not current thread");744745// Restore caller's signal mask746sigset_t sigmask = osthread->caller_sigmask();747pthread_sigmask(SIG_SETMASK, &sigmask, NULL);748749delete osthread;750}751752////////////////////////////////////////////////////////////////////////////////753// time support754755// Time since start-up in seconds to a fine granularity.756double os::elapsedTime() {757return ((double)os::elapsed_counter()) / os::elapsed_frequency();758}759760jlong os::elapsed_counter() {761return javaTimeNanos() - initial_time_count;762}763764jlong os::elapsed_frequency() {765return NANOSECS_PER_SEC; // nanosecond resolution766}767768bool os::supports_vtime() { return true; }769770double os::elapsedVTime() {771// better than nothing, but not much772return elapsedTime();773}774775#ifdef __APPLE__776void os::Bsd::clock_init() {777mach_timebase_info(&_timebase_info);778}779#else780void os::Bsd::clock_init() {781// Nothing to do782}783#endif784785786787#ifdef __APPLE__788789jlong os::javaTimeNanos() {790const uint64_t tm = mach_absolute_time();791const uint64_t now = (tm * Bsd::_timebase_info.numer) / Bsd::_timebase_info.denom;792const uint64_t prev = Bsd::_max_abstime;793if (now <= prev) {794return prev; // same or retrograde time;795}796const uint64_t obsv = Atomic::cmpxchg(&Bsd::_max_abstime, prev, now);797assert(obsv >= prev, "invariant"); // Monotonicity798// If the CAS succeeded then we're done and return "now".799// If the CAS failed and the observed value "obsv" is >= now then800// we should return "obsv". If the CAS failed and now > obsv > prv then801// some other thread raced this thread and installed a new value, in which case802// we could either (a) retry the entire operation, (b) retry trying to install now803// or (c) just return obsv. We use (c). No loop is required although in some cases804// we might discard a higher "now" value in deference to a slightly lower but freshly805// installed obsv value. That's entirely benign -- it admits no new orderings compared806// to (a) or (b) -- and greatly reduces coherence traffic.807// We might also condition (c) on the magnitude of the delta between obsv and now.808// Avoiding excessive CAS operations to hot RW locations is critical.809// See https://blogs.oracle.com/dave/entry/cas_and_cache_trivia_invalidate810return (prev == obsv) ? now : obsv;811}812813void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {814info_ptr->max_value = ALL_64_BITS;815info_ptr->may_skip_backward = false; // not subject to resetting or drifting816info_ptr->may_skip_forward = false; // not subject to resetting or drifting817info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time818}819820#endif // __APPLE__821822// Return the real, user, and system times in seconds from an823// arbitrary fixed point in the past.824bool os::getTimesSecs(double* process_real_time,825double* process_user_time,826double* process_system_time) {827struct tms ticks;828clock_t real_ticks = times(&ticks);829830if (real_ticks == (clock_t) (-1)) {831return false;832} else {833double ticks_per_second = (double) clock_tics_per_sec;834*process_user_time = ((double) ticks.tms_utime) / ticks_per_second;835*process_system_time = ((double) ticks.tms_stime) / ticks_per_second;836*process_real_time = ((double) real_ticks) / ticks_per_second;837838return true;839}840}841842843char * os::local_time_string(char *buf, size_t buflen) {844struct tm t;845time_t long_time;846time(&long_time);847localtime_r(&long_time, &t);848jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",849t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,850t.tm_hour, t.tm_min, t.tm_sec);851return buf;852}853854struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {855return localtime_r(clock, res);856}857858// Information of current thread in variety of formats859pid_t os::Bsd::gettid() {860int retval = -1;861862#ifdef __APPLE__ // XNU kernel863mach_port_t port = mach_thread_self();864guarantee(MACH_PORT_VALID(port), "just checking");865mach_port_deallocate(mach_task_self(), port);866return (pid_t)port;867868#else869#ifdef __FreeBSD__870retval = syscall(SYS_thr_self);871#else872#ifdef __OpenBSD__873retval = syscall(SYS_getthrid);874#else875#ifdef __NetBSD__876retval = (pid_t) syscall(SYS__lwp_self);877#endif878#endif879#endif880#endif881882if (retval == -1) {883return getpid();884}885}886887intx os::current_thread_id() {888#ifdef __APPLE__889return (intx)os::Bsd::gettid();890#else891return (intx)::pthread_self();892#endif893}894895int os::current_process_id() {896return (int)(getpid());897}898899// DLL functions900901const char* os::dll_file_extension() { return JNI_LIB_SUFFIX; }902903// This must be hard coded because it's the system's temporary904// directory not the java application's temp directory, ala java.io.tmpdir.905#ifdef __APPLE__906// macosx has a secure per-user temporary directory907char temp_path_storage[PATH_MAX];908const char* os::get_temp_directory() {909static char *temp_path = NULL;910if (temp_path == NULL) {911int pathSize = confstr(_CS_DARWIN_USER_TEMP_DIR, temp_path_storage, PATH_MAX);912if (pathSize == 0 || pathSize > PATH_MAX) {913strlcpy(temp_path_storage, "/tmp/", sizeof(temp_path_storage));914}915temp_path = temp_path_storage;916}917return temp_path;918}919#else // __APPLE__920const char* os::get_temp_directory() { return "/tmp"; }921#endif // __APPLE__922923// check if addr is inside libjvm.so924bool os::address_is_in_vm(address addr) {925static address libjvm_base_addr;926Dl_info dlinfo;927928if (libjvm_base_addr == NULL) {929if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) {930libjvm_base_addr = (address)dlinfo.dli_fbase;931}932assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm");933}934935if (dladdr((void *)addr, &dlinfo) != 0) {936if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true;937}938939return false;940}941942943#define MACH_MAXSYMLEN 256944945bool os::dll_address_to_function_name(address addr, char *buf,946int buflen, int *offset,947bool demangle) {948// buf is not optional, but offset is optional949assert(buf != NULL, "sanity check");950951Dl_info dlinfo;952char localbuf[MACH_MAXSYMLEN];953954if (dladdr((void*)addr, &dlinfo) != 0) {955// see if we have a matching symbol956if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) {957if (!(demangle && Decoder::demangle(dlinfo.dli_sname, buf, buflen))) {958jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);959}960if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;961return true;962}963// no matching symbol so try for just file info964if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {965if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),966buf, buflen, offset, dlinfo.dli_fname, demangle)) {967return true;968}969}970971// Handle non-dynamic manually:972if (dlinfo.dli_fbase != NULL &&973Decoder::decode(addr, localbuf, MACH_MAXSYMLEN, offset,974dlinfo.dli_fbase)) {975if (!(demangle && Decoder::demangle(localbuf, buf, buflen))) {976jio_snprintf(buf, buflen, "%s", localbuf);977}978return true;979}980}981buf[0] = '\0';982if (offset != NULL) *offset = -1;983return false;984}985986// ported from solaris version987bool os::dll_address_to_library_name(address addr, char* buf,988int buflen, int* offset) {989// buf is not optional, but offset is optional990assert(buf != NULL, "sanity check");991992Dl_info dlinfo;993994if (dladdr((void*)addr, &dlinfo) != 0) {995if (dlinfo.dli_fname != NULL) {996jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);997}998if (dlinfo.dli_fbase != NULL && offset != NULL) {999*offset = addr - (address)dlinfo.dli_fbase;1000}1001return true;1002}10031004buf[0] = '\0';1005if (offset) *offset = -1;1006return false;1007}10081009// Loads .dll/.so and1010// in case of error it checks if .dll/.so was built for the1011// same architecture as Hotspot is running on10121013#ifdef __APPLE__1014void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {1015#ifdef STATIC_BUILD1016return os::get_default_process_handle();1017#else1018log_info(os)("attempting shared library load of %s", filename);10191020void * result= ::dlopen(filename, RTLD_LAZY);1021if (result != NULL) {1022Events::log(NULL, "Loaded shared library %s", filename);1023// Successful loading1024log_info(os)("shared library load of %s was successful", filename);1025return result;1026}10271028const char* error_report = ::dlerror();1029if (error_report == NULL) {1030error_report = "dlerror returned no error description";1031}1032if (ebuf != NULL && ebuflen > 0) {1033// Read system error message into ebuf1034::strncpy(ebuf, error_report, ebuflen-1);1035ebuf[ebuflen-1]='\0';1036}1037Events::log(NULL, "Loading shared library %s failed, %s", filename, error_report);1038log_info(os)("shared library load of %s failed, %s", filename, error_report);10391040return NULL;1041#endif // STATIC_BUILD1042}1043#else1044void * os::dll_load(const char *filename, char *ebuf, int ebuflen) {1045#ifdef STATIC_BUILD1046return os::get_default_process_handle();1047#else1048log_info(os)("attempting shared library load of %s", filename);1049void * result= ::dlopen(filename, RTLD_LAZY);1050if (result != NULL) {1051Events::log(NULL, "Loaded shared library %s", filename);1052// Successful loading1053log_info(os)("shared library load of %s was successful", filename);1054return result;1055}10561057Elf32_Ehdr elf_head;10581059const char* const error_report = ::dlerror();1060if (error_report == NULL) {1061error_report = "dlerror returned no error description";1062}1063if (ebuf != NULL && ebuflen > 0) {1064// Read system error message into ebuf1065::strncpy(ebuf, error_report, ebuflen-1);1066ebuf[ebuflen-1]='\0';1067}1068Events::log(NULL, "Loading shared library %s failed, %s", filename, error_report);1069log_info(os)("shared library load of %s failed, %s", filename, error_report);10701071int diag_msg_max_length=ebuflen-strlen(ebuf);1072char* diag_msg_buf=ebuf+strlen(ebuf);10731074if (diag_msg_max_length==0) {1075// No more space in ebuf for additional diagnostics message1076return NULL;1077}107810791080int file_descriptor= ::open(filename, O_RDONLY | O_NONBLOCK);10811082if (file_descriptor < 0) {1083// Can't open library, report dlerror() message1084return NULL;1085}10861087bool failed_to_read_elf_head=1088(sizeof(elf_head)!=1089(::read(file_descriptor, &elf_head,sizeof(elf_head))));10901091::close(file_descriptor);1092if (failed_to_read_elf_head) {1093// file i/o error - report dlerror() msg1094return NULL;1095}10961097typedef struct {1098Elf32_Half code; // Actual value as defined in elf.h1099Elf32_Half compat_class; // Compatibility of archs at VM's sense1100char elf_class; // 32 or 64 bit1101char endianess; // MSB or LSB1102char* name; // String representation1103} arch_t;11041105#ifndef EM_4861106#define EM_486 6 /* Intel 80486 */1107#endif11081109#ifndef EM_MIPS_RS3_LE1110#define EM_MIPS_RS3_LE 10 /* MIPS */1111#endif11121113#ifndef EM_PPC641114#define EM_PPC64 21 /* PowerPC64 */1115#endif11161117#ifndef EM_S3901118#define EM_S390 22 /* IBM System/390 */1119#endif11201121#ifndef EM_IA_641122#define EM_IA_64 50 /* HP/Intel IA-64 */1123#endif11241125#ifndef EM_X86_641126#define EM_X86_64 62 /* AMD x86-64 */1127#endif11281129static const arch_t arch_array[]={1130{EM_386, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},1131{EM_486, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},1132{EM_IA_64, EM_IA_64, ELFCLASS64, ELFDATA2LSB, (char*)"IA 64"},1133{EM_X86_64, EM_X86_64, ELFCLASS64, ELFDATA2LSB, (char*)"AMD 64"},1134{EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"},1135{EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"},1136{EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM"},1137{EM_S390, EM_S390, ELFCLASSNONE, ELFDATA2MSB, (char*)"IBM System/390"},1138{EM_ALPHA, EM_ALPHA, ELFCLASS64, ELFDATA2LSB, (char*)"Alpha"},1139{EM_MIPS_RS3_LE, EM_MIPS_RS3_LE, ELFCLASS32, ELFDATA2LSB, (char*)"MIPSel"},1140{EM_MIPS, EM_MIPS, ELFCLASS32, ELFDATA2MSB, (char*)"MIPS"},1141{EM_PARISC, EM_PARISC, ELFCLASS32, ELFDATA2MSB, (char*)"PARISC"},1142{EM_68K, EM_68K, ELFCLASS32, ELFDATA2MSB, (char*)"M68k"}1143};11441145#if (defined IA32)1146static Elf32_Half running_arch_code=EM_386;1147#elif (defined AMD64)1148static Elf32_Half running_arch_code=EM_X86_64;1149#elif (defined IA64)1150static Elf32_Half running_arch_code=EM_IA_64;1151#elif (defined __powerpc64__)1152static Elf32_Half running_arch_code=EM_PPC64;1153#elif (defined __powerpc__)1154static Elf32_Half running_arch_code=EM_PPC;1155#elif (defined ARM)1156static Elf32_Half running_arch_code=EM_ARM;1157#elif (defined S390)1158static Elf32_Half running_arch_code=EM_S390;1159#elif (defined ALPHA)1160static Elf32_Half running_arch_code=EM_ALPHA;1161#elif (defined MIPSEL)1162static Elf32_Half running_arch_code=EM_MIPS_RS3_LE;1163#elif (defined PARISC)1164static Elf32_Half running_arch_code=EM_PARISC;1165#elif (defined MIPS)1166static Elf32_Half running_arch_code=EM_MIPS;1167#elif (defined M68K)1168static Elf32_Half running_arch_code=EM_68K;1169#else1170#error Method os::dll_load requires that one of following is defined:\1171IA32, AMD64, IA64, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K1172#endif11731174// Identify compatability class for VM's architecture and library's architecture1175// Obtain string descriptions for architectures11761177arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL};1178int running_arch_index=-1;11791180for (unsigned int i=0; i < ARRAY_SIZE(arch_array); i++) {1181if (running_arch_code == arch_array[i].code) {1182running_arch_index = i;1183}1184if (lib_arch.code == arch_array[i].code) {1185lib_arch.compat_class = arch_array[i].compat_class;1186lib_arch.name = arch_array[i].name;1187}1188}11891190assert(running_arch_index != -1,1191"Didn't find running architecture code (running_arch_code) in arch_array");1192if (running_arch_index == -1) {1193// Even though running architecture detection failed1194// we may still continue with reporting dlerror() message1195return NULL;1196}11971198if (lib_arch.endianess != arch_array[running_arch_index].endianess) {1199::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)");1200return NULL;1201}12021203#ifndef S3901204if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {1205::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)");1206return NULL;1207}1208#endif // !S39012091210if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) {1211if (lib_arch.name!=NULL) {1212::snprintf(diag_msg_buf, diag_msg_max_length-1,1213" (Possible cause: can't load %s-bit .so on a %s-bit platform)",1214lib_arch.name, arch_array[running_arch_index].name);1215} else {1216::snprintf(diag_msg_buf, diag_msg_max_length-1,1217" (Possible cause: can't load this .so (machine code=0x%x) on a %s-bit platform)",1218lib_arch.code,1219arch_array[running_arch_index].name);1220}1221}12221223return NULL;1224#endif // STATIC_BUILD1225}1226#endif // !__APPLE__12271228void* os::get_default_process_handle() {1229#ifdef __APPLE__1230// MacOS X needs to use RTLD_FIRST instead of RTLD_LAZY1231// to avoid finding unexpected symbols on second (or later)1232// loads of a library.1233return (void*)::dlopen(NULL, RTLD_FIRST);1234#else1235return (void*)::dlopen(NULL, RTLD_LAZY);1236#endif1237}12381239// XXX: Do we need a lock around this as per Linux?1240void* os::dll_lookup(void* handle, const char* name) {1241return dlsym(handle, name);1242}12431244int _print_dll_info_cb(const char * name, address base_address, address top_address, void * param) {1245outputStream * out = (outputStream *) param;1246out->print_cr(INTPTR_FORMAT " \t%s", (intptr_t)base_address, name);1247return 0;1248}12491250void os::print_dll_info(outputStream *st) {1251st->print_cr("Dynamic libraries:");1252if (get_loaded_modules_info(_print_dll_info_cb, (void *)st)) {1253st->print_cr("Error: Cannot print dynamic libraries.");1254}1255}12561257int os::get_loaded_modules_info(os::LoadedModulesCallbackFunc callback, void *param) {1258#ifdef RTLD_DI_LINKMAP1259Dl_info dli;1260void *handle;1261Link_map *map;1262Link_map *p;12631264if (dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli) == 0 ||1265dli.dli_fname == NULL) {1266return 1;1267}1268handle = dlopen(dli.dli_fname, RTLD_LAZY);1269if (handle == NULL) {1270return 1;1271}1272dlinfo(handle, RTLD_DI_LINKMAP, &map);1273if (map == NULL) {1274dlclose(handle);1275return 1;1276}12771278while (map->l_prev != NULL)1279map = map->l_prev;12801281while (map != NULL) {1282// Value for top_address is returned as 0 since we don't have any information about module size1283if (callback(map->l_name, (address)map->l_addr, (address)0, param)) {1284dlclose(handle);1285return 1;1286}1287map = map->l_next;1288}12891290dlclose(handle);1291#elif defined(__APPLE__)1292for (uint32_t i = 1; i < _dyld_image_count(); i++) {1293// Value for top_address is returned as 0 since we don't have any information about module size1294if (callback(_dyld_get_image_name(i), (address)_dyld_get_image_header(i), (address)0, param)) {1295return 1;1296}1297}1298return 0;1299#else1300return 1;1301#endif1302}13031304void os::get_summary_os_info(char* buf, size_t buflen) {1305// These buffers are small because we want this to be brief1306// and not use a lot of stack while generating the hs_err file.1307char os[100];1308size_t size = sizeof(os);1309int mib_kern[] = { CTL_KERN, KERN_OSTYPE };1310if (sysctl(mib_kern, 2, os, &size, NULL, 0) < 0) {1311#ifdef __APPLE__1312strncpy(os, "Darwin", sizeof(os));1313#elif __OpenBSD__1314strncpy(os, "OpenBSD", sizeof(os));1315#else1316strncpy(os, "BSD", sizeof(os));1317#endif1318}13191320char release[100];1321size = sizeof(release);1322int mib_release[] = { CTL_KERN, KERN_OSRELEASE };1323if (sysctl(mib_release, 2, release, &size, NULL, 0) < 0) {1324// if error, leave blank1325strncpy(release, "", sizeof(release));1326}13271328#ifdef __APPLE__1329char osproductversion[100];1330size_t sz = sizeof(osproductversion);1331int ret = sysctlbyname("kern.osproductversion", osproductversion, &sz, NULL, 0);1332if (ret == 0) {1333char build[100];1334size = sizeof(build);1335int mib_build[] = { CTL_KERN, KERN_OSVERSION };1336if (sysctl(mib_build, 2, build, &size, NULL, 0) < 0) {1337snprintf(buf, buflen, "%s %s, macOS %s", os, release, osproductversion);1338} else {1339snprintf(buf, buflen, "%s %s, macOS %s (%s)", os, release, osproductversion, build);1340}1341} else1342#endif1343snprintf(buf, buflen, "%s %s", os, release);1344}13451346void os::print_os_info_brief(outputStream* st) {1347os::Posix::print_uname_info(st);1348}13491350void os::print_os_info(outputStream* st) {1351st->print_cr("OS:");13521353os::Posix::print_uname_info(st);13541355os::Bsd::print_uptime_info(st);13561357os::Posix::print_rlimit_info(st);13581359os::Posix::print_load_average(st);13601361VM_Version::print_platform_virtualization_info(st);1362}13631364void os::pd_print_cpu_info(outputStream* st, char* buf, size_t buflen) {1365// Nothing to do for now.1366}13671368void os::get_summary_cpu_info(char* buf, size_t buflen) {1369unsigned int mhz;1370size_t size = sizeof(mhz);1371int mib[] = { CTL_HW, HW_CPU_FREQ };1372if (sysctl(mib, 2, &mhz, &size, NULL, 0) < 0) {1373mhz = 1; // looks like an error but can be divided by1374} else {1375mhz /= 1000000; // reported in millions1376}13771378char model[100];1379size = sizeof(model);1380int mib_model[] = { CTL_HW, HW_MODEL };1381if (sysctl(mib_model, 2, model, &size, NULL, 0) < 0) {1382strncpy(model, cpu_arch, sizeof(model));1383}13841385char machine[100];1386size = sizeof(machine);1387int mib_machine[] = { CTL_HW, HW_MACHINE };1388if (sysctl(mib_machine, 2, machine, &size, NULL, 0) < 0) {1389strncpy(machine, "", sizeof(machine));1390}13911392const char* emulated = "";1393#if defined(__APPLE__) && !defined(ZERO)1394if (VM_Version::is_cpu_emulated()) {1395emulated = " (EMULATED)";1396}1397#endif1398snprintf(buf, buflen, "\"%s\" %s%s %d MHz", model, machine, emulated, mhz);1399}14001401void os::print_memory_info(outputStream* st) {1402xsw_usage swap_usage;1403size_t size = sizeof(swap_usage);14041405st->print("Memory:");1406st->print(" %dk page", os::vm_page_size()>>10);14071408st->print(", physical " UINT64_FORMAT "k",1409os::physical_memory() >> 10);1410st->print("(" UINT64_FORMAT "k free)",1411os::available_memory() >> 10);14121413if((sysctlbyname("vm.swapusage", &swap_usage, &size, NULL, 0) == 0) || (errno == ENOMEM)) {1414if (size >= offset_of(xsw_usage, xsu_used)) {1415st->print(", swap " UINT64_FORMAT "k",1416((julong) swap_usage.xsu_total) >> 10);1417st->print("(" UINT64_FORMAT "k free)",1418((julong) swap_usage.xsu_avail) >> 10);1419}1420}14211422st->cr();1423}14241425static char saved_jvm_path[MAXPATHLEN] = {0};14261427// Find the full path to the current module, libjvm1428void os::jvm_path(char *buf, jint buflen) {1429// Error checking.1430if (buflen < MAXPATHLEN) {1431assert(false, "must use a large-enough buffer");1432buf[0] = '\0';1433return;1434}1435// Lazy resolve the path to current module.1436if (saved_jvm_path[0] != 0) {1437strcpy(buf, saved_jvm_path);1438return;1439}14401441char dli_fname[MAXPATHLEN];1442dli_fname[0] = '\0';1443bool ret = dll_address_to_library_name(1444CAST_FROM_FN_PTR(address, os::jvm_path),1445dli_fname, sizeof(dli_fname), NULL);1446assert(ret, "cannot locate libjvm");1447char *rp = NULL;1448if (ret && dli_fname[0] != '\0') {1449rp = os::Posix::realpath(dli_fname, buf, buflen);1450}1451if (rp == NULL) {1452return;1453}14541455if (Arguments::sun_java_launcher_is_altjvm()) {1456// Support for the java launcher's '-XXaltjvm=<path>' option. Typical1457// value for buf is "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so"1458// or "<JAVA_HOME>/jre/lib/<vmtype>/libjvm.dylib". If "/jre/lib/"1459// appears at the right place in the string, then assume we are1460// installed in a JDK and we're done. Otherwise, check for a1461// JAVA_HOME environment variable and construct a path to the JVM1462// being overridden.14631464const char *p = buf + strlen(buf) - 1;1465for (int count = 0; p > buf && count < 5; ++count) {1466for (--p; p > buf && *p != '/'; --p)1467/* empty */ ;1468}14691470if (strncmp(p, "/jre/lib/", 9) != 0) {1471// Look for JAVA_HOME in the environment.1472char* java_home_var = ::getenv("JAVA_HOME");1473if (java_home_var != NULL && java_home_var[0] != 0) {1474char* jrelib_p;1475int len;14761477// Check the current module name "libjvm"1478p = strrchr(buf, '/');1479assert(strstr(p, "/libjvm") == p, "invalid library name");14801481rp = os::Posix::realpath(java_home_var, buf, buflen);1482if (rp == NULL) {1483return;1484}14851486// determine if this is a legacy image or modules image1487// modules image doesn't have "jre" subdirectory1488len = strlen(buf);1489assert(len < buflen, "Ran out of buffer space");1490jrelib_p = buf + len;14911492// Add the appropriate library subdir1493snprintf(jrelib_p, buflen-len, "/jre/lib");1494if (0 != access(buf, F_OK)) {1495snprintf(jrelib_p, buflen-len, "/lib");1496}14971498// Add the appropriate client or server subdir1499len = strlen(buf);1500jrelib_p = buf + len;1501snprintf(jrelib_p, buflen-len, "/%s", COMPILER_VARIANT);1502if (0 != access(buf, F_OK)) {1503snprintf(jrelib_p, buflen-len, "%s", "");1504}15051506// If the path exists within JAVA_HOME, add the JVM library name1507// to complete the path to JVM being overridden. Otherwise fallback1508// to the path to the current library.1509if (0 == access(buf, F_OK)) {1510// Use current module name "libjvm"1511len = strlen(buf);1512snprintf(buf + len, buflen-len, "/libjvm%s", JNI_LIB_SUFFIX);1513} else {1514// Fall back to path of current library1515rp = os::Posix::realpath(dli_fname, buf, buflen);1516if (rp == NULL) {1517return;1518}1519}1520}1521}1522}15231524strncpy(saved_jvm_path, buf, MAXPATHLEN);1525saved_jvm_path[MAXPATHLEN - 1] = '\0';1526}15271528void os::print_jni_name_prefix_on(outputStream* st, int args_size) {1529// no prefix required, not even "_"1530}15311532void os::print_jni_name_suffix_on(outputStream* st, int args_size) {1533// no suffix required1534}15351536////////////////////////////////////////////////////////////////////////////////1537// Virtual Memory15381539int os::vm_page_size() {1540// Seems redundant as all get out1541assert(os::Bsd::page_size() != -1, "must call os::init");1542return os::Bsd::page_size();1543}15441545// Solaris allocates memory by pages.1546int os::vm_allocation_granularity() {1547assert(os::Bsd::page_size() != -1, "must call os::init");1548return os::Bsd::page_size();1549}15501551static void warn_fail_commit_memory(char* addr, size_t size, bool exec,1552int err) {1553warning("INFO: os::commit_memory(" INTPTR_FORMAT ", " SIZE_FORMAT1554", %d) failed; error='%s' (errno=%d)", (intptr_t)addr, size, exec,1555os::errno_name(err), err);1556}15571558// NOTE: Bsd kernel does not really reserve the pages for us.1559// All it does is to check if there are enough free pages1560// left at the time of mmap(). This could be a potential1561// problem.1562bool os::pd_commit_memory(char* addr, size_t size, bool exec) {1563int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;1564#if defined(__OpenBSD__)1565// XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD1566Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(addr), p2i(addr+size), prot);1567if (::mprotect(addr, size, prot) == 0) {1568return true;1569}1570#elif defined(__APPLE__)1571if (exec) {1572// Do not replace MAP_JIT mappings, see JDK-82349301573if (::mprotect(addr, size, prot) == 0) {1574return true;1575}1576} else {1577uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,1578MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);1579if (res != (uintptr_t) MAP_FAILED) {1580return true;1581}1582}1583#else1584uintptr_t res = (uintptr_t) ::mmap(addr, size, prot,1585MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);1586if (res != (uintptr_t) MAP_FAILED) {1587return true;1588}1589#endif15901591// Warn about any commit errors we see in non-product builds just1592// in case mmap() doesn't work as described on the man page.1593NOT_PRODUCT(warn_fail_commit_memory(addr, size, exec, errno);)15941595return false;1596}15971598bool os::pd_commit_memory(char* addr, size_t size, size_t alignment_hint,1599bool exec) {1600// alignment_hint is ignored on this OS1601return pd_commit_memory(addr, size, exec);1602}16031604void os::pd_commit_memory_or_exit(char* addr, size_t size, bool exec,1605const char* mesg) {1606assert(mesg != NULL, "mesg must be specified");1607if (!pd_commit_memory(addr, size, exec)) {1608// add extra info in product mode for vm_exit_out_of_memory():1609PRODUCT_ONLY(warn_fail_commit_memory(addr, size, exec, errno);)1610vm_exit_out_of_memory(size, OOM_MMAP_ERROR, "%s", mesg);1611}1612}16131614void os::pd_commit_memory_or_exit(char* addr, size_t size,1615size_t alignment_hint, bool exec,1616const char* mesg) {1617// alignment_hint is ignored on this OS1618pd_commit_memory_or_exit(addr, size, exec, mesg);1619}16201621void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {1622}16231624void os::pd_free_memory(char *addr, size_t bytes, size_t alignment_hint) {1625::madvise(addr, bytes, MADV_DONTNEED);1626}16271628void os::numa_make_global(char *addr, size_t bytes) {1629}16301631void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) {1632}16331634bool os::numa_topology_changed() { return false; }16351636size_t os::numa_get_groups_num() {1637return 1;1638}16391640int os::numa_get_group_id() {1641return 0;1642}16431644size_t os::numa_get_leaf_groups(int *ids, size_t size) {1645if (size > 0) {1646ids[0] = 0;1647return 1;1648}1649return 0;1650}16511652int os::numa_get_group_id_for_address(const void* address) {1653return 0;1654}16551656bool os::get_page_info(char *start, page_info* info) {1657return false;1658}16591660char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) {1661return end;1662}166316641665bool os::pd_uncommit_memory(char* addr, size_t size, bool exec) {1666#if defined(__OpenBSD__)1667// XXX: Work-around mmap/MAP_FIXED bug temporarily on OpenBSD1668Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with PROT_NONE", p2i(addr), p2i(addr+size));1669return ::mprotect(addr, size, PROT_NONE) == 0;1670#elif defined(__APPLE__)1671if (exec) {1672if (::madvise(addr, size, MADV_FREE) != 0) {1673return false;1674}1675return ::mprotect(addr, size, PROT_NONE) == 0;1676} else {1677uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE,1678MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0);1679return res != (uintptr_t) MAP_FAILED;1680}1681#else1682uintptr_t res = (uintptr_t) ::mmap(addr, size, PROT_NONE,1683MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE|MAP_ANONYMOUS, -1, 0);1684return res != (uintptr_t) MAP_FAILED;1685#endif1686}16871688bool os::pd_create_stack_guard_pages(char* addr, size_t size) {1689return os::commit_memory(addr, size, !ExecMem);1690}16911692// If this is a growable mapping, remove the guard pages entirely by1693// munmap()ping them. If not, just call uncommit_memory().1694bool os::remove_stack_guard_pages(char* addr, size_t size) {1695return os::uncommit_memory(addr, size);1696}16971698// 'requested_addr' is only treated as a hint, the return value may or1699// may not start from the requested address. Unlike Bsd mmap(), this1700// function returns NULL to indicate failure.1701static char* anon_mmap(char* requested_addr, size_t bytes, bool exec) {1702// MAP_FIXED is intentionally left out, to leave existing mappings intact.1703const int flags = MAP_PRIVATE | MAP_NORESERVE | MAP_ANONYMOUS1704MACOS_ONLY(| (exec ? MAP_JIT : 0));17051706// Map reserved/uncommitted pages PROT_NONE so we fail early if we1707// touch an uncommitted page. Otherwise, the read/write might1708// succeed if we have enough swap space to back the physical page.1709char* addr = (char*)::mmap(requested_addr, bytes, PROT_NONE, flags, -1, 0);17101711return addr == MAP_FAILED ? NULL : addr;1712}17131714static int anon_munmap(char * addr, size_t size) {1715return ::munmap(addr, size) == 0;1716}17171718char* os::pd_reserve_memory(size_t bytes, bool exec) {1719return anon_mmap(NULL /* addr */, bytes, exec);1720}17211722bool os::pd_release_memory(char* addr, size_t size) {1723return anon_munmap(addr, size);1724}17251726static bool bsd_mprotect(char* addr, size_t size, int prot) {1727// Bsd wants the mprotect address argument to be page aligned.1728char* bottom = (char*)align_down((intptr_t)addr, os::Bsd::page_size());17291730// According to SUSv3, mprotect() should only be used with mappings1731// established by mmap(), and mmap() always maps whole pages. Unaligned1732// 'addr' likely indicates problem in the VM (e.g. trying to change1733// protection of malloc'ed or statically allocated memory). Check the1734// caller if you hit this assert.1735assert(addr == bottom, "sanity check");17361737size = align_up(pointer_delta(addr, bottom, 1) + size, os::Bsd::page_size());1738Events::log(NULL, "Protecting memory [" INTPTR_FORMAT "," INTPTR_FORMAT "] with protection modes %x", p2i(bottom), p2i(bottom+size), prot);1739return ::mprotect(bottom, size, prot) == 0;1740}17411742// Set protections specified1743bool os::protect_memory(char* addr, size_t bytes, ProtType prot,1744bool is_committed) {1745unsigned int p = 0;1746switch (prot) {1747case MEM_PROT_NONE: p = PROT_NONE; break;1748case MEM_PROT_READ: p = PROT_READ; break;1749case MEM_PROT_RW: p = PROT_READ|PROT_WRITE; break;1750case MEM_PROT_RWX: p = PROT_READ|PROT_WRITE|PROT_EXEC; break;1751default:1752ShouldNotReachHere();1753}1754// is_committed is unused.1755return bsd_mprotect(addr, bytes, p);1756}17571758bool os::guard_memory(char* addr, size_t size) {1759return bsd_mprotect(addr, size, PROT_NONE);1760}17611762bool os::unguard_memory(char* addr, size_t size) {1763return bsd_mprotect(addr, size, PROT_READ|PROT_WRITE);1764}17651766bool os::Bsd::hugetlbfs_sanity_check(bool warn, size_t page_size) {1767return false;1768}17691770// Large page support17711772static size_t _large_page_size = 0;17731774void os::large_page_init() {1775}177617771778char* os::pd_reserve_memory_special(size_t bytes, size_t alignment, size_t page_size, char* req_addr, bool exec) {1779fatal("os::reserve_memory_special should not be called on BSD.");1780return NULL;1781}17821783bool os::pd_release_memory_special(char* base, size_t bytes) {1784fatal("os::release_memory_special should not be called on BSD.");1785return false;1786}17871788size_t os::large_page_size() {1789return _large_page_size;1790}17911792bool os::can_commit_large_page_memory() {1793// Does not matter, we do not support huge pages.1794return false;1795}17961797bool os::can_execute_large_page_memory() {1798// Does not matter, we do not support huge pages.1799return false;1800}18011802char* os::pd_attempt_map_memory_to_file_at(char* requested_addr, size_t bytes, int file_desc) {1803assert(file_desc >= 0, "file_desc is not valid");1804char* result = pd_attempt_reserve_memory_at(requested_addr, bytes, !ExecMem);1805if (result != NULL) {1806if (replace_existing_mapping_with_file_mapping(result, bytes, file_desc) == NULL) {1807vm_exit_during_initialization(err_msg("Error in mapping Java heap at the given filesystem directory"));1808}1809}1810return result;1811}18121813// Reserve memory at an arbitrary address, only if that area is1814// available (and not reserved for something else).18151816char* os::pd_attempt_reserve_memory_at(char* requested_addr, size_t bytes, bool exec) {1817// Assert only that the size is a multiple of the page size, since1818// that's all that mmap requires, and since that's all we really know1819// about at this low abstraction level. If we need higher alignment,1820// we can either pass an alignment to this method or verify alignment1821// in one of the methods further up the call chain. See bug 5044738.1822assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block");18231824// Repeatedly allocate blocks until the block is allocated at the1825// right spot.18261827// Bsd mmap allows caller to pass an address as hint; give it a try first,1828// if kernel honors the hint then we can return immediately.1829char * addr = anon_mmap(requested_addr, bytes, exec);1830if (addr == requested_addr) {1831return requested_addr;1832}18331834if (addr != NULL) {1835// mmap() is successful but it fails to reserve at the requested address1836anon_munmap(addr, bytes);1837}18381839return NULL;1840}18411842// Sleep forever; naked call to OS-specific sleep; use with CAUTION1843void os::infinite_sleep() {1844while (true) { // sleep forever ...1845::sleep(100); // ... 100 seconds at a time1846}1847}18481849// Used to convert frequent JVM_Yield() to nops1850bool os::dont_yield() {1851return DontYieldALot;1852}18531854void os::naked_yield() {1855sched_yield();1856}18571858////////////////////////////////////////////////////////////////////////////////1859// thread priority support18601861// Note: Normal Bsd applications are run with SCHED_OTHER policy. SCHED_OTHER1862// only supports dynamic priority, static priority must be zero. For real-time1863// applications, Bsd supports SCHED_RR which allows static priority (1-99).1864// However, for large multi-threaded applications, SCHED_RR is not only slower1865// than SCHED_OTHER, but also very unstable (my volano tests hang hard 4 out1866// of 5 runs - Sep 2005).1867//1868// The following code actually changes the niceness of kernel-thread/LWP. It1869// has an assumption that setpriority() only modifies one kernel-thread/LWP,1870// not the entire user process, and user level threads are 1:1 mapped to kernel1871// threads. It has always been the case, but could change in the future. For1872// this reason, the code should not be used as default (ThreadPriorityPolicy=0).1873// It is only used when ThreadPriorityPolicy=1 and may require system level permission1874// (e.g., root privilege or CAP_SYS_NICE capability).18751876#if !defined(__APPLE__)1877int os::java_to_os_priority[CriticalPriority + 1] = {187819, // 0 Entry should never be used187918800, // 1 MinPriority18813, // 218826, // 31883188410, // 4188515, // 5 NormPriority188618, // 61887188821, // 7188925, // 8189028, // 9 NearMaxPriority1891189231, // 10 MaxPriority1893189431 // 11 CriticalPriority1895};1896#else1897// Using Mach high-level priority assignments1898int os::java_to_os_priority[CriticalPriority + 1] = {18990, // 0 Entry should never be used (MINPRI_USER)1900190127, // 1 MinPriority190228, // 2190329, // 31904190530, // 4190631, // 5 NormPriority (BASEPRI_DEFAULT)190732, // 61908190933, // 7191034, // 8191135, // 9 NearMaxPriority1912191336, // 10 MaxPriority1914191536 // 11 CriticalPriority1916};1917#endif19181919static int prio_init() {1920if (ThreadPriorityPolicy == 1) {1921if (geteuid() != 0) {1922if (!FLAG_IS_DEFAULT(ThreadPriorityPolicy) && !FLAG_IS_JIMAGE_RESOURCE(ThreadPriorityPolicy)) {1923warning("-XX:ThreadPriorityPolicy=1 may require system level permission, " \1924"e.g., being the root user. If the necessary permission is not " \1925"possessed, changes to priority will be silently ignored.");1926}1927}1928}1929if (UseCriticalJavaThreadPriority) {1930os::java_to_os_priority[MaxPriority] = os::java_to_os_priority[CriticalPriority];1931}1932return 0;1933}19341935OSReturn os::set_native_priority(Thread* thread, int newpri) {1936if (!UseThreadPriorities || ThreadPriorityPolicy == 0) return OS_OK;19371938#ifdef __OpenBSD__1939// OpenBSD pthread_setprio starves low priority threads1940return OS_OK;1941#elif defined(__FreeBSD__)1942int ret = pthread_setprio(thread->osthread()->pthread_id(), newpri);1943return (ret == 0) ? OS_OK : OS_ERR;1944#elif defined(__APPLE__) || defined(__NetBSD__)1945struct sched_param sp;1946int policy;19471948if (pthread_getschedparam(thread->osthread()->pthread_id(), &policy, &sp) != 0) {1949return OS_ERR;1950}19511952sp.sched_priority = newpri;1953if (pthread_setschedparam(thread->osthread()->pthread_id(), policy, &sp) != 0) {1954return OS_ERR;1955}19561957return OS_OK;1958#else1959int ret = setpriority(PRIO_PROCESS, thread->osthread()->thread_id(), newpri);1960return (ret == 0) ? OS_OK : OS_ERR;1961#endif1962}19631964OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {1965if (!UseThreadPriorities || ThreadPriorityPolicy == 0) {1966*priority_ptr = java_to_os_priority[NormPriority];1967return OS_OK;1968}19691970errno = 0;1971#if defined(__OpenBSD__) || defined(__FreeBSD__)1972*priority_ptr = pthread_getprio(thread->osthread()->pthread_id());1973#elif defined(__APPLE__) || defined(__NetBSD__)1974int policy;1975struct sched_param sp;19761977int res = pthread_getschedparam(thread->osthread()->pthread_id(), &policy, &sp);1978if (res != 0) {1979*priority_ptr = -1;1980return OS_ERR;1981} else {1982*priority_ptr = sp.sched_priority;1983return OS_OK;1984}1985#else1986*priority_ptr = getpriority(PRIO_PROCESS, thread->osthread()->thread_id());1987#endif1988return (*priority_ptr != -1 || errno == 0 ? OS_OK : OS_ERR);1989}19901991extern void report_error(char* file_name, int line_no, char* title,1992char* format, ...);19931994// this is called _before_ the most of global arguments have been parsed1995void os::init(void) {1996char dummy; // used to get a guess on initial stack address19971998clock_tics_per_sec = CLK_TCK;19992000Bsd::set_page_size(getpagesize());2001if (Bsd::page_size() == -1) {2002fatal("os_bsd.cpp: os::init: sysconf failed (%s)", os::strerror(errno));2003}2004_page_sizes.add(Bsd::page_size());20052006Bsd::initialize_system_info();20072008// _main_thread points to the thread that created/loaded the JVM.2009Bsd::_main_thread = pthread_self();20102011Bsd::clock_init();2012initial_time_count = javaTimeNanos();20132014os::Posix::init();2015}20162017// To install functions for atexit system call2018extern "C" {2019static void perfMemory_exit_helper() {2020perfMemory_exit();2021}2022}20232024// this is called _after_ the global arguments have been parsed2025jint os::init_2(void) {20262027// This could be set after os::Posix::init() but all platforms2028// have to set it the same so we have to mirror Solaris.2029DEBUG_ONLY(os::set_mutex_init_done();)20302031os::Posix::init_2();20322033if (PosixSignals::init() == JNI_ERR) {2034return JNI_ERR;2035}20362037// Check and sets minimum stack sizes against command line options2038if (Posix::set_minimum_stack_sizes() == JNI_ERR) {2039return JNI_ERR;2040}20412042// Not supported.2043FLAG_SET_ERGO(UseNUMA, false);2044FLAG_SET_ERGO(UseNUMAInterleaving, false);20452046if (MaxFDLimit) {2047// set the number of file descriptors to max. print out error2048// if getrlimit/setrlimit fails but continue regardless.2049struct rlimit nbr_files;2050int status = getrlimit(RLIMIT_NOFILE, &nbr_files);2051if (status != 0) {2052log_info(os)("os::init_2 getrlimit failed: %s", os::strerror(errno));2053} else {2054nbr_files.rlim_cur = nbr_files.rlim_max;20552056#ifdef __APPLE__2057// Darwin returns RLIM_INFINITY for rlim_max, but fails with EINVAL if2058// you attempt to use RLIM_INFINITY. As per setrlimit(2), OPEN_MAX must2059// be used instead2060nbr_files.rlim_cur = MIN(OPEN_MAX, nbr_files.rlim_cur);2061#endif20622063status = setrlimit(RLIMIT_NOFILE, &nbr_files);2064if (status != 0) {2065log_info(os)("os::init_2 setrlimit failed: %s", os::strerror(errno));2066}2067}2068}20692070// at-exit methods are called in the reverse order of their registration.2071// atexit functions are called on return from main or as a result of a2072// call to exit(3C). There can be only 32 of these functions registered2073// and atexit() does not set errno.20742075if (PerfAllowAtExitRegistration) {2076// only register atexit functions if PerfAllowAtExitRegistration is set.2077// atexit functions can be delayed until process exit time, which2078// can be problematic for embedded VM situations. Embedded VMs should2079// call DestroyJavaVM() to assure that VM resources are released.20802081// note: perfMemory_exit_helper atexit function may be removed in2082// the future if the appropriate cleanup code can be added to the2083// VM_Exit VMOperation's doit method.2084if (atexit(perfMemory_exit_helper) != 0) {2085warning("os::init_2 atexit(perfMemory_exit_helper) failed");2086}2087}20882089// initialize thread priority policy2090prio_init();20912092#ifdef __APPLE__2093// dynamically link to objective c gc registration2094void *handleLibObjc = dlopen(OBJC_LIB, RTLD_LAZY);2095if (handleLibObjc != NULL) {2096objc_registerThreadWithCollectorFunction = (objc_registerThreadWithCollector_t) dlsym(handleLibObjc, OBJC_GCREGISTER);2097}2098#endif20992100return JNI_OK;2101}21022103int os::active_processor_count() {2104// User has overridden the number of active processors2105if (ActiveProcessorCount > 0) {2106log_trace(os)("active_processor_count: "2107"active processor count set by user : %d",2108ActiveProcessorCount);2109return ActiveProcessorCount;2110}21112112return _processor_count;2113}21142115uint os::processor_id() {2116#if defined(__APPLE__) && defined(__x86_64__)2117// Get the initial APIC id and return the associated processor id. The initial APIC2118// id is limited to 8-bits, which means we can have at most 256 unique APIC ids. If2119// the system has more processors (or the initial APIC ids are discontiguous) the2120// APIC id will be truncated and more than one processor will potentially share the2121// same processor id. This is not optimal, but unlikely to happen in practice. Should2122// this become a real problem we could switch to using x2APIC ids, which are 32-bit2123// wide. However, note that x2APIC is Intel-specific, and the wider number space2124// would require a more complicated mapping approach.2125uint eax = 0x1;2126uint ebx;2127uint ecx = 0;2128uint edx;21292130__asm__ ("cpuid\n\t" : "+a" (eax), "+b" (ebx), "+c" (ecx), "+d" (edx) : );21312132uint apic_id = (ebx >> 24) & (processor_id_map_size - 1);2133int processor_id = Atomic::load(&processor_id_map[apic_id]);21342135while (processor_id < 0) {2136// Assign processor id to APIC id2137processor_id = Atomic::cmpxchg(&processor_id_map[apic_id], processor_id_unassigned, processor_id_assigning);2138if (processor_id == processor_id_unassigned) {2139processor_id = Atomic::fetch_and_add(&processor_id_next, 1) % os::processor_count();2140Atomic::store(&processor_id_map[apic_id], processor_id);2141}2142}21432144assert(processor_id >= 0 && processor_id < os::processor_count(), "invalid processor id");21452146return (uint)processor_id;2147#else // defined(__APPLE__) && defined(__x86_64__)2148// Return 0 until we find a good way to get the current processor id on2149// the platform. Returning 0 is safe, since there is always at least one2150// processor, but might not be optimal for performance in some cases.2151return 0;2152#endif2153}21542155void os::set_native_thread_name(const char *name) {2156#if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_52157// This is only supported in Snow Leopard and beyond2158if (name != NULL) {2159// Add a "Java: " prefix to the name2160char buf[MAXTHREADNAMESIZE];2161snprintf(buf, sizeof(buf), "Java: %s", name);2162pthread_setname_np(buf);2163}2164#endif2165}21662167bool os::bind_to_processor(uint processor_id) {2168// Not yet implemented.2169return false;2170}21712172////////////////////////////////////////////////////////////////////////////////2173// debug support21742175bool os::find(address addr, outputStream* st) {2176Dl_info dlinfo;2177memset(&dlinfo, 0, sizeof(dlinfo));2178if (dladdr(addr, &dlinfo) != 0) {2179st->print(INTPTR_FORMAT ": ", (intptr_t)addr);2180if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) {2181st->print("%s+%#x", dlinfo.dli_sname,2182(uint)((uintptr_t)addr - (uintptr_t)dlinfo.dli_saddr));2183} else if (dlinfo.dli_fbase != NULL) {2184st->print("<offset %#x>", (uint)((uintptr_t)addr - (uintptr_t)dlinfo.dli_fbase));2185} else {2186st->print("<absolute address>");2187}2188if (dlinfo.dli_fname != NULL) {2189st->print(" in %s", dlinfo.dli_fname);2190}2191if (dlinfo.dli_fbase != NULL) {2192st->print(" at " INTPTR_FORMAT, (intptr_t)dlinfo.dli_fbase);2193}2194st->cr();21952196if (Verbose) {2197// decode some bytes around the PC2198address begin = clamp_address_in_page(addr-40, addr, os::vm_page_size());2199address end = clamp_address_in_page(addr+40, addr, os::vm_page_size());2200address lowest = (address) dlinfo.dli_sname;2201if (!lowest) lowest = (address) dlinfo.dli_fbase;2202if (begin < lowest) begin = lowest;2203Dl_info dlinfo2;2204if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr2205&& end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) {2206end = (address) dlinfo2.dli_saddr;2207}2208Disassembler::decode(begin, end, st);2209}2210return true;2211}2212return false;2213}22142215////////////////////////////////////////////////////////////////////////////////2216// misc22172218// This does not do anything on Bsd. This is basically a hook for being2219// able to use structured exception handling (thread-local exception filters)2220// on, e.g., Win32.2221void os::os_exception_wrapper(java_call_t f, JavaValue* value,2222const methodHandle& method, JavaCallArguments* args,2223JavaThread* thread) {2224f(value, method, args, thread);2225}22262227void os::print_statistics() {2228}22292230bool os::message_box(const char* title, const char* message) {2231int i;2232fdStream err(defaultStream::error_fd());2233for (i = 0; i < 78; i++) err.print_raw("=");2234err.cr();2235err.print_raw_cr(title);2236for (i = 0; i < 78; i++) err.print_raw("-");2237err.cr();2238err.print_raw_cr(message);2239for (i = 0; i < 78; i++) err.print_raw("=");2240err.cr();22412242char buf[16];2243// Prevent process from exiting upon "read error" without consuming all CPU2244while (::read(0, buf, sizeof(buf)) <= 0) { ::sleep(100); }22452246return buf[0] == 'y' || buf[0] == 'Y';2247}22482249static inline struct timespec get_mtime(const char* filename) {2250struct stat st;2251int ret = os::stat(filename, &st);2252assert(ret == 0, "failed to stat() file '%s': %s", filename, os::strerror(errno));2253#ifdef __APPLE__2254return st.st_mtimespec;2255#else2256return st.st_mtim;2257#endif2258}22592260int os::compare_file_modified_times(const char* file1, const char* file2) {2261struct timespec filetime1 = get_mtime(file1);2262struct timespec filetime2 = get_mtime(file2);2263int diff = filetime1.tv_sec - filetime2.tv_sec;2264if (diff == 0) {2265return filetime1.tv_nsec - filetime2.tv_nsec;2266}2267return diff;2268}22692270// Is a (classpath) directory empty?2271bool os::dir_is_empty(const char* path) {2272DIR *dir = NULL;2273struct dirent *ptr;22742275dir = opendir(path);2276if (dir == NULL) return true;22772278// Scan the directory2279bool result = true;2280while (result && (ptr = readdir(dir)) != NULL) {2281if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) {2282result = false;2283}2284}2285closedir(dir);2286return result;2287}22882289// This code originates from JDK's sysOpen and open64_w2290// from src/solaris/hpi/src/system_md.c22912292int os::open(const char *path, int oflag, int mode) {2293if (strlen(path) > MAX_PATH - 1) {2294errno = ENAMETOOLONG;2295return -1;2296}2297int fd;22982299fd = ::open(path, oflag, mode);2300if (fd == -1) return -1;23012302// If the open succeeded, the file might still be a directory2303{2304struct stat buf;2305int ret = ::fstat(fd, &buf);2306int st_mode = buf.st_mode;23072308if (ret != -1) {2309if ((st_mode & S_IFMT) == S_IFDIR) {2310errno = EISDIR;2311::close(fd);2312return -1;2313}2314} else {2315::close(fd);2316return -1;2317}2318}23192320// All file descriptors that are opened in the JVM and not2321// specifically destined for a subprocess should have the2322// close-on-exec flag set. If we don't set it, then careless 3rd2323// party native code might fork and exec without closing all2324// appropriate file descriptors (e.g. as we do in closeDescriptors in2325// UNIXProcess.c), and this in turn might:2326//2327// - cause end-of-file to fail to be detected on some file2328// descriptors, resulting in mysterious hangs, or2329//2330// - might cause an fopen in the subprocess to fail on a system2331// suffering from bug 1085341.2332//2333// (Yes, the default setting of the close-on-exec flag is a Unix2334// design flaw)2335//2336// See:2337// 1085341: 32-bit stdio routines should support file descriptors >2552338// 4843136: (process) pipe file descriptor from Runtime.exec not being closed2339// 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 92340//2341#ifdef FD_CLOEXEC2342{2343int flags = ::fcntl(fd, F_GETFD);2344if (flags != -1) {2345::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);2346}2347}2348#endif23492350return fd;2351}235223532354// create binary file, rewriting existing file if required2355int os::create_binary_file(const char* path, bool rewrite_existing) {2356int oflags = O_WRONLY | O_CREAT;2357if (!rewrite_existing) {2358oflags |= O_EXCL;2359}2360return ::open(path, oflags, S_IREAD | S_IWRITE);2361}23622363// return current position of file pointer2364jlong os::current_file_offset(int fd) {2365return (jlong)::lseek(fd, (off_t)0, SEEK_CUR);2366}23672368// move file pointer to the specified offset2369jlong os::seek_to_file_offset(int fd, jlong offset) {2370return (jlong)::lseek(fd, (off_t)offset, SEEK_SET);2371}23722373// This code originates from JDK's sysAvailable2374// from src/solaris/hpi/src/native_threads/src/sys_api_td.c23752376int os::available(int fd, jlong *bytes) {2377jlong cur, end;2378int mode;2379struct stat buf;23802381if (::fstat(fd, &buf) >= 0) {2382mode = buf.st_mode;2383if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {2384int n;2385if (::ioctl(fd, FIONREAD, &n) >= 0) {2386*bytes = n;2387return 1;2388}2389}2390}2391if ((cur = ::lseek(fd, 0L, SEEK_CUR)) == -1) {2392return 0;2393} else if ((end = ::lseek(fd, 0L, SEEK_END)) == -1) {2394return 0;2395} else if (::lseek(fd, cur, SEEK_SET) == -1) {2396return 0;2397}2398*bytes = end - cur;2399return 1;2400}24012402// Map a block of memory.2403char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,2404char *addr, size_t bytes, bool read_only,2405bool allow_exec) {2406int prot;2407int flags;24082409if (read_only) {2410prot = PROT_READ;2411flags = MAP_SHARED;2412} else {2413prot = PROT_READ | PROT_WRITE;2414flags = MAP_PRIVATE;2415}24162417if (allow_exec) {2418prot |= PROT_EXEC;2419}24202421if (addr != NULL) {2422flags |= MAP_FIXED;2423}24242425char* mapped_address = (char*)mmap(addr, (size_t)bytes, prot, flags,2426fd, file_offset);2427if (mapped_address == MAP_FAILED) {2428return NULL;2429}2430return mapped_address;2431}243224332434// Remap a block of memory.2435char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset,2436char *addr, size_t bytes, bool read_only,2437bool allow_exec) {2438// same as map_memory() on this OS2439return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only,2440allow_exec);2441}244224432444// Unmap a block of memory.2445bool os::pd_unmap_memory(char* addr, size_t bytes) {2446return munmap(addr, bytes) == 0;2447}24482449// current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)2450// are used by JVM M&M and JVMTI to get user+sys or user CPU time2451// of a thread.2452//2453// current_thread_cpu_time() and thread_cpu_time(Thread*) returns2454// the fast estimate available on the platform.24552456jlong os::current_thread_cpu_time() {2457#ifdef __APPLE__2458return os::thread_cpu_time(Thread::current(), true /* user + sys */);2459#else2460Unimplemented();2461return 0;2462#endif2463}24642465jlong os::thread_cpu_time(Thread* thread) {2466#ifdef __APPLE__2467return os::thread_cpu_time(thread, true /* user + sys */);2468#else2469Unimplemented();2470return 0;2471#endif2472}24732474jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {2475#ifdef __APPLE__2476return os::thread_cpu_time(Thread::current(), user_sys_cpu_time);2477#else2478Unimplemented();2479return 0;2480#endif2481}24822483jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {2484#ifdef __APPLE__2485struct thread_basic_info tinfo;2486mach_msg_type_number_t tcount = THREAD_INFO_MAX;2487kern_return_t kr;2488thread_t mach_thread;24892490mach_thread = thread->osthread()->thread_id();2491kr = thread_info(mach_thread, THREAD_BASIC_INFO, (thread_info_t)&tinfo, &tcount);2492if (kr != KERN_SUCCESS) {2493return -1;2494}24952496if (user_sys_cpu_time) {2497jlong nanos;2498nanos = ((jlong) tinfo.system_time.seconds + tinfo.user_time.seconds) * (jlong)1000000000;2499nanos += ((jlong) tinfo.system_time.microseconds + (jlong) tinfo.user_time.microseconds) * (jlong)1000;2500return nanos;2501} else {2502return ((jlong)tinfo.user_time.seconds * 1000000000) + ((jlong)tinfo.user_time.microseconds * (jlong)1000);2503}2504#else2505Unimplemented();2506return 0;2507#endif2508}250925102511void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {2512info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits2513info_ptr->may_skip_backward = false; // elapsed time not wall time2514info_ptr->may_skip_forward = false; // elapsed time not wall time2515info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned2516}25172518void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {2519info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits2520info_ptr->may_skip_backward = false; // elapsed time not wall time2521info_ptr->may_skip_forward = false; // elapsed time not wall time2522info_ptr->kind = JVMTI_TIMER_TOTAL_CPU; // user+system time is returned2523}25242525bool os::is_thread_cpu_time_supported() {2526#ifdef __APPLE__2527return true;2528#else2529return false;2530#endif2531}25322533// System loadavg support. Returns -1 if load average cannot be obtained.2534// Bsd doesn't yet have a (official) notion of processor sets,2535// so just return the system wide load average.2536int os::loadavg(double loadavg[], int nelem) {2537return ::getloadavg(loadavg, nelem);2538}25392540void os::pause() {2541char filename[MAX_PATH];2542if (PauseAtStartupFile && PauseAtStartupFile[0]) {2543jio_snprintf(filename, MAX_PATH, "%s", PauseAtStartupFile);2544} else {2545jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());2546}25472548int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);2549if (fd != -1) {2550struct stat buf;2551::close(fd);2552while (::stat(filename, &buf) == 0) {2553(void)::poll(NULL, 0, 100);2554}2555} else {2556jio_fprintf(stderr,2557"Could not open pause file '%s', continuing immediately.\n", filename);2558}2559}25602561// Get the kern.corefile setting, or otherwise the default path to the core file2562// Returns the length of the string2563int os::get_core_path(char* buffer, size_t bufferSize) {2564int n = 0;2565#ifdef __APPLE__2566char coreinfo[MAX_PATH];2567size_t sz = sizeof(coreinfo);2568int ret = sysctlbyname("kern.corefile", coreinfo, &sz, NULL, 0);2569if (ret == 0) {2570char *pid_pos = strstr(coreinfo, "%P");2571// skip over the "%P" to preserve any optional custom user pattern2572const char* tail = (pid_pos != NULL) ? (pid_pos + 2) : "";25732574if (pid_pos != NULL) {2575*pid_pos = '\0';2576n = jio_snprintf(buffer, bufferSize, "%s%d%s", coreinfo, os::current_process_id(), tail);2577} else {2578n = jio_snprintf(buffer, bufferSize, "%s", coreinfo);2579}2580} else2581#endif2582{2583n = jio_snprintf(buffer, bufferSize, "/cores/core.%d", os::current_process_id());2584}2585// Truncate if theoretical string was longer than bufferSize2586n = MIN2(n, (int)bufferSize);25872588return n;2589}25902591bool os::supports_map_sync() {2592return false;2593}25942595bool os::start_debugging(char *buf, int buflen) {2596int len = (int)strlen(buf);2597char *p = &buf[len];25982599jio_snprintf(p, buflen-len,2600"\n\n"2601"Do you want to debug the problem?\n\n"2602"To debug, run 'gdb /proc/%d/exe %d'; then switch to thread " INTX_FORMAT " (" INTPTR_FORMAT ")\n"2603"Enter 'yes' to launch gdb automatically (PATH must include gdb)\n"2604"Otherwise, press RETURN to abort...",2605os::current_process_id(), os::current_process_id(),2606os::current_thread_id(), os::current_thread_id());26072608bool yes = os::message_box("Unexpected Error", buf);26092610if (yes) {2611// yes, user asked VM to launch debugger2612jio_snprintf(buf, sizeof(buf), "gdb /proc/%d/exe %d",2613os::current_process_id(), os::current_process_id());26142615os::fork_and_exec(buf);2616yes = false;2617}2618return yes;2619}26202621void os::print_memory_mappings(char* addr, size_t bytes, outputStream* st) {}262226232624