os_solaris.cpp revision 6649:01ab9db4584f
1218065Sadrian/* 2218065Sadrian * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. 3240592Sadrian * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4218065Sadrian * 5218065Sadrian * This code is free software; you can redistribute it and/or modify it 6218065Sadrian * under the terms of the GNU General Public License version 2 only, as 7218065Sadrian * published by the Free Software Foundation. 8218065Sadrian * 9218065Sadrian * This code is distributed in the hope that it will be useful, but WITHOUT 10218065Sadrian * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11218065Sadrian * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12218065Sadrian * version 2 for more details (a copy is included in the LICENSE file that 13218065Sadrian * accompanied this code). 14218065Sadrian * 15218065Sadrian * You should have received a copy of the GNU General Public License version 16218065Sadrian * 2 along with this work; if not, write to the Free Software Foundation, 17218065Sadrian * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18218065Sadrian * 19218065Sadrian * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20218065Sadrian * or visit www.oracle.com if you need additional information or have any 21218065Sadrian * questions. 22218065Sadrian * 23218065Sadrian */ 24218065Sadrian 25218065Sadrian// no precompiled headers 26218065Sadrian#include "classfile/classLoader.hpp" 27218065Sadrian#include "classfile/systemDictionary.hpp" 28218065Sadrian#include "classfile/vmSymbols.hpp" 29218065Sadrian#include "code/icBuffer.hpp" 30218065Sadrian#include "code/vtableStubs.hpp" 31218065Sadrian#include "compiler/compileBroker.hpp" 32218065Sadrian#include "compiler/disassembler.hpp" 33218065Sadrian#include "interpreter/interpreter.hpp" 34218065Sadrian#include "jvm_solaris.h" 35218065Sadrian#include "memory/allocation.inline.hpp" 36218065Sadrian#include "memory/filemap.hpp" 37218065Sadrian#include "mutex_solaris.inline.hpp" 38218065Sadrian#include "oops/oop.inline.hpp" 39218065Sadrian#include "os_share_solaris.hpp" 40218065Sadrian#include "prims/jniFastGetField.hpp" 41218065Sadrian#include "prims/jvm.h" 42218065Sadrian#include "prims/jvm_misc.hpp" 43218065Sadrian#include "runtime/arguments.hpp" 44218065Sadrian#include "runtime/atomic.inline.hpp" 45218065Sadrian#include "runtime/extendedPC.hpp" 46218065Sadrian#include "runtime/globals.hpp" 47218065Sadrian#include "runtime/interfaceSupport.hpp" 48218065Sadrian#include "runtime/java.hpp" 49218065Sadrian#include "runtime/javaCalls.hpp" 50218065Sadrian#include "runtime/mutexLocker.hpp" 51218065Sadrian#include "runtime/objectMonitor.hpp" 52218065Sadrian#include "runtime/orderAccess.inline.hpp" 53218065Sadrian#include "runtime/osThread.hpp" 54218065Sadrian#include "runtime/perfMemory.hpp" 55218065Sadrian#include "runtime/sharedRuntime.hpp" 56218065Sadrian#include "runtime/statSampler.hpp" 57218065Sadrian#include "runtime/stubRoutines.hpp" 58218065Sadrian#include "runtime/thread.inline.hpp" 59218065Sadrian#include "runtime/threadCritical.hpp" 60218065Sadrian#include "runtime/timer.hpp" 61218065Sadrian#include "services/attachListener.hpp" 62218065Sadrian#include "services/memTracker.hpp" 63218065Sadrian#include "services/runtimeService.hpp" 64218065Sadrian#include "utilities/decoder.hpp" 65218065Sadrian#include "utilities/defaultStream.hpp" 66218065Sadrian#include "utilities/events.hpp" 67218065Sadrian#include "utilities/growableArray.hpp" 68218065Sadrian#include "utilities/vmError.hpp" 69218065Sadrian 70218065Sadrian// put OS-includes here 71218065Sadrian# include <dlfcn.h> 72218065Sadrian# include <errno.h> 73218065Sadrian# include <exception> 74218065Sadrian# include <link.h> 75218065Sadrian# include <poll.h> 76218065Sadrian# include <pthread.h> 77218065Sadrian# include <pwd.h> 78218065Sadrian# include <schedctl.h> 79218065Sadrian# include <setjmp.h> 80218065Sadrian# include <signal.h> 81227364Sadrian# include <stdio.h> 82218065Sadrian# include <alloca.h> 83218065Sadrian# include <sys/filio.h> 84218065Sadrian# include <sys/ipc.h> 85218065Sadrian# include <sys/lwp.h> 86218065Sadrian# include <sys/machelf.h> // for elf Sym structure used by dladdr1 87218065Sadrian# include <sys/mman.h> 88218065Sadrian# include <sys/processor.h> 89218065Sadrian# include <sys/procset.h> 90218065Sadrian# include <sys/pset.h> 91218065Sadrian# include <sys/resource.h> 92218065Sadrian# include <sys/shm.h> 93218065Sadrian# include <sys/socket.h> 94218065Sadrian# include <sys/stat.h> 95218065Sadrian# include <sys/systeminfo.h> 96218065Sadrian# include <sys/time.h> 97218065Sadrian# include <sys/times.h> 98218065Sadrian# include <sys/types.h> 99218065Sadrian# include <sys/wait.h> 100218065Sadrian# include <sys/utsname.h> 101218065Sadrian# include <thread.h> 102218240Sadrian# include <unistd.h> 103218065Sadrian# include <sys/priocntl.h> 104242782Sadrian# include <sys/rtpriocntl.h> 105242782Sadrian# include <sys/tspriocntl.h> 106242782Sadrian# include <sys/iapriocntl.h> 107242782Sadrian# include <sys/fxpriocntl.h> 108218154Sadrian# include <sys/loadavg.h> 109227364Sadrian# include <string.h> 110227364Sadrian# include <stdio.h> 111227364Sadrian 112227364Sadrian# define _STRUCTURED_PROC 1 // this gets us the new structured proc interfaces of 5.6 & later 113240946Sadrian# include <sys/procfs.h> // see comment in <sys/procfs.h> 114240946Sadrian 115240946Sadrian#define MAX_PATH (2 * K) 116240946Sadrian 117240946Sadrian// for timer info max values which include all bits 118241170Sadrian#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF) 119241170Sadrian 120241170Sadrian 121227364Sadrian// Here are some liblgrp types from sys/lgrp_user.h to be able to 122227364Sadrian// compile on older systems without this header file. 123227364Sadrian 124227364Sadrian#ifndef MADV_ACCESS_LWP 125236872Sadrian# define MADV_ACCESS_LWP 7 /* next LWP to access heavily */ 126236872Sadrian#endif 127227364Sadrian#ifndef MADV_ACCESS_MANY 128227364Sadrian# define MADV_ACCESS_MANY 8 /* many processes to access heavily */ 129240639Sadrian#endif 130240639Sadrian 131240639Sadrian#ifndef LGRP_RSRC_CPU 132227364Sadrian# define LGRP_RSRC_CPU 0 /* CPU resources */ 133243162Sadrian#endif 134243162Sadrian#ifndef LGRP_RSRC_MEM 135243162Sadrian# define LGRP_RSRC_MEM 1 /* memory resources */ 136243162Sadrian#endif 137243162Sadrian 138243162Sadrian// see thr_setprio(3T) for the basis of these numbers 139243162Sadrian#define MinimumPriority 0 140243162Sadrian#define NormalPriority 64 141243162Sadrian#define MaximumPriority 127 142243162Sadrian 143243162Sadrian// Values for ThreadPriorityPolicy == 1 144243162Sadrianint prio_policy1[CriticalPriority+1] = { 145243162Sadrian -99999, 0, 16, 32, 48, 64, 146243162Sadrian 80, 96, 112, 124, 127, 127 }; 147243162Sadrian 148243162Sadrian// System parameters used internally 149243162Sadrianstatic clock_t clock_tics_per_sec = 100; 150243162Sadrian 151243162Sadrian// Track if we have called enable_extended_FILE_stdio (on Solaris 10u4+) 152243162Sadrianstatic bool enabled_extended_FILE_stdio = false; 153243162Sadrian 154243162Sadrian// For diagnostics to print a message once. see run_periodic_checks 155243162Sadrianstatic bool check_addr0_done = false; 156243162Sadrianstatic sigset_t check_signal_done; 157243162Sadrianstatic bool check_signals = true; 158243162Sadrian 159243162Sadrianaddress os::Solaris::handler_start; // start pc of thr_sighndlrinfo 160243162Sadrianaddress os::Solaris::handler_end; // end pc of thr_sighndlrinfo 161243162Sadrian 162227364Sadrianaddress os::Solaris::_main_stack_base = NULL; // 4352906 workaround 163218154Sadrian 164218154Sadrian 165218154Sadrian// "default" initializers for missing libc APIs 166218154Sadrianextern "C" { 167218154Sadrian static int lwp_mutex_init(mutex_t *mx, int scope, void *arg) { memset(mx, 0, sizeof(mutex_t)); return 0; } 168239198Sadrian static int lwp_mutex_destroy(mutex_t *mx) { return 0; } 169239198Sadrian 170218154Sadrian static int lwp_cond_init(cond_t *cv, int scope, void *arg){ memset(cv, 0, sizeof(cond_t)); return 0; } 171218154Sadrian static int lwp_cond_destroy(cond_t *cv) { return 0; } 172227364Sadrian} 173227364Sadrian 174227364Sadrian// "default" initializers for pthread-based synchronization 175227364Sadrianextern "C" { 176227364Sadrian static int pthread_mutex_default_init(mutex_t *mx, int scope, void *arg) { memset(mx, 0, sizeof(mutex_t)); return 0; } 177227364Sadrian static int pthread_cond_default_init(cond_t *cv, int scope, void *arg){ memset(cv, 0, sizeof(cond_t)); return 0; } 178227364Sadrian} 179227364Sadrian 180227364Sadrianstatic void unpackTime(timespec* absTime, bool isAbsolute, jlong time); 181227364Sadrian 182227364Sadrian// Thread Local Storage 183227364Sadrian// This is common to all Solaris platforms so it is defined here, 184227364Sadrian// in this common file. 185227364Sadrian// The declarations are in the os_cpu threadLS*.hpp files. 186227364Sadrian// 187227364Sadrian// Static member initialization for TLS 188227364SadrianThread* ThreadLocalStorage::_get_thread_cache[ThreadLocalStorage::_pd_cache_size] = {NULL}; 189227364Sadrian 190227364Sadrian#ifndef PRODUCT 191227364Sadrian#define _PCT(n,d) ((100.0*(double)(n))/(double)(d)) 192240639Sadrian 193240639Sadrianint ThreadLocalStorage::_tcacheHit = 0; 194240639Sadrianint ThreadLocalStorage::_tcacheMiss = 0; 195240639Sadrian 196240639Sadrianvoid ThreadLocalStorage::print_statistics() { 197240639Sadrian int total = _tcacheMiss+_tcacheHit; 198240639Sadrian tty->print_cr("Thread cache hits %d misses %d total %d percent %f\n", 199240639Sadrian _tcacheHit, _tcacheMiss, total, _PCT(_tcacheHit, total)); 200240639Sadrian} 201240639Sadrian#undef _PCT 202240639Sadrian#endif // PRODUCT 203240639Sadrian 204240639SadrianThread* ThreadLocalStorage::get_thread_via_cache_slowly(uintptr_t raw_id, 205240639Sadrian int index) { 206240639Sadrian Thread *thread = get_thread_slow(); 207240639Sadrian if (thread != NULL) { 208227364Sadrian address sp = os::current_stack_pointer(); 209227364Sadrian guarantee(thread->_stack_base == NULL || 210227364Sadrian (sp <= thread->_stack_base && 211227364Sadrian sp >= thread->_stack_base - thread->_stack_size) || 212227364Sadrian is_error_reported(), 213227364Sadrian "sp must be inside of selected thread stack"); 214227364Sadrian 215227364Sadrian thread->set_self_raw_id(raw_id); // mark for quick retrieval 216227364Sadrian _get_thread_cache[index] = thread; 217227364Sadrian } 218227364Sadrian return thread; 219227364Sadrian} 220227364Sadrian 221227364Sadrian 222227364Sadrianstatic const double all_zero[sizeof(Thread) / sizeof(double) + 1] = {0}; 223227364Sadrian#define NO_CACHED_THREAD ((Thread*)all_zero) 224227364Sadrian 225227364Sadrianvoid ThreadLocalStorage::pd_set_thread(Thread* thread) { 226227364Sadrian 227227364Sadrian // Store the new value before updating the cache to prevent a race 228227364Sadrian // between get_thread_via_cache_slowly() and this store operation. 229227364Sadrian os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread); 230227364Sadrian 231227364Sadrian // Update thread cache with new thread if setting on thread create, 232227364Sadrian // or NO_CACHED_THREAD (zeroed) thread if resetting thread on exit. 233227364Sadrian uintptr_t raw = pd_raw_thread_id(); 234227364Sadrian int ix = pd_cache_index(raw); 235240946Sadrian _get_thread_cache[ix] = thread == NULL ? NO_CACHED_THREAD : thread; 236227364Sadrian} 237227364Sadrian 238218065Sadrianvoid ThreadLocalStorage::pd_init() { 239218065Sadrian for (int i = 0; i < _pd_cache_size; i++) { 240218065Sadrian _get_thread_cache[i] = NO_CACHED_THREAD; 241218065Sadrian } 242218065Sadrian} 243218065Sadrian 244218065Sadrian// Invalidate all the caches (happens to be the same as pd_init). 245218065Sadrianvoid ThreadLocalStorage::pd_invalidate_all() { pd_init(); } 246227344Sadrian 247218065Sadrian#undef NO_CACHED_THREAD 248227344Sadrian 249236993Sadrian// END Thread Local Storage 250218065Sadrian 251218065Sadrianstatic inline size_t adjust_stack_size(address base, size_t size) { 252218065Sadrian if ((ssize_t)size < 0) { 253218065Sadrian // 4759953: Compensate for ridiculous stack size. 254218065Sadrian size = max_intx; 255218065Sadrian } 256218065Sadrian if (size > (size_t)base) { 257218065Sadrian // 4812466: Make sure size doesn't allow the stack to wrap the address space. 258218065Sadrian size = (size_t)base; 259218065Sadrian } 260218065Sadrian return size; 261218065Sadrian} 262218065Sadrian 263218065Sadrianstatic inline stack_t get_stack_info() { 264218065Sadrian stack_t st; 265218065Sadrian int retval = thr_stksegment(&st); 266218065Sadrian st.ss_size = adjust_stack_size((address)st.ss_sp, st.ss_size); 267218065Sadrian assert(retval == 0, "incorrect return value from thr_stksegment"); 268237000Sadrian assert((address)&st < (address)st.ss_sp, "Invalid stack base returned"); 269237000Sadrian assert((address)&st > (address)st.ss_sp-st.ss_size, "Invalid stack size returned"); 270218065Sadrian return st; 271234009Sadrian} 272234009Sadrian 273218065Sadrianaddress os::current_stack_base() { 274218065Sadrian int r = thr_main(); 275218065Sadrian guarantee(r == 0 || r == 1, "CR6501650 or CR6493689"); 276218065Sadrian bool is_primordial_thread = r; 277227344Sadrian 278218065Sadrian // Workaround 4352906, avoid calls to thr_stksegment by 279218065Sadrian // thr_main after the first one (it looks like we trash 280218065Sadrian // some data, causing the value for ss_sp to be incorrect). 281227344Sadrian if (!is_primordial_thread || os::Solaris::_main_stack_base == NULL) { 282218065Sadrian stack_t st = get_stack_info(); 283218065Sadrian if (is_primordial_thread) { 284218065Sadrian // cache initial value of stack base 285218065Sadrian os::Solaris::_main_stack_base = (address)st.ss_sp; 286218065Sadrian } 287218065Sadrian return (address)st.ss_sp; 288218065Sadrian } else { 289218065Sadrian guarantee(os::Solaris::_main_stack_base != NULL, "Attempt to use null cached stack base"); 290218065Sadrian return os::Solaris::_main_stack_base; 291218065Sadrian } 292218065Sadrian} 293218065Sadrian 294218065Sadriansize_t os::current_stack_size() { 295218065Sadrian size_t size; 296218065Sadrian 297218065Sadrian int r = thr_main(); 298218065Sadrian guarantee(r == 0 || r == 1, "CR6501650 or CR6493689"); 299218065Sadrian if (!r) { 300218065Sadrian size = get_stack_info().ss_size; 301218065Sadrian } else { 302218065Sadrian struct rlimit limits; 303218065Sadrian getrlimit(RLIMIT_STACK, &limits); 304218065Sadrian size = adjust_stack_size(os::Solaris::_main_stack_base, (size_t)limits.rlim_cur); 305218065Sadrian } 306218065Sadrian // base may not be page aligned 307218065Sadrian address base = current_stack_base(); 308218065Sadrian address bottom = (address)align_size_up((intptr_t)(base - size), os::vm_page_size());; 309218065Sadrian return (size_t)(base - bottom); 310218065Sadrian} 311218065Sadrian 312218065Sadrianstruct tm* os::localtime_pd(const time_t* clock, struct tm* res) { 313218065Sadrian return localtime_r(clock, res); 314218065Sadrian} 315248985Sadrian 316218065Sadrianvoid os::Solaris::try_enable_extended_io() { 317218065Sadrian typedef int (*enable_extended_FILE_stdio_t)(int, int); 318218065Sadrian 319218065Sadrian if (!UseExtendedFileIO) { 320218065Sadrian return; 321218065Sadrian } 322218065Sadrian 323218065Sadrian enable_extended_FILE_stdio_t enabler = 324218065Sadrian (enable_extended_FILE_stdio_t) dlsym(RTLD_DEFAULT, 325218065Sadrian "enable_extended_FILE_stdio"); 326248985Sadrian if (enabler) { 327218065Sadrian enabler(-1, -1); 328248985Sadrian } 329218065Sadrian} 330218065Sadrian 331218065Sadrianstatic int _processors_online = 0; 332218065Sadrian 333218065Sadrian jint os::Solaris::_os_thread_limit = 0; 334218065Sadrianvolatile jint os::Solaris::_os_thread_count = 0; 335218065Sadrian 336218065Sadrianjulong os::available_memory() { 337218065Sadrian return Solaris::available_memory(); 338218065Sadrian} 339218065Sadrian 340218065Sadrianjulong os::Solaris::available_memory() { 341218065Sadrian return (julong)sysconf(_SC_AVPHYS_PAGES) * os::vm_page_size(); 342218065Sadrian} 343248985Sadrian 344218065Sadrianjulong os::Solaris::_physical_memory = 0; 345218065Sadrian 346218065Sadrianjulong os::physical_memory() { 347218065Sadrian return Solaris::physical_memory(); 348218065Sadrian} 349218065Sadrian 350218065Sadrianstatic hrtime_t first_hrtime = 0; 351218065Sadrianstatic const hrtime_t hrtime_hz = 1000*1000*1000; 352218065Sadrianstatic volatile hrtime_t max_hrtime = 0; 353218065Sadrian 354218065Sadrian 355218065Sadrianvoid os::Solaris::initialize_system_info() { 356218065Sadrian set_processor_count(sysconf(_SC_NPROCESSORS_CONF)); 357218065Sadrian _processors_online = sysconf (_SC_NPROCESSORS_ONLN); 358227360Sadrian _physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE); 359242656Sadrian} 360242656Sadrian 361242656Sadrianint os::active_processor_count() { 362227360Sadrian int online_cpus = sysconf(_SC_NPROCESSORS_ONLN); 363218065Sadrian pid_t pid = getpid(); 364242656Sadrian psetid_t pset = PS_NONE; 365242656Sadrian // Are we running in a processor set or is there any processor set around? 366242656Sadrian if (pset_bind(PS_QUERY, P_PID, pid, &pset) == 0) { 367218065Sadrian uint_t pset_cpus; 368218065Sadrian // Query the number of cpus available to us. 369242656Sadrian if (pset_info(pset, NULL, &pset_cpus, NULL) == 0) { 370239290Sadrian assert(pset_cpus > 0 && pset_cpus <= online_cpus, "sanity check"); 371239051Sadrian _processors_online = pset_cpus; 372239051Sadrian return pset_cpus; 373239290Sadrian } 374239380Sadrian } 375239051Sadrian // Otherwise return number of online cpus 376238708Sadrian return online_cpus; 377238708Sadrian} 378238708Sadrian 379238708Sadrianstatic bool find_processors_in_pset(psetid_t pset, 380238708Sadrian processorid_t** id_array, 381218065Sadrian uint_t* id_length) { 382218065Sadrian bool result = false; 383218065Sadrian // Find the number of processors in the processor set. 384218065Sadrian if (pset_info(pset, NULL, id_length, NULL) == 0) { 385239290Sadrian // Make up an array to hold their ids. 386239290Sadrian *id_array = NEW_C_HEAP_ARRAY(processorid_t, *id_length, mtInternal); 387248527Sadrian // Fill in the array with their processor ids. 388248527Sadrian if (pset_info(pset, NULL, id_length, *id_array) == 0) { 389248527Sadrian result = true; 390239290Sadrian } 391248527Sadrian } 392239290Sadrian return result; 393239290Sadrian} 394239290Sadrian 395239290Sadrian// Callers of find_processors_online() must tolerate imprecise results -- 396239290Sadrian// the system configuration can change asynchronously because of DR 397242656Sadrian// or explicit psradm operations. 398239290Sadrian// 399239290Sadrian// We also need to take care that the loop (below) terminates as the 400239290Sadrian// number of processors online can change between the _SC_NPROCESSORS_ONLN 401239290Sadrian// request and the loop that builds the list of processor ids. Unfortunately 402239290Sadrian// there's no reliable way to determine the maximum valid processor id, 403239290Sadrian// so we use a manifest constant, MAX_PROCESSOR_ID, instead. See p_online 404239290Sadrian// man pages, which claim the processor id set is "sparse, but 405239051Sadrian// not too sparse". MAX_PROCESSOR_ID is used to ensure that we eventually 406239290Sadrian// exit the loop. 407239290Sadrian// 408239290Sadrian// In the future we'll be able to use sysconf(_SC_CPUID_MAX), but that's 409239290Sadrian// not available on S8.0. 410239290Sadrian 411239290Sadrianstatic bool find_processors_online(processorid_t** id_array, 412239051Sadrian uint* id_length) { 413239290Sadrian const processorid_t MAX_PROCESSOR_ID = 100000; 414239290Sadrian // Find the number of processors online. 415239290Sadrian *id_length = sysconf(_SC_NPROCESSORS_ONLN); 416239290Sadrian // Make up an array to hold their ids. 417239290Sadrian *id_array = NEW_C_HEAP_ARRAY(processorid_t, *id_length, mtInternal); 418218065Sadrian // Processors need not be numbered consecutively. 419239409Sadrian long found = 0; 420218065Sadrian processorid_t next = 0; 421239409Sadrian while (found < *id_length && next < MAX_PROCESSOR_ID) { 422239290Sadrian processor_info_t info; 423239051Sadrian if (processor_info(next, &info) == 0) { 424239051Sadrian // NB, PI_NOINTR processors are effectively online ... 425244109Sadrian if (info.pi_state == P_ONLINE || info.pi_state == P_NOINTR) { 426244109Sadrian (*id_array)[found] = next; 427244109Sadrian found += 1; 428244109Sadrian } 429239051Sadrian } 430239409Sadrian next += 1; 431239051Sadrian } 432239051Sadrian if (found < *id_length) { 433239290Sadrian // The loop above didn't identify the expected number of processors. 434244109Sadrian // We could always retry the operation, calling sysconf(_SC_NPROCESSORS_ONLN) 435239380Sadrian // and re-running the loop, above, but there's no guarantee of progress 436218065Sadrian // if the system configuration is in flux. Instead, we just return what 437239409Sadrian // we've got. Note that in the worst case find_processors_online() could 438218065Sadrian // return an empty set. (As a fall-back in the case of the empty set we 439240255Sadrian // could just return the ID of the current processor). 440242656Sadrian *id_length = found; 441242656Sadrian } 442242656Sadrian 443242656Sadrian return true; 444242656Sadrian} 445242656Sadrian 446242656Sadrianstatic bool assign_distribution(processorid_t* id_array, 447242656Sadrian uint id_length, 448242656Sadrian uint* distribution, 449240255Sadrian uint distribution_length) { 450240333Sadrian // We assume we can assign processorid_t's to uint's. 451240255Sadrian assert(sizeof(processorid_t) == sizeof(uint), 452242656Sadrian "can't convert processorid_t to uint"); 453242656Sadrian // Quick check to see if we won't succeed. 454242656Sadrian if (id_length < distribution_length) { 455242656Sadrian return false; 456242656Sadrian } 457242656Sadrian // Assign processor ids to the distribution. 458242656Sadrian // Try to shuffle processors to distribute work across boards, 459242656Sadrian // assuming 4 processors per board. 460242656Sadrian const uint processors_per_board = ProcessDistributionStride; 461242656Sadrian // Find the maximum processor id. 462242656Sadrian processorid_t max_id = 0; 463242656Sadrian for (uint m = 0; m < id_length; m += 1) { 464242656Sadrian max_id = MAX2(max_id, id_array[m]); 465242656Sadrian } 466242656Sadrian // The next id, to limit loops. 467242656Sadrian const processorid_t limit_id = max_id + 1; 468242656Sadrian // Make up markers for available processors. 469242656Sadrian bool* available_id = NEW_C_HEAP_ARRAY(bool, limit_id, mtInternal); 470242656Sadrian for (uint c = 0; c < limit_id; c += 1) { 471242656Sadrian available_id[c] = false; 472239380Sadrian } 473239409Sadrian for (uint a = 0; a < id_length; a += 1) { 474239290Sadrian available_id[id_array[a]] = true; 475239290Sadrian } 476239290Sadrian // Step by "boards", then by "slot", copying to "assigned". 477239290Sadrian // NEEDS_CLEANUP: The assignment of processors should be stateful, 478239409Sadrian // remembering which processors have been assigned by 479239290Sadrian // previous calls, etc., so as to distribute several 480239290Sadrian // independent calls of this method. What we'd like is 481239290Sadrian // It would be nice to have an API that let us ask 482239290Sadrian // how many processes are bound to a processor, 483239290Sadrian // but we don't have that, either. 484239290Sadrian // In the short term, "board" is static so that 485239290Sadrian // subsequent distributions don't all start at board 0. 486218065Sadrian static uint board = 0; 487233990Sadrian uint assigned = 0; 488218154Sadrian // Until we've found enough processors .... 489218154Sadrian while (assigned < distribution_length) { 490227364Sadrian // ... find the next available processor in the board. 491238947Sadrian for (uint slot = 0; slot < processors_per_board; slot += 1) { 492238947Sadrian uint try_id = board * processors_per_board + slot; 493238947Sadrian if ((try_id < limit_id) && (available_id[try_id] == true)) { 494238947Sadrian distribution[assigned] = try_id; 495238947Sadrian available_id[try_id] = false; 496238947Sadrian assigned += 1; 497238947Sadrian break; 498238947Sadrian } 499238947Sadrian } 500238947Sadrian board += 1; 501238947Sadrian if (board * processors_per_board + 0 >= limit_id) { 502238947Sadrian board = 0; 503238947Sadrian } 504238947Sadrian } 505238947Sadrian if (available_id != NULL) { 506238947Sadrian FREE_C_HEAP_ARRAY(bool, available_id, mtInternal); 507238947Sadrian } 508238947Sadrian return true; 509238947Sadrian} 510238947Sadrian 511238947Sadrianvoid os::set_native_thread_name(const char *name) { 512238947Sadrian // Not yet implemented. 513238947Sadrian return; 514238947Sadrian} 515243647Sadrian 516238947Sadrianbool os::distribute_processes(uint length, uint* distribution) { 517243647Sadrian bool result = false; 518243647Sadrian // Find the processor id's of all the available CPUs. 519243647Sadrian processorid_t* id_array = NULL; 520243647Sadrian uint id_length = 0; 521243647Sadrian // There are some races between querying information and using it, 522243647Sadrian // since processor sets can change dynamically. 523243647Sadrian psetid_t pset = PS_NONE; 524243647Sadrian // Are we running in a processor set? 525243647Sadrian if ((pset_bind(PS_QUERY, P_PID, P_MYID, &pset) == 0) && pset != PS_NONE) { 526238947Sadrian result = find_processors_in_pset(pset, &id_array, &id_length); 527238947Sadrian } else { 528238947Sadrian result = find_processors_online(&id_array, &id_length); 529238947Sadrian } 530238947Sadrian if (result == true) { 531238947Sadrian if (id_length >= length) { 532238947Sadrian result = assign_distribution(id_array, id_length, distribution, length); 533238947Sadrian } else { 534238947Sadrian result = false; 535238947Sadrian } 536238947Sadrian } 537238947Sadrian if (id_array != NULL) { 538238947Sadrian FREE_C_HEAP_ARRAY(processorid_t, id_array, mtInternal); 539238947Sadrian } 540238947Sadrian return result; 541238947Sadrian} 542238947Sadrian 543238947Sadrianbool os::bind_to_processor(uint processor_id) { 544238947Sadrian // We assume that a processorid_t can be stored in a uint. 545227364Sadrian assert(sizeof(uint) == sizeof(processorid_t), 546227364Sadrian "can't convert uint to processorid_t"); 547227364Sadrian int bind_result = 548227364Sadrian processor_bind(P_LWPID, // bind LWP. 549227364Sadrian P_MYID, // bind current LWP. 550227364Sadrian (processorid_t) processor_id, // id. 551227364Sadrian NULL); // don't return old binding. 552227364Sadrian return (bind_result == 0); 553227364Sadrian} 554242656Sadrian 555227364Sadrianbool os::getenv(const char* name, char* buffer, int len) { 556227364Sadrian char* val = ::getenv(name); 557227364Sadrian if (val == NULL 558227364Sadrian || strlen(val) + 1 > len ) { 559227364Sadrian if (len > 0) buffer[0] = 0; // return a null string 560242951Sadrian return false; 561242951Sadrian } 562242951Sadrian strcpy(buffer, val); 563242951Sadrian return true; 564242951Sadrian} 565242951Sadrian 566242951Sadrian 567242951Sadrian// Return true if user is running as root. 568242951Sadrian 569227364Sadrianbool os::have_special_privileges() { 570242656Sadrian static bool init = false; 571242656Sadrian static bool privileges = false; 572227364Sadrian if (!init) { 573227364Sadrian privileges = (getuid() != geteuid()) || (getgid() != getegid()); 574227364Sadrian init = true; 575227364Sadrian } 576227364Sadrian return privileges; 577227364Sadrian} 578227364Sadrian 579242656Sadrian 580242656Sadrianvoid os::init_system_properties_values() { 581242656Sadrian // The next steps are taken in the product version: 582242656Sadrian // 583242656Sadrian // Obtain the JAVA_HOME value from the location of libjvm.so. 584242656Sadrian // This library should be located at: 585242656Sadrian // <JAVA_HOME>/jre/lib/<arch>/{client|server}/libjvm.so. 586242656Sadrian // 587242656Sadrian // If "/jre/lib/" appears at the right place in the path, then we 588242656Sadrian // assume libjvm.so is installed in a JDK and we use this path. 589242656Sadrian // 590242656Sadrian // Otherwise exit with message: "Could not create the Java virtual machine." 591242656Sadrian // 592242656Sadrian // The following extra steps are taken in the debugging version: 593242656Sadrian // 594242656Sadrian // If "/jre/lib/" does NOT appear at the right place in the path 595242656Sadrian // instead of exit check for $JAVA_HOME environment variable. 596227364Sadrian // 597227364Sadrian // If it is defined and we are able to locate $JAVA_HOME/jre/lib/<arch>, 598242656Sadrian // then we append a fake suffix "hotspot/libjvm.so" to this path so 599242656Sadrian // it looks like libjvm.so is installed there 600242656Sadrian // <JAVA_HOME>/jre/lib/<arch>/hotspot/libjvm.so. 601242656Sadrian // 602242656Sadrian // Otherwise exit. 603242656Sadrian // 604242656Sadrian // Important note: if the location of libjvm.so changes this 605242656Sadrian // code needs to be changed accordingly. 606242656Sadrian 607242656Sadrian// Base path of extensions installed on the system. 608242656Sadrian#define SYS_EXT_DIR "/usr/jdk/packages" 609242656Sadrian#define EXTENSIONS_DIR "/lib/ext" 610242656Sadrian#define ENDORSED_DIR "/lib/endorsed" 611242656Sadrian 612242656Sadrian char cpu_arch[12]; 613242656Sadrian // Buffer that fits several sprintfs. 614242656Sadrian // Note that the space for the colon and the trailing null are provided 615242656Sadrian // by the nulls included by the sizeof operator. 616242656Sadrian const size_t bufsize = 617242656Sadrian MAX4((size_t)MAXPATHLEN, // For dll_dir & friends. 618242656Sadrian sizeof(SYS_EXT_DIR) + sizeof("/lib/") + strlen(cpu_arch), // invariant ld_library_path 619242656Sadrian (size_t)MAXPATHLEN + sizeof(EXTENSIONS_DIR) + sizeof(SYS_EXT_DIR) + sizeof(EXTENSIONS_DIR), // extensions dir 620242656Sadrian (size_t)MAXPATHLEN + sizeof(ENDORSED_DIR)); // endorsed dir 621242656Sadrian char *buf = (char *)NEW_C_HEAP_ARRAY(char, bufsize, mtInternal); 622242656Sadrian 623242656Sadrian // sysclasspath, java_home, dll_dir 624242656Sadrian { 625242656Sadrian char *pslash; 626242656Sadrian os::jvm_path(buf, bufsize); 627242656Sadrian 628242656Sadrian // Found the full path to libjvm.so. 629242656Sadrian // Now cut the path to <java_home>/jre if we can. 630227364Sadrian *(strrchr(buf, '/')) = '\0'; // Get rid of /libjvm.so. 631227364Sadrian pslash = strrchr(buf, '/'); 632227364Sadrian if (pslash != NULL) { 633227364Sadrian *pslash = '\0'; // Get rid of /{client|server|hotspot}. 634238609Sadrian } 635238609Sadrian Arguments::set_dll_dir(buf); 636227364Sadrian 637227364Sadrian if (pslash != NULL) { 638227364Sadrian pslash = strrchr(buf, '/'); 639227364Sadrian if (pslash != NULL) { 640227364Sadrian *pslash = '\0'; // Get rid of /<arch>. 641227364Sadrian pslash = strrchr(buf, '/'); 642227364Sadrian if (pslash != NULL) { 643227364Sadrian *pslash = '\0'; // Get rid of /lib. 644227364Sadrian } 645227364Sadrian } 646227364Sadrian } 647227364Sadrian Arguments::set_java_home(buf); 648227364Sadrian set_boot_path('/', ':'); 649227364Sadrian } 650227364Sadrian 651227364Sadrian // Where to look for native libraries. 652227364Sadrian { 653227364Sadrian // Use dlinfo() to determine the correct java.library.path. 654227364Sadrian // 655243047Sadrian // If we're launched by the Java launcher, and the user 656243047Sadrian // does not set java.library.path explicitly on the commandline, 657243047Sadrian // the Java launcher sets LD_LIBRARY_PATH for us and unsets 658243047Sadrian // LD_LIBRARY_PATH_32 and LD_LIBRARY_PATH_64. In this case 659243047Sadrian // dlinfo returns LD_LIBRARY_PATH + crle settings (including 660243047Sadrian // /usr/lib), which is exactly what we want. 661243047Sadrian // 662243047Sadrian // If the user does set java.library.path, it completely 663243047Sadrian // overwrites this setting, and always has. 664243047Sadrian // 665243047Sadrian // If we're not launched by the Java launcher, we may 666243047Sadrian // get here with any/all of the LD_LIBRARY_PATH[_32|64] 667243047Sadrian // settings. Again, dlinfo does exactly what we want. 668243047Sadrian 669243047Sadrian Dl_serinfo info_sz, *info = &info_sz; 670243047Sadrian Dl_serpath *path; 671243047Sadrian char *library_path; 672243047Sadrian char *common_path = buf; 673243047Sadrian 674243047Sadrian // Determine search path count and required buffer size. 675243047Sadrian if (dlinfo(RTLD_SELF, RTLD_DI_SERINFOSIZE, (void *)info) == -1) { 676243047Sadrian FREE_C_HEAP_ARRAY(char, buf, mtInternal); 677243047Sadrian vm_exit_during_initialization("dlinfo SERINFOSIZE request", dlerror()); 678243047Sadrian } 679243047Sadrian 680227364Sadrian // Allocate new buffer and initialize. 681227364Sadrian info = (Dl_serinfo*)NEW_C_HEAP_ARRAY(char, info_sz.dls_size, mtInternal); 682227364Sadrian info->dls_size = info_sz.dls_size; 683239051Sadrian info->dls_cnt = info_sz.dls_cnt; 684239051Sadrian 685239051Sadrian // Obtain search path information. 686239051Sadrian if (dlinfo(RTLD_SELF, RTLD_DI_SERINFO, (void *)info) == -1) { 687239051Sadrian FREE_C_HEAP_ARRAY(char, buf, mtInternal); 688239051Sadrian FREE_C_HEAP_ARRAY(char, info, mtInternal); 689239051Sadrian vm_exit_during_initialization("dlinfo SERINFO request", dlerror()); 690244109Sadrian } 691239051Sadrian 692239051Sadrian path = &info->dls_serpath[0]; 693239051Sadrian 694244109Sadrian // Note: Due to a legacy implementation, most of the library path 695239051Sadrian // is set in the launcher. This was to accomodate linking restrictions 696239051Sadrian // on legacy Solaris implementations (which are no longer supported). 697227364Sadrian // Eventually, all the library path setting will be done here. 698227364Sadrian // 699227364Sadrian // However, to prevent the proliferation of improperly built native 700227364Sadrian // libraries, the new path component /usr/jdk/packages is added here. 701243786Sadrian 702243786Sadrian // Determine the actual CPU architecture. 703227364Sadrian sysinfo(SI_ARCHITECTURE, cpu_arch, sizeof(cpu_arch)); 704227364Sadrian#ifdef _LP64 705248676Sadrian // If we are a 64-bit vm, perform the following translations: 706248676Sadrian // sparc -> sparcv9 707248713Sadrian // i386 -> amd64 708248713Sadrian if (strcmp(cpu_arch, "sparc") == 0) { 709227364Sadrian strcat(cpu_arch, "v9"); 710227364Sadrian } else if (strcmp(cpu_arch, "i386") == 0) { 711227364Sadrian strcpy(cpu_arch, "amd64"); 712248713Sadrian } 713227364Sadrian#endif 714248713Sadrian 715227364Sadrian // Construct the invariant part of ld_library_path. 716227364Sadrian sprintf(common_path, SYS_EXT_DIR "/lib/%s", cpu_arch); 717227364Sadrian 718248713Sadrian // Struct size is more than sufficient for the path components obtained 719248713Sadrian // through the dlinfo() call, so only add additional space for the path 720248713Sadrian // components explicitly added here. 721227364Sadrian size_t library_path_size = info->dls_size + strlen(common_path); 722227364Sadrian library_path = (char *)NEW_C_HEAP_ARRAY(char, library_path_size, mtInternal); 723248671Sadrian library_path[0] = '\0'; 724227364Sadrian 725227364Sadrian // Construct the desired Java library path from the linker's library 726227364Sadrian // search path. 727227364Sadrian // 728227364Sadrian // For compatibility, it is optimal that we insert the additional path 729227364Sadrian // components specific to the Java VM after those components specified 730229949Sadrian // in LD_LIBRARY_PATH (if any) but before those added by the ld.so 731229949Sadrian // infrastructure. 732227364Sadrian if (info->dls_cnt == 0) { // Not sure this can happen, but allow for it. 733227364Sadrian strcpy(library_path, common_path); 734227364Sadrian } else { 735227364Sadrian int inserted = 0; 736218065Sadrian int i; 737218065Sadrian for (i = 0; i < info->dls_cnt; i++, path++) { 738218065Sadrian uint_t flags = path->dls_flags & LA_SER_MASK; 739218065Sadrian if (((flags & LA_SER_LIBPATH) == 0) && !inserted) { 740218065Sadrian strcat(library_path, common_path); 741218065Sadrian strcat(library_path, os::path_separator()); 742218065Sadrian inserted = 1; 743243786Sadrian } 744218065Sadrian strcat(library_path, path->dls_name); 745227364Sadrian strcat(library_path, os::path_separator()); 746227364Sadrian } 747227364Sadrian // Eliminate trailing path separator. 748227364Sadrian library_path[strlen(library_path)-1] = '\0'; 749227651Sadrian } 750227651Sadrian 751227651Sadrian // happens before argument parsing - can't use a trace flag 752227651Sadrian // tty->print_raw("init_system_properties_values: native lib path: "); 753227651Sadrian // tty->print_raw_cr(library_path); 754227651Sadrian 755227651Sadrian // Callee copies into its own buffer. 756227651Sadrian Arguments::set_library_path(library_path); 757227651Sadrian 758227651Sadrian FREE_C_HEAP_ARRAY(char, library_path, mtInternal); 759227651Sadrian FREE_C_HEAP_ARRAY(char, info, mtInternal); 760227651Sadrian } 761227651Sadrian 762227651Sadrian // Extensions directories. 763227651Sadrian sprintf(buf, "%s" EXTENSIONS_DIR ":" SYS_EXT_DIR EXTENSIONS_DIR, Arguments::get_java_home()); 764227651Sadrian Arguments::set_ext_dirs(buf); 765227651Sadrian 766227651Sadrian // Endorsed standards default directory. 767227651Sadrian sprintf(buf, "%s" ENDORSED_DIR, Arguments::get_java_home()); 768227651Sadrian Arguments::set_endorsed_dirs(buf); 769227651Sadrian 770227651Sadrian FREE_C_HEAP_ARRAY(char, buf, mtInternal); 771227651Sadrian 772227651Sadrian#undef SYS_EXT_DIR 773227651Sadrian#undef EXTENSIONS_DIR 774227651Sadrian#undef ENDORSED_DIR 775227651Sadrian} 776227651Sadrian 777227651Sadrianvoid os::breakpoint() { 778227651Sadrian BREAKPOINT; 779227364Sadrian} 780227364Sadrian 781248671Sadrianbool os::obsolete_option(const JavaVMOption *option) 782218065Sadrian{ 783218065Sadrian if (!strncmp(option->optionString, "-Xt", 3)) { 784218065Sadrian return true; 785218065Sadrian } else if (!strncmp(option->optionString, "-Xtm", 4)) { 786218065Sadrian return true; 787240899Sadrian } else if (!strncmp(option->optionString, "-Xverifyheap", 12)) { 788240899Sadrian return true; 789240899Sadrian } else if (!strncmp(option->optionString, "-Xmaxjitcodesize", 16)) { 790240899Sadrian return true; 791218065Sadrian } 792218065Sadrian return false; 793218065Sadrian} 794218065Sadrian 795218065Sadrianbool os::Solaris::valid_stack_address(Thread* thread, address sp) { 796218065Sadrian address stackStart = (address)thread->stack_base(); 797218065Sadrian address stackEnd = (address)(stackStart - (address)thread->stack_size()); 798218065Sadrian if (sp < stackStart && sp >= stackEnd) return true; 799218065Sadrian return false; 800218065Sadrian} 801218065Sadrian 802218065Sadrianextern "C" void breakpoint() { 803229949Sadrian // use debugger to set breakpoint here 804229949Sadrian} 805218065Sadrian 806218065Sadrianstatic thread_t main_thread; 807240899Sadrian 808218065Sadrian// Thread start routine for all new Java threads 809218065Sadrianextern "C" void* java_start(void* thread_addr) { 810240899Sadrian // Try to randomize the cache line index of hot stack frames. 811218065Sadrian // This helps when threads of the same stack traces evict each other's 812240899Sadrian // cache lines. The threads can be either from the same JVM instance, or 813240899Sadrian // from different JVM instances. The benefit is especially true for 814240899Sadrian // processors with hyperthreading technology. 815240899Sadrian static int counter = 0; 816240899Sadrian int pid = os::current_process_id(); 817240899Sadrian alloca(((pid ^ counter++) & 7) * 128); 818240899Sadrian 819218065Sadrian int prio; 820218065Sadrian Thread* thread = (Thread*)thread_addr; 821218065Sadrian OSThread* osthr = thread->osthread(); 822218065Sadrian 823218065Sadrian osthr->set_lwp_id(_lwp_self()); // Store lwp in case we are bound 824240899Sadrian thread->_schedctl = (void *) schedctl_init(); 825218065Sadrian 826218065Sadrian if (UseNUMA) { 827218065Sadrian int lgrp_id = os::numa_get_group_id(); 828218065Sadrian if (lgrp_id != -1) { 829218065Sadrian thread->set_lgrp_id(lgrp_id); 830218065Sadrian } 831229949Sadrian } 832229949Sadrian 833240899Sadrian // If the creator called set priority before we started, 834240899Sadrian // we need to call set_native_priority now that we have an lwp. 835240899Sadrian // We used to get the priority from thr_getprio (we called 836240899Sadrian // thr_setprio way back in create_thread) and pass it to 837240899Sadrian // set_native_priority, but Solaris scales the priority 838240899Sadrian // in java_to_os_priority, so when we read it back here, 839218065Sadrian // we pass trash to set_native_priority instead of what's 840218065Sadrian // in java_to_os_priority. So we save the native priority 841218065Sadrian // in the osThread and recall it here. 842218065Sadrian 843218065Sadrian if (osthr->thread_id() != -1) { 844218065Sadrian if (UseThreadPriorities) { 845218065Sadrian int prio = osthr->native_priority(); 846218065Sadrian if (ThreadPriorityVerbose) { 847218065Sadrian tty->print_cr("Starting Thread " INTPTR_FORMAT ", LWP is " 848218065Sadrian INTPTR_FORMAT ", setting priority: %d\n", 849218065Sadrian osthr->thread_id(), osthr->lwp_id(), prio); 850227344Sadrian } 851218065Sadrian os::set_native_priority(thread, prio); 852218065Sadrian } 853218065Sadrian } else if (ThreadPriorityVerbose) { 854218065Sadrian warning("Can't set priority in _start routine, thread id hasn't been set\n"); 855240899Sadrian } 856240899Sadrian 857240899Sadrian assert(osthr->get_state() == RUNNABLE, "invalid os thread state"); 858240899Sadrian 859240899Sadrian // initialize signal mask for this thread 860240899Sadrian os::Solaris::hotspot_sigmask(thread); 861240899Sadrian 862218065Sadrian thread->run(); 863218065Sadrian 864218065Sadrian // One less thread is executing 865218065Sadrian // When the VMThread gets here, the main thread may have already exited 866241500Sadrian // which frees the CodeHeap containing the Atomic::dec code 867241500Sadrian if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) { 868240899Sadrian Atomic::dec(&os::Solaris::_os_thread_count); 869240899Sadrian } 870240899Sadrian 871240899Sadrian if (UseDetachedThreads) { 872218065Sadrian thr_exit(NULL); 873218065Sadrian ShouldNotReachHere(); 874218065Sadrian } 875218065Sadrian return NULL; 876218065Sadrian} 877218065Sadrian 878218065Sadrianstatic OSThread* create_os_thread(Thread* thread, thread_t thread_id) { 879240899Sadrian // Allocate the OSThread object 880240899Sadrian OSThread* osthread = new OSThread(NULL, NULL); 881240899Sadrian if (osthread == NULL) return NULL; 882240899Sadrian 883240899Sadrian // Store info on the Solaris thread into the OSThread 884240899Sadrian osthread->set_thread_id(thread_id); 885240899Sadrian osthread->set_lwp_id(_lwp_self()); 886240899Sadrian thread->_schedctl = (void *) schedctl_init(); 887218065Sadrian 888218065Sadrian if (UseNUMA) { 889218065Sadrian int lgrp_id = os::numa_get_group_id(); 890218065Sadrian if (lgrp_id != -1) { 891218065Sadrian thread->set_lgrp_id(lgrp_id); 892229949Sadrian } 893229949Sadrian } 894240899Sadrian 895240899Sadrian if (ThreadPriorityVerbose) { 896240899Sadrian tty->print_cr("In create_os_thread, Thread " INTPTR_FORMAT ", LWP is " INTPTR_FORMAT "\n", 897240899Sadrian osthread->thread_id(), osthread->lwp_id()); 898240899Sadrian } 899240899Sadrian 900240899Sadrian // Initial thread state is INITIALIZED, not SUSPENDED 901218065Sadrian osthread->set_state(INITIALIZED); 902218065Sadrian 903227360Sadrian return osthread; 904227360Sadrian} 905238609Sadrian 906218065Sadrianvoid os::Solaris::hotspot_sigmask(Thread* thread) { 907248671Sadrian 908240899Sadrian //Save caller's signal mask 909240899Sadrian sigset_t sigmask; 910227364Sadrian thr_sigsetmask(SIG_SETMASK, NULL, &sigmask); 911227364Sadrian OSThread *osthread = thread->osthread(); 912218065Sadrian osthread->set_caller_sigmask(sigmask); 913227364Sadrian 914227364Sadrian thr_sigsetmask(SIG_UNBLOCK, os::Solaris::unblocked_signals(), NULL); 915227364Sadrian if (!ReduceSignalUsage) { 916227364Sadrian if (thread->is_VM_thread()) { 917227364Sadrian // Only the VM thread handles BREAK_SIGNAL ... 918238930Sadrian thr_sigsetmask(SIG_UNBLOCK, vm_signals(), NULL); 919238930Sadrian } else { 920227364Sadrian // ... all other threads block BREAK_SIGNAL 921227364Sadrian assert(!sigismember(vm_signals(), SIGINT), "SIGINT should not be blocked"); 922232707Sadrian thr_sigsetmask(SIG_BLOCK, vm_signals(), NULL); 923218065Sadrian } 924248671Sadrian } 925227364Sadrian} 926227364Sadrian 927227364Sadrianbool os::create_attached_thread(JavaThread* thread) { 928232707Sadrian#ifdef ASSERT 929227364Sadrian thread->verify_not_published(); 930232707Sadrian#endif 931232707Sadrian OSThread* osthread = create_os_thread(thread, thr_self()); 932227364Sadrian if (osthread == NULL) { 933227364Sadrian return false; 934227364Sadrian } 935227364Sadrian 936239120Sadrian // Initial thread state is RUNNABLE 937227364Sadrian osthread->set_state(RUNNABLE); 938218065Sadrian thread->set_osthread(osthread); 939218065Sadrian 940227364Sadrian // initialize signal mask for this thread 941227364Sadrian // and save the caller's signal mask 942227364Sadrian os::Solaris::hotspot_sigmask(thread); 943227364Sadrian 944227364Sadrian return true; 945227364Sadrian} 946238930Sadrian 947238930Sadrianbool os::create_main_thread(JavaThread* thread) { 948227364Sadrian#ifdef ASSERT 949243786Sadrian thread->verify_not_published(); 950227364Sadrian#endif 951243162Sadrian if (_starting_thread == NULL) { 952243162Sadrian _starting_thread = create_os_thread(thread, main_thread); 953243162Sadrian if (_starting_thread == NULL) { 954243162Sadrian return false; 955243162Sadrian } 956227364Sadrian } 957227364Sadrian 958227364Sadrian // The primodial thread is runnable from the start 959227364Sadrian _starting_thread->set_state(RUNNABLE); 960227364Sadrian 961227364Sadrian thread->set_osthread(_starting_thread); 962218154Sadrian 963218154Sadrian // initialize signal mask for this thread 964229949Sadrian // and save the caller's signal mask 965229949Sadrian os::Solaris::hotspot_sigmask(thread); 966218154Sadrian 967233330Sadrian return true; 968233330Sadrian} 969233330Sadrian 970233330Sadrian 971233330Sadrianbool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) { 972233330Sadrian // Allocate the OSThread object 973233330Sadrian OSThread* osthread = new OSThread(NULL, NULL); 974233330Sadrian if (osthread == NULL) { 975233330Sadrian return false; 976218154Sadrian } 977218154Sadrian 978218154Sadrian if (ThreadPriorityVerbose) { 979218154Sadrian char *thrtyp; 980218154Sadrian switch (thr_type) { 981218154Sadrian case vm_thread: 982218154Sadrian thrtyp = (char *)"vm"; 983218154Sadrian break; 984218154Sadrian case cgc_thread: 985218154Sadrian thrtyp = (char *)"cgc"; 986218154Sadrian break; 987218154Sadrian case pgc_thread: 988218154Sadrian thrtyp = (char *)"pgc"; 989218154Sadrian break; 990218154Sadrian case java_thread: 991218154Sadrian thrtyp = (char *)"java"; 992218154Sadrian break; 993229949Sadrian case compiler_thread: 994218154Sadrian thrtyp = (char *)"compiler"; 995218154Sadrian break; 996218154Sadrian case watcher_thread: 997218154Sadrian thrtyp = (char *)"watcher"; 998218154Sadrian break; 999218154Sadrian default: 1000218154Sadrian thrtyp = (char *)"unknown"; 1001218154Sadrian break; 1002218154Sadrian } 1003218154Sadrian tty->print_cr("In create_thread, creating a %s thread\n", thrtyp); 1004218154Sadrian } 1005218154Sadrian 1006218154Sadrian // Calculate stack size if it's not specified by caller. 1007218154Sadrian if (stack_size == 0) { 1008218154Sadrian // The default stack size 1M (2M for LP64). 1009218154Sadrian stack_size = (BytesPerWord >> 2) * K * K; 1010218154Sadrian 1011218154Sadrian switch (thr_type) { 1012218154Sadrian case os::java_thread: 1013218154Sadrian // Java threads use ThreadStackSize which default value can be changed with the flag -Xss 1014218154Sadrian if (JavaThread::stack_size_at_create() > 0) stack_size = JavaThread::stack_size_at_create(); 1015218154Sadrian break; 1016218154Sadrian case os::compiler_thread: 1017218154Sadrian if (CompilerThreadStackSize > 0) { 1018218154Sadrian stack_size = (size_t)(CompilerThreadStackSize * K); 1019218154Sadrian break; 1020229949Sadrian } // else fall through: 1021218154Sadrian // use VMThreadStackSize if CompilerThreadStackSize is not defined 1022218154Sadrian case os::vm_thread: 1023233989Sadrian case os::pgc_thread: 1024233989Sadrian case os::cgc_thread: 1025233989Sadrian case os::watcher_thread: 1026233989Sadrian if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K); 1027233989Sadrian break; 1028233989Sadrian } 1029233989Sadrian } 1030233989Sadrian stack_size = MAX2(stack_size, os::Solaris::min_stack_allowed); 1031233989Sadrian 1032233989Sadrian // Initial state is ALLOCATED but not INITIALIZED 1033233989Sadrian osthread->set_state(ALLOCATED); 1034233989Sadrian 1035233989Sadrian if (os::Solaris::_os_thread_count > os::Solaris::_os_thread_limit) { 1036233989Sadrian // We got lots of threads. Check if we still have some address space left. 1037233989Sadrian // Need to be at least 5Mb of unreserved address space. We do check by 1038233989Sadrian // trying to reserve some. 1039233989Sadrian const size_t VirtualMemoryBangSize = 20*K*K; 1040233989Sadrian char* mem = os::reserve_memory(VirtualMemoryBangSize); 1041233989Sadrian if (mem == NULL) { 1042233989Sadrian delete osthread; 1043233989Sadrian return false; 1044233989Sadrian } else { 1045233989Sadrian // Release the memory again 1046233989Sadrian os::release_memory(mem, VirtualMemoryBangSize); 1047233989Sadrian } 1048233989Sadrian } 1049233989Sadrian 1050233989Sadrian // Setup osthread because the child thread may need it. 1051233989Sadrian thread->set_osthread(osthread); 1052233989Sadrian 1053233989Sadrian // Create the Solaris thread 1054233989Sadrian thread_t tid = 0; 1055233989Sadrian long flags = (UseDetachedThreads ? THR_DETACHED : 0) | THR_SUSPENDED; 1056233989Sadrian int status; 1057233989Sadrian 1058233989Sadrian // Mark that we don't have an lwp or thread id yet. 1059233989Sadrian // In case we attempt to set the priority before the thread starts. 1060233989Sadrian osthread->set_lwp_id(-1); 1061233989Sadrian osthread->set_thread_id(-1); 1062233989Sadrian 1063233989Sadrian status = thr_create(NULL, stack_size, java_start, thread, flags, &tid); 1064233989Sadrian if (status != 0) { 1065233989Sadrian if (PrintMiscellaneous && (Verbose || WizardMode)) { 1066233989Sadrian perror("os::create_thread"); 1067233989Sadrian } 1068233989Sadrian thread->set_osthread(NULL); 1069233989Sadrian // Need to clean up stuff we've allocated so far 1070233989Sadrian delete osthread; 1071233989Sadrian return false; 1072233989Sadrian } 1073233989Sadrian 1074233989Sadrian Atomic::inc(&os::Solaris::_os_thread_count); 1075233989Sadrian 1076233989Sadrian // Store info on the Solaris thread into the OSThread 1077233989Sadrian osthread->set_thread_id(tid); 1078233989Sadrian 1079233989Sadrian // Remember that we created this thread so we can set priority on it 1080233989Sadrian osthread->set_vm_created(); 1081233989Sadrian 1082233989Sadrian // Initial thread state is INITIALIZED, not SUSPENDED 1083233989Sadrian osthread->set_state(INITIALIZED); 1084233989Sadrian 1085233989Sadrian // The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain 1086233989Sadrian return true; 1087233989Sadrian} 1088233989Sadrian 1089233989Sadrian/* defined for >= Solaris 10. This allows builds on earlier versions 1090233989Sadrian * of Solaris to take advantage of the newly reserved Solaris JVM signals 1091233989Sadrian * With SIGJVM1, SIGJVM2, INTERRUPT_SIGNAL is SIGJVM1, ASYNC_SIGNAL is SIGJVM2 1092233989Sadrian * and -XX:+UseAltSigs does nothing since these should have no conflict 1093233989Sadrian */ 1094233989Sadrian#if !defined(SIGJVM1) 1095233989Sadrian#define SIGJVM1 39 1096233989Sadrian#define SIGJVM2 40 1097233989Sadrian#endif 1098233989Sadrian 1099233989Sadriandebug_only(static bool signal_sets_initialized = false); 1100233989Sadrianstatic sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs; 1101233989Sadrianint os::Solaris::_SIGinterrupt = INTERRUPT_SIGNAL; 1102233989Sadrianint os::Solaris::_SIGasync = ASYNC_SIGNAL; 1103233989Sadrian 1104233989Sadrianbool os::Solaris::is_sig_ignored(int sig) { 1105233989Sadrian struct sigaction oact; 1106233989Sadrian sigaction(sig, (struct sigaction*)NULL, &oact); 1107233989Sadrian void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*, oact.sa_sigaction) 1108233989Sadrian : CAST_FROM_FN_PTR(void*, oact.sa_handler); 1109233989Sadrian if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN)) 1110233989Sadrian return true; 1111233989Sadrian else 1112233989Sadrian return false; 1113233989Sadrian} 1114233989Sadrian 1115233989Sadrian// Note: SIGRTMIN is a macro that calls sysconf() so it will 1116233989Sadrian// dynamically detect SIGRTMIN value for the system at runtime, not buildtime 1117233989Sadrianstatic bool isJVM1available() { 1118233989Sadrian return SIGJVM1 < SIGRTMIN; 1119233989Sadrian} 1120233989Sadrian 1121233989Sadrianvoid os::Solaris::signal_sets_init() { 1122233989Sadrian // Should also have an assertion stating we are still single-threaded. 1123233989Sadrian assert(!signal_sets_initialized, "Already initialized"); 1124246745Sadrian // Fill in signals that are necessarily unblocked for all threads in 1125233989Sadrian // the VM. Currently, we unblock the following signals: 1126233989Sadrian // SHUTDOWN{1,2,3}_SIGNAL: for shutdown hooks support (unless over-ridden 1127233989Sadrian // by -Xrs (=ReduceSignalUsage)); 1128233989Sadrian // BREAK_SIGNAL which is unblocked only by the VM thread and blocked by all 1129242144Sadrian // other threads. The "ReduceSignalUsage" boolean tells us not to alter 1130242144Sadrian // the dispositions or masks wrt these signals. 1131242144Sadrian // Programs embedding the VM that want to use the above signals for their 1132242144Sadrian // own purposes must, at this time, use the "-Xrs" option to prevent 1133233989Sadrian // interference with shutdown hooks and BREAK_SIGNAL thread dumping. 1134233989Sadrian // (See bug 4345157, and other related bugs). 1135246745Sadrian // In reality, though, unblocking these signals is really a nop, since 1136233989Sadrian // these signals are not blocked by default. 1137233989Sadrian sigemptyset(&unblocked_sigs); 1138233989Sadrian sigemptyset(&allowdebug_blocked_sigs); 1139233989Sadrian sigaddset(&unblocked_sigs, SIGILL); 1140233989Sadrian sigaddset(&unblocked_sigs, SIGSEGV); 1141233989Sadrian sigaddset(&unblocked_sigs, SIGBUS); 1142233989Sadrian sigaddset(&unblocked_sigs, SIGFPE); 1143233989Sadrian 1144233989Sadrian if (isJVM1available) { 1145233989Sadrian os::Solaris::set_SIGinterrupt(SIGJVM1); 1146233989Sadrian os::Solaris::set_SIGasync(SIGJVM2); 1147233989Sadrian } else if (UseAltSigs) { 1148233989Sadrian os::Solaris::set_SIGinterrupt(ALT_INTERRUPT_SIGNAL); 1149233989Sadrian os::Solaris::set_SIGasync(ALT_ASYNC_SIGNAL); 1150233989Sadrian } else { 1151233989Sadrian os::Solaris::set_SIGinterrupt(INTERRUPT_SIGNAL); 1152233989Sadrian os::Solaris::set_SIGasync(ASYNC_SIGNAL); 1153233989Sadrian } 1154218932Sadrian 1155218932Sadrian sigaddset(&unblocked_sigs, os::Solaris::SIGinterrupt()); 1156227364Sadrian sigaddset(&unblocked_sigs, os::Solaris::SIGasync()); 1157218157Sadrian 1158218932Sadrian if (!ReduceSignalUsage) { 1159218932Sadrian if (!os::Solaris::is_sig_ignored(SHUTDOWN1_SIGNAL)) { 1160218157Sadrian sigaddset(&unblocked_sigs, SHUTDOWN1_SIGNAL); 1161218157Sadrian sigaddset(&allowdebug_blocked_sigs, SHUTDOWN1_SIGNAL); 1162218157Sadrian } 1163218157Sadrian if (!os::Solaris::is_sig_ignored(SHUTDOWN2_SIGNAL)) { 1164218157Sadrian sigaddset(&unblocked_sigs, SHUTDOWN2_SIGNAL); 1165218157Sadrian sigaddset(&allowdebug_blocked_sigs, SHUTDOWN2_SIGNAL); 1166218157Sadrian } 1167218932Sadrian if (!os::Solaris::is_sig_ignored(SHUTDOWN3_SIGNAL)) { 1168218932Sadrian sigaddset(&unblocked_sigs, SHUTDOWN3_SIGNAL); 1169218932Sadrian sigaddset(&allowdebug_blocked_sigs, SHUTDOWN3_SIGNAL); 1170218932Sadrian } 1171218932Sadrian } 1172218932Sadrian // Fill in signals that are blocked by all but the VM thread. 1173229949Sadrian sigemptyset(&vm_sigs); 1174218932Sadrian if (!ReduceSignalUsage) 1175218932Sadrian sigaddset(&vm_sigs, BREAK_SIGNAL); 1176218932Sadrian debug_only(signal_sets_initialized = true); 1177218932Sadrian 1178218932Sadrian // For diagnostics only used in run_periodic_checks 1179218932Sadrian sigemptyset(&check_signal_done); 1180218932Sadrian} 1181218932Sadrian 1182218932Sadrian// These are signals that are unblocked while a thread is running Java. 1183218932Sadrian// (For some reason, they get blocked by default.) 1184218932Sadriansigset_t* os::Solaris::unblocked_signals() { 1185218932Sadrian assert(signal_sets_initialized, "Not initialized"); 1186218932Sadrian return &unblocked_sigs; 1187218932Sadrian} 1188218932Sadrian 1189218932Sadrian// These are the signals that are blocked while a (non-VM) thread is 1190229949Sadrian// running Java. Only the VM thread handles these signals. 1191218932Sadriansigset_t* os::Solaris::vm_signals() { 1192218932Sadrian assert(signal_sets_initialized, "Not initialized"); 1193218157Sadrian return &vm_sigs; 1194218157Sadrian} 1195218157Sadrian 1196218157Sadrian// These are signals that are blocked during cond_wait to allow debugger in 1197218157Sadriansigset_t* os::Solaris::allowdebug_blocked_signals() { 1198218157Sadrian assert(signal_sets_initialized, "Not initialized"); 1199218157Sadrian return &allowdebug_blocked_sigs; 1200218157Sadrian} 1201218157Sadrian 1202218157Sadrian 1203218157Sadrianvoid _handle_uncaught_cxx_exception() { 1204218932Sadrian VMError err("An uncaught C++ exception"); 1205218932Sadrian err.report_and_die(); 1206218157Sadrian} 1207218157Sadrian 1208218932Sadrian 1209218157Sadrian// First crack at OS-specific initialization, from inside the new thread. 1210218157Sadrianvoid os::initialize_thread(Thread* thr) { 1211218932Sadrian int r = thr_main(); 1212218932Sadrian guarantee(r == 0 || r == 1, "CR6501650 or CR6493689"); 1213218157Sadrian if (r) { 1214218157Sadrian JavaThread* jt = (JavaThread *)thr; 1215218932Sadrian assert(jt != NULL, "Sanity check"); 1216218157Sadrian size_t stack_size; 1217218932Sadrian address base = jt->stack_base(); 1218229949Sadrian if (Arguments::created_by_java_launcher()) { 1219218157Sadrian // Use 2MB to allow for Solaris 7 64 bit mode. 1220218157Sadrian stack_size = JavaThread::stack_size_at_create() == 0 1221227364Sadrian ? 2048*K : JavaThread::stack_size_at_create(); 1222227364Sadrian 1223227364Sadrian // There are rare cases when we may have already used more than 1224227364Sadrian // the basic stack size allotment before this method is invoked. 1225227364Sadrian // Attempt to allow for a normally sized java_stack. 1226227364Sadrian size_t current_stack_offset = (size_t)(base - (address)&stack_size); 1227227364Sadrian stack_size += ReservedSpace::page_align_size_down(current_stack_offset); 1228227364Sadrian } else { 1229227364Sadrian // 6269555: If we were not created by a Java launcher, i.e. if we are 1230227364Sadrian // running embedded in a native application, treat the primordial thread 1231227364Sadrian // as much like a native attached thread as possible. This means using 1232227364Sadrian // the current stack size from thr_stksegment(), unless it is too large 1233227364Sadrian // to reliably setup guard pages. A reasonable max size is 8MB. 1234227364Sadrian size_t current_size = current_stack_size(); 1235227364Sadrian // This should never happen, but just in case.... 1236218065Sadrian if (current_size == 0) current_size = 2 * K * K; 1237227364Sadrian stack_size = current_size > (8 * K * K) ? (8 * K * K) : current_size; 1238227364Sadrian } 1239227364Sadrian address bottom = (address)align_size_up((intptr_t)(base - stack_size), os::vm_page_size());; 1240227364Sadrian stack_size = (size_t)(base - bottom); 1241227364Sadrian 1242227364Sadrian assert(stack_size > 0, "Stack size calculation problem"); 1243227364Sadrian 1244227364Sadrian if (stack_size > jt->stack_size()) { 1245227364Sadrian NOT_PRODUCT( 1246233966Sadrian struct rlimit limits; 1247227364Sadrian getrlimit(RLIMIT_STACK, &limits); 1248227364Sadrian size_t size = adjust_stack_size(base, (size_t)limits.rlim_cur); 1249227364Sadrian assert(size >= jt->stack_size(), "Stack size problem in main thread"); 1250227364Sadrian ) 1251227364Sadrian tty->print_cr( 1252227364Sadrian "Stack size of %d Kb exceeds current limit of %d Kb.\n" 1253227364Sadrian "(Stack sizes are rounded up to a multiple of the system page size.)\n" 1254227364Sadrian "See limit(1) to increase the stack size limit.", 1255227364Sadrian stack_size / K, jt->stack_size() / K); 1256227364Sadrian vm_exit(1); 1257227364Sadrian } 1258227364Sadrian assert(jt->stack_size() >= stack_size, 1259227364Sadrian "Attempt to map more stack than was allocated"); 1260227364Sadrian jt->set_stack_size(stack_size); 1261227364Sadrian } 1262227364Sadrian 1263227364Sadrian // With the T2 libthread (T1 is no longer supported) threads are always bound 1264227364Sadrian // and we use stackbanging in all cases. 1265227364Sadrian 1266227364Sadrian os::Solaris::init_thread_fpu_state(); 1267227364Sadrian std::set_terminate(_handle_uncaught_cxx_exception); 1268227364Sadrian} 1269227364Sadrian 1270227364Sadrian 1271227364Sadrian 1272227364Sadrian// Free Solaris resources related to the OSThread 1273227364Sadrianvoid os::free_thread(OSThread* osthread) { 1274227364Sadrian assert(osthread != NULL, "os::free_thread but osthread not set"); 1275227364Sadrian 1276227364Sadrian 1277227364Sadrian // We are told to free resources of the argument thread, 1278227364Sadrian // but we can only really operate on the current thread. 1279227364Sadrian // The main thread must take the VMThread down synchronously 1280227364Sadrian // before the main thread exits and frees up CodeHeap 1281233966Sadrian guarantee((Thread::current()->osthread() == osthread 1282227364Sadrian || (osthread == VMThread::vm_thread()->osthread())), "os::free_thread but not current thread"); 1283227364Sadrian if (Thread::current()->osthread() == osthread) { 1284227364Sadrian // Restore caller's signal mask 1285227364Sadrian sigset_t sigmask = osthread->caller_sigmask(); 1286227364Sadrian thr_sigsetmask(SIG_SETMASK, &sigmask, NULL); 1287227364Sadrian } 1288227364Sadrian delete osthread; 1289227364Sadrian} 1290238961Sadrian 1291238961Sadrianvoid os::pd_start_thread(Thread* thread) { 1292238961Sadrian int status = thr_continue(thread->osthread()->thread_id()); 1293238961Sadrian assert_status(status == 0, status, "thr_continue failed"); 1294238961Sadrian} 1295227364Sadrian 1296227364Sadrian 1297227364Sadrianintx os::current_thread_id() { 1298227364Sadrian return (intx)thr_self(); 1299227364Sadrian} 1300239051Sadrian 1301239051Sadrianstatic pid_t _initial_pid = 0; 1302239051Sadrian 1303239051Sadrianint os::current_process_id() { 1304239051Sadrian return (int)(_initial_pid ? _initial_pid : getpid()); 1305227364Sadrian} 1306227364Sadrian 1307227364Sadrianint os::allocate_thread_local_storage() { 1308227364Sadrian // %%% in Win32 this allocates a memory segment pointed to by a 1309227364Sadrian // register. Dan Stein can implement a similar feature in 1310227364Sadrian // Solaris. Alternatively, the VM can do the same thing 1311227364Sadrian // explicitly: malloc some storage and keep the pointer in a 1312242951Sadrian // register (which is part of the thread's context) (or keep it 1313242951Sadrian // in TLS). 1314242951Sadrian // %%% In current versions of Solaris, thr_self and TSD can 1315242951Sadrian // be accessed via short sequences of displaced indirections. 1316227364Sadrian // The value of thr_self is available as %g7(36). 1317227364Sadrian // The value of thr_getspecific(k) is stored in %g7(12)(4)(k*4-4), 1318227364Sadrian // assuming that the current thread already has a value bound to k. 1319227364Sadrian // It may be worth experimenting with such access patterns, 1320227364Sadrian // and later having the parameters formally exported from a Solaris 1321227364Sadrian // interface. I think, however, that it will be faster to 1322227364Sadrian // maintain the invariant that %g2 always contains the 1323227364Sadrian // JavaThread in Java code, and have stubs simply 1324227364Sadrian // treat %g2 as a caller-save register, preserving it in a %lN. 1325233966Sadrian thread_key_t tk; 1326227364Sadrian if (thr_keycreate( &tk, NULL)) 1327227364Sadrian fatal(err_msg("os::allocate_thread_local_storage: thr_keycreate failed " 1328227364Sadrian "(%s)", strerror(errno))); 1329227364Sadrian return int(tk); 1330227364Sadrian} 1331227364Sadrian 1332227364Sadrianvoid os::free_thread_local_storage(int index) { 1333227364Sadrian // %%% don't think we need anything here 1334227364Sadrian // if ( pthread_key_delete((pthread_key_t) tk) ) 1335227364Sadrian // fatal("os::free_thread_local_storage: pthread_key_delete failed"); 1336238947Sadrian} 1337238947Sadrian 1338242656Sadrian#define SMALLINT 32 // libthread allocate for tsd_common is a version specific 1339227364Sadrian // small number - point is NO swap space available 1340227364Sadrianvoid os::thread_local_storage_at_put(int index, void* value) { 1341227364Sadrian // %%% this is used only in threadLocalStorage.cpp 1342227364Sadrian if (thr_setspecific((thread_key_t)index, value)) { 1343227364Sadrian if (errno == ENOMEM) { 1344227364Sadrian vm_exit_out_of_memory(SMALLINT, OOM_MALLOC_ERROR, 1345227364Sadrian "thr_setspecific: out of swap space"); 1346227364Sadrian } else { 1347227364Sadrian fatal(err_msg("os::thread_local_storage_at_put: thr_setspecific failed " 1348227364Sadrian "(%s)", strerror(errno))); 1349227364Sadrian } 1350227364Sadrian } else { 1351227364Sadrian ThreadLocalStorage::set_thread_in_slot((Thread *) value); 1352227364Sadrian } 1353227364Sadrian} 1354227364Sadrian 1355227364Sadrian// This function could be called before TLS is initialized, for example, when 1356227364Sadrian// VM receives an async signal or when VM causes a fatal error during 1357227364Sadrian// initialization. Return NULL if thr_getspecific() fails. 1358227364Sadrianvoid* os::thread_local_storage_at(int index) { 1359227364Sadrian // %%% this is used only in threadLocalStorage.cpp 1360227364Sadrian void* r = NULL; 1361227364Sadrian return thr_getspecific((thread_key_t)index, &r) != 0 ? NULL : r; 1362227364Sadrian} 1363227364Sadrian 1364227364Sadrian 1365227364Sadrian// gethrtime() should be monotonic according to the documentation, 1366227364Sadrian// but some virtualized platforms are known to break this guarantee. 1367227364Sadrian// getTimeNanos() must be guaranteed not to move backwards, so we 1368227364Sadrian// are forced to add a check here. 1369227364Sadrianinline hrtime_t getTimeNanos() { 1370227364Sadrian const hrtime_t now = gethrtime(); 1371227364Sadrian const hrtime_t prev = max_hrtime; 1372227364Sadrian if (now <= prev) { 1373227364Sadrian return prev; // same or retrograde time; 1374227364Sadrian } 1375227364Sadrian const hrtime_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&max_hrtime, prev); 1376227364Sadrian assert(obsv >= prev, "invariant"); // Monotonicity 1377227364Sadrian // If the CAS succeeded then we're done and return "now". 1378227364Sadrian // If the CAS failed and the observed value "obsv" is >= now then 1379227364Sadrian // we should return "obsv". If the CAS failed and now > obsv > prv then 1380227364Sadrian // some other thread raced this thread and installed a new value, in which case 1381227364Sadrian // we could either (a) retry the entire operation, (b) retry trying to install now 1382227364Sadrian // or (c) just return obsv. We use (c). No loop is required although in some cases 1383227364Sadrian // we might discard a higher "now" value in deference to a slightly lower but freshly 1384227364Sadrian // installed obsv value. That's entirely benign -- it admits no new orderings compared 1385227364Sadrian // to (a) or (b) -- and greatly reduces coherence traffic. 1386227364Sadrian // We might also condition (c) on the magnitude of the delta between obsv and now. 1387240883Sadrian // Avoiding excessive CAS operations to hot RW locations is critical. 1388240883Sadrian // See https://blogs.oracle.com/dave/entry/cas_and_cache_trivia_invalidate 1389240883Sadrian return (prev == obsv) ? now : obsv; 1390240883Sadrian} 1391240883Sadrian 1392240883Sadrian// Time since start-up in seconds to a fine granularity. 1393245708Sadrian// Used by VMSelfDestructTimer and the MemProfiler. 1394240883Sadriandouble os::elapsedTime() { 1395243786Sadrian return (double)(getTimeNanos() - first_hrtime) / (double)hrtime_hz; 1396240883Sadrian} 1397245708Sadrian 1398240883Sadrianjlong os::elapsed_counter() { 1399245708Sadrian return (jlong)(getTimeNanos() - first_hrtime); 1400240883Sadrian} 1401240883Sadrian 1402240883Sadrianjlong os::elapsed_frequency() { 1403240883Sadrian return hrtime_hz; 1404227364Sadrian} 1405227364Sadrian 1406227364Sadrian// Return the real, user, and system times in seconds from an 1407227364Sadrian// arbitrary fixed point in the past. 1408227364Sadrianbool os::getTimesSecs(double* process_real_time, 1409227364Sadrian double* process_user_time, 1410227364Sadrian double* process_system_time) { 1411227364Sadrian struct tms ticks; 1412227364Sadrian clock_t real_ticks = times(&ticks); 1413227364Sadrian 1414227364Sadrian if (real_ticks == (clock_t) (-1)) { 1415227364Sadrian return false; 1416227364Sadrian } else { 1417227364Sadrian double ticks_per_second = (double) clock_tics_per_sec; 1418240883Sadrian *process_user_time = ((double) ticks.tms_utime) / ticks_per_second; 1419240883Sadrian *process_system_time = ((double) ticks.tms_stime) / ticks_per_second; 1420227364Sadrian // For consistency return the real time from getTimeNanos() 1421243786Sadrian // converted to seconds. 1422227364Sadrian *process_real_time = ((double) getTimeNanos()) / ((double) NANOUNITS); 1423240883Sadrian 1424240883Sadrian return true; 1425240883Sadrian } 1426240883Sadrian} 1427240883Sadrian 1428240883Sadrianbool os::supports_vtime() { return true; } 1429240883Sadrian 1430240883Sadrianbool os::enable_vtime() { 1431240883Sadrian int fd = ::open("/proc/self/ctl", O_WRONLY); 1432240883Sadrian if (fd == -1) 1433240883Sadrian return false; 1434227364Sadrian 1435227364Sadrian long cmd[] = { PCSET, PR_MSACCT }; 1436233989Sadrian int res = ::write(fd, cmd, sizeof(long) * 2); 1437233989Sadrian ::close(fd); 1438233989Sadrian if (res != sizeof(long) * 2) 1439227364Sadrian return false; 1440227364Sadrian 1441227364Sadrian return true; 1442240883Sadrian} 1443240883Sadrian 1444240724Sadrianbool os::vtime_enabled() { 1445240883Sadrian int fd = ::open("/proc/self/status", O_RDONLY); 1446240883Sadrian if (fd == -1) 1447240883Sadrian return false; 1448227364Sadrian 1449227364Sadrian pstatus_t status; 1450227364Sadrian int res = os::read(fd, (void*) &status, sizeof(pstatus_t)); 1451227364Sadrian ::close(fd); 1452240722Sadrian if (res != sizeof(pstatus_t)) 1453240722Sadrian return false; 1454240722Sadrian 1455240722Sadrian return status.pr_flags & PR_MSACCT; 1456240722Sadrian} 1457240722Sadrian 1458240722Sadriandouble os::elapsedVTime() { 1459240722Sadrian return (double)gethrvtime() / (double)hrtime_hz; 1460240722Sadrian} 1461240722Sadrian 1462240722Sadrian// Used internally for comparisons only 1463240722Sadrian// getTimeMillis guaranteed to not move backwards on Solaris 1464227364Sadrianjlong getTimeMillis() { 1465227364Sadrian jlong nanotime = getTimeNanos(); 1466234009Sadrian return (jlong)(nanotime / NANOSECS_PER_MILLISEC); 1467227364Sadrian} 1468218065Sadrian 1469218065Sadrian// Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis 1470218065Sadrianjlong os::javaTimeMillis() { 1471218065Sadrian timeval t; 1472218065Sadrian if (gettimeofday( &t, NULL) == -1) 1473218065Sadrian fatal(err_msg("os::javaTimeMillis: gettimeofday (%s)", strerror(errno))); 1474227364Sadrian return jlong(t.tv_sec) * 1000 + jlong(t.tv_usec) / 1000; 1475227364Sadrian} 1476218065Sadrian 1477218065Sadrianjlong os::javaTimeNanos() { 1478227364Sadrian return (jlong)getTimeNanos(); 1479218065Sadrian} 1480218065Sadrian 1481218065Sadrianvoid os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) { 1482218065Sadrian info_ptr->max_value = ALL_64_BITS; // gethrtime() uses all 64 bits 1483218065Sadrian info_ptr->may_skip_backward = false; // not subject to resetting or drifting 1484218065Sadrian info_ptr->may_skip_forward = false; // not subject to resetting or drifting 1485236880Sadrian info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time 1486236880Sadrian} 1487236880Sadrian 1488236880Sadrianchar * os::local_time_string(char *buf, size_t buflen) { 1489236880Sadrian struct tm t; 1490236880Sadrian time_t long_time; 1491236880Sadrian time(&long_time); 1492243786Sadrian localtime_r(&long_time, &t); 1493236880Sadrian jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d", 1494218065Sadrian t.tm_year + 1900, t.tm_mon + 1, t.tm_mday, 1495218065Sadrian t.tm_hour, t.tm_min, t.tm_sec); 1496218065Sadrian return buf; 1497218065Sadrian} 1498218065Sadrian 1499218065Sadrian// Note: os::shutdown() might be called very early during initialization, or 1500218065Sadrian// called from signal handler. Before adding something to os::shutdown(), make 1501218065Sadrian// sure it is async-safe and can handle partially initialized VM. 1502218065Sadrianvoid os::shutdown() { 1503218065Sadrian 1504218065Sadrian // allow PerfMemory to attempt cleanup of any persistent resources 1505218154Sadrian perfMemory_exit(); 1506227364Sadrian 1507227364Sadrian // needs to remove object in file system 1508218154Sadrian AttachListener::abort(); 1509218154Sadrian 1510218154Sadrian // flush buffered output, finish log files 1511218065Sadrian ostream_abort(); 1512218154Sadrian 1513218154Sadrian // Check for abort hook 1514218065Sadrian abort_hook_t abort_hook = Arguments::abort_hook(); 1515218065Sadrian if (abort_hook != NULL) { 1516218065Sadrian abort_hook(); 1517218065Sadrian } 1518218065Sadrian} 1519218065Sadrian 1520218065Sadrian// Note: os::abort() might be called very early during initialization, or 1521218065Sadrian// called from signal handler. Before adding something to os::abort(), make 1522218065Sadrian// sure it is async-safe and can handle partially initialized VM. 1523218065Sadrianvoid os::abort(bool dump_core) { 1524218065Sadrian os::shutdown(); 1525218065Sadrian if (dump_core) { 1526218065Sadrian#ifndef PRODUCT 1527218065Sadrian fdStream out(defaultStream::output_fd()); 1528218065Sadrian out.print_raw("Current thread is "); 1529218065Sadrian char buf[16]; 1530218065Sadrian jio_snprintf(buf, sizeof(buf), UINTX_FORMAT, os::current_thread_id()); 1531218065Sadrian out.print_raw_cr(buf); 1532218065Sadrian out.print_raw_cr("Dumping core ..."); 1533218065Sadrian#endif 1534218065Sadrian ::abort(); // dump core (for debugging) 1535218065Sadrian } 1536218065Sadrian 1537218065Sadrian ::exit(1); 1538218065Sadrian} 1539218065Sadrian 1540218065Sadrian// Die immediately, no exit hook, no abort hook, no cleanup. 1541218065Sadrianvoid os::die() { 1542218065Sadrian ::abort(); // dump core (for debugging) 1543218065Sadrian} 1544218065Sadrian 1545218065Sadrian// unused 1546218065Sadrianvoid os::set_error_file(const char *logfile) {} 1547240724Sadrian 1548240724Sadrian// DLL functions 1549218065Sadrian 1550218065Sadrianconst char* os::dll_file_extension() { return ".so"; } 1551218065Sadrian 1552218065Sadrian// This must be hard coded because it's the system's temporary 1553218065Sadrian// directory not the java application's temp directory, ala java.io.tmpdir. 1554218065Sadrianconst char* os::get_temp_directory() { return "/tmp"; } 1555218065Sadrian 1556218065Sadrianstatic bool file_exists(const char* filename) { 1557218065Sadrian struct stat statbuf; 1558218065Sadrian if (filename == NULL || strlen(filename) == 0) { 1559218065Sadrian return false; 1560218065Sadrian } 1561218065Sadrian return os::stat(filename, &statbuf) == 0; 1562218065Sadrian} 1563218065Sadrian 1564218065Sadrianbool os::dll_build_name(char* buffer, size_t buflen, 1565218065Sadrian const char* pname, const char* fname) { 1566218065Sadrian bool retval = false; 1567218065Sadrian const size_t pnamelen = pname ? strlen(pname) : 0; 1568218065Sadrian 1569218065Sadrian // Return error on buffer overflow. 1570218065Sadrian if (pnamelen + strlen(fname) + 10 > (size_t) buflen) { 1571218065Sadrian return retval; 1572218065Sadrian } 1573218065Sadrian 1574218065Sadrian if (pnamelen == 0) { 1575218065Sadrian snprintf(buffer, buflen, "lib%s.so", fname); 1576218065Sadrian retval = true; 1577218065Sadrian } else if (strchr(pname, *os::path_separator()) != NULL) { 1578218065Sadrian int n; 1579218065Sadrian char** pelements = split_path(pname, &n); 1580218065Sadrian if (pelements == NULL) { 1581218065Sadrian return false; 1582218065Sadrian } 1583218065Sadrian for (int i = 0; i < n; i++) { 1584218065Sadrian // really shouldn't be NULL but what the heck, check can't hurt 1585218065Sadrian if (pelements[i] == NULL || strlen(pelements[i]) == 0) { 1586218065Sadrian continue; // skip the empty path values 1587218065Sadrian } 1588218065Sadrian snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname); 1589218065Sadrian if (file_exists(buffer)) { 1590218065Sadrian retval = true; 1591218065Sadrian break; 1592218065Sadrian } 1593218065Sadrian } 1594218065Sadrian // release the storage 1595218065Sadrian for (int i = 0; i < n; i++) { 1596218065Sadrian if (pelements[i] != NULL) { 1597218065Sadrian FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal); 1598218065Sadrian } 1599218065Sadrian } 1600218065Sadrian if (pelements != NULL) { 1601218065Sadrian FREE_C_HEAP_ARRAY(char*, pelements, mtInternal); 1602218065Sadrian } 1603218065Sadrian } else { 1604227364Sadrian snprintf(buffer, buflen, "%s/lib%s.so", pname, fname); 1605227364Sadrian retval = true; 1606227364Sadrian } 1607227364Sadrian return retval; 1608227364Sadrian} 1609227364Sadrian 1610218065Sadrian// check if addr is inside libjvm.so 1611218065Sadrianbool os::address_is_in_vm(address addr) { 1612218065Sadrian static address libjvm_base_addr; 1613218065Sadrian Dl_info dlinfo; 1614218065Sadrian 1615218065Sadrian if (libjvm_base_addr == NULL) { 1616218065Sadrian if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) { 1617218065Sadrian libjvm_base_addr = (address)dlinfo.dli_fbase; 1618218065Sadrian } 1619218065Sadrian assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm"); 1620218065Sadrian } 1621218065Sadrian 1622237041Sadrian if (dladdr((void *)addr, &dlinfo) != 0) { 1623237041Sadrian if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true; 1624237041Sadrian } 1625237041Sadrian 1626237041Sadrian return false; 1627237041Sadrian} 1628237041Sadrian 1629237041Sadriantypedef int (*dladdr1_func_type) (void *, Dl_info *, void **, int); 1630237041Sadrianstatic dladdr1_func_type dladdr1_func = NULL; 1631237041Sadrian 1632237041Sadrianbool os::dll_address_to_function_name(address addr, char *buf, 1633237041Sadrian int buflen, int * offset) { 1634237041Sadrian // buf is not optional, but offset is optional 1635237041Sadrian assert(buf != NULL, "sanity check"); 1636237041Sadrian 1637237041Sadrian Dl_info dlinfo; 1638237041Sadrian 1639237041Sadrian // dladdr1_func was initialized in os::init() 1640237041Sadrian if (dladdr1_func != NULL) { 1641237041Sadrian // yes, we have dladdr1 1642237041Sadrian 1643237041Sadrian // Support for dladdr1 is checked at runtime; it may be 1644235750Sadrian // available even if the vm is built on a machine that does 1645235750Sadrian // not have dladdr1 support. Make sure there is a value for 1646235750Sadrian // RTLD_DL_SYMENT. 1647235750Sadrian #ifndef RTLD_DL_SYMENT 1648235750Sadrian #define RTLD_DL_SYMENT 1 1649235750Sadrian #endif 1650235750Sadrian#ifdef _LP64 1651235750Sadrian Elf64_Sym * info; 1652235750Sadrian#else 1653235750Sadrian Elf32_Sym * info; 1654237041Sadrian#endif 1655235750Sadrian if (dladdr1_func((void *)addr, &dlinfo, (void **)&info, 1656218065Sadrian RTLD_DL_SYMENT) != 0) { 1657218065Sadrian // see if we have a matching symbol that covers our address 1658218065Sadrian if (dlinfo.dli_saddr != NULL && 1659218065Sadrian (char *)dlinfo.dli_saddr + info->st_size > (char *)addr) { 1660218065Sadrian if (dlinfo.dli_sname != NULL) { 1661218065Sadrian if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) { 1662218065Sadrian jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname); 1663218065Sadrian } 1664218065Sadrian if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; 1665218065Sadrian return true; 1666218065Sadrian } 1667218065Sadrian } 1668218065Sadrian // no matching symbol so try for just file info 1669218065Sadrian if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) { 1670218065Sadrian if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), 1671218065Sadrian buf, buflen, offset, dlinfo.dli_fname)) { 1672218065Sadrian return true; 1673218065Sadrian } 1674218065Sadrian } 1675218065Sadrian } 1676218065Sadrian buf[0] = '\0'; 1677218065Sadrian if (offset != NULL) *offset = -1; 1678218065Sadrian return false; 1679227364Sadrian } 1680227364Sadrian 1681227364Sadrian // no, only dladdr is available 1682227364Sadrian if (dladdr((void *)addr, &dlinfo) != 0) { 1683227364Sadrian // see if we have a matching symbol 1684227364Sadrian if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) { 1685227364Sadrian if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) { 1686227364Sadrian jio_snprintf(buf, buflen, dlinfo.dli_sname); 1687227364Sadrian } 1688227364Sadrian if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr; 1689227364Sadrian return true; 1690227364Sadrian } 1691227364Sadrian // no matching symbol so try for just file info 1692218065Sadrian if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) { 1693227364Sadrian if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase), 1694227364Sadrian buf, buflen, offset, dlinfo.dli_fname)) { 1695227364Sadrian return true; 1696227364Sadrian } 1697227364Sadrian } 1698227364Sadrian } 1699218932Sadrian buf[0] = '\0'; 1700227364Sadrian if (offset != NULL) *offset = -1; 1701218065Sadrian return false; 1702218065Sadrian} 1703218065Sadrian 1704218065Sadrianbool os::dll_address_to_library_name(address addr, char* buf, 1705218065Sadrian int buflen, int* offset) { 1706218065Sadrian // buf is not optional, but offset is optional 1707218065Sadrian assert(buf != NULL, "sanity check"); 1708218065Sadrian 1709218065Sadrian Dl_info dlinfo; 1710218065Sadrian 1711218065Sadrian if (dladdr((void*)addr, &dlinfo) != 0) { 1712218065Sadrian if (dlinfo.dli_fname != NULL) { 1713218065Sadrian jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname); 1714218065Sadrian } 1715218065Sadrian if (dlinfo.dli_fbase != NULL && offset != NULL) { 1716218065Sadrian *offset = addr - (address)dlinfo.dli_fbase; 1717218065Sadrian } 1718218065Sadrian return true; 1719218065Sadrian } 1720218065Sadrian 1721218065Sadrian buf[0] = '\0'; 1722218065Sadrian if (offset) *offset = -1; 1723218065Sadrian return false; 1724218065Sadrian} 1725218065Sadrian 1726218065Sadrian// Prints the names and full paths of all opened dynamic libraries 1727218065Sadrian// for current process 1728218065Sadrianvoid os::print_dll_info(outputStream * st) { 1729227364Sadrian Dl_info dli; 1730227364Sadrian void *handle; 1731227364Sadrian Link_map *map; 1732218065Sadrian Link_map *p; 1733227364Sadrian 1734227364Sadrian st->print_cr("Dynamic libraries:"); st->flush(); 1735227364Sadrian 1736227364Sadrian if (dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli) == 0 || 1737227364Sadrian dli.dli_fname == NULL) { 1738227364Sadrian st->print_cr("Error: Cannot print dynamic libraries."); 1739227364Sadrian return; 1740227364Sadrian } 1741227364Sadrian handle = dlopen(dli.dli_fname, RTLD_LAZY); 1742227364Sadrian if (handle == NULL) { 1743227364Sadrian st->print_cr("Error: Cannot print dynamic libraries."); 1744227364Sadrian return; 1745227364Sadrian } 1746227364Sadrian dlinfo(handle, RTLD_DI_LINKMAP, &map); 1747227364Sadrian if (map == NULL) { 1748227364Sadrian st->print_cr("Error: Cannot print dynamic libraries."); 1749233966Sadrian return; 1750227364Sadrian } 1751227364Sadrian 1752227364Sadrian while (map->l_prev != NULL) 1753227364Sadrian map = map->l_prev; 1754227364Sadrian 1755227364Sadrian while (map != NULL) { 1756227364Sadrian st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name); 1757227364Sadrian map = map->l_next; 1758227364Sadrian } 1759227364Sadrian 1760227364Sadrian dlclose(handle); 1761227364Sadrian} 1762240724Sadrian 1763227364Sadrian // Loads .dll/.so and 1764227364Sadrian // in case of error it checks if .dll/.so was built for the 1765227364Sadrian // same architecture as Hotspot is running on 1766227364Sadrian 1767227364Sadrianvoid * os::dll_load(const char *filename, char *ebuf, int ebuflen) 1768240724Sadrian{ 1769240724Sadrian void * result= ::dlopen(filename, RTLD_LAZY); 1770240724Sadrian if (result != NULL) { 1771227364Sadrian // Successful loading 1772227364Sadrian return result; 1773227364Sadrian } 1774227364Sadrian 1775227364Sadrian Elf32_Ehdr elf_head; 1776227364Sadrian 1777227364Sadrian // Read system error message into ebuf 1778232764Sadrian // It may or may not be overwritten below 1779227364Sadrian ::strncpy(ebuf, ::dlerror(), ebuflen-1); 1780227364Sadrian ebuf[ebuflen-1]='\0'; 1781227364Sadrian int diag_msg_max_length=ebuflen-strlen(ebuf); 1782227364Sadrian char* diag_msg_buf=ebuf+strlen(ebuf); 1783227364Sadrian 1784227364Sadrian if (diag_msg_max_length==0) { 1785236872Sadrian // No more space in ebuf for additional diagnostics message 1786227364Sadrian return NULL; 1787227364Sadrian } 1788243786Sadrian 1789243786Sadrian 1790227364Sadrian int file_descriptor= ::open(filename, O_RDONLY | O_NONBLOCK); 1791227364Sadrian 1792218065Sadrian if (file_descriptor < 0) { 1793234009Sadrian // Can't open library, report dlerror() message 1794234009Sadrian return NULL; 1795227364Sadrian } 1796227364Sadrian 1797227364Sadrian bool failed_to_read_elf_head= 1798227364Sadrian (sizeof(elf_head)!= 1799227364Sadrian (::read(file_descriptor, &elf_head,sizeof(elf_head)))); 1800227364Sadrian 1801227364Sadrian ::close(file_descriptor); 1802227364Sadrian if (failed_to_read_elf_head) { 1803218065Sadrian // file i/o error - report dlerror() msg 1804227364Sadrian return NULL; 1805227364Sadrian } 1806218065Sadrian 1807227364Sadrian typedef struct { 1808227364Sadrian Elf32_Half code; // Actual value as defined in elf.h 1809227364Sadrian Elf32_Half compat_class; // Compatibility of archs at VM's sense 1810227364Sadrian char elf_class; // 32 or 64 bit 1811227364Sadrian char endianess; // MSB or LSB 1812227364Sadrian char* name; // String representation 1813232764Sadrian } arch_t; 1814232764Sadrian 1815232764Sadrian static const arch_t arch_array[]={ 1816232764Sadrian {EM_386, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"}, 1817232764Sadrian {EM_486, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"}, 1818232764Sadrian {EM_IA_64, EM_IA_64, ELFCLASS64, ELFDATA2LSB, (char*)"IA 64"}, 1819248750Sadrian {EM_X86_64, EM_X86_64, ELFCLASS64, ELFDATA2LSB, (char*)"AMD 64"}, 1820248750Sadrian {EM_SPARC, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"}, 1821232764Sadrian {EM_SPARC32PLUS, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"}, 1822232764Sadrian {EM_SPARCV9, EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"}, 1823232764Sadrian {EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"}, 1824232764Sadrian {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"}, 1825232764Sadrian {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM 32"} 1826232764Sadrian }; 1827232764Sadrian 1828232764Sadrian #if (defined IA32) 1829232764Sadrian static Elf32_Half running_arch_code=EM_386; 1830227364Sadrian #elif (defined AMD64) 1831227364Sadrian static Elf32_Half running_arch_code=EM_X86_64; 1832227364Sadrian #elif (defined IA64) 1833227364Sadrian static Elf32_Half running_arch_code=EM_IA_64; 1834227364Sadrian #elif (defined __sparc) && (defined _LP64) 1835236872Sadrian static Elf32_Half running_arch_code=EM_SPARCV9; 1836236872Sadrian #elif (defined __sparc) && (!defined _LP64) 1837227364Sadrian static Elf32_Half running_arch_code=EM_SPARC; 1838239051Sadrian #elif (defined __powerpc64__) 1839239051Sadrian static Elf32_Half running_arch_code=EM_PPC64; 1840244109Sadrian #elif (defined __powerpc__) 1841239051Sadrian static Elf32_Half running_arch_code=EM_PPC; 1842239051Sadrian #elif (defined ARM) 1843248671Sadrian static Elf32_Half running_arch_code=EM_ARM; 1844232753Sadrian #else 1845234009Sadrian #error Method os::dll_load requires that one of following is defined:\ 1846234009Sadrian IA32, AMD64, IA64, __sparc, __powerpc__, ARM, ARM 1847234009Sadrian #endif 1848234009Sadrian 1849234009Sadrian // Identify compatability class for VM's architecture and library's architecture 1850234009Sadrian // Obtain string descriptions for architectures 1851232753Sadrian 1852248671Sadrian arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL}; 1853227364Sadrian int running_arch_index=-1; 1854239051Sadrian 1855239051Sadrian for (unsigned int i=0; i < ARRAY_SIZE(arch_array); i++) { 1856239051Sadrian if (running_arch_code == arch_array[i].code) { 1857239051Sadrian running_arch_index = i; 1858239051Sadrian } 1859244109Sadrian if (lib_arch.code == arch_array[i].code) { 1860239051Sadrian lib_arch.compat_class = arch_array[i].compat_class; 1861248671Sadrian lib_arch.name = arch_array[i].name; 1862227364Sadrian } 1863227364Sadrian } 1864227364Sadrian 1865227364Sadrian assert(running_arch_index != -1, 1866227364Sadrian "Didn't find running architecture code (running_arch_code) in arch_array"); 1867227364Sadrian if (running_arch_index == -1) { 1868236880Sadrian // Even though running architecture detection failed 1869236880Sadrian // we may still continue with reporting dlerror() message 1870236880Sadrian return NULL; 1871236880Sadrian } 1872227364Sadrian 1873227364Sadrian if (lib_arch.endianess != arch_array[running_arch_index].endianess) { 1874227364Sadrian ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)"); 1875227364Sadrian return NULL; 1876227364Sadrian } 1877227364Sadrian 1878227364Sadrian if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) { 1879236872Sadrian ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)"); 1880236874Sadrian return NULL; 1881236874Sadrian } 1882236874Sadrian 1883236874Sadrian if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) { 1884236872Sadrian if (lib_arch.name!=NULL) { 1885236872Sadrian ::snprintf(diag_msg_buf, diag_msg_max_length-1, 1886227364Sadrian " (Possible cause: can't load %s-bit .so on a %s-bit platform)", 1887227364Sadrian lib_arch.name, arch_array[running_arch_index].name); 1888218240Sadrian } else { 1889218240Sadrian ::snprintf(diag_msg_buf, diag_msg_max_length-1, 1890218065Sadrian " (Possible cause: can't load this .so (machine code=0x%x) on a %s-bit platform)", 1891227364Sadrian lib_arch.code, 1892227364Sadrian arch_array[running_arch_index].name); 1893218065Sadrian } 1894236872Sadrian } 1895227364Sadrian 1896227364Sadrian return NULL; 1897227364Sadrian} 1898227364Sadrian 1899227364Sadrianvoid* os::dll_lookup(void* handle, const char* name) { 1900227364Sadrian return dlsym(handle, name); 1901227364Sadrian} 1902227364Sadrian 1903234009Sadrianvoid* os::get_default_process_handle() { 1904227364Sadrian return (void*)::dlopen(NULL, RTLD_LAZY); 1905227364Sadrian} 1906236880Sadrian 1907227364Sadrianint os::stat(const char *path, struct stat *sbuf) { 1908227364Sadrian char pathbuf[MAX_PATH]; 1909227364Sadrian if (strlen(path) > MAX_PATH - 1) { 1910227364Sadrian errno = ENAMETOOLONG; 1911227364Sadrian return -1; 1912218065Sadrian } 1913227364Sadrian os::native_path(strcpy(pathbuf, path)); 1914227364Sadrian return ::stat(pathbuf, sbuf); 1915227364Sadrian} 1916218065Sadrian 1917227364Sadrianstatic bool _print_ascii_file(const char* filename, outputStream* st) { 1918227364Sadrian int fd = ::open(filename, O_RDONLY); 1919227364Sadrian if (fd == -1) { 1920227364Sadrian return false; 1921227364Sadrian } 1922227364Sadrian 1923227364Sadrian char buf[32]; 1924227364Sadrian int bytes; 1925227364Sadrian while ((bytes = ::read(fd, buf, sizeof(buf))) > 0) { 1926227364Sadrian st->print_raw(buf, bytes); 1927227364Sadrian } 1928227364Sadrian 1929235774Sadrian ::close(fd); 1930233227Sadrian 1931240724Sadrian return true; 1932227364Sadrian} 1933227364Sadrian 1934227364Sadrianvoid os::print_os_info_brief(outputStream* st) { 1935235774Sadrian os::Solaris::print_distro_info(st); 1936227364Sadrian 1937240724Sadrian os::Posix::print_uname_info(st); 1938227364Sadrian 1939227364Sadrian os::Solaris::print_libversion_info(st); 1940227364Sadrian} 1941235774Sadrian 1942233227Sadrianvoid os::print_os_info(outputStream* st) { 1943227364Sadrian st->print("OS:"); 1944227364Sadrian 1945227364Sadrian os::Solaris::print_distro_info(st); 1946227364Sadrian 1947227364Sadrian os::Posix::print_uname_info(st); 1948227364Sadrian 1949227364Sadrian os::Solaris::print_libversion_info(st); 1950240724Sadrian 1951227364Sadrian os::Posix::print_rlimit_info(st); 1952236880Sadrian 1953236880Sadrian os::Posix::print_load_average(st); 1954218065Sadrian} 1955218065Sadrian 1956218065Sadrianvoid os::Solaris::print_distro_info(outputStream* st) { 1957218065Sadrian if (!_print_ascii_file("/etc/release", st)) { 1958218065Sadrian st->print("Solaris"); 1959218065Sadrian } 1960218065Sadrian st->cr(); 1961218065Sadrian} 1962218065Sadrian 1963218065Sadrianvoid os::Solaris::print_libversion_info(outputStream* st) { 1964218065Sadrian st->print(" (T2 libthread)"); 1965218065Sadrian st->cr(); 1966218065Sadrian} 1967218065Sadrian 1968227364Sadrianstatic bool check_addr0(outputStream* st) { 1969218065Sadrian jboolean status = false; 1970227364Sadrian int fd = ::open("/proc/self/map",O_RDONLY); 1971218065Sadrian if (fd >= 0) { 1972218065Sadrian prmap_t p; 1973218065Sadrian while (::read(fd, &p, sizeof(p)) > 0) { 1974218065Sadrian if (p.pr_vaddr == 0x0) { 1975227364Sadrian st->print("Warning: Address: 0x%x, Size: %dK, ",p.pr_vaddr, p.pr_size/1024, p.pr_mapname); 1976227364Sadrian st->print("Mapped file: %s, ", p.pr_mapname[0] == '\0' ? "None" : p.pr_mapname); 1977218065Sadrian st->print("Access:"); 1978243786Sadrian st->print("%s",(p.pr_mflags & MA_READ) ? "r" : "-"); 1979243786Sadrian st->print("%s",(p.pr_mflags & MA_WRITE) ? "w" : "-"); 1980218065Sadrian st->print("%s",(p.pr_mflags & MA_EXEC) ? "x" : "-"); 1981218065Sadrian st->cr(); 1982218065Sadrian status = true; 1983218065Sadrian } 1984218065Sadrian } 1985218065Sadrian ::close(fd); 1986218065Sadrian } 1987218065Sadrian return status; 1988218065Sadrian} 1989218065Sadrian 1990240899Sadrianvoid os::pd_print_cpu_info(outputStream* st) { 1991240899Sadrian // Nothing to do for now. 1992240899Sadrian} 1993227364Sadrian 1994227364Sadrianvoid os::print_memory_info(outputStream* st) { 1995227364Sadrian st->print("Memory:"); 1996236880Sadrian st->print(" %dk page", os::vm_page_size()>>10); 1997236880Sadrian st->print(", physical " UINT64_FORMAT "k", os::physical_memory()>>10); 1998236880Sadrian st->print("(" UINT64_FORMAT "k free)", os::available_memory() >> 10); 1999236880Sadrian st->cr(); 2000236880Sadrian (void) check_addr0(st); 2001236880Sadrian} 2002236880Sadrian 2003236880Sadrianvoid os::print_siginfo(outputStream* st, void* siginfo) { 2004236880Sadrian const siginfo_t* si = (const siginfo_t*)siginfo; 2005236880Sadrian 2006236880Sadrian os::Posix::print_siginfo_brief(st, si); 2007236880Sadrian 2008236880Sadrian if (si && (si->si_signo == SIGBUS || si->si_signo == SIGSEGV) && 2009236880Sadrian UseSharedSpaces) { 2010236880Sadrian FileMapInfo* mapinfo = FileMapInfo::current_info(); 2011236880Sadrian if (mapinfo->is_in_shared_space(si->si_addr)) { 2012236880Sadrian st->print("\n\nError accessing class data sharing archive." \ 2013236880Sadrian " Mapped file inaccessible during execution, " \ 2014218154Sadrian " possible disk/network problem."); 2015227364Sadrian } 2016227364Sadrian } 2017227364Sadrian st->cr(); 2018218154Sadrian} 2019218154Sadrian 2020218154Sadrian// Moved from whole group, because we need them here for diagnostic 2021218154Sadrian// prints. 2022218154Sadrian#define OLDMAXSIGNUM 32 2023218065Sadrianstatic int Maxsignum = 0; 2024227364Sadrianstatic int *ourSigFlags = NULL; 2025227364Sadrian 2026227364Sadrianextern "C" void sigINTRHandler(int, siginfo_t*, void*); 2027227364Sadrian 2028218065Sadrianint os::Solaris::get_our_sigflags(int sig) { 2029218065Sadrian assert(ourSigFlags!=NULL, "signal data structure not initialized"); 2030218065Sadrian assert(sig > 0 && sig < Maxsignum, "vm signal out of expected range"); 2031218065Sadrian return ourSigFlags[sig]; 2032218065Sadrian} 2033218065Sadrian 2034218065Sadrianvoid os::Solaris::set_our_sigflags(int sig, int flags) { 2035240724Sadrian assert(ourSigFlags!=NULL, "signal data structure not initialized"); 2036218065Sadrian assert(sig > 0 && sig < Maxsignum, "vm signal out of expected range"); 2037218065Sadrian ourSigFlags[sig] = flags; 2038218065Sadrian} 2039218065Sadrian 2040227364Sadrian 2041227364Sadrianstatic const char* get_signal_handler_name(address handler, 2042227364Sadrian char* buf, int buflen) { 2043218065Sadrian int offset; 2044227364Sadrian bool found = os::dll_address_to_library_name(handler, buf, buflen, &offset); 2045218065Sadrian if (found) { 2046218065Sadrian // skip directory names 2047218065Sadrian const char *p1, *p2; 2048218065Sadrian p1 = buf; 2049218065Sadrian size_t len = strlen(os::file_separator()); 2050218065Sadrian while ((p2 = strstr(p1, os::file_separator())) != NULL) p1 = p2 + len; 2051218065Sadrian jio_snprintf(buf, buflen, "%s+0x%x", p1, offset); 2052218065Sadrian } else { 2053218065Sadrian jio_snprintf(buf, buflen, PTR_FORMAT, handler); 2054218065Sadrian } 2055218065Sadrian return buf; 2056218065Sadrian} 2057218065Sadrian 2058218065Sadrianstatic void print_signal_handler(outputStream* st, int sig, 2059218065Sadrian char* buf, size_t buflen) { 2060218065Sadrian struct sigaction sa; 2061218157Sadrian 2062227364Sadrian sigaction(sig, NULL, &sa); 2063227364Sadrian 2064227364Sadrian st->print("%s: ", os::exception_name(sig, buf, buflen)); 2065227364Sadrian 2066227364Sadrian address handler = (sa.sa_flags & SA_SIGINFO) 2067227364Sadrian ? CAST_FROM_FN_PTR(address, sa.sa_sigaction) 2068218157Sadrian : CAST_FROM_FN_PTR(address, sa.sa_handler); 2069218065Sadrian 2070218065Sadrian if (handler == CAST_FROM_FN_PTR(address, SIG_DFL)) { 2071218065Sadrian st->print("SIG_DFL"); 2072218065Sadrian } else if (handler == CAST_FROM_FN_PTR(address, SIG_IGN)) { 2073218065Sadrian st->print("SIG_IGN"); 2074218065Sadrian } else { 2075218065Sadrian st->print("[%s]", get_signal_handler_name(handler, buf, buflen)); 2076218065Sadrian } 2077218065Sadrian 2078218065Sadrian st->print(", sa_mask[0]="); 2079218065Sadrian os::Posix::print_signal_set_short(st, &sa.sa_mask); 2080218065Sadrian 2081218065Sadrian address rh = VMError::get_resetted_sighandler(sig); 2082218065Sadrian // May be, handler was resetted by VMError? 2083218065Sadrian if (rh != NULL) { 2084218065Sadrian handler = rh; 2085218065Sadrian sa.sa_flags = VMError::get_resetted_sigflags(sig); 2086218065Sadrian } 2087218065Sadrian 2088218065Sadrian st->print(", sa_flags="); 2089218065Sadrian os::Posix::print_sa_flags(st, sa.sa_flags); 2090218065Sadrian 2091218065Sadrian // Check: is it our handler? 2092218065Sadrian if (handler == CAST_FROM_FN_PTR(address, signalHandler) || 2093218065Sadrian handler == CAST_FROM_FN_PTR(address, sigINTRHandler)) { 2094218065Sadrian // It is our signal handler 2095218065Sadrian // check for flags 2096218065Sadrian if (sa.sa_flags != os::Solaris::get_our_sigflags(sig)) { 2097218065Sadrian st->print( 2098218065Sadrian ", flags was changed from " PTR32_FORMAT ", consider using jsig library", 2099218065Sadrian os::Solaris::get_our_sigflags(sig)); 2100227364Sadrian } 2101227364Sadrian } 2102227364Sadrian st->cr(); 2103227364Sadrian} 2104227364Sadrian 2105227364Sadrianvoid os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) { 2106227364Sadrian st->print_cr("Signal Handlers:"); 2107227364Sadrian print_signal_handler(st, SIGSEGV, buf, buflen); 2108227364Sadrian print_signal_handler(st, SIGBUS , buf, buflen); 2109227364Sadrian print_signal_handler(st, SIGFPE , buf, buflen); 2110233966Sadrian print_signal_handler(st, SIGPIPE, buf, buflen); 2111227364Sadrian print_signal_handler(st, SIGXFSZ, buf, buflen); 2112227364Sadrian print_signal_handler(st, SIGILL , buf, buflen); 2113218065Sadrian print_signal_handler(st, INTERRUPT_SIGNAL, buf, buflen); 2114239051Sadrian print_signal_handler(st, ASYNC_SIGNAL, buf, buflen); 2115239051Sadrian print_signal_handler(st, BREAK_SIGNAL, buf, buflen); 2116244109Sadrian print_signal_handler(st, SHUTDOWN1_SIGNAL , buf, buflen); 2117239051Sadrian print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen); 2118239051Sadrian print_signal_handler(st, SHUTDOWN3_SIGNAL, buf, buflen); 2119227364Sadrian print_signal_handler(st, os::Solaris::SIGinterrupt(), buf, buflen); 2120227364Sadrian print_signal_handler(st, os::Solaris::SIGasync(), buf, buflen); 2121227364Sadrian} 2122227364Sadrian 2123218240Sadrianstatic char saved_jvm_path[MAXPATHLEN] = { 0 }; 2124227364Sadrian 2125227364Sadrian// Find the full path to the current module, libjvm.so 2126218240Sadrianvoid os::jvm_path(char *buf, jint buflen) { 2127227364Sadrian // Error checking. 2128227364Sadrian if (buflen < MAXPATHLEN) { 2129227364Sadrian assert(false, "must use a large-enough buffer"); 2130227364Sadrian buf[0] = '\0'; 2131227364Sadrian return; 2132227364Sadrian } 2133227364Sadrian // Lazy resolve the path to current module. 2134227364Sadrian if (saved_jvm_path[0] != 0) { 2135227364Sadrian strcpy(buf, saved_jvm_path); 2136227364Sadrian return; 2137227364Sadrian } 2138227364Sadrian 2139227364Sadrian Dl_info dlinfo; 2140227364Sadrian int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo); 2141227364Sadrian assert(ret != 0, "cannot locate libjvm"); 2142227364Sadrian if (ret != 0 && dlinfo.dli_fname != NULL) { 2143227364Sadrian realpath((char *)dlinfo.dli_fname, buf); 2144227364Sadrian } else { 2145227364Sadrian buf[0] = '\0'; 2146218065Sadrian return; 2147227364Sadrian } 2148227364Sadrian 2149227364Sadrian if (Arguments::sun_java_launcher_is_altjvm()) { 2150227364Sadrian // Support for the java launcher's '-XXaltjvm=<path>' option. Typical 2151227364Sadrian // value for buf is "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". 2152218065Sadrian // If "/jre/lib/" appears at the right place in the string, then 2153227364Sadrian // assume we are installed in a JDK and we're done. Otherwise, check 2154227364Sadrian // for a JAVA_HOME environment variable and fix up the path so it 2155227364Sadrian // looks like libjvm.so is installed there (append a fake suffix 2156227364Sadrian // hotspot/libjvm.so). 2157227364Sadrian const char *p = buf + strlen(buf) - 1; 2158227364Sadrian for (int count = 0; p > buf && count < 5; ++count) { 2159227364Sadrian for (--p; p > buf && *p != '/'; --p) 2160227364Sadrian /* empty */ ; 2161227364Sadrian } 2162227364Sadrian 2163240882Sadrian if (strncmp(p, "/jre/lib/", 9) != 0) { 2164227364Sadrian // Look for JAVA_HOME in the environment. 2165240724Sadrian char* java_home_var = ::getenv("JAVA_HOME"); 2166227364Sadrian if (java_home_var != NULL && java_home_var[0] != 0) { 2167227364Sadrian char cpu_arch[12]; 2168227364Sadrian char* jrelib_p; 2169227364Sadrian int len; 2170227364Sadrian sysinfo(SI_ARCHITECTURE, cpu_arch, sizeof(cpu_arch)); 2171240882Sadrian#ifdef _LP64 2172240882Sadrian // If we are on sparc running a 64-bit vm, look in jre/lib/sparcv9. 2173240882Sadrian if (strcmp(cpu_arch, "sparc") == 0) { 2174240882Sadrian strcat(cpu_arch, "v9"); 2175240882Sadrian } else if (strcmp(cpu_arch, "i386") == 0) { 2176218065Sadrian strcpy(cpu_arch, "amd64"); 2177218065Sadrian } 2178218065Sadrian#endif 2179227364Sadrian // Check the current module name "libjvm.so". 2180227364Sadrian p = strrchr(buf, '/'); 2181227364Sadrian assert(strstr(p, "/libjvm") == p, "invalid library name"); 2182227364Sadrian 2183227364Sadrian realpath(java_home_var, buf); 2184218065Sadrian // determine if this is a legacy image or modules image 2185218065Sadrian // modules image doesn't have "jre" subdirectory 2186218065Sadrian len = strlen(buf); 2187218065Sadrian jrelib_p = buf + len; 2188218065Sadrian snprintf(jrelib_p, buflen-len, "/jre/lib/%s", cpu_arch); 2189218065Sadrian if (0 != access(buf, F_OK)) { 2190218065Sadrian snprintf(jrelib_p, buflen-len, "/lib/%s", cpu_arch); 2191218065Sadrian } 2192232764Sadrian 2193232764Sadrian if (0 == access(buf, F_OK)) { 2194218065Sadrian // Use current module name "libjvm.so" 2195227651Sadrian len = strlen(buf); 2196227651Sadrian snprintf(buf + len, buflen-len, "/hotspot/libjvm.so"); 2197227651Sadrian } else { 2198227651Sadrian // Go back to path of .so 2199227651Sadrian realpath((char *)dlinfo.dli_fname, buf); 2200227651Sadrian } 2201227651Sadrian } 2202227651Sadrian } 2203227651Sadrian } 2204227651Sadrian 2205227651Sadrian strcpy(saved_jvm_path, buf); 2206242391Sadrian} 2207242391Sadrian 2208218065Sadrian 2209218065Sadrianvoid os::print_jni_name_prefix_on(outputStream* st, int args_size) { 2210218065Sadrian // no prefix required, not even "_" 2211218065Sadrian} 2212218065Sadrian 2213218065Sadrian 2214218065Sadrianvoid os::print_jni_name_suffix_on(outputStream* st, int args_size) { 2215218065Sadrian // no suffix required 2216232764Sadrian} 2217218065Sadrian 2218232764Sadrian// This method is a copy of JDK's sysGetLastErrorString 2219232764Sadrian// from src/solaris/hpi/src/system_md.c 2220232764Sadrian 2221232764Sadriansize_t os::lasterror(char *buf, size_t len) { 2222232764Sadrian 2223248750Sadrian if (errno == 0) return 0; 2224248750Sadrian 2225232764Sadrian const char *s = ::strerror(errno); 2226232764Sadrian size_t n = ::strlen(s); 2227232764Sadrian if (n >= len) { 2228232764Sadrian n = len - 1; 2229232764Sadrian } 2230232764Sadrian ::strncpy(buf, s, n); 2231232764Sadrian buf[n] = '\0'; 2232232764Sadrian return n; 2233232764Sadrian} 2234232764Sadrian 2235232764Sadrian 2236218065Sadrian// sun.misc.Signal 2237218065Sadrian 2238237000Sadrianextern "C" { 2239218065Sadrian static void UserHandler(int sig, void *siginfo, void *context) { 2240218065Sadrian // Ctrl-C is pressed during error reporting, likely because the error 2241218065Sadrian // handler fails to abort. Let VM die immediately. 2242218065Sadrian if (sig == SIGINT && is_error_reported()) { 2243218065Sadrian os::die(); 2244218065Sadrian } 2245240899Sadrian 2246240899Sadrian os::signal_notify(sig); 2247218065Sadrian // We do not need to reinstate the signal handler each time... 2248218065Sadrian } 2249218065Sadrian} 2250218065Sadrian 2251218065Sadrianvoid* os::user_handler() { 2252218065Sadrian return CAST_FROM_FN_PTR(void*, UserHandler); 2253218065Sadrian} 2254218065Sadrian 2255218065Sadrianclass Semaphore : public StackObj { 2256218065Sadrian public: 2257218065Sadrian Semaphore(); 2258218065Sadrian ~Semaphore(); 2259218065Sadrian void signal(); 2260218065Sadrian void wait(); 2261218065Sadrian bool trywait(); 2262218065Sadrian bool timedwait(unsigned int sec, int nsec); 2263218065Sadrian private: 2264218065Sadrian sema_t _semaphore; 2265218065Sadrian}; 2266218065Sadrian 2267218065Sadrian 2268218065SadrianSemaphore::Semaphore() { 2269218065Sadrian sema_init(&_semaphore, 0, NULL, NULL); 2270218065Sadrian} 2271242271Sadrian 2272242271SadrianSemaphore::~Semaphore() { 2273242271Sadrian sema_destroy(&_semaphore); 2274242271Sadrian} 2275242271Sadrian 2276242271Sadrianvoid Semaphore::signal() { 2277242271Sadrian sema_post(&_semaphore); 2278243787Sadrian} 2279243787Sadrian 2280227651Sadrianvoid Semaphore::wait() { 2281227651Sadrian sema_wait(&_semaphore); 2282227651Sadrian} 2283227651Sadrian 2284218065Sadrianbool Semaphore::trywait() { 2285218065Sadrian return sema_trywait(&_semaphore) == 0; 2286240899Sadrian} 2287240899Sadrian 2288240899Sadrianbool Semaphore::timedwait(unsigned int sec, int nsec) { 2289240899Sadrian struct timespec ts; 2290240899Sadrian unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec); 2291218065Sadrian 2292236993Sadrian while (1) { 2293218065Sadrian int result = sema_timedwait(&_semaphore, &ts); 2294218065Sadrian if (result == 0) { 2295242391Sadrian return true; 2296242391Sadrian } else if (errno == EINTR) { 2297242391Sadrian continue; 2298227651Sadrian } else if (errno == ETIME) { 2299227651Sadrian return false; 2300227651Sadrian } else { 2301227651Sadrian return false; 2302240899Sadrian } 2303240899Sadrian } 2304218065Sadrian} 2305218065Sadrian 2306218065Sadrianextern "C" { 2307227651Sadrian typedef void (*sa_handler_t)(int); 2308218065Sadrian typedef void (*sa_sigaction_t)(int, siginfo_t *, void *); 2309218065Sadrian} 2310227364Sadrian 2311227364Sadrianvoid* os::signal(int signal_number, void* handler) { 2312227364Sadrian struct sigaction sigAct, oldSigAct; 2313227364Sadrian sigfillset(&(sigAct.sa_mask)); 2314227364Sadrian sigAct.sa_flags = SA_RESTART & ~SA_RESETHAND; 2315227364Sadrian sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler); 2316227364Sadrian 2317227364Sadrian if (sigaction(signal_number, &sigAct, &oldSigAct)) 2318227364Sadrian // -1 means registration failed 2319227364Sadrian return (void *)-1; 2320227364Sadrian 2321227364Sadrian return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler); 2322227364Sadrian} 2323227364Sadrian 2324227364Sadrianvoid os::signal_raise(int signal_number) { 2325227364Sadrian raise(signal_number); 2326227364Sadrian} 2327227364Sadrian 2328227364Sadrian/* 2329227364Sadrian * The following code is moved from os.cpp for making this 2330227364Sadrian * code platform specific, which it is by its very nature. 2331227364Sadrian */ 2332227364Sadrian 2333227364Sadrian// a counter for each possible signal value 2334227364Sadrianstatic int Sigexit = 0; 2335227364Sadrianstatic int Maxlibjsigsigs; 2336227364Sadrianstatic jint *pending_signals = NULL; 2337227364Sadrianstatic int *preinstalled_sigs = NULL; 2338227364Sadrianstatic struct sigaction *chainedsigactions = NULL; 2339227364Sadrianstatic sema_t sig_sem; 2340227364Sadriantypedef int (*version_getting_t)(); 2341227364Sadrianversion_getting_t os::Solaris::get_libjsig_version = NULL; 2342227364Sadrianstatic int libjsigversion = NULL; 2343227364Sadrian 2344227364Sadrianint os::sigexitnum_pd() { 2345227364Sadrian assert(Sigexit > 0, "signal memory not yet initialized"); 2346227364Sadrian return Sigexit; 2347227364Sadrian} 2348227364Sadrian 2349227364Sadrianvoid os::Solaris::init_signal_mem() { 2350227364Sadrian // Initialize signal structures 2351227364Sadrian Maxsignum = SIGRTMAX; 2352227364Sadrian Sigexit = Maxsignum+1; 2353227364Sadrian assert(Maxsignum >0, "Unable to obtain max signal number"); 2354227364Sadrian 2355227364Sadrian Maxlibjsigsigs = Maxsignum; 2356227364Sadrian 2357227364Sadrian // pending_signals has one int per signal 2358227364Sadrian // The additional signal is for SIGEXIT - exit signal to signal_thread 2359227364Sadrian pending_signals = (jint *)os::malloc(sizeof(jint) * (Sigexit+1), mtInternal); 2360227364Sadrian memset(pending_signals, 0, (sizeof(jint) * (Sigexit+1))); 2361227364Sadrian 2362227364Sadrian if (UseSignalChaining) { 2363227364Sadrian chainedsigactions = (struct sigaction *)malloc(sizeof(struct sigaction) 2364227364Sadrian * (Maxsignum + 1), mtInternal); 2365227364Sadrian memset(chainedsigactions, 0, (sizeof(struct sigaction) * (Maxsignum + 1))); 2366227364Sadrian preinstalled_sigs = (int *)os::malloc(sizeof(int) * (Maxsignum + 1), mtInternal); 2367227364Sadrian memset(preinstalled_sigs, 0, (sizeof(int) * (Maxsignum + 1))); 2368227364Sadrian } 2369227364Sadrian ourSigFlags = (int*)malloc(sizeof(int) * (Maxsignum + 1 ), mtInternal); 2370227364Sadrian memset(ourSigFlags, 0, sizeof(int) * (Maxsignum + 1)); 2371227364Sadrian} 2372227364Sadrian 2373227364Sadrianvoid os::signal_init_pd() { 2374227364Sadrian int ret; 2375227364Sadrian 2376227364Sadrian ret = ::sema_init(&sig_sem, 0, NULL, NULL); 2377227364Sadrian assert(ret == 0, "sema_init() failed"); 2378227364Sadrian} 2379227364Sadrian 2380227364Sadrianvoid os::signal_notify(int signal_number) { 2381227364Sadrian int ret; 2382227364Sadrian 2383227364Sadrian Atomic::inc(&pending_signals[signal_number]); 2384227364Sadrian ret = ::sema_post(&sig_sem); 2385227364Sadrian assert(ret == 0, "sema_post() failed"); 2386227364Sadrian} 2387227364Sadrian 2388227364Sadrianstatic int check_pending_signals(bool wait_for_signal) { 2389227364Sadrian int ret; 2390227364Sadrian while (true) { 2391227364Sadrian for (int i = 0; i < Sigexit + 1; i++) { 2392227364Sadrian jint n = pending_signals[i]; 2393227364Sadrian if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) { 2394227364Sadrian return i; 2395227364Sadrian } 2396227364Sadrian } 2397227364Sadrian if (!wait_for_signal) { 2398227364Sadrian return -1; 2399227364Sadrian } 2400227364Sadrian JavaThread *thread = JavaThread::current(); 2401227364Sadrian ThreadBlockInVM tbivm(thread); 2402227364Sadrian 2403227364Sadrian bool threadIsSuspended; 2404227364Sadrian do { 2405227364Sadrian thread->set_suspend_equivalent(); 2406227364Sadrian // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() 2407227364Sadrian while ((ret = ::sema_wait(&sig_sem)) == EINTR) 2408227364Sadrian ; 2409227364Sadrian assert(ret == 0, "sema_wait() failed"); 2410227364Sadrian 2411227364Sadrian // were we externally suspended while we were waiting? 2412227364Sadrian threadIsSuspended = thread->handle_special_suspend_equivalent_condition(); 2413227364Sadrian if (threadIsSuspended) { 2414227364Sadrian // 2415227364Sadrian // The semaphore has been incremented, but while we were waiting 2416227364Sadrian // another thread suspended us. We don't want to continue running 2417227364Sadrian // while suspended because that would surprise the thread that 2418243786Sadrian // suspended us. 2419227364Sadrian // 2420227364Sadrian ret = ::sema_post(&sig_sem); 2421227364Sadrian assert(ret == 0, "sema_post() failed"); 2422227364Sadrian 2423236886Sadrian thread->java_suspend_self(); 2424236886Sadrian } 2425236880Sadrian } while (threadIsSuspended); 2426236880Sadrian } 2427236880Sadrian} 2428236880Sadrian 2429236880Sadrianint os::signal_lookup() { 2430236880Sadrian return check_pending_signals(false); 2431236880Sadrian} 2432236880Sadrian 2433236880Sadrianint os::signal_wait() { 2434227364Sadrian return check_pending_signals(true); 2435227364Sadrian} 2436236872Sadrian 2437229949Sadrian//////////////////////////////////////////////////////////////////////////////// 2438236872Sadrian// Virtual Memory 2439229949Sadrian 2440229949Sadrianstatic int page_size = -1; 2441227364Sadrian 2442227364Sadrian// The mmap MAP_ALIGN flag is supported on Solaris 9 and later. init_2() will 2443236880Sadrian// clear this var if support is not available. 2444236880Sadrianstatic bool has_map_align = true; 2445236880Sadrian 2446236880Sadrianint os::vm_page_size() { 2447236880Sadrian assert(page_size != -1, "must call os::init"); 2448236880Sadrian return page_size; 2449236880Sadrian} 2450236880Sadrian 2451236880Sadrian// Solaris allocates memory by pages. 2452236880Sadrianint os::vm_allocation_granularity() { 2453236880Sadrian assert(page_size != -1, "must call os::init"); 2454236880Sadrian return page_size; 2455236880Sadrian} 2456236880Sadrian 2457227364Sadrianstatic bool recoverable_mmap_error(int err) { 2458227364Sadrian // See if the error is one we can let the caller handle. This 2459227364Sadrian // list of errno values comes from the Solaris mmap(2) man page. 2460227364Sadrian switch (err) { 2461227364Sadrian case EBADF: 2462227364Sadrian case EINVAL: 2463236872Sadrian case ENOTSUP: 2464229949Sadrian // let the caller deal with these errors 2465236872Sadrian return true; 2466229949Sadrian 2467229949Sadrian default: 2468227364Sadrian // Any remaining errors on this OS can cause our reserved mapping 2469227364Sadrian // to be lost. That can cause confusion where different data 2470227364Sadrian // structures think they have the same memory mapped. The worst 2471227364Sadrian // scenario is if both the VM and a library think they have the 2472227364Sadrian // same memory mapped. 2473227364Sadrian return false; 2474227364Sadrian } 2475227364Sadrian} 2476227364Sadrian 2477227364Sadrianstatic void warn_fail_commit_memory(char* addr, size_t bytes, bool exec, 2478227364Sadrian int err) { 2479227364Sadrian warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT 2480227364Sadrian ", %d) failed; error='%s' (errno=%d)", addr, bytes, exec, 2481227364Sadrian strerror(err), err); 2482227364Sadrian} 2483227364Sadrian 2484227364Sadrianstatic void warn_fail_commit_memory(char* addr, size_t bytes, 2485227364Sadrian size_t alignment_hint, bool exec, 2486227364Sadrian int err) { 2487227364Sadrian warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT 2488227364Sadrian ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", addr, bytes, 2489229949Sadrian alignment_hint, exec, strerror(err), err); 2490229949Sadrian} 2491227364Sadrian 2492227364Sadrianint os::Solaris::commit_memory_impl(char* addr, size_t bytes, bool exec) { 2493227364Sadrian int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE; 2494227364Sadrian size_t size = bytes; 2495227364Sadrian char *res = Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED, prot); 2496227364Sadrian if (res != NULL) { 2497227398Sadrian if (UseNUMAInterleaving) { 2498227398Sadrian numa_make_global(addr, bytes); 2499227398Sadrian } 2500227398Sadrian return 0; 2501227398Sadrian } 2502227398Sadrian 2503227398Sadrian int err = errno; // save errno from mmap() call in mmap_chunk() 2504227398Sadrian 2505227398Sadrian if (!recoverable_mmap_error(err)) { 2506227398Sadrian warn_fail_commit_memory(addr, bytes, exec, err); 2507227398Sadrian vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, "committing reserved memory."); 2508227398Sadrian } 2509227398Sadrian 2510227398Sadrian return err; 2511227398Sadrian} 2512227398Sadrian 2513243786Sadrianbool os::pd_commit_memory(char* addr, size_t bytes, bool exec) { 2514227398Sadrian return Solaris::commit_memory_impl(addr, bytes, exec) == 0; 2515227398Sadrian} 2516227398Sadrian 2517227398Sadrianvoid os::pd_commit_memory_or_exit(char* addr, size_t bytes, bool exec, 2518227398Sadrian const char* mesg) { 2519227398Sadrian assert(mesg != NULL, "mesg must be specified"); 2520227398Sadrian int err = os::Solaris::commit_memory_impl(addr, bytes, exec); 2521227398Sadrian if (err != 0) { 2522227398Sadrian // the caller wants all commit errors to exit with the specified mesg: 2523227398Sadrian warn_fail_commit_memory(addr, bytes, exec, err); 2524227398Sadrian vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, mesg); 2525227398Sadrian } 2526227398Sadrian} 2527227398Sadrian 2528227398Sadrianint os::Solaris::commit_memory_impl(char* addr, size_t bytes, 2529227398Sadrian size_t alignment_hint, bool exec) { 2530227398Sadrian int err = Solaris::commit_memory_impl(addr, bytes, exec); 2531227398Sadrian if (err == 0) { 2532227398Sadrian if (UseLargePages && (alignment_hint > (size_t)vm_page_size())) { 2533227398Sadrian // If the large page size has been set and the VM 2534227398Sadrian // is using large pages, use the large page size 2535227398Sadrian // if it is smaller than the alignment hint. This is 2536227398Sadrian // a case where the VM wants to use a larger alignment size 2537227398Sadrian // for its own reasons but still want to use large pages 2538227398Sadrian // (which is what matters to setting the mpss range. 2539227398Sadrian size_t page_size = 0; 2540227398Sadrian if (large_page_size() < alignment_hint) { 2541227398Sadrian assert(UseLargePages, "Expected to be here for large page use only"); 2542227398Sadrian page_size = large_page_size(); 2543227398Sadrian } else { 2544227398Sadrian // If the alignment hint is less than the large page 2545227398Sadrian // size, the VM wants a particular alignment (thus the hint) 2546227398Sadrian // for internal reasons. Try to set the mpss range using 2547227364Sadrian // the alignment_hint. 2548227364Sadrian page_size = alignment_hint; 2549227364Sadrian } 2550227364Sadrian // Since this is a hint, ignore any failures. 2551227364Sadrian (void)Solaris::setup_large_pages(addr, bytes, page_size); 2552227364Sadrian } 2553227364Sadrian } 2554227364Sadrian return err; 2555227364Sadrian} 2556227364Sadrian 2557227364Sadrianbool os::pd_commit_memory(char* addr, size_t bytes, size_t alignment_hint, 2558227364Sadrian bool exec) { 2559227364Sadrian return Solaris::commit_memory_impl(addr, bytes, alignment_hint, exec) == 0; 2560227364Sadrian} 2561243786Sadrian 2562227364Sadrianvoid os::pd_commit_memory_or_exit(char* addr, size_t bytes, 2563227364Sadrian size_t alignment_hint, bool exec, 2564227364Sadrian const char* mesg) { 2565227364Sadrian assert(mesg != NULL, "mesg must be specified"); 2566227364Sadrian int err = os::Solaris::commit_memory_impl(addr, bytes, alignment_hint, exec); 2567227364Sadrian if (err != 0) { 2568236872Sadrian // the caller wants all commit errors to exit with the specified mesg: 2569229949Sadrian warn_fail_commit_memory(addr, bytes, alignment_hint, exec, err); 2570236872Sadrian vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, mesg); 2571227364Sadrian } 2572227364Sadrian} 2573227364Sadrian 2574227364Sadrian// Uncommit the pages in a specified region. 2575227364Sadrianvoid os::pd_free_memory(char* addr, size_t bytes, size_t alignment_hint) { 2576227364Sadrian if (madvise(addr, bytes, MADV_FREE) < 0) { 2577227364Sadrian debug_only(warning("MADV_FREE failed.")); 2578227364Sadrian return; 2579227364Sadrian } 2580227364Sadrian} 2581227364Sadrian 2582227364Sadrianbool os::pd_create_stack_guard_pages(char* addr, size_t size) { 2583227364Sadrian return os::commit_memory(addr, size, !ExecMem); 2584227364Sadrian} 2585227364Sadrian 2586227364Sadrianbool os::remove_stack_guard_pages(char* addr, size_t size) { 2587227364Sadrian return os::uncommit_memory(addr, size); 2588227364Sadrian} 2589227364Sadrian 2590227364Sadrian// Change the page size in a given range. 2591227364Sadrianvoid os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) { 2592227364Sadrian assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned."); 2593227364Sadrian assert((intptr_t)(addr + bytes) % alignment_hint == 0, "End should be aligned."); 2594229949Sadrian if (UseLargePages) { 2595229949Sadrian Solaris::setup_large_pages(addr, bytes, alignment_hint); 2596227364Sadrian } 2597227364Sadrian} 2598227364Sadrian 2599229949Sadrian// Tell the OS to make the range local to the first-touching LWP 2600229949Sadrianvoid os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) { 2601227364Sadrian assert((intptr_t)addr % os::vm_page_size() == 0, "Address should be page-aligned."); 2602227364Sadrian if (madvise(addr, bytes, MADV_ACCESS_LWP) < 0) { 2603227364Sadrian debug_only(warning("MADV_ACCESS_LWP failed.")); 2604227364Sadrian } 2605227364Sadrian} 2606227364Sadrian 2607227364Sadrian// Tell the OS that this range would be accessed from different LWPs. 2608227364Sadrianvoid os::numa_make_global(char *addr, size_t bytes) { 2609227364Sadrian assert((intptr_t)addr % os::vm_page_size() == 0, "Address should be page-aligned."); 2610227364Sadrian if (madvise(addr, bytes, MADV_ACCESS_MANY) < 0) { 2611227364Sadrian debug_only(warning("MADV_ACCESS_MANY failed.")); 2612227364Sadrian } 2613227364Sadrian} 2614227364Sadrian 2615227364Sadrian// Get the number of the locality groups. 2616227364Sadriansize_t os::numa_get_groups_num() { 2617243786Sadrian size_t n = Solaris::lgrp_nlgrps(Solaris::lgrp_cookie()); 2618227364Sadrian return n != -1 ? n : 1; 2619227364Sadrian} 2620227364Sadrian 2621227364Sadrian// Get a list of leaf locality groups. A leaf lgroup is group that 2622227364Sadrian// doesn't have any children. Typical leaf group is a CPU or a CPU/memory 2623227364Sadrian// board. An LWP is assigned to one of these groups upon creation. 2624227364Sadriansize_t os::numa_get_leaf_groups(int *ids, size_t size) { 2625227364Sadrian if ((ids[0] = Solaris::lgrp_root(Solaris::lgrp_cookie())) == -1) { 2626227364Sadrian ids[0] = 0; 2627227364Sadrian return 1; 2628227364Sadrian } 2629227364Sadrian int result_size = 0, top = 1, bottom = 0, cur = 0; 2630227364Sadrian for (int k = 0; k < size; k++) { 2631227364Sadrian int r = Solaris::lgrp_children(Solaris::lgrp_cookie(), ids[cur], 2632227364Sadrian (Solaris::lgrp_id_t*)&ids[top], size - top); 2633227364Sadrian if (r == -1) { 2634227364Sadrian ids[0] = 0; 2635227364Sadrian return 1; 2636227364Sadrian } 2637227364Sadrian if (!r) { 2638227364Sadrian // That's a leaf node. 2639227364Sadrian assert(bottom <= cur, "Sanity check"); 2640227364Sadrian // Check if the node has memory 2641243786Sadrian if (Solaris::lgrp_resources(Solaris::lgrp_cookie(), ids[cur], 2642227364Sadrian NULL, 0, LGRP_RSRC_MEM) > 0) { 2643227364Sadrian ids[bottom++] = ids[cur]; 2644227364Sadrian } 2645227364Sadrian } 2646227364Sadrian top += r; 2647227364Sadrian cur++; 2648227364Sadrian } 2649227364Sadrian if (bottom == 0) { 2650227364Sadrian // Handle a situation, when the OS reports no memory available. 2651227364Sadrian // Assume UMA architecture. 2652227364Sadrian ids[0] = 0; 2653227364Sadrian return 1; 2654227364Sadrian } 2655236872Sadrian return bottom; 2656227364Sadrian} 2657227364Sadrian 2658227364Sadrian// Detect the topology change. Typically happens during CPU plugging-unplugging. 2659227364Sadrianbool os::numa_topology_changed() { 2660227364Sadrian int is_stale = Solaris::lgrp_cookie_stale(Solaris::lgrp_cookie()); 2661227364Sadrian if (is_stale != -1 && is_stale) { 2662227364Sadrian Solaris::lgrp_fini(Solaris::lgrp_cookie()); 2663227364Sadrian Solaris::lgrp_cookie_t c = Solaris::lgrp_init(Solaris::LGRP_VIEW_CALLER); 2664227364Sadrian assert(c != 0, "Failure to initialize LGRP API"); 2665227364Sadrian Solaris::set_lgrp_cookie(c); 2666227364Sadrian return true; 2667227364Sadrian } 2668236872Sadrian return false; 2669236872Sadrian} 2670227364Sadrian 2671227364Sadrian// Get the group id of the current LWP. 2672227364Sadrianint os::numa_get_group_id() { 2673227364Sadrian int lgrp_id = Solaris::lgrp_home(P_LWPID, P_MYID); 2674227364Sadrian if (lgrp_id == -1) { 2675227364Sadrian return 0; 2676227364Sadrian } 2677243786Sadrian const int size = os::numa_get_groups_num(); 2678236880Sadrian int *ids = (int*)alloca(size * sizeof(int)); 2679227364Sadrian 2680227364Sadrian // Get the ids of all lgroups with memory; r is the count. 2681227364Sadrian int r = Solaris::lgrp_resources(Solaris::lgrp_cookie(), lgrp_id, 2682227364Sadrian (Solaris::lgrp_id_t*)ids, size, LGRP_RSRC_MEM); 2683227364Sadrian if (r <= 0) { 2684227364Sadrian return 0; 2685227364Sadrian } 2686227364Sadrian return ids[os::random() % r]; 2687227364Sadrian} 2688227364Sadrian 2689227364Sadrian// Request information about the page. 2690236880Sadrianbool os::get_page_info(char *start, page_info* info) { 2691227364Sadrian const uint_t info_types[] = { MEMINFO_VLGRP, MEMINFO_VPAGESIZE }; 2692227364Sadrian uint64_t addr = (uintptr_t)start; 2693227364Sadrian uint64_t outdata[2]; 2694227364Sadrian uint_t validity = 0; 2695227364Sadrian 2696227364Sadrian if (os::Solaris::meminfo(&addr, 1, info_types, 2, outdata, &validity) < 0) { 2697227364Sadrian return false; 2698227364Sadrian } 2699227364Sadrian 2700227364Sadrian info->size = 0; 2701227364Sadrian info->lgrp_id = -1; 2702236872Sadrian 2703227364Sadrian if ((validity & 1) != 0) { 2704227364Sadrian if ((validity & 2) != 0) { 2705227364Sadrian info->lgrp_id = outdata[0]; 2706227364Sadrian } 2707227364Sadrian if ((validity & 4) != 0) { 2708227364Sadrian info->size = outdata[1]; 2709227364Sadrian } 2710227364Sadrian return true; 2711227364Sadrian } 2712239051Sadrian return false; 2713239051Sadrian} 2714227364Sadrian 2715227364Sadrian// Scan the pages from start to end until a page different than 2716227364Sadrian// the one described in the info parameter is encountered. 2717227364Sadrianchar *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) { 2718243786Sadrian const uint_t info_types[] = { MEMINFO_VLGRP, MEMINFO_VPAGESIZE }; 2719227364Sadrian const size_t types = sizeof(info_types) / sizeof(info_types[0]); 2720227364Sadrian uint64_t addrs[MAX_MEMINFO_CNT], outdata[types * MAX_MEMINFO_CNT + 1]; 2721227364Sadrian uint_t validity[MAX_MEMINFO_CNT]; 2722227364Sadrian 2723227364Sadrian size_t page_size = MAX2((size_t)os::vm_page_size(), page_expected->size); 2724241336Sadrian uint64_t p = (uint64_t)start; 2725233480Sadrian while (p < (uint64_t)end) { 2726227364Sadrian addrs[0] = p; 2727227364Sadrian size_t addrs_count = 1; 2728227364Sadrian while (addrs_count < MAX_MEMINFO_CNT && addrs[addrs_count - 1] + page_size < (uint64_t)end) { 2729227364Sadrian addrs[addrs_count] = addrs[addrs_count - 1] + page_size; 2730227364Sadrian addrs_count++; 2731227364Sadrian } 2732227364Sadrian 2733241336Sadrian if (os::Solaris::meminfo(addrs, addrs_count, info_types, types, outdata, validity) < 0) { 2734227364Sadrian return NULL; 2735227364Sadrian } 2736227364Sadrian 2737227364Sadrian size_t i = 0; 2738240180Sadrian for (; i < addrs_count; i++) { 2739240180Sadrian if ((validity[i] & 1) != 0) { 2740240180Sadrian if ((validity[i] & 4) != 0) { 2741240180Sadrian if (outdata[types * i + 1] != page_expected->size) { 2742240180Sadrian break; 2743240180Sadrian } 2744240180Sadrian } else 2745240180Sadrian if (page_expected->size != 0) { 2746240180Sadrian break; 2747240180Sadrian } 2748240180Sadrian 2749240180Sadrian if ((validity[i] & 2) != 0 && page_expected->lgrp_id > 0) { 2750240180Sadrian if (outdata[types * i] != page_expected->lgrp_id) { 2751240180Sadrian break; 2752240180Sadrian } 2753240180Sadrian } 2754240180Sadrian } else { 2755240180Sadrian return NULL; 2756240180Sadrian } 2757240724Sadrian } 2758240724Sadrian 2759240724Sadrian if (i < addrs_count) { 2760227364Sadrian if ((validity[i] & 2) != 0) { 2761227364Sadrian page_found->lgrp_id = outdata[types * i]; 2762233989Sadrian } else { 2763233989Sadrian page_found->lgrp_id = -1; 2764233989Sadrian } 2765227364Sadrian if ((validity[i] & 4) != 0) { 2766227364Sadrian page_found->size = outdata[types * i + 1]; 2767227364Sadrian } else { 2768227364Sadrian page_found->size = 0; 2769227364Sadrian } 2770227364Sadrian return (char*)addrs[i]; 2771227364Sadrian } 2772227364Sadrian 2773227364Sadrian p = addrs[addrs_count - 1] + page_size; 2774227364Sadrian } 2775227364Sadrian return end; 2776227364Sadrian} 2777227364Sadrian 2778227364Sadrianbool os::pd_uncommit_memory(char* addr, size_t bytes) { 2779227364Sadrian size_t size = bytes; 2780227364Sadrian // Map uncommitted pages PROT_NONE so we fail early if we touch an 2781227364Sadrian // uncommitted page. Otherwise, the read/write might succeed if we 2782227364Sadrian // have enough swap space to back the physical page. 2783227364Sadrian return 2784227364Sadrian NULL != Solaris::mmap_chunk(addr, size, 2785227364Sadrian MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE, 2786227364Sadrian PROT_NONE); 2787227364Sadrian} 2788227364Sadrian 2789227364Sadrianchar* os::Solaris::mmap_chunk(char *addr, size_t size, int flags, int prot) { 2790227364Sadrian char *b = (char *)mmap(addr, size, prot, flags, os::Solaris::_dev_zero_fd, 0); 2791227364Sadrian 2792227364Sadrian if (b == MAP_FAILED) { 2793227364Sadrian return NULL; 2794227364Sadrian } 2795227364Sadrian return b; 2796227364Sadrian} 2797227364Sadrian 2798227364Sadrianchar* os::Solaris::anon_mmap(char* requested_addr, size_t bytes, size_t alignment_hint, bool fixed) { 2799227364Sadrian char* addr = requested_addr; 2800227364Sadrian int flags = MAP_PRIVATE | MAP_NORESERVE; 2801227364Sadrian 2802227364Sadrian assert(!(fixed && (alignment_hint > 0)), "alignment hint meaningless with fixed mmap"); 2803243786Sadrian 2804236880Sadrian if (fixed) { 2805227364Sadrian flags |= MAP_FIXED; 2806227364Sadrian } else if (has_map_align && (alignment_hint > (size_t) vm_page_size())) { 2807227364Sadrian flags |= MAP_ALIGN; 2808227364Sadrian addr = (char*) alignment_hint; 2809227364Sadrian } 2810227364Sadrian 2811236872Sadrian // Map uncommitted pages PROT_NONE so we fail early if we touch an 2812236872Sadrian // uncommitted page. Otherwise, the read/write might succeed if we 2813227364Sadrian // have enough swap space to back the physical page. 2814227364Sadrian return mmap_chunk(addr, bytes, flags, PROT_NONE); 2815239051Sadrian} 2816227364Sadrian 2817244109Sadrianchar* os::pd_reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) { 2818227364Sadrian char* addr = Solaris::anon_mmap(requested_addr, bytes, alignment_hint, (requested_addr != NULL)); 2819227364Sadrian 2820227364Sadrian guarantee(requested_addr == NULL || requested_addr == addr, 2821227364Sadrian "OS failed to return requested mmap address."); 2822227364Sadrian return addr; 2823227364Sadrian} 2824227364Sadrian 2825227364Sadrian// Reserve memory at an arbitrary address, only if that area is 2826227364Sadrian// available (and not reserved for something else). 2827227364Sadrian 2828236872Sadrianchar* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) { 2829241336Sadrian const int max_tries = 10; 2830227364Sadrian char* base[max_tries]; 2831227364Sadrian size_t size[max_tries]; 2832236872Sadrian 2833241336Sadrian // Solaris adds a gap between mmap'ed regions. The size of the gap 2834227364Sadrian // is dependent on the requested size and the MMU. Our initial gap 2835227364Sadrian // value here is just a guess and will be corrected later. 2836227364Sadrian bool had_top_overlap = false; 2837236877Sadrian bool have_adjusted_gap = false; 2838236877Sadrian size_t gap = 0x400000; 2839236877Sadrian 2840236877Sadrian // Assert only that the size is a multiple of the page size, since 2841241336Sadrian // that's all that mmap requires, and since that's all we really know 2842236877Sadrian // about at this low abstraction level. If we need higher alignment, 2843236877Sadrian // we can either pass an alignment to this method or verify alignment 2844236877Sadrian // in one of the methods further up the call chain. See bug 5044738. 2845236877Sadrian assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block"); 2846236877Sadrian 2847236877Sadrian // Since snv_84, Solaris attempts to honor the address hint - see 5003415. 2848236877Sadrian // Give it a try, if the kernel honors the hint we can return immediately. 2849236877Sadrian char* addr = Solaris::anon_mmap(requested_addr, bytes, 0, false); 2850248750Sadrian 2851241336Sadrian volatile int err = errno; 2852241336Sadrian if (addr == requested_addr) { 2853240180Sadrian return addr; 2854240180Sadrian } else if (addr != NULL) { 2855240180Sadrian pd_unmap_memory(addr, bytes); 2856240180Sadrian } 2857240180Sadrian 2858240180Sadrian if (PrintMiscellaneous && Verbose) { 2859240180Sadrian char buf[256]; 2860240180Sadrian buf[0] = '\0'; 2861240180Sadrian if (addr == NULL) { 2862240180Sadrian jio_snprintf(buf, sizeof(buf), ": %s", strerror(err)); 2863239051Sadrian } 2864233227Sadrian warning("attempt_reserve_memory_at: couldn't reserve " SIZE_FORMAT " bytes at " 2865236872Sadrian PTR_FORMAT ": reserve_memory_helper returned " PTR_FORMAT 2866236872Sadrian "%s", bytes, requested_addr, addr, buf); 2867229949Sadrian } 2868229949Sadrian 2869236872Sadrian // Address hint method didn't work. Fall back to the old method. 2870236872Sadrian // In theory, once SNV becomes our oldest supported platform, this 2871240899Sadrian // code will no longer be needed. 2872227364Sadrian // 2873227364Sadrian // Repeatedly allocate blocks until the block is allocated at the 2874248750Sadrian // right spot. Give up after max_tries. 2875227364Sadrian int i; 2876236872Sadrian for (i = 0; i < max_tries; ++i) { 2877240926Sadrian base[i] = reserve_memory(bytes); 2878240926Sadrian 2879227364Sadrian if (base[i] != NULL) { 2880227364Sadrian // Is this the block we wanted? 2881227364Sadrian if (base[i] == requested_addr) { 2882236872Sadrian size[i] = bytes; 2883241336Sadrian break; 2884227364Sadrian } 2885227364Sadrian 2886227364Sadrian // check that the gap value is right 2887227364Sadrian if (had_top_overlap && !have_adjusted_gap) { 2888227364Sadrian size_t actual_gap = base[i-1] - base[i] - bytes; 2889245708Sadrian if (gap != actual_gap) { 2890245708Sadrian // adjust the gap value and retry the last 2 allocations 2891245708Sadrian assert(i > 0, "gap adjustment code problem"); 2892245708Sadrian have_adjusted_gap = true; // adjust the gap only once, just in case 2893245708Sadrian gap = actual_gap; 2894245708Sadrian if (PrintMiscellaneous && Verbose) { 2895245708Sadrian warning("attempt_reserve_memory_at: adjusted gap to 0x%lx", gap); 2896245708Sadrian } 2897245708Sadrian unmap_memory(base[i], bytes); 2898245708Sadrian unmap_memory(base[i-1], size[i-1]); 2899245708Sadrian i-=2; 2900245708Sadrian continue; 2901245708Sadrian } 2902245708Sadrian } 2903245708Sadrian 2904245708Sadrian // Does this overlap the block we wanted? Give back the overlapped 2905245708Sadrian // parts and try again. 2906245739Sadrian // 2907245708Sadrian // There is still a bug in this code: if top_overlap == bytes, 2908245708Sadrian // the overlap is offset from requested region by the value of gap. 2909245708Sadrian // In this case giving back the overlapped part will not work, 2910245708Sadrian // because we'll give back the entire block at base[i] and 2911245708Sadrian // therefore the subsequent allocation will not generate a new gap. 2912227364Sadrian // This could be fixed with a new algorithm that used larger 2913227364Sadrian // or variable size chunks to find the requested region - 2914227364Sadrian // but such a change would introduce additional complications. 2915227364Sadrian // It's rare enough that the planets align for this bug, 2916227364Sadrian // so we'll just wait for a fix for 6204603/5003415 which 2917227364Sadrian // will provide a mmap flag to allow us to avoid this business. 2918227364Sadrian 2919227364Sadrian size_t top_overlap = requested_addr + (bytes + gap) - base[i]; 2920227364Sadrian if (top_overlap >= 0 && top_overlap < bytes) { 2921227364Sadrian had_top_overlap = true; 2922227364Sadrian unmap_memory(base[i], top_overlap); 2923227364Sadrian base[i] += top_overlap; 2924227364Sadrian size[i] = bytes - top_overlap; 2925227364Sadrian } else { 2926227364Sadrian size_t bottom_overlap = base[i] + bytes - requested_addr; 2927240639Sadrian if (bottom_overlap >= 0 && bottom_overlap < bytes) { 2928240639Sadrian if (PrintMiscellaneous && Verbose && bottom_overlap == 0) { 2929240639Sadrian warning("attempt_reserve_memory_at: possible alignment bug"); 2930240639Sadrian } 2931241336Sadrian unmap_memory(requested_addr, bottom_overlap); 2932241336Sadrian size[i] = bytes - bottom_overlap; 2933227364Sadrian } else { 2934227364Sadrian size[i] = bytes; 2935227364Sadrian } 2936227364Sadrian } 2937227364Sadrian } 2938227364Sadrian } 2939227364Sadrian 2940227364Sadrian // Give back the unused reserved pieces. 2941227364Sadrian 2942227364Sadrian for (int j = 0; j < i; ++j) { 2943240946Sadrian if (base[j] != NULL) { 2944227364Sadrian unmap_memory(base[j], size[j]); 2945227364Sadrian } 2946227364Sadrian } 2947245708Sadrian 2948227364Sadrian return (i < max_tries) ? requested_addr : NULL; 2949227364Sadrian} 2950227364Sadrian 2951227364Sadrianbool os::pd_release_memory(char* addr, size_t bytes) { 2952227364Sadrian size_t size = bytes; 2953227364Sadrian return munmap(addr, size) == 0; 2954227364Sadrian} 2955227364Sadrian 2956227364Sadrianstatic bool solaris_mprotect(char* addr, size_t bytes, int prot) { 2957227364Sadrian assert(addr == (char*)align_size_down((uintptr_t)addr, os::vm_page_size()), 2958227364Sadrian "addr must be page aligned"); 2959227364Sadrian int retVal = mprotect(addr, bytes, prot); 2960233908Sadrian return retVal == 0; 2961243786Sadrian} 2962227364Sadrian 2963227364Sadrian// Protect memory (Used to pass readonly pages through 2964227364Sadrian// JNI GetArray<type>Elements with empty arrays.) 2965227364Sadrian// Also, used for serialization page and for compressed oops null pointer 2966227364Sadrian// checking. 2967227364Sadrianbool os::protect_memory(char* addr, size_t bytes, ProtType prot, 2968227364Sadrian bool is_committed) { 2969227364Sadrian unsigned int p = 0; 2970227364Sadrian switch (prot) { 2971227364Sadrian case MEM_PROT_NONE: p = PROT_NONE; break; 2972227364Sadrian case MEM_PROT_READ: p = PROT_READ; break; 2973243786Sadrian case MEM_PROT_RW: p = PROT_READ|PROT_WRITE; break; 2974243786Sadrian case MEM_PROT_RWX: p = PROT_READ|PROT_WRITE|PROT_EXEC; break; 2975227364Sadrian default: 2976227364Sadrian ShouldNotReachHere(); 2977227364Sadrian } 2978227364Sadrian // is_committed is unused. 2979227364Sadrian return solaris_mprotect(addr, bytes, p); 2980241170Sadrian} 2981227364Sadrian 2982227364Sadrian// guard_memory and unguard_memory only happens within stack guard pages. 2983241170Sadrian// Since ISM pertains only to the heap, guard and unguard memory should not 2984241170Sadrian/// happen with an ISM region. 2985241170Sadrianbool os::guard_memory(char* addr, size_t bytes) { 2986241170Sadrian return solaris_mprotect(addr, bytes, PROT_NONE); 2987245708Sadrian} 2988241170Sadrian 2989241170Sadrianbool os::unguard_memory(char* addr, size_t bytes) { 2990241170Sadrian return solaris_mprotect(addr, bytes, PROT_READ|PROT_WRITE); 2991241170Sadrian} 2992240639Sadrian 2993240639Sadrian// Large page support 2994240639Sadrianstatic size_t _large_page_size = 0; 2995240639Sadrian 2996240639Sadrian// Insertion sort for small arrays (descending order). 2997240639Sadrianstatic void insertion_sort_descending(size_t* array, int len) { 2998227364Sadrian for (int i = 0; i < len; i++) { 2999246450Sadrian size_t val = array[i]; 3000246450Sadrian for (size_t key = i; key > 0 && array[key - 1] < val; --key) { 3001246450Sadrian size_t tmp = array[key]; 3002246450Sadrian array[key] = array[key - 1]; 3003246450Sadrian array[key - 1] = tmp; 3004227364Sadrian } 3005227364Sadrian } 3006227364Sadrian} 3007240639Sadrian 3008240639Sadrianbool os::Solaris::mpss_sanity_check(bool warn, size_t* page_size) { 3009240639Sadrian const unsigned int usable_count = VM_Version::page_size_count(); 3010240639Sadrian if (usable_count == 1) { 3011240639Sadrian return false; 3012240639Sadrian } 3013240639Sadrian 3014240639Sadrian // Find the right getpagesizes interface. When solaris 11 is the minimum 3015243786Sadrian // build platform, getpagesizes() (without the '2') can be called directly. 3016243786Sadrian typedef int (*gps_t)(size_t[], int); 3017240639Sadrian gps_t gps_func = CAST_TO_FN_PTR(gps_t, dlsym(RTLD_DEFAULT, "getpagesizes2")); 3018240639Sadrian if (gps_func == NULL) { 3019240639Sadrian gps_func = CAST_TO_FN_PTR(gps_t, dlsym(RTLD_DEFAULT, "getpagesizes")); 3020240639Sadrian if (gps_func == NULL) { 3021240639Sadrian if (warn) { 3022240639Sadrian warning("MPSS is not supported by the operating system."); 3023240639Sadrian } 3024240639Sadrian return false; 3025240639Sadrian } 3026241566Sadrian } 3027240639Sadrian 3028240639Sadrian // Fill the array of page sizes. 3029240639Sadrian int n = (*gps_func)(_page_sizes, page_sizes_max); 3030240639Sadrian assert(n > 0, "Solaris bug?"); 3031240639Sadrian 3032240639Sadrian if (n == page_sizes_max) { 3033240639Sadrian // Add a sentinel value (necessary only if the array was completely filled 3034240639Sadrian // since it is static (zeroed at initialization)). 3035240639Sadrian _page_sizes[--n] = 0; 3036240639Sadrian DEBUG_ONLY(warning("increase the size of the os::_page_sizes array.");) 3037240639Sadrian } 3038240639Sadrian assert(_page_sizes[n] == 0, "missing sentinel"); 3039243786Sadrian trace_page_sizes("available page sizes", _page_sizes, n); 3040240639Sadrian 3041240639Sadrian if (n == 1) return false; // Only one page size available. 3042240639Sadrian 3043240639Sadrian // Skip sizes larger than 4M (or LargePageSizeInBytes if it was set) and 3044240639Sadrian // select up to usable_count elements. First sort the array, find the first 3045240639Sadrian // acceptable value, then copy the usable sizes to the top of the array and 3046240639Sadrian // trim the rest. Make sure to include the default page size :-). 3047240639Sadrian // 3048240639Sadrian // A better policy could get rid of the 4M limit by taking the sizes of the 3049240639Sadrian // important VM memory regions (java heap and possibly the code cache) into 3050240639Sadrian // account. 3051240639Sadrian insertion_sort_descending(_page_sizes, n); 3052240639Sadrian const size_t size_limit = 3053240639Sadrian FLAG_IS_DEFAULT(LargePageSizeInBytes) ? 4 * M : LargePageSizeInBytes; 3054240639Sadrian int beg; 3055240639Sadrian for (beg = 0; beg < n && _page_sizes[beg] > size_limit; ++beg) /* empty */; 3056240639Sadrian const int end = MIN2((int)usable_count, n) - 1; 3057240639Sadrian for (int cur = 0; cur < end; ++cur, ++beg) { 3058240639Sadrian _page_sizes[cur] = _page_sizes[beg]; 3059240639Sadrian } 3060240639Sadrian _page_sizes[end] = vm_page_size(); 3061240639Sadrian _page_sizes[end + 1] = 0; 3062240639Sadrian 3063240639Sadrian if (_page_sizes[end] > _page_sizes[end - 1]) { 3064243786Sadrian // Default page size is not the smallest; sort again. 3065240639Sadrian insertion_sort_descending(_page_sizes, end + 1); 3066240639Sadrian } 3067240639Sadrian *page_size = _page_sizes[0]; 3068240639Sadrian 3069240639Sadrian trace_page_sizes("usable page sizes", _page_sizes, end + 1); 3070240639Sadrian return true; 3071240639Sadrian} 3072245708Sadrian 3073245708Sadrianvoid os::large_page_init() { 3074240639Sadrian if (UseLargePages) { 3075240639Sadrian // print a warning if any large page related flag is specified on command line 3076241566Sadrian bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages) || 3077241566Sadrian !FLAG_IS_DEFAULT(LargePageSizeInBytes); 3078241336Sadrian 3079240639Sadrian UseLargePages = Solaris::mpss_sanity_check(warn_on_failure, &_large_page_size); 3080240639Sadrian } 3081240639Sadrian} 3082240639Sadrian 3083240639Sadrianbool os::Solaris::setup_large_pages(caddr_t start, size_t bytes, size_t align) { 3084240639Sadrian // Signal to OS that we want large pages for addresses 3085240639Sadrian // from addr, addr + bytes 3086240639Sadrian struct memcntl_mha mpss_struct; 3087240639Sadrian mpss_struct.mha_cmd = MHA_MAPSIZE_VA; 3088240639Sadrian mpss_struct.mha_pagesize = align; 3089240639Sadrian mpss_struct.mha_flags = 0; 3090240639Sadrian // Upon successful completion, memcntl() returns 0 3091240639Sadrian if (memcntl(start, bytes, MC_HAT_ADVISE, (caddr_t) &mpss_struct, 0, 0)) { 3092240639Sadrian debug_only(warning("Attempt to use MPSS failed.")); 3093240639Sadrian return false; 3094240639Sadrian } 3095240639Sadrian return true; 3096240639Sadrian} 3097240639Sadrian 3098240639Sadrianchar* os::reserve_memory_special(size_t size, size_t alignment, char* addr, bool exec) { 3099243786Sadrian fatal("os::reserve_memory_special should not be called on Solaris."); 3100240639Sadrian return NULL; 3101240639Sadrian} 3102240639Sadrian 3103240639Sadrianbool os::release_memory_special(char* base, size_t bytes) { 3104240639Sadrian fatal("os::release_memory_special should not be called on Solaris."); 3105241170Sadrian return false; 3106240639Sadrian} 3107240639Sadrian 3108240639Sadriansize_t os::large_page_size() { 3109240639Sadrian return _large_page_size; 3110240639Sadrian} 3111240639Sadrian 3112240639Sadrian// MPSS allows application to commit large page memory on demand; with ISM 3113240639Sadrian// the entire memory region must be allocated as shared memory. 3114240639Sadrianbool os::can_commit_large_page_memory() { 3115240639Sadrian return true; 3116240639Sadrian} 3117240639Sadrian 3118240639Sadrianbool os::can_execute_large_page_memory() { 3119240639Sadrian return true; 3120240639Sadrian} 3121240639Sadrian 3122240639Sadrian// Read calls from inside the vm need to perform state transitions 3123240639Sadriansize_t os::read(int fd, void *buf, unsigned int nBytes) { 3124240639Sadrian size_t res; 3125240639Sadrian JavaThread* thread = (JavaThread*)Thread::current(); 3126240639Sadrian assert(thread->thread_state() == _thread_in_vm, "Assumed _thread_in_vm"); 3127240639Sadrian ThreadBlockInVM tbiv(thread); 3128240639Sadrian RESTARTABLE(::read(fd, buf, (size_t) nBytes), res); 3129240639Sadrian return res; 3130240639Sadrian} 3131240639Sadrian 3132240639Sadriansize_t os::restartable_read(int fd, void *buf, unsigned int nBytes) { 3133240639Sadrian size_t res; 3134240639Sadrian assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, 3135240639Sadrian "Assumed _thread_in_native"); 3136240639Sadrian RESTARTABLE(::read(fd, buf, (size_t) nBytes), res); 3137240639Sadrian return res; 3138240639Sadrian} 3139240639Sadrian 3140240639Sadrianvoid os::naked_short_sleep(jlong ms) { 3141240639Sadrian assert(ms < 1000, "Un-interruptable sleep, short time use only"); 3142240639Sadrian 3143240639Sadrian // usleep is deprecated and removed from POSIX, in favour of nanosleep, but 3144240639Sadrian // Solaris requires -lrt for this. 3145240639Sadrian usleep((ms * 1000)); 3146240639Sadrian 3147243786Sadrian return; 3148240639Sadrian} 3149240639Sadrian 3150240639Sadrian// Sleep forever; naked call to OS-specific sleep; use with CAUTION 3151240639Sadrianvoid os::infinite_sleep() { 3152240639Sadrian while (true) { // sleep forever ... 3153240639Sadrian ::sleep(100); // ... 100 seconds at a time 3154240639Sadrian } 3155240639Sadrian} 3156240639Sadrian 3157240639Sadrian// Used to convert frequent JVM_Yield() to nops 3158247029Sadrianbool os::dont_yield() { 3159240639Sadrian if (DontYieldALot) { 3160240639Sadrian static hrtime_t last_time = 0; 3161240639Sadrian hrtime_t diff = getTimeNanos() - last_time; 3162240639Sadrian 3163240639Sadrian if (diff < DontYieldALotInterval * 1000000) 3164240639Sadrian return true; 3165240639Sadrian 3166240639Sadrian last_time += diff; 3167240639Sadrian 3168240639Sadrian return false; 3169240639Sadrian } 3170240639Sadrian else { 3171240639Sadrian return false; 3172240639Sadrian } 3173240639Sadrian} 3174240639Sadrian 3175240639Sadrian// Caveat: Solaris os::yield() causes a thread-state transition whereas 3176240639Sadrian// the linux and win32 implementations do not. This should be checked. 3177240639Sadrian 3178240639Sadrianvoid os::yield() { 3179240639Sadrian // Yields to all threads with same or greater priority 3180240639Sadrian os::sleep(Thread::current(), 0, false); 3181240639Sadrian} 3182240639Sadrian 3183240639Sadrian// Note that yield semantics are defined by the scheduling class to which 3184240639Sadrian// the thread currently belongs. Typically, yield will _not yield to 3185240639Sadrian// other equal or higher priority threads that reside on the dispatch queues 3186240639Sadrian// of other CPUs. 3187240639Sadrian 3188240639Sadrianos::YieldResult os::NakedYield() { thr_yield(); return os::YIELD_UNKNOWN; } 3189240639Sadrian 3190240639Sadrian// Interface for setting lwp priorities. If we are using T2 libthread, 3191240639Sadrian// which forces the use of BoundThreads or we manually set UseBoundThreads, 3192240639Sadrian// all of our threads will be assigned to real lwp's. Using the thr_setprio 3193240639Sadrian// function is meaningless in this mode so we must adjust the real lwp's priority 3194240639Sadrian// The routines below implement the getting and setting of lwp priorities. 3195240639Sadrian// 3196240639Sadrian// Note: T2 is now the only supported libthread. UseBoundThreads flag is 3197233908Sadrian// being deprecated and all threads are now BoundThreads 3198233908Sadrian// 3199233908Sadrian// Note: There are three priority scales used on Solaris. Java priotities 3200233908Sadrian// which range from 1 to 10, libthread "thr_setprio" scale which range 3201233908Sadrian// from 0 to 127, and the current scheduling class of the process we 3202233908Sadrian// are running in. This is typically from -60 to +60. 3203243786Sadrian// The setting of the lwp priorities in done after a call to thr_setprio 3204243786Sadrian// so Java priorities are mapped to libthread priorities and we map from 3205235491Sadrian// the latter to lwp priorities. We don't keep priorities stored in 3206235676Sadrian// Java priorities since some of our worker threads want to set priorities 3207233908Sadrian// higher than all Java threads. 3208235676Sadrian// 3209235676Sadrian// For related information: 3210235676Sadrian// (1) man -s 2 priocntl 3211233908Sadrian// (2) man -s 4 priocntl 3212233908Sadrian// (3) man dispadmin 3213233908Sadrian// = librt.so 3214233908Sadrian// = libthread/common/rtsched.c - thrp_setlwpprio(). 3215233908Sadrian// = ps -cL <pid> ... to validate priority. 3216233908Sadrian// = sched_get_priority_min and _max 3217233908Sadrian// pthread_create 3218233908Sadrian// sched_setparam 3219233908Sadrian// pthread_setschedparam 3220233908Sadrian// 3221233908Sadrian// Assumptions: 3222233908Sadrian// + We assume that all threads in the process belong to the same 3223233908Sadrian// scheduling class. IE. an homogenous process. 3224233908Sadrian// + Must be root or in IA group to change change "interactive" attribute. 3225233908Sadrian// Priocntl() will fail silently. The only indication of failure is when 3226233908Sadrian// we read-back the value and notice that it hasn't changed. 3227233908Sadrian// + Interactive threads enter the runq at the head, non-interactive at the tail. 3228233908Sadrian// + For RT, change timeslice as well. Invariant: 3229233908Sadrian// constant "priority integral" 3230233908Sadrian// Konst == TimeSlice * (60-Priority) 3231233908Sadrian// Given a priority, compute appropriate timeslice. 3232233908Sadrian// + Higher numerical values have higher priority. 3233233908Sadrian 3234233908Sadrian// sched class attributes 3235233908Sadriantypedef struct { 3236233908Sadrian int schedPolicy; // classID 3237243786Sadrian int maxPrio; 3238243786Sadrian int minPrio; 3239235491Sadrian} SchedInfo; 3240233908Sadrian 3241233908Sadrian 3242233908Sadrianstatic SchedInfo tsLimits, iaLimits, rtLimits, fxLimits; 3243233908Sadrian 3244233908Sadrian#ifdef ASSERT 3245233908Sadrianstatic int ReadBackValidate = 1; 3246233908Sadrian#endif 3247233908Sadrianstatic int myClass = 0; 3248233908Sadrianstatic int myMin = 0; 3249233908Sadrianstatic int myMax = 0; 3250233908Sadrianstatic int myCur = 0; 3251233908Sadrianstatic bool priocntl_enable = false; 3252233908Sadrian 3253233908Sadrianstatic const int criticalPrio = 60; // FX/60 is critical thread class/priority on T4 3254233908Sadrianstatic int java_MaxPriority_to_os_priority = 0; // Saved mapping 3255233908Sadrian 3256233908Sadrian 3257233908Sadrian// lwp_priocntl_init 3258233908Sadrian// 3259233908Sadrian// Try to determine the priority scale for our process. 3260233908Sadrian// 3261233908Sadrian// Return errno or 0 if OK. 3262243786Sadrian// 3263233908Sadrianstatic int lwp_priocntl_init() { 3264233908Sadrian int rslt; 3265233908Sadrian pcinfo_t ClassInfo; 3266233908Sadrian pcparms_t ParmInfo; 3267235491Sadrian int i; 3268235491Sadrian 3269235491Sadrian if (!UseThreadPriorities) return 0; 3270233908Sadrian 3271233908Sadrian // If ThreadPriorityPolicy is 1, switch tables 3272233908Sadrian if (ThreadPriorityPolicy == 1) { 3273233908Sadrian for (i = 0; i < CriticalPriority+1; i++) 3274233908Sadrian os::java_to_os_priority[i] = prio_policy1[i]; 3275233908Sadrian } 3276233908Sadrian if (UseCriticalJavaThreadPriority) { 3277233908Sadrian // MaxPriority always maps to the FX scheduling class and criticalPrio. 3278233908Sadrian // See set_native_priority() and set_lwp_class_and_priority(). 3279233908Sadrian // Save original MaxPriority mapping in case attempt to 3280233908Sadrian // use critical priority fails. 3281233908Sadrian java_MaxPriority_to_os_priority = os::java_to_os_priority[MaxPriority]; 3282233908Sadrian // Set negative to distinguish from other priorities 3283233908Sadrian os::java_to_os_priority[MaxPriority] = -criticalPrio; 3284233908Sadrian } 3285233908Sadrian 3286233908Sadrian // Get IDs for a set of well-known scheduling classes. 3287233908Sadrian // TODO-FIXME: GETCLINFO returns the current # of classes in the 3288233908Sadrian // the system. We should have a loop that iterates over the 3289233908Sadrian // classID values, which are known to be "small" integers. 3290243786Sadrian 3291233908Sadrian strcpy(ClassInfo.pc_clname, "TS"); 3292235491Sadrian ClassInfo.pc_cid = -1; 3293233908Sadrian rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); 3294233908Sadrian if (rslt < 0) return errno; 3295233908Sadrian assert(ClassInfo.pc_cid != -1, "cid for TS class is -1"); 3296233908Sadrian tsLimits.schedPolicy = ClassInfo.pc_cid; 3297233908Sadrian tsLimits.maxPrio = ((tsinfo_t*)ClassInfo.pc_clinfo)->ts_maxupri; 3298233908Sadrian tsLimits.minPrio = -tsLimits.maxPrio; 3299233908Sadrian 3300233908Sadrian strcpy(ClassInfo.pc_clname, "IA"); 3301233908Sadrian ClassInfo.pc_cid = -1; 3302233908Sadrian rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); 3303233908Sadrian if (rslt < 0) return errno; 3304233908Sadrian assert(ClassInfo.pc_cid != -1, "cid for IA class is -1"); 3305233908Sadrian iaLimits.schedPolicy = ClassInfo.pc_cid; 3306233908Sadrian iaLimits.maxPrio = ((iainfo_t*)ClassInfo.pc_clinfo)->ia_maxupri; 3307233908Sadrian iaLimits.minPrio = -iaLimits.maxPrio; 3308233908Sadrian 3309233908Sadrian strcpy(ClassInfo.pc_clname, "RT"); 3310233908Sadrian ClassInfo.pc_cid = -1; 3311233908Sadrian rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); 3312233908Sadrian if (rslt < 0) return errno; 3313233908Sadrian assert(ClassInfo.pc_cid != -1, "cid for RT class is -1"); 3314235491Sadrian rtLimits.schedPolicy = ClassInfo.pc_cid; 3315233908Sadrian rtLimits.maxPrio = ((rtinfo_t*)ClassInfo.pc_clinfo)->rt_maxpri; 3316233908Sadrian rtLimits.minPrio = 0; 3317233908Sadrian 3318233908Sadrian strcpy(ClassInfo.pc_clname, "FX"); 3319233908Sadrian ClassInfo.pc_cid = -1; 3320233908Sadrian rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo); 3321233908Sadrian if (rslt < 0) return errno; 3322233908Sadrian assert(ClassInfo.pc_cid != -1, "cid for FX class is -1"); 3323233908Sadrian fxLimits.schedPolicy = ClassInfo.pc_cid; 3324233908Sadrian fxLimits.maxPrio = ((fxinfo_t*)ClassInfo.pc_clinfo)->fx_maxupri; 3325233908Sadrian fxLimits.minPrio = 0; 3326240724Sadrian 3327240724Sadrian // Query our "current" scheduling class. 3328240724Sadrian // This will normally be IA, TS or, rarely, FX or RT. 3329245708Sadrian memset(&ParmInfo, 0, sizeof(ParmInfo)); 3330240724Sadrian ParmInfo.pc_cid = PC_CLNULL; 3331240724Sadrian rslt = priocntl(P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo); 3332233908Sadrian if (rslt < 0) return errno; 3333233908Sadrian myClass = ParmInfo.pc_cid; 3334233908Sadrian 3335233908Sadrian // We now know our scheduling classId, get specific information 3336233908Sadrian // about the class. 3337235491Sadrian ClassInfo.pc_cid = myClass; 3338233908Sadrian ClassInfo.pc_clname[0] = 0; 3339233908Sadrian rslt = priocntl((idtype)0, 0, PC_GETCLINFO, (caddr_t)&ClassInfo); 3340233908Sadrian if (rslt < 0) return errno; 3341233908Sadrian 3342233908Sadrian if (ThreadPriorityVerbose) { 3343233908Sadrian tty->print_cr("lwp_priocntl_init: Class=%d(%s)...", myClass, ClassInfo.pc_clname); 3344233908Sadrian } 3345233908Sadrian 3346243786Sadrian memset(&ParmInfo, 0, sizeof(pcparms_t)); 3347233908Sadrian ParmInfo.pc_cid = PC_CLNULL; 3348233908Sadrian rslt = priocntl(P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo); 3349243786Sadrian if (rslt < 0) return errno; 3350233908Sadrian 3351233908Sadrian if (ParmInfo.pc_cid == rtLimits.schedPolicy) { 3352233908Sadrian myMin = rtLimits.minPrio; 3353233908Sadrian myMax = rtLimits.maxPrio; 3354243786Sadrian } else if (ParmInfo.pc_cid == iaLimits.schedPolicy) { 3355233908Sadrian iaparms_t *iaInfo = (iaparms_t*)ParmInfo.pc_clparms; 3356233908Sadrian myMin = iaLimits.minPrio; 3357233908Sadrian myMax = iaLimits.maxPrio; 3358233908Sadrian myMax = MIN2(myMax, (int)iaInfo->ia_uprilim); // clamp - restrict 3359233908Sadrian } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) { 3360240639Sadrian tsparms_t *tsInfo = (tsparms_t*)ParmInfo.pc_clparms; 3361240639Sadrian myMin = tsLimits.minPrio; 3362240639Sadrian myMax = tsLimits.maxPrio; 3363240639Sadrian myMax = MIN2(myMax, (int)tsInfo->ts_uprilim); // clamp - restrict 3364233908Sadrian } else if (ParmInfo.pc_cid == fxLimits.schedPolicy) { 3365243786Sadrian fxparms_t *fxInfo = (fxparms_t*)ParmInfo.pc_clparms; 3366240639Sadrian myMin = fxLimits.minPrio; 3367240639Sadrian myMax = fxLimits.maxPrio; 3368240639Sadrian myMax = MIN2(myMax, (int)fxInfo->fx_uprilim); // clamp - restrict 3369240639Sadrian } else { 3370240639Sadrian // No clue - punt 3371240639Sadrian if (ThreadPriorityVerbose) 3372240639Sadrian tty->print_cr("Unknown scheduling class: %s ... \n", ClassInfo.pc_clname); 3373240639Sadrian return EINVAL; // no clue, punt 3374240639Sadrian } 3375240639Sadrian 3376240639Sadrian if (ThreadPriorityVerbose) { 3377240639Sadrian tty->print_cr("Thread priority Range: [%d..%d]\n", myMin, myMax); 3378240639Sadrian } 3379240639Sadrian 3380240639Sadrian priocntl_enable = true; // Enable changing priorities 3381240639Sadrian return 0; 3382247135Sadrian} 3383240639Sadrian 3384240639Sadrian#define IAPRI(x) ((iaparms_t *)((x).pc_clparms)) 3385240639Sadrian#define RTPRI(x) ((rtparms_t *)((x).pc_clparms)) 3386240639Sadrian#define TSPRI(x) ((tsparms_t *)((x).pc_clparms)) 3387240639Sadrian#define FXPRI(x) ((fxparms_t *)((x).pc_clparms)) 3388240639Sadrian 3389240639Sadrian 3390247135Sadrian// scale_to_lwp_priority 3391240639Sadrian// 3392248671Sadrian// Convert from the libthread "thr_setprio" scale to our current 3393248671Sadrian// lwp scheduling class scale. 3394248671Sadrian// 3395248671Sadrianstatic 3396248671Sadrianint scale_to_lwp_priority (int rMin, int rMax, int x) 3397240639Sadrian{ 3398240639Sadrian int v; 3399240639Sadrian 3400240639Sadrian if (x == 127) return rMax; // avoid round-down 3401240639Sadrian v = (((x*(rMax-rMin)))/128)+rMin; 3402240899Sadrian return v; 3403240639Sadrian} 3404240639Sadrian 3405240639Sadrian 3406240639Sadrian// set_lwp_class_and_priority 3407240639Sadrianint set_lwp_class_and_priority(int ThreadID, int lwpid, 3408240639Sadrian int newPrio, int new_class, bool scale) { 3409240639Sadrian int rslt; 3410240639Sadrian int Actual, Expected, prv; 3411240899Sadrian pcparms_t ParmInfo; // for GET-SET 3412240639Sadrian#ifdef ASSERT 3413240899Sadrian pcparms_t ReadBack; // for readback 3414240639Sadrian#endif 3415240639Sadrian 3416240639Sadrian // Set priority via PC_GETPARMS, update, PC_SETPARMS 3417240639Sadrian // Query current values. 3418240639Sadrian // TODO: accelerate this by eliminating the PC_GETPARMS call. 3419240899Sadrian // Cache "pcparms_t" in global ParmCache. 3420240724Sadrian // TODO: elide set-to-same-value 3421240899Sadrian 3422240899Sadrian // If something went wrong on init, don't change priorities. 3423240899Sadrian if (!priocntl_enable) { 3424240724Sadrian if (ThreadPriorityVerbose) 3425240724Sadrian tty->print_cr("Trying to set priority but init failed, ignoring"); 3426240639Sadrian return EINVAL; 3427240639Sadrian } 3428240639Sadrian 3429240639Sadrian // If lwp hasn't started yet, just return 3430240639Sadrian // the _start routine will call us again. 3431240639Sadrian if (lwpid <= 0) { 3432240639Sadrian if (ThreadPriorityVerbose) { 3433240724Sadrian tty->print_cr("deferring the set_lwp_class_and_priority of thread " 3434240724Sadrian INTPTR_FORMAT " to %d, lwpid not set", 3435240724Sadrian ThreadID, newPrio); 3436240639Sadrian } 3437240724Sadrian return 0; 3438240724Sadrian } 3439240724Sadrian 3440240639Sadrian if (ThreadPriorityVerbose) { 3441240639Sadrian tty->print_cr ("set_lwp_class_and_priority(" 3442240639Sadrian INTPTR_FORMAT "@" INTPTR_FORMAT " %d) ", 3443240639Sadrian ThreadID, lwpid, newPrio); 3444240639Sadrian } 3445240639Sadrian 3446240639Sadrian memset(&ParmInfo, 0, sizeof(pcparms_t)); 3447240639Sadrian ParmInfo.pc_cid = PC_CLNULL; 3448240639Sadrian rslt = priocntl(P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ParmInfo); 3449233908Sadrian if (rslt < 0) return errno; 3450227364Sadrian 3451227364Sadrian int cur_class = ParmInfo.pc_cid; 3452227364Sadrian ParmInfo.pc_cid = (id_t)new_class; 3453227364Sadrian 3454227364Sadrian if (new_class == rtLimits.schedPolicy) { 3455227364Sadrian rtparms_t *rtInfo = (rtparms_t*)ParmInfo.pc_clparms; 3456227364Sadrian rtInfo->rt_pri = scale ? scale_to_lwp_priority(rtLimits.minPrio, 3457227364Sadrian rtLimits.maxPrio, newPrio) 3458227364Sadrian : newPrio; 3459227364Sadrian rtInfo->rt_tqsecs = RT_NOCHANGE; 3460227364Sadrian rtInfo->rt_tqnsecs = RT_NOCHANGE; 3461227364Sadrian if (ThreadPriorityVerbose) { 3462227364Sadrian tty->print_cr("RT: %d->%d\n", newPrio, rtInfo->rt_pri); 3463227364Sadrian } 3464227364Sadrian } else if (new_class == iaLimits.schedPolicy) { 3465229949Sadrian iaparms_t* iaInfo = (iaparms_t*)ParmInfo.pc_clparms; 3466229949Sadrian int maxClamped = MIN2(iaLimits.maxPrio, 3467227364Sadrian cur_class == new_class 3468227364Sadrian ? (int)iaInfo->ia_uprilim : iaLimits.maxPrio); 3469227364Sadrian iaInfo->ia_upri = scale ? scale_to_lwp_priority(iaLimits.minPrio, 3470227364Sadrian maxClamped, newPrio) 3471240639Sadrian : newPrio; 3472227364Sadrian iaInfo->ia_uprilim = cur_class == new_class 3473227364Sadrian ? IA_NOCHANGE : (pri_t)iaLimits.maxPrio; 3474227364Sadrian iaInfo->ia_mode = IA_NOCHANGE; 3475243786Sadrian if (ThreadPriorityVerbose) { 3476227364Sadrian tty->print_cr("IA: [%d...%d] %d->%d\n", 3477227364Sadrian iaLimits.minPrio, maxClamped, newPrio, iaInfo->ia_upri); 3478240639Sadrian } 3479227364Sadrian } else if (new_class == tsLimits.schedPolicy) { 3480241336Sadrian tsparms_t* tsInfo = (tsparms_t*)ParmInfo.pc_clparms; 3481227364Sadrian int maxClamped = MIN2(tsLimits.maxPrio, 3482227364Sadrian cur_class == new_class 3483227364Sadrian ? (int)tsInfo->ts_uprilim : tsLimits.maxPrio); 3484227364Sadrian tsInfo->ts_upri = scale ? scale_to_lwp_priority(tsLimits.minPrio, 3485227364Sadrian maxClamped, newPrio) 3486240899Sadrian : newPrio; 3487240639Sadrian tsInfo->ts_uprilim = cur_class == new_class 3488240639Sadrian ? TS_NOCHANGE : (pri_t)tsLimits.maxPrio; 3489229165Sadrian if (ThreadPriorityVerbose) { 3490241336Sadrian tty->print_cr("TS: [%d...%d] %d->%d\n", 3491240639Sadrian tsLimits.minPrio, maxClamped, newPrio, tsInfo->ts_upri); 3492240639Sadrian } 3493229165Sadrian } else if (new_class == fxLimits.schedPolicy) { 3494240639Sadrian fxparms_t* fxInfo = (fxparms_t*)ParmInfo.pc_clparms; 3495240639Sadrian int maxClamped = MIN2(fxLimits.maxPrio, 3496240639Sadrian cur_class == new_class 3497241566Sadrian ? (int)fxInfo->fx_uprilim : fxLimits.maxPrio); 3498240639Sadrian fxInfo->fx_upri = scale ? scale_to_lwp_priority(fxLimits.minPrio, 3499240639Sadrian maxClamped, newPrio) 3500240639Sadrian : newPrio; 3501240639Sadrian fxInfo->fx_uprilim = cur_class == new_class 3502240899Sadrian ? FX_NOCHANGE : (pri_t)fxLimits.maxPrio; 3503233897Sadrian fxInfo->fx_tqsecs = FX_NOCHANGE; 3504227364Sadrian fxInfo->fx_tqnsecs = FX_NOCHANGE; 3505227364Sadrian if (ThreadPriorityVerbose) { 3506241566Sadrian tty->print_cr("FX: [%d...%d] %d->%d\n", 3507240639Sadrian fxLimits.minPrio, maxClamped, newPrio, fxInfo->fx_upri); 3508227364Sadrian } 3509227364Sadrian } else { 3510227364Sadrian if (ThreadPriorityVerbose) { 3511240724Sadrian tty->print_cr("Unknown new scheduling class %d\n", new_class); 3512240724Sadrian } 3513240724Sadrian return EINVAL; // no clue, punt 3514240724Sadrian } 3515240724Sadrian 3516240724Sadrian rslt = priocntl(P_LWPID, lwpid, PC_SETPARMS, (caddr_t)&ParmInfo); 3517245708Sadrian if (ThreadPriorityVerbose && rslt) { 3518240724Sadrian tty->print_cr ("PC_SETPARMS ->%d %d\n", rslt, errno); 3519240724Sadrian } 3520227364Sadrian if (rslt < 0) return errno; 3521227364Sadrian 3522227364Sadrian#ifdef ASSERT 3523227364Sadrian // Sanity check: read back what we just attempted to set. 3524227364Sadrian // In theory it could have changed in the interim ... 3525227364Sadrian // 3526227364Sadrian // The priocntl system call is tricky. 3527227364Sadrian // Sometimes it'll validate the priority value argument and 3528227364Sadrian // return EINVAL if unhappy. At other times it fails silently. 3529227364Sadrian // Readbacks are prudent. 3530227364Sadrian 3531227364Sadrian if (!ReadBackValidate) return 0; 3532227364Sadrian 3533227364Sadrian memset(&ReadBack, 0, sizeof(pcparms_t)); 3534227364Sadrian ReadBack.pc_cid = PC_CLNULL; 3535227364Sadrian rslt = priocntl(P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ReadBack); 3536227364Sadrian assert(rslt >= 0, "priocntl failed"); 3537227364Sadrian Actual = Expected = 0xBAD; 3538227364Sadrian assert(ParmInfo.pc_cid == ReadBack.pc_cid, "cid's don't match"); 3539227364Sadrian if (ParmInfo.pc_cid == rtLimits.schedPolicy) { 3540227364Sadrian Actual = RTPRI(ReadBack)->rt_pri; 3541227364Sadrian Expected = RTPRI(ParmInfo)->rt_pri; 3542227364Sadrian } else if (ParmInfo.pc_cid == iaLimits.schedPolicy) { 3543227364Sadrian Actual = IAPRI(ReadBack)->ia_upri; 3544227364Sadrian Expected = IAPRI(ParmInfo)->ia_upri; 3545227364Sadrian } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) { 3546227364Sadrian Actual = TSPRI(ReadBack)->ts_upri; 3547227364Sadrian Expected = TSPRI(ParmInfo)->ts_upri; 3548227364Sadrian } else if (ParmInfo.pc_cid == fxLimits.schedPolicy) { 3549227364Sadrian Actual = FXPRI(ReadBack)->fx_upri; 3550227364Sadrian Expected = FXPRI(ParmInfo)->fx_upri; 3551227364Sadrian } else { 3552227364Sadrian if (ThreadPriorityVerbose) { 3553227364Sadrian tty->print_cr("set_lwp_class_and_priority: unexpected class in readback: %d\n", 3554227364Sadrian ParmInfo.pc_cid); 3555227364Sadrian } 3556227364Sadrian } 3557227364Sadrian 3558227364Sadrian if (Actual != Expected) { 3559227364Sadrian if (ThreadPriorityVerbose) { 3560240899Sadrian tty->print_cr ("set_lwp_class_and_priority(%d %d) Class=%d: actual=%d vs expected=%d\n", 3561240899Sadrian lwpid, newPrio, ReadBack.pc_cid, Actual, Expected); 3562240899Sadrian } 3563243786Sadrian } 3564227364Sadrian#endif 3565227364Sadrian 3566227364Sadrian return 0; 3567227364Sadrian} 3568227364Sadrian 3569240914Sadrian// Solaris only gives access to 128 real priorities at a time, 3570240914Sadrian// so we expand Java's ten to fill this range. This would be better 3571227364Sadrian// if we dynamically adjusted relative priorities. 3572243786Sadrian// 3573227364Sadrian// The ThreadPriorityPolicy option allows us to select 2 different 3574227364Sadrian// priority scales. 3575227364Sadrian// 3576227364Sadrian// ThreadPriorityPolicy=0 3577227364Sadrian// Since the Solaris' default priority is MaximumPriority, we do not 3578227364Sadrian// set a priority lower than Max unless a priority lower than 3579227364Sadrian// NormPriority is requested. 3580227364Sadrian// 3581227364Sadrian// ThreadPriorityPolicy=1 3582227364Sadrian// This mode causes the priority table to get filled with 3583227364Sadrian// linear values. NormPriority get's mapped to 50% of the 3584227364Sadrian// Maximum priority an so on. This will cause VM threads 3585227364Sadrian// to get unfair treatment against other Solaris processes 3586227364Sadrian// which do not explicitly alter their thread priorities. 3587227364Sadrian// 3588227364Sadrian 3589227364Sadrianint os::java_to_os_priority[CriticalPriority + 1] = { 3590227364Sadrian -99999, // 0 Entry should never be used 3591227364Sadrian 3592243786Sadrian 0, // 1 MinPriority 3593227364Sadrian 32, // 2 3594227364Sadrian 64, // 3 3595227364Sadrian 3596227364Sadrian 96, // 4 3597227364Sadrian 127, // 5 NormPriority 3598227364Sadrian 127, // 6 3599227364Sadrian 3600227364Sadrian 127, // 7 3601227364Sadrian 127, // 8 3602227364Sadrian 127, // 9 NearMaxPriority 3603227364Sadrian 3604243786Sadrian 127, // 10 MaxPriority 3605227364Sadrian 3606227364Sadrian -criticalPrio // 11 CriticalPriority 3607227364Sadrian}; 3608227364Sadrian 3609227364SadrianOSReturn os::set_native_priority(Thread* thread, int newpri) { 3610227364Sadrian OSThread* osthread = thread->osthread(); 3611227364Sadrian 3612227364Sadrian // Save requested priority in case the thread hasn't been started 3613227364Sadrian osthread->set_native_priority(newpri); 3614240883Sadrian 3615240883Sadrian // Check for critical priority request 3616240883Sadrian bool fxcritical = false; 3617240883Sadrian if (newpri == -criticalPrio) { 3618240883Sadrian fxcritical = true; 3619240883Sadrian newpri = criticalPrio; 3620240883Sadrian } 3621240883Sadrian 3622240883Sadrian assert(newpri >= MinimumPriority && newpri <= MaximumPriority, "bad priority mapping"); 3623240883Sadrian if (!UseThreadPriorities) return OS_OK; 3624240883Sadrian 3625240883Sadrian int status = 0; 3626240883Sadrian 3627227364Sadrian if (!fxcritical) { 3628227364Sadrian // Use thr_setprio only if we have a priority that thr_setprio understands 3629227364Sadrian status = thr_setprio(thread->osthread()->thread_id(), newpri); 3630227364Sadrian } 3631227364Sadrian 3632227364Sadrian int lwp_status = 3633227364Sadrian set_lwp_class_and_priority(osthread->thread_id(), 3634227364Sadrian osthread->lwp_id(), 3635227364Sadrian newpri, 3636227364Sadrian fxcritical ? fxLimits.schedPolicy : myClass, 3637227364Sadrian !fxcritical); 3638243786Sadrian if (lwp_status != 0 && fxcritical) { 3639227364Sadrian // Try again, this time without changing the scheduling class 3640227364Sadrian newpri = java_MaxPriority_to_os_priority; 3641227364Sadrian lwp_status = set_lwp_class_and_priority(osthread->thread_id(), 3642227364Sadrian osthread->lwp_id(), 3643227364Sadrian newpri, myClass, false); 3644240639Sadrian } 3645240883Sadrian status |= lwp_status; 3646240883Sadrian return (status == 0) ? OS_OK : OS_ERR; 3647240883Sadrian} 3648240883Sadrian 3649240883Sadrian 3650240883SadrianOSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) { 3651240883Sadrian int p; 3652240883Sadrian if (!UseThreadPriorities) { 3653240883Sadrian *priority_ptr = NormalPriority; 3654240883Sadrian return OS_OK; 3655240883Sadrian } 3656240883Sadrian int status = thr_getprio(thread->osthread()->thread_id(), &p); 3657240883Sadrian if (status != 0) { 3658240883Sadrian return OS_ERR; 3659240883Sadrian } 3660240639Sadrian *priority_ptr = p; 3661240883Sadrian return OS_OK; 3662227364Sadrian} 3663227364Sadrian 3664227364Sadrian 3665240639Sadrian// Hint to the underlying OS that a task switch would not be good. 3666240639Sadrian// Void return because it's a hint and can fail. 3667240639Sadrianvoid os::hint_no_preempt() { 3668240639Sadrian schedctl_start(schedctl_init()); 3669240639Sadrian} 3670240639Sadrian 3671240639Sadrianstatic void resume_clear_context(OSThread *osthread) { 3672240639Sadrian osthread->set_ucontext(NULL); 3673240639Sadrian} 3674240639Sadrian 3675240639Sadrianstatic void suspend_save_context(OSThread *osthread, ucontext_t* context) { 3676240639Sadrian osthread->set_ucontext(context); 3677240639Sadrian} 3678240639Sadrian 3679243786Sadrianstatic Semaphore sr_semaphore; 3680227364Sadrian 3681227364Sadrianvoid os::Solaris::SR_handler(Thread* thread, ucontext_t* uc) { 3682227364Sadrian // Save and restore errno to avoid confusing native code with EINTR 3683227364Sadrian // after sigsuspend. 3684227364Sadrian int old_errno = errno; 3685233966Sadrian 3686227364Sadrian OSThread* osthread = thread->osthread(); 3687227364Sadrian assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread"); 3688227364Sadrian 3689227364Sadrian os::SuspendResume::State current = osthread->sr.state(); 3690227364Sadrian if (current == os::SuspendResume::SR_SUSPEND_REQUEST) { 3691227364Sadrian suspend_save_context(osthread, uc); 3692227364Sadrian 3693227364Sadrian // attempt to switch the state, we assume we had a SUSPEND_REQUEST 3694227364Sadrian os::SuspendResume::State state = osthread->sr.suspended(); 3695227364Sadrian if (state == os::SuspendResume::SR_SUSPENDED) { 3696227364Sadrian sigset_t suspend_set; // signals for sigsuspend() 3697227364Sadrian 3698227364Sadrian // get current set of blocked signals and unblock resume signal 3699227364Sadrian thr_sigsetmask(SIG_BLOCK, NULL, &suspend_set); 3700227364Sadrian sigdelset(&suspend_set, os::Solaris::SIGasync()); 3701227364Sadrian 3702227364Sadrian sr_semaphore.signal(); 3703227364Sadrian // wait here until we are resumed 3704227364Sadrian while (1) { 3705227364Sadrian sigsuspend(&suspend_set); 3706227364Sadrian 3707227364Sadrian os::SuspendResume::State result = osthread->sr.running(); 3708227364Sadrian if (result == os::SuspendResume::SR_RUNNING) { 3709227364Sadrian sr_semaphore.signal(); 3710227364Sadrian break; 3711243786Sadrian } 3712227364Sadrian } 3713227364Sadrian 3714227364Sadrian } else if (state == os::SuspendResume::SR_RUNNING) { 3715227364Sadrian // request was cancelled, continue 3716227364Sadrian } else { 3717227364Sadrian ShouldNotReachHere(); 3718227364Sadrian } 3719227364Sadrian 3720243786Sadrian resume_clear_context(osthread); 3721227364Sadrian } else if (current == os::SuspendResume::SR_RUNNING) { 3722227364Sadrian // request was cancelled, continue 3723227364Sadrian } else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) { 3724227364Sadrian // ignore 3725227364Sadrian } else { 3726227364Sadrian // ignore 3727227364Sadrian } 3728227364Sadrian 3729227364Sadrian errno = old_errno; 3730227364Sadrian} 3731227364Sadrian 3732227364Sadrianvoid os::print_statistics() { 3733227364Sadrian} 3734227364Sadrian 3735227364Sadrianint os::message_box(const char* title, const char* message) { 3736227364Sadrian int i; 3737235749Sadrian fdStream err(defaultStream::error_fd()); 3738227364Sadrian for (i = 0; i < 78; i++) err.print_raw("="); 3739227364Sadrian err.cr(); 3740227364Sadrian err.print_raw_cr(title); 3741227364Sadrian for (i = 0; i < 78; i++) err.print_raw("-"); 3742227364Sadrian err.cr(); 3743227364Sadrian err.print_raw_cr(message); 3744235774Sadrian for (i = 0; i < 78; i++) err.print_raw("="); 3745227364Sadrian err.cr(); 3746227364Sadrian 3747227364Sadrian char buf[16]; 3748243786Sadrian // Prevent process from exiting upon "read error" without consuming all CPU 3749227364Sadrian while (::read(0, buf, sizeof(buf)) <= 0) { ::sleep(100); } 3750227364Sadrian 3751240639Sadrian return buf[0] == 'y' || buf[0] == 'Y'; 3752240639Sadrian} 3753240639Sadrian 3754240639Sadrianstatic int sr_notify(OSThread* osthread) { 3755241566Sadrian int status = thr_kill(osthread->thread_id(), os::Solaris::SIGasync()); 3756241566Sadrian assert_status(status == 0, status, "thr_kill"); 3757241336Sadrian return status; 3758240639Sadrian} 3759240639Sadrian 3760240639Sadrian// "Randomly" selected value for how long we want to spin 3761227364Sadrian// before bailing out on suspending a thread, also how often 3762227364Sadrian// we send a signal to a thread we want to resume 3763227364Sadrianstatic const int RANDOMLY_LARGE_INTEGER = 1000000; 3764227364Sadrianstatic const int RANDOMLY_LARGE_INTEGER2 = 100; 3765227364Sadrian 3766241336Sadrianstatic bool do_suspend(OSThread* osthread) { 3767227364Sadrian assert(osthread->sr.is_running(), "thread should be running"); 3768227364Sadrian assert(!sr_semaphore.trywait(), "semaphore has invalid state"); 3769227364Sadrian 3770241336Sadrian // mark as suspended and send signal 3771227364Sadrian if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) { 3772227364Sadrian // failed to switch, state wasn't running? 3773227364Sadrian ShouldNotReachHere(); 3774227364Sadrian return false; 3775227364Sadrian } 3776229949Sadrian 3777229949Sadrian if (sr_notify(osthread) != 0) { 3778227364Sadrian ShouldNotReachHere(); 3779227364Sadrian } 3780227364Sadrian 3781227364Sadrian // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED 3782227364Sadrian while (true) { 3783227364Sadrian if (sr_semaphore.timedwait(0, 2000 * NANOSECS_PER_MILLISEC)) { 3784227364Sadrian break; 3785227364Sadrian } else { 3786227364Sadrian // timeout 3787227364Sadrian os::SuspendResume::State cancelled = osthread->sr.cancel_suspend(); 3788227364Sadrian if (cancelled == os::SuspendResume::SR_RUNNING) { 3789227364Sadrian return false; 3790227364Sadrian } else if (cancelled == os::SuspendResume::SR_SUSPENDED) { 3791227364Sadrian // make sure that we consume the signal on the semaphore as well 3792227364Sadrian sr_semaphore.wait(); 3793227364Sadrian break; 3794227364Sadrian } else { 3795227364Sadrian ShouldNotReachHere(); 3796227364Sadrian return false; 3797227364Sadrian } 3798227364Sadrian } 3799227364Sadrian } 3800227364Sadrian 3801227364Sadrian guarantee(osthread->sr.is_suspended(), "Must be suspended"); 3802227364Sadrian return true; 3803227364Sadrian} 3804227364Sadrian 3805227364Sadrianstatic void do_resume(OSThread* osthread) { 3806227364Sadrian assert(osthread->sr.is_suspended(), "thread should be suspended"); 3807227364Sadrian assert(!sr_semaphore.trywait(), "invalid semaphore state"); 3808227364Sadrian 3809227364Sadrian if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) { 3810227364Sadrian // failed to switch to WAKEUP_REQUEST 3811227364Sadrian ShouldNotReachHere(); 3812227364Sadrian return; 3813227364Sadrian } 3814227364Sadrian 3815227364Sadrian while (true) { 3816227364Sadrian if (sr_notify(osthread) == 0) { 3817227364Sadrian if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) { 3818227364Sadrian if (osthread->sr.is_running()) { 3819227364Sadrian return; 3820227364Sadrian } 3821227364Sadrian } 3822227364Sadrian } else { 3823227364Sadrian ShouldNotReachHere(); 3824227364Sadrian } 3825227364Sadrian } 3826227364Sadrian 3827227364Sadrian guarantee(osthread->sr.is_running(), "Must be running!"); 3828227364Sadrian} 3829243786Sadrian 3830227364Sadrianvoid os::SuspendedThreadTask::internal_do_task() { 3831227364Sadrian if (do_suspend(_thread->osthread())) { 3832227364Sadrian SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext()); 3833227364Sadrian do_task(context); 3834227364Sadrian do_resume(_thread->osthread()); 3835227364Sadrian } 3836227364Sadrian} 3837227364Sadrian 3838227364Sadrianclass PcFetcher : public os::SuspendedThreadTask { 3839227398Sadrianpublic: 3840227398Sadrian PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {} 3841227364Sadrian ExtendedPC result(); 3842227364Sadrianprotected: 3843227364Sadrian void do_task(const os::SuspendedThreadTaskContext& context); 3844227364Sadrianprivate: 3845248988Sadrian ExtendedPC _epc; 3846248988Sadrian}; 3847248988Sadrian 3848248988SadrianExtendedPC PcFetcher::result() { 3849248988Sadrian guarantee(is_done(), "task is not done yet."); 3850248988Sadrian return _epc; 3851227364Sadrian} 3852227364Sadrian 3853227364Sadrianvoid PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) { 3854227364Sadrian Thread* thread = context.thread(); 3855227364Sadrian OSThread* osthread = thread->osthread(); 3856227364Sadrian if (osthread->ucontext() != NULL) { 3857227364Sadrian _epc = os::Solaris::ucontext_get_pc((ucontext_t *) context.ucontext()); 3858227364Sadrian } else { 3859227364Sadrian // NULL context is unexpected, double-check this is the VMThread 3860227364Sadrian guarantee(thread->is_VM_thread(), "can only be called for VMThread"); 3861227364Sadrian } 3862227364Sadrian} 3863227364Sadrian 3864227364Sadrian// A lightweight implementation that does not suspend the target thread and 3865227364Sadrian// thus returns only a hint. Used for profiling only! 3866227364SadrianExtendedPC os::get_thread_pc(Thread* thread) { 3867227364Sadrian // Make sure that it is called by the watcher and the Threads lock is owned. 3868227364Sadrian assert(Thread::current()->is_Watcher_thread(), "Must be watcher and own Threads_lock"); 3869227364Sadrian // For now, is only used to profile the VM Thread 3870227364Sadrian assert(thread->is_VM_thread(), "Can only be called for VMThread"); 3871227364Sadrian PcFetcher fetcher(thread); 3872227364Sadrian fetcher.run(); 3873227364Sadrian return fetcher.result(); 3874227364Sadrian} 3875227364Sadrian 3876227364Sadrian 3877227364Sadrian// This does not do anything on Solaris. This is basically a hook for being 3878227364Sadrian// able to use structured exception handling (thread-local exception filters) on, e.g., Win32. 3879236994Sadrianvoid os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread) { 3880227364Sadrian f(value, method, args, thread); 3881227364Sadrian} 3882227364Sadrian 3883227364Sadrian// This routine may be used by user applications as a "hook" to catch signals. 3884227398Sadrian// The user-defined signal handler must pass unrecognized signals to this 3885227398Sadrian// routine, and if it returns true (non-zero), then the signal handler must 3886227398Sadrian// return immediately. If the flag "abort_if_unrecognized" is true, then this 3887227398Sadrian// routine will never retun false (zero), but instead will execute a VM panic 3888248988Sadrian// routine kill the process. 3889227364Sadrian// 3890240639Sadrian// If this routine returns false, it is OK to call it again. This allows 3891227364Sadrian// the user-defined signal handler to perform checks either before or after 3892227364Sadrian// the VM performs its own checks. Naturally, the user code would be making 3893227364Sadrian// a serious error if it tried to handle an exception (such as a null check 3894227364Sadrian// or breakpoint) that the VM was generating for its own correct operation. 3895227364Sadrian// 3896227364Sadrian// This routine may recognize any of the following kinds of signals: 3897227364Sadrian// SIGBUS, SIGSEGV, SIGILL, SIGFPE, BREAK_SIGNAL, SIGPIPE, SIGXFSZ, 3898227364Sadrian// os::Solaris::SIGasync 3899227364Sadrian// It should be consulted by handlers for any of those signals. 3900227364Sadrian// It explicitly does not recognize os::Solaris::SIGinterrupt 3901227364Sadrian// 3902227364Sadrian// The caller of this routine must pass in the three arguments supplied 3903227364Sadrian// to the function referred to in the "sa_sigaction" (not the "sa_handler") 3904227364Sadrian// field of the structure passed to sigaction(). This routine assumes that 3905227364Sadrian// the sa_flags field passed to sigaction() includes SA_SIGINFO and SA_RESTART. 3906227364Sadrian// 3907227364Sadrian// Note that the VM will print warnings if it detects conflicting signal 3908227364Sadrian// handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers". 3909227364Sadrian// 3910227364Sadrianextern "C" JNIEXPORT int 3911227364SadrianJVM_handle_solaris_signal(int signo, siginfo_t* siginfo, void* ucontext, 3912227364Sadrian int abort_if_unrecognized); 3913243786Sadrian 3914227364Sadrian 3915227364Sadrianvoid signalHandler(int sig, siginfo_t* info, void* ucVoid) { 3916227364Sadrian int orig_errno = errno; // Preserve errno value over signal handler. 3917227364Sadrian JVM_handle_solaris_signal(sig, info, ucVoid, true); 3918227364Sadrian errno = orig_errno; 3919227364Sadrian} 3920227364Sadrian 3921227364Sadrian/* Do not delete - if guarantee is ever removed, a signal handler (even empty) 3922227364Sadrian is needed to provoke threads blocked on IO to return an EINTR 3923227364Sadrian Note: this explicitly does NOT call JVM_handle_solaris_signal and 3924227364Sadrian does NOT participate in signal chaining due to requirement for 3925227364Sadrian NOT setting SA_RESTART to make EINTR work. */ 3926227364Sadrianextern "C" void sigINTRHandler(int sig, siginfo_t* info, void* ucVoid) { 3927227364Sadrian if (UseSignalChaining) { 3928227398Sadrian struct sigaction *actp = os::Solaris::get_chained_signal_action(sig); 3929227364Sadrian if (actp && actp->sa_handler) { 3930227364Sadrian vm_exit_during_initialization("Signal chaining detected for VM interrupt signal, try -XX:+UseAltSigs"); 3931227364Sadrian } 3932227364Sadrian } 3933227364Sadrian} 3934227364Sadrian 3935227364Sadrian// This boolean allows users to forward their own non-matching signals 3936227364Sadrian// to JVM_handle_solaris_signal, harmlessly. 3937227364Sadrianbool os::Solaris::signal_handlers_are_installed = false; 3938227364Sadrian 3939227364Sadrian// For signal-chaining 3940227364Sadrianbool os::Solaris::libjsig_is_loaded = false; 3941227364Sadriantypedef struct sigaction *(*get_signal_t)(int); 3942227364Sadrianget_signal_t os::Solaris::get_signal_action = NULL; 3943227364Sadrian 3944227364Sadrianstruct sigaction* os::Solaris::get_chained_signal_action(int sig) { 3945227364Sadrian struct sigaction *actp = NULL; 3946227364Sadrian 3947227364Sadrian if ((libjsig_is_loaded) && (sig <= Maxlibjsigsigs)) { 3948227364Sadrian // Retrieve the old signal handler from libjsig 3949227364Sadrian actp = (*get_signal_action)(sig); 3950227364Sadrian } 3951227364Sadrian if (actp == NULL) { 3952233908Sadrian // Retrieve the preinstalled signal handler from jvm 3953233908Sadrian actp = get_preinstalled_handler(sig); 3954227364Sadrian } 3955233908Sadrian 3956233908Sadrian return actp; 3957233908Sadrian} 3958227364Sadrian 3959243786Sadrianstatic bool call_chained_handler(struct sigaction *actp, int sig, 3960227364Sadrian siginfo_t *siginfo, void *context) { 3961227364Sadrian // Call the old signal handler 3962227364Sadrian if (actp->sa_handler == SIG_DFL) { 3963227364Sadrian // It's more reasonable to let jvm treat it as an unexpected exception 3964227364Sadrian // instead of taking the default action. 3965227364Sadrian return false; 3966227364Sadrian } else if (actp->sa_handler != SIG_IGN) { 3967227364Sadrian if ((actp->sa_flags & SA_NODEFER) == 0) { 3968227364Sadrian // automaticlly block the signal 3969227364Sadrian sigaddset(&(actp->sa_mask), sig); 3970227364Sadrian } 3971227364Sadrian 3972240639Sadrian sa_handler_t hand; 3973227364Sadrian sa_sigaction_t sa; 3974227364Sadrian bool siginfo_flag_set = (actp->sa_flags & SA_SIGINFO) != 0; 3975227364Sadrian // retrieve the chained handler 3976227364Sadrian if (siginfo_flag_set) { 3977227364Sadrian sa = actp->sa_sigaction; 3978241336Sadrian } else { 3979227364Sadrian hand = actp->sa_handler; 3980233908Sadrian } 3981233908Sadrian 3982233908Sadrian if ((actp->sa_flags & SA_RESETHAND) != 0) { 3983227364Sadrian actp->sa_handler = SIG_DFL; 3984243786Sadrian } 3985227364Sadrian 3986227364Sadrian // try to honor the signal mask 3987227364Sadrian sigset_t oset; 3988227364Sadrian thr_sigsetmask(SIG_SETMASK, &(actp->sa_mask), &oset); 3989227364Sadrian 3990227364Sadrian // call into the chained handler 3991227364Sadrian if (siginfo_flag_set) { 3992227364Sadrian (*sa)(sig, siginfo, context); 3993227364Sadrian } else { 3994227364Sadrian (*hand)(sig); 3995227364Sadrian } 3996227364Sadrian 3997227364Sadrian // restore the signal mask 3998227364Sadrian thr_sigsetmask(SIG_SETMASK, &oset, 0); 3999227364Sadrian } 4000227364Sadrian // Tell jvm's signal handler the signal is taken care of. 4001227364Sadrian return true; 4002227364Sadrian} 4003243786Sadrian 4004227364Sadrianbool os::Solaris::chained_handler(int sig, siginfo_t* siginfo, void* context) { 4005240255Sadrian bool chained = false; 4006227364Sadrian // signal-chaining 4007227364Sadrian if (UseSignalChaining) { 4008240639Sadrian struct sigaction *actp = get_chained_signal_action(sig); 4009227364Sadrian if (actp != NULL) { 4010227364Sadrian chained = call_chained_handler(actp, sig, siginfo, context); 4011227364Sadrian } 4012227364Sadrian } 4013227364Sadrian return chained; 4014227364Sadrian} 4015227364Sadrian 4016227364Sadrianstruct sigaction* os::Solaris::get_preinstalled_handler(int sig) { 4017227364Sadrian assert((chainedsigactions != (struct sigaction *)NULL) && (preinstalled_sigs != (int *)NULL) , "signals not yet initialized"); 4018227364Sadrian if (preinstalled_sigs[sig] != 0) { 4019227364Sadrian return &chainedsigactions[sig]; 4020227364Sadrian } 4021227364Sadrian return NULL; 4022227398Sadrian} 4023227364Sadrian 4024227364Sadrianvoid os::Solaris::save_preinstalled_handler(int sig, struct sigaction& oldAct) { 4025227364Sadrian 4026227364Sadrian assert(sig > 0 && sig <= Maxsignum, "vm signal out of expected range"); 4027227364Sadrian assert((chainedsigactions != (struct sigaction *)NULL) && (preinstalled_sigs != (int *)NULL) , "signals not yet initialized"); 4028227364Sadrian chainedsigactions[sig] = oldAct; 4029227364Sadrian preinstalled_sigs[sig] = 1; 4030227364Sadrian} 4031227364Sadrian 4032227364Sadrianvoid os::Solaris::set_signal_handler(int sig, bool set_installed, bool oktochain) { 4033227364Sadrian // Check for overwrite. 4034227364Sadrian struct sigaction oldAct; 4035227364Sadrian sigaction(sig, (struct sigaction*)NULL, &oldAct); 4036227364Sadrian void* oldhand = oldAct.sa_sigaction ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction) 4037227364Sadrian : CAST_FROM_FN_PTR(void*, oldAct.sa_handler); 4038227364Sadrian if (oldhand != CAST_FROM_FN_PTR(void*, SIG_DFL) && 4039227364Sadrian oldhand != CAST_FROM_FN_PTR(void*, SIG_IGN) && 4040227364Sadrian oldhand != CAST_FROM_FN_PTR(void*, signalHandler)) { 4041227364Sadrian if (AllowUserSignalHandlers || !set_installed) { 4042227364Sadrian // Do not overwrite; user takes responsibility to forward to us. 4043227364Sadrian return; 4044227364Sadrian } else if (UseSignalChaining) { 4045240639Sadrian if (oktochain) { 4046227364Sadrian // save the old handler in jvm 4047227364Sadrian save_preinstalled_handler(sig, oldAct); 4048240255Sadrian } else { 4049240255Sadrian vm_exit_during_initialization("Signal chaining not allowed for VM interrupt signal, try -XX:+UseAltSigs."); 4050240255Sadrian } 4051240255Sadrian // libjsig also interposes the sigaction() call below and saves the 4052240255Sadrian // old sigaction on it own. 4053227364Sadrian } else { 4054227364Sadrian fatal(err_msg("Encountered unexpected pre-existing sigaction handler " 4055227364Sadrian "%#lx for signal %d.", (long)oldhand, sig)); 4056227364Sadrian } 4057227364Sadrian } 4058227364Sadrian 4059227364Sadrian struct sigaction sigAct; 4060227364Sadrian sigfillset(&(sigAct.sa_mask)); 4061227364Sadrian sigAct.sa_handler = SIG_DFL; 4062227364Sadrian 4063227364Sadrian sigAct.sa_sigaction = signalHandler; 4064227364Sadrian // Handle SIGSEGV on alternate signal stack if 4065227364Sadrian // not using stack banging 4066227364Sadrian if (!UseStackBanging && sig == SIGSEGV) { 4067227364Sadrian sigAct.sa_flags = SA_SIGINFO | SA_RESTART | SA_ONSTACK; 4068227364Sadrian // Interruptible i/o requires SA_RESTART cleared so EINTR 4069227364Sadrian // is returned instead of restarting system calls 4070227364Sadrian } else if (sig == os::Solaris::SIGinterrupt()) { 4071227364Sadrian sigemptyset(&sigAct.sa_mask); 4072227364Sadrian sigAct.sa_handler = NULL; 4073227364Sadrian sigAct.sa_flags = SA_SIGINFO; 4074227364Sadrian sigAct.sa_sigaction = sigINTRHandler; 4075227364Sadrian } else { 4076227364Sadrian sigAct.sa_flags = SA_SIGINFO | SA_RESTART; 4077227364Sadrian } 4078227364Sadrian os::Solaris::set_our_sigflags(sig, sigAct.sa_flags); 4079227364Sadrian 4080227364Sadrian sigaction(sig, &sigAct, &oldAct); 4081227364Sadrian 4082227364Sadrian void* oldhand2 = oldAct.sa_sigaction ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction) 4083227364Sadrian : CAST_FROM_FN_PTR(void*, oldAct.sa_handler); 4084227364Sadrian assert(oldhand2 == oldhand, "no concurrent signal handler installation"); 4085227364Sadrian} 4086243786Sadrian 4087227364Sadrian 4088227868Sadrian#define DO_SIGNAL_CHECK(sig) \ 4089227364Sadrian if (!sigismember(&check_signal_done, sig)) \ 4090227364Sadrian os::Solaris::check_signal_handler(sig) 4091227364Sadrian 4092227364Sadrian// This method is a periodic task to check for misbehaving JNI applications 4093227364Sadrian// under CheckJNI, we can add any periodic checks here 4094227364Sadrian 4095227868Sadrianvoid os::run_periodic_checks() { 4096227364Sadrian // A big source of grief is hijacking virt. addr 0x0 on Solaris, 4097227364Sadrian // thereby preventing a NULL checks. 4098227364Sadrian if (!check_addr0_done) check_addr0_done = check_addr0(tty); 4099227364Sadrian 4100227364Sadrian if (check_signals == false) return; 4101227364Sadrian 4102227364Sadrian // SEGV and BUS if overridden could potentially prevent 4103227364Sadrian // generation of hs*.log in the event of a crash, debugging 4104227364Sadrian // such a case can be very challenging, so we absolutely 4105227364Sadrian // check for the following for a good measure: 4106227364Sadrian DO_SIGNAL_CHECK(SIGSEGV); 4107241336Sadrian DO_SIGNAL_CHECK(SIGILL); 4108227364Sadrian DO_SIGNAL_CHECK(SIGFPE); 4109227364Sadrian DO_SIGNAL_CHECK(SIGBUS); 4110234725Sadrian DO_SIGNAL_CHECK(SIGPIPE); 4111234725Sadrian DO_SIGNAL_CHECK(SIGXFSZ); 4112234725Sadrian 4113227364Sadrian // ReduceSignalUsage allows the user to override these handlers 4114227364Sadrian // see comments at the very top and jvm_solaris.h 4115227364Sadrian if (!ReduceSignalUsage) { 4116227364Sadrian DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL); 4117227364Sadrian DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL); 4118227364Sadrian DO_SIGNAL_CHECK(SHUTDOWN3_SIGNAL); 4119227364Sadrian DO_SIGNAL_CHECK(BREAK_SIGNAL); 4120227364Sadrian } 4121227364Sadrian 4122227364Sadrian // See comments above for using JVM1/JVM2 and UseAltSigs 4123233908Sadrian DO_SIGNAL_CHECK(os::Solaris::SIGinterrupt()); 4124233908Sadrian DO_SIGNAL_CHECK(os::Solaris::SIGasync()); 4125227364Sadrian 4126227364Sadrian} 4127233908Sadrian 4128233908Sadriantypedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *); 4129233908Sadrian 4130233908Sadrianstatic os_sigaction_t os_sigaction = NULL; 4131233908Sadrian 4132240639Sadrianvoid os::Solaris::check_signal_handler(int sig) { 4133243786Sadrian char buf[O_BUFLEN]; 4134233908Sadrian address jvmHandler = NULL; 4135227364Sadrian 4136227364Sadrian struct sigaction act; 4137227364Sadrian if (os_sigaction == NULL) { 4138227364Sadrian // only trust the default sigaction, in case it has been interposed 4139227364Sadrian os_sigaction = (os_sigaction_t)dlsym(RTLD_DEFAULT, "sigaction"); 4140227364Sadrian if (os_sigaction == NULL) return; 4141227364Sadrian } 4142227364Sadrian 4143227364Sadrian os_sigaction(sig, (struct sigaction*)NULL, &act); 4144227364Sadrian 4145227364Sadrian address thisHandler = (act.sa_flags & SA_SIGINFO) 4146227364Sadrian ? CAST_FROM_FN_PTR(address, act.sa_sigaction) 4147227364Sadrian : CAST_FROM_FN_PTR(address, act.sa_handler); 4148227364Sadrian 4149227364Sadrian 4150227364Sadrian switch (sig) { 4151227364Sadrian case SIGSEGV: 4152227364Sadrian case SIGBUS: 4153227364Sadrian case SIGFPE: 4154227364Sadrian case SIGPIPE: 4155227364Sadrian case SIGXFSZ: 4156227364Sadrian case SIGILL: 4157243786Sadrian jvmHandler = CAST_FROM_FN_PTR(address, signalHandler); 4158227364Sadrian break; 4159227364Sadrian 4160248341Sadrian case SHUTDOWN1_SIGNAL: 4161227364Sadrian case SHUTDOWN2_SIGNAL: 4162227364Sadrian case SHUTDOWN3_SIGNAL: 4163227364Sadrian case BREAK_SIGNAL: 4164227364Sadrian jvmHandler = (address)user_handler(); 4165227364Sadrian break; 4166227364Sadrian 4167227364Sadrian default: 4168227364Sadrian int intrsig = os::Solaris::SIGinterrupt(); 4169227364Sadrian int asynsig = os::Solaris::SIGasync(); 4170227364Sadrian 4171227364Sadrian if (sig == intrsig) { 4172227364Sadrian jvmHandler = CAST_FROM_FN_PTR(address, sigINTRHandler); 4173233908Sadrian } else if (sig == asynsig) { 4174233908Sadrian jvmHandler = CAST_FROM_FN_PTR(address, signalHandler); 4175240639Sadrian } else { 4176248341Sadrian return; 4177248341Sadrian } 4178248341Sadrian break; 4179248341Sadrian } 4180233908Sadrian 4181233908Sadrian 4182240639Sadrian if (thisHandler != jvmHandler) { 4183243786Sadrian tty->print("Warning: %s handler ", exception_name(sig, buf, O_BUFLEN)); 4184227364Sadrian tty->print("expected:%s", get_signal_handler_name(jvmHandler, buf, O_BUFLEN)); 4185227364Sadrian tty->print_cr(" found:%s", get_signal_handler_name(thisHandler, buf, O_BUFLEN)); 4186248341Sadrian // No need to check this sig any longer 4187227364Sadrian sigaddset(&check_signal_done, sig); 4188227364Sadrian // Running under non-interactive shell, SHUTDOWN2_SIGNAL will be reassigned SIG_IGN 4189227364Sadrian if (sig == SHUTDOWN2_SIGNAL && !isatty(fileno(stdin))) { 4190227364Sadrian tty->print_cr("Running in non-interactive shell, %s handler is replaced by shell", 4191227364Sadrian exception_name(sig, buf, O_BUFLEN)); 4192227364Sadrian } 4193227364Sadrian } else if(os::Solaris::get_our_sigflags(sig) != 0 && act.sa_flags != os::Solaris::get_our_sigflags(sig)) { 4194227364Sadrian tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN)); 4195227364Sadrian tty->print("expected:" PTR32_FORMAT, os::Solaris::get_our_sigflags(sig)); 4196227364Sadrian tty->print_cr(" found:" PTR32_FORMAT, act.sa_flags); 4197227364Sadrian // No need to check this sig any longer 4198227364Sadrian sigaddset(&check_signal_done, sig); 4199227364Sadrian } 4200227364Sadrian 4201229949Sadrian // Print all the signal handler state 4202229949Sadrian if (sigismember(&check_signal_done, sig)) { 4203227364Sadrian print_signal_handlers(tty, buf, O_BUFLEN); 4204227364Sadrian } 4205227364Sadrian 4206227364Sadrian} 4207227364Sadrian 4208227364Sadrianvoid os::Solaris::install_signal_handlers() { 4209227364Sadrian bool libjsigdone = false; 4210227364Sadrian signal_handlers_are_installed = true; 4211227364Sadrian 4212227364Sadrian // signal-chaining 4213227364Sadrian typedef void (*signal_setting_t)(); 4214227364Sadrian signal_setting_t begin_signal_setting = NULL; 4215227364Sadrian signal_setting_t end_signal_setting = NULL; 4216227364Sadrian begin_signal_setting = CAST_TO_FN_PTR(signal_setting_t, 4217227364Sadrian dlsym(RTLD_DEFAULT, "JVM_begin_signal_setting")); 4218227364Sadrian if (begin_signal_setting != NULL) { 4219227364Sadrian end_signal_setting = CAST_TO_FN_PTR(signal_setting_t, 4220227364Sadrian dlsym(RTLD_DEFAULT, "JVM_end_signal_setting")); 4221227364Sadrian get_signal_action = CAST_TO_FN_PTR(get_signal_t, 4222236038Sadrian dlsym(RTLD_DEFAULT, "JVM_get_signal_action")); 4223227364Sadrian get_libjsig_version = CAST_TO_FN_PTR(version_getting_t, 4224227364Sadrian dlsym(RTLD_DEFAULT, "JVM_get_libjsig_version")); 4225227364Sadrian libjsig_is_loaded = true; 4226227364Sadrian if (os::Solaris::get_libjsig_version != NULL) { 4227227364Sadrian libjsigversion = (*os::Solaris::get_libjsig_version)(); 4228240677Sadrian } 4229240677Sadrian assert(UseSignalChaining, "should enable signal-chaining"); 4230240677Sadrian } 4231240677Sadrian if (libjsig_is_loaded) { 4232240677Sadrian // Tell libjsig jvm is setting signal handlers 4233240677Sadrian (*begin_signal_setting)(); 4234240639Sadrian } 4235240639Sadrian 4236240639Sadrian set_signal_handler(SIGSEGV, true, true); 4237227364Sadrian set_signal_handler(SIGPIPE, true, true); 4238243786Sadrian set_signal_handler(SIGXFSZ, true, true); 4239227364Sadrian set_signal_handler(SIGBUS, true, true); 4240227364Sadrian set_signal_handler(SIGILL, true, true); 4241227364Sadrian set_signal_handler(SIGFPE, true, true); 4242227364Sadrian 4243227364Sadrian 4244227364Sadrian if (os::Solaris::SIGinterrupt() > OLDMAXSIGNUM || os::Solaris::SIGasync() > OLDMAXSIGNUM) { 4245227364Sadrian 4246240639Sadrian // Pre-1.4.1 Libjsig limited to signal chaining signals <= 32 so 4247240639Sadrian // can not register overridable signals which might be > 32 4248240639Sadrian if (libjsig_is_loaded && libjsigversion <= JSIG_VERSION_1_4_1) { 4249240677Sadrian // Tell libjsig jvm has finished setting signal handlers 4250240677Sadrian (*end_signal_setting)(); 4251240639Sadrian libjsigdone = true; 4252240639Sadrian } 4253240639Sadrian } 4254240639Sadrian 4255240639Sadrian // Never ok to chain our SIGinterrupt 4256227364Sadrian set_signal_handler(os::Solaris::SIGinterrupt(), true, false); 4257227364Sadrian set_signal_handler(os::Solaris::SIGasync(), true, true); 4258227364Sadrian 4259240639Sadrian if (libjsig_is_loaded && !libjsigdone) { 4260240639Sadrian // Tell libjsig jvm finishes setting signal handlers 4261240639Sadrian (*end_signal_setting)(); 4262240639Sadrian } 4263243786Sadrian 4264227364Sadrian // We don't activate signal checker if libjsig is in place, we trust ourselves 4265227364Sadrian // and if UserSignalHandler is installed all bets are off. 4266227364Sadrian // Log that signal checking is off only if -verbose:jni is specified. 4267227364Sadrian if (CheckJNICalls) { 4268227364Sadrian if (libjsig_is_loaded) { 4269240639Sadrian if (PrintJNIResolving) { 4270240639Sadrian tty->print_cr("Info: libjsig is activated, all active signal checking is disabled"); 4271240639Sadrian } 4272240639Sadrian check_signals = false; 4273240639Sadrian } 4274240639Sadrian if (AllowUserSignalHandlers) { 4275240639Sadrian if (PrintJNIResolving) { 4276240639Sadrian tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled"); 4277240639Sadrian } 4278240639Sadrian check_signals = false; 4279240639Sadrian } 4280240639Sadrian } 4281240639Sadrian} 4282240639Sadrian 4283240639Sadrian 4284240639Sadrianvoid report_error(const char* file_name, int line_no, const char* title, const char* format, ...); 4285240639Sadrian 4286240639Sadrianconst char * signames[] = { 4287240639Sadrian "SIG0", 4288240639Sadrian "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGTRAP", 4289240639Sadrian "SIGABRT", "SIGEMT", "SIGFPE", "SIGKILL", "SIGBUS", 4290240639Sadrian "SIGSEGV", "SIGSYS", "SIGPIPE", "SIGALRM", "SIGTERM", 4291240639Sadrian "SIGUSR1", "SIGUSR2", "SIGCLD", "SIGPWR", "SIGWINCH", 4292240639Sadrian "SIGURG", "SIGPOLL", "SIGSTOP", "SIGTSTP", "SIGCONT", 4293240639Sadrian "SIGTTIN", "SIGTTOU", "SIGVTALRM", "SIGPROF", "SIGXCPU", 4294240639Sadrian "SIGXFSZ", "SIGWAITING", "SIGLWP", "SIGFREEZE", "SIGTHAW", 4295240639Sadrian "SIGCANCEL", "SIGLOST" 4296240639Sadrian}; 4297240639Sadrian 4298240639Sadrianconst char* os::exception_name(int exception_code, char* buf, size_t size) { 4299240639Sadrian if (0 < exception_code && exception_code <= SIGRTMAX) { 4300240639Sadrian // signal 4301240639Sadrian if (exception_code < sizeof(signames)/sizeof(const char*)) { 4302240639Sadrian jio_snprintf(buf, size, "%s", signames[exception_code]); 4303240639Sadrian } else { 4304240639Sadrian jio_snprintf(buf, size, "SIG%d", exception_code); 4305240639Sadrian } 4306240639Sadrian return buf; 4307240639Sadrian } else { 4308240639Sadrian return NULL; 4309240639Sadrian } 4310240639Sadrian} 4311227364Sadrian 4312227364Sadrian// (Static) wrapper for getisax(2) call. 4313227364Sadrianos::Solaris::getisax_func_t os::Solaris::_getisax = 0; 4314227364Sadrian 4315227364Sadrian// (Static) wrappers for the liblgrp API 4316227364Sadrianos::Solaris::lgrp_home_func_t os::Solaris::_lgrp_home; 4317235461Sadrianos::Solaris::lgrp_init_func_t os::Solaris::_lgrp_init; 4318235461Sadrianos::Solaris::lgrp_fini_func_t os::Solaris::_lgrp_fini; 4319235461Sadrianos::Solaris::lgrp_root_func_t os::Solaris::_lgrp_root; 4320235461Sadrianos::Solaris::lgrp_children_func_t os::Solaris::_lgrp_children; 4321235461Sadrianos::Solaris::lgrp_resources_func_t os::Solaris::_lgrp_resources; 4322227364Sadrianos::Solaris::lgrp_nlgrps_func_t os::Solaris::_lgrp_nlgrps; 4323235461Sadrianos::Solaris::lgrp_cookie_stale_func_t os::Solaris::_lgrp_cookie_stale; 4324227364Sadrianos::Solaris::lgrp_cookie_t os::Solaris::_lgrp_cookie = 0; 4325235461Sadrian 4326235461Sadrian// (Static) wrapper for meminfo() call. 4327243786Sadrianos::Solaris::meminfo_func_t os::Solaris::_meminfo = 0; 4328227364Sadrian 4329227364Sadrianstatic address resolve_symbol_lazy(const char* name) { 4330227364Sadrian address addr = (address) dlsym(RTLD_DEFAULT, name); 4331227364Sadrian if (addr == NULL) { 4332227364Sadrian // RTLD_DEFAULT was not defined on some early versions of 2.5.1 4333227364Sadrian addr = (address) dlsym(RTLD_NEXT, name); 4334227364Sadrian } 4335227364Sadrian return addr; 4336227364Sadrian} 4337227364Sadrian 4338227364Sadrianstatic address resolve_symbol(const char* name) { 4339227364Sadrian address addr = resolve_symbol_lazy(name); 4340227364Sadrian if (addr == NULL) { 4341227364Sadrian fatal(dlerror()); 4342227364Sadrian } 4343227364Sadrian return addr; 4344227364Sadrian} 4345227364Sadrian 4346227364Sadrianvoid os::Solaris::libthread_init() { 4347227364Sadrian address func = (address)dlsym(RTLD_DEFAULT, "_thr_suspend_allmutators"); 4348227364Sadrian 4349227364Sadrian lwp_priocntl_init(); 4350227364Sadrian 4351227364Sadrian // RTLD_DEFAULT was not defined on some early versions of 5.5.1 4352227364Sadrian if (func == NULL) { 4353227364Sadrian func = (address) dlsym(RTLD_NEXT, "_thr_suspend_allmutators"); 4354229949Sadrian // Guarantee that this VM is running on an new enough OS (5.6 or 4355229949Sadrian // later) that it will have a new enough libthread.so. 4356227364Sadrian guarantee(func != NULL, "libthread.so is too old."); 4357227364Sadrian } 4358227364Sadrian 4359248091Sadrian int size; 4360248091Sadrian void (*handler_info_func)(address *, int *); 4361248091Sadrian handler_info_func = CAST_TO_FN_PTR(void (*)(address *, int *), resolve_symbol("thr_sighndlrinfo")); 4362248091Sadrian handler_info_func(&handler_start, &size); 4363248091Sadrian handler_end = handler_start + size; 4364248091Sadrian} 4365248091Sadrian 4366248091Sadrian 4367248091Sadrianint_fnP_mutex_tP os::Solaris::_mutex_lock; 4368248091Sadrianint_fnP_mutex_tP os::Solaris::_mutex_trylock; 4369227364Sadrianint_fnP_mutex_tP os::Solaris::_mutex_unlock; 4370227364Sadrianint_fnP_mutex_tP_i_vP os::Solaris::_mutex_init; 4371227364Sadrianint_fnP_mutex_tP os::Solaris::_mutex_destroy; 4372227364Sadrianint os::Solaris::_mutex_scope = USYNC_THREAD; 4373227364Sadrian 4374227364Sadrianint_fnP_cond_tP_mutex_tP_timestruc_tP os::Solaris::_cond_timedwait; 4375248091Sadrianint_fnP_cond_tP_mutex_tP os::Solaris::_cond_wait; 4376227364Sadrianint_fnP_cond_tP os::Solaris::_cond_signal; 4377227364Sadrianint_fnP_cond_tP os::Solaris::_cond_broadcast; 4378227364Sadrianint_fnP_cond_tP_i_vP os::Solaris::_cond_init; 4379227364Sadrianint_fnP_cond_tP os::Solaris::_cond_destroy; 4380229949Sadrianint os::Solaris::_cond_scope = USYNC_THREAD; 4381229949Sadrian 4382227364Sadrianvoid os::Solaris::synchronization_init() { 4383227364Sadrian if (UseLWPSynchronization) { 4384238350Sjhb os::Solaris::set_mutex_lock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("_lwp_mutex_lock"))); 4385238338Sadrian os::Solaris::set_mutex_trylock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("_lwp_mutex_trylock"))); 4386238338Sadrian os::Solaris::set_mutex_unlock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("_lwp_mutex_unlock"))); 4387238350Sjhb os::Solaris::set_mutex_init(lwp_mutex_init); 4388227364Sadrian os::Solaris::set_mutex_destroy(lwp_mutex_destroy); 4389227364Sadrian os::Solaris::set_mutex_scope(USYNC_THREAD); 4390227364Sadrian 4391227364Sadrian os::Solaris::set_cond_timedwait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP_timestruc_tP, resolve_symbol("_lwp_cond_timedwait"))); 4392227364Sadrian os::Solaris::set_cond_wait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP, resolve_symbol("_lwp_cond_wait"))); 4393227364Sadrian os::Solaris::set_cond_signal(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("_lwp_cond_signal"))); 4394227364Sadrian os::Solaris::set_cond_broadcast(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("_lwp_cond_broadcast"))); 4395227364Sadrian os::Solaris::set_cond_init(lwp_cond_init); 4396227364Sadrian os::Solaris::set_cond_destroy(lwp_cond_destroy); 4397227364Sadrian os::Solaris::set_cond_scope(USYNC_THREAD); 4398227364Sadrian } 4399227364Sadrian else { 4400227364Sadrian os::Solaris::set_mutex_scope(USYNC_THREAD); 4401227364Sadrian os::Solaris::set_cond_scope(USYNC_THREAD); 4402227364Sadrian 4403227364Sadrian if (UsePthreads) { 4404227364Sadrian os::Solaris::set_mutex_lock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_lock"))); 4405227364Sadrian os::Solaris::set_mutex_trylock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_trylock"))); 4406227364Sadrian os::Solaris::set_mutex_unlock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_unlock"))); 4407227364Sadrian os::Solaris::set_mutex_init(pthread_mutex_default_init); 4408227364Sadrian os::Solaris::set_mutex_destroy(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_destroy"))); 4409227364Sadrian 4410227364Sadrian os::Solaris::set_cond_timedwait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP_timestruc_tP, resolve_symbol("pthread_cond_timedwait"))); 4411227364Sadrian os::Solaris::set_cond_wait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP, resolve_symbol("pthread_cond_wait"))); 4412227364Sadrian os::Solaris::set_cond_signal(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("pthread_cond_signal"))); 4413227364Sadrian os::Solaris::set_cond_broadcast(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("pthread_cond_broadcast"))); 4414227364Sadrian os::Solaris::set_cond_init(pthread_cond_default_init); 4415227364Sadrian os::Solaris::set_cond_destroy(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("pthread_cond_destroy"))); 4416229949Sadrian } 4417229949Sadrian else { 4418227364Sadrian os::Solaris::set_mutex_lock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("mutex_lock"))); 4419227364Sadrian os::Solaris::set_mutex_trylock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("mutex_trylock"))); 4420227364Sadrian os::Solaris::set_mutex_unlock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("mutex_unlock"))); 4421227364Sadrian os::Solaris::set_mutex_init(::mutex_init); 4422227364Sadrian os::Solaris::set_mutex_destroy(::mutex_destroy); 4423227364Sadrian 4424227364Sadrian os::Solaris::set_cond_timedwait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP_timestruc_tP, resolve_symbol("cond_timedwait"))); 4425227364Sadrian os::Solaris::set_cond_wait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP, resolve_symbol("cond_wait"))); 4426227364Sadrian os::Solaris::set_cond_signal(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("cond_signal"))); 4427227868Sadrian os::Solaris::set_cond_broadcast(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("cond_broadcast"))); 4428227364Sadrian os::Solaris::set_cond_init(::cond_init); 4429227364Sadrian os::Solaris::set_cond_destroy(::cond_destroy); 4430227364Sadrian } 4431227364Sadrian } 4432227364Sadrian} 4433227364Sadrian 4434227364Sadrianbool os::Solaris::liblgrp_init() { 4435227364Sadrian void *handle = dlopen("liblgrp.so.1", RTLD_LAZY); 4436227364Sadrian if (handle != NULL) { 4437227868Sadrian os::Solaris::set_lgrp_home(CAST_TO_FN_PTR(lgrp_home_func_t, dlsym(handle, "lgrp_home"))); 4438227364Sadrian os::Solaris::set_lgrp_init(CAST_TO_FN_PTR(lgrp_init_func_t, dlsym(handle, "lgrp_init"))); 4439227364Sadrian os::Solaris::set_lgrp_fini(CAST_TO_FN_PTR(lgrp_fini_func_t, dlsym(handle, "lgrp_fini"))); 4440227364Sadrian os::Solaris::set_lgrp_root(CAST_TO_FN_PTR(lgrp_root_func_t, dlsym(handle, "lgrp_root"))); 4441227364Sadrian os::Solaris::set_lgrp_children(CAST_TO_FN_PTR(lgrp_children_func_t, dlsym(handle, "lgrp_children"))); 4442227364Sadrian os::Solaris::set_lgrp_resources(CAST_TO_FN_PTR(lgrp_resources_func_t, dlsym(handle, "lgrp_resources"))); 4443227364Sadrian os::Solaris::set_lgrp_nlgrps(CAST_TO_FN_PTR(lgrp_nlgrps_func_t, dlsym(handle, "lgrp_nlgrps"))); 4444227364Sadrian os::Solaris::set_lgrp_cookie_stale(CAST_TO_FN_PTR(lgrp_cookie_stale_func_t, 4445227364Sadrian dlsym(handle, "lgrp_cookie_stale"))); 4446227364Sadrian 4447227364Sadrian lgrp_cookie_t c = lgrp_init(LGRP_VIEW_CALLER); 4448227364Sadrian set_lgrp_cookie(c); 4449227364Sadrian return true; 4450227364Sadrian } 4451227364Sadrian return false; 4452227364Sadrian} 4453227364Sadrian 4454227364Sadrianvoid os::Solaris::misc_sym_init() { 4455227364Sadrian address func; 4456227364Sadrian 4457243786Sadrian // getisax 4458227364Sadrian func = resolve_symbol_lazy("getisax"); 4459227364Sadrian if (func != NULL) { 4460227364Sadrian os::Solaris::_getisax = CAST_TO_FN_PTR(getisax_func_t, func); 4461227364Sadrian } 4462227364Sadrian 4463227364Sadrian // meminfo 4464227364Sadrian func = resolve_symbol_lazy("meminfo"); 4465227364Sadrian if (func != NULL) { 4466227364Sadrian os::Solaris::set_meminfo(CAST_TO_FN_PTR(meminfo_func_t, func)); 4467227364Sadrian } 4468227364Sadrian} 4469229949Sadrian 4470229949Sadrianuint_t os::Solaris::getisax(uint32_t* array, uint_t n) { 4471227364Sadrian assert(_getisax != NULL, "_getisax not set"); 4472227364Sadrian return _getisax(array, n); 4473227364Sadrian} 4474227364Sadrian 4475227364Sadrian// int pset_getloadavg(psetid_t pset, double loadavg[], int nelem); 4476233908Sadriantypedef long (*pset_getloadavg_type)(psetid_t pset, double loadavg[], int nelem); 4477243786Sadrianstatic pset_getloadavg_type pset_getloadavg_ptr = NULL; 4478233908Sadrian 4479243786Sadrianvoid init_pset_getloadavg_ptr(void) { 4480227364Sadrian pset_getloadavg_ptr = 4481227364Sadrian (pset_getloadavg_type)dlsym(RTLD_DEFAULT, "pset_getloadavg"); 4482234725Sadrian if (PrintMiscellaneous && Verbose && pset_getloadavg_ptr == NULL) { 4483234725Sadrian warning("pset_getloadavg function not found"); 4484234725Sadrian } 4485243786Sadrian} 4486234725Sadrian 4487227364Sadrianint os::Solaris::_dev_zero_fd = -1; 4488227364Sadrian 4489227364Sadrian// this is called _before_ the global arguments have been parsed 4490241336Sadrianvoid os::init(void) { 4491227364Sadrian _initial_pid = getpid(); 4492234725Sadrian 4493234725Sadrian max_hrtime = first_hrtime = gethrtime(); 4494234725Sadrian 4495234725Sadrian init_random(1234567); 4496227364Sadrian 4497227364Sadrian page_size = sysconf(_SC_PAGESIZE); 4498233908Sadrian if (page_size == -1) 4499240639Sadrian fatal(err_msg("os_solaris.cpp: os::init: sysconf failed (%s)", 4500240639Sadrian strerror(errno))); 4501240639Sadrian init_page_sizes((size_t) page_size); 4502240639Sadrian 4503240639Sadrian Solaris::initialize_system_info(); 4504240639Sadrian 4505240639Sadrian // Initialize misc. symbols as soon as possible, so we can use them 4506240639Sadrian // if we need them. 4507240639Sadrian Solaris::misc_sym_init(); 4508240639Sadrian 4509240639Sadrian int fd = ::open("/dev/zero", O_RDWR); 4510240639Sadrian if (fd < 0) { 4511240639Sadrian fatal(err_msg("os::init: cannot open /dev/zero (%s)", strerror(errno))); 4512240639Sadrian } else { 4513240639Sadrian Solaris::set_dev_zero_fd(fd); 4514233908Sadrian 4515233908Sadrian // Close on exec, child won't inherit. 4516233908Sadrian fcntl(fd, F_SETFD, FD_CLOEXEC); 4517233908Sadrian } 4518234725Sadrian 4519243786Sadrian clock_tics_per_sec = CLK_TCK; 4520233908Sadrian 4521227364Sadrian // check if dladdr1() exists; dladdr1 can provide more information than 4522227364Sadrian // dladdr for os::dll_address_to_function_name. It comes with SunOS 5.9 4523227364Sadrian // and is available on linker patches for 5.7 and 5.8. 4524227364Sadrian // libdl.so must have been loaded, this call is just an entry lookup 4525227364Sadrian void * hdl = dlopen("libdl.so", RTLD_NOW); 4526227364Sadrian if (hdl) 4527227364Sadrian dladdr1_func = CAST_TO_FN_PTR(dladdr1_func_type, dlsym(hdl, "dladdr1")); 4528227364Sadrian 4529227364Sadrian // (Solaris only) this switches to calls that actually do locking. 4530227364Sadrian ThreadCritical::initialize(); 4531227364Sadrian 4532227364Sadrian main_thread = thr_self(); 4533227364Sadrian 4534227364Sadrian // Constant minimum stack size allowed. It must be at least 4535227364Sadrian // the minimum of what the OS supports (thr_min_stack()), and 4536227364Sadrian // enough to allow the thread to get to user bytecode execution. 4537227364Sadrian Solaris::min_stack_allowed = MAX2(thr_min_stack(), Solaris::min_stack_allowed); 4538227364Sadrian // If the pagesize of the VM is greater than 8K determine the appropriate 4539227364Sadrian // number of initial guard pages. The user can change this with the 4540227364Sadrian // command line arguments, if needed. 4541227364Sadrian if (vm_page_size() > 8*K) { 4542240677Sadrian StackYellowPages = 1; 4543240639Sadrian StackRedPages = 1; 4544227364Sadrian StackShadowPages = round_to((StackShadowPages*8*K), vm_page_size()) / vm_page_size(); 4545227364Sadrian } 4546240677Sadrian} 4547240677Sadrian 4548240677Sadrian// To install functions for atexit system call 4549240677Sadrianextern "C" { 4550240677Sadrian static void perfMemory_exit_helper() { 4551240677Sadrian perfMemory_exit(); 4552227364Sadrian } 4553227364Sadrian} 4554227364Sadrian 4555227364Sadrian// this is called _after_ the global arguments have been parsed 4556227364Sadrianjint os::init_2(void) { 4557233966Sadrian // try to enable extended file IO ASAP, see 6431278 4558227364Sadrian os::Solaris::try_enable_extended_io(); 4559227364Sadrian 4560227364Sadrian // Allocate a single page and mark it as readable for safepoint polling. Also 4561240677Sadrian // use this first mmap call to check support for MAP_ALIGN. 4562227364Sadrian address polling_page = (address)Solaris::mmap_chunk((char*)page_size, 4563227364Sadrian page_size, 4564227364Sadrian MAP_PRIVATE | MAP_ALIGN, 4565227364Sadrian PROT_READ); 4566227364Sadrian if (polling_page == NULL) { 4567227364Sadrian has_map_align = false; 4568243786Sadrian polling_page = (address)Solaris::mmap_chunk(NULL, page_size, MAP_PRIVATE, 4569227364Sadrian PROT_READ); 4570227364Sadrian } 4571227364Sadrian 4572227364Sadrian os::set_polling_page(polling_page); 4573229949Sadrian 4574229949Sadrian#ifndef PRODUCT 4575229949Sadrian if (Verbose && PrintMiscellaneous) 4576229949Sadrian tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page); 4577227364Sadrian#endif 4578227364Sadrian 4579227364Sadrian if (!UseMembar) { 4580227364Sadrian address mem_serialize_page = (address)Solaris::mmap_chunk(NULL, page_size, MAP_PRIVATE, PROT_READ | PROT_WRITE); 4581227364Sadrian guarantee(mem_serialize_page != NULL, "mmap Failed for memory serialize page"); 4582227364Sadrian os::set_memory_serialize_page(mem_serialize_page); 4583227364Sadrian 4584240639Sadrian#ifndef PRODUCT 4585240639Sadrian if (Verbose && PrintMiscellaneous) 4586240639Sadrian tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page); 4587240639Sadrian#endif 4588240639Sadrian } 4589240639Sadrian 4590240639Sadrian // Check minimum allowable stack size for thread creation and to initialize 4591240639Sadrian // the java system classes, including StackOverflowError - depends on page 4592227364Sadrian // size. Add a page for compiler2 recursion in main thread. 4593227364Sadrian // Add in 2*BytesPerWord times page size to account for VM stack during 4594227364Sadrian // class initialization depending on 32 or 64 bit VM. 4595227364Sadrian os::Solaris::min_stack_allowed = MAX2(os::Solaris::min_stack_allowed, 4596227364Sadrian (size_t)(StackYellowPages+StackRedPages+StackShadowPages+ 4597227364Sadrian 2*BytesPerWord COMPILER2_PRESENT(+1)) * page_size); 4598240639Sadrian 4599240639Sadrian size_t threadStackSizeInBytes = ThreadStackSize * K; 4600240639Sadrian if (threadStackSizeInBytes != 0 && 4601240639Sadrian threadStackSizeInBytes < os::Solaris::min_stack_allowed) { 4602243786Sadrian tty->print_cr("\nThe stack size specified is too small, Specify at least %dk", 4603229949Sadrian os::Solaris::min_stack_allowed/K); 4604229949Sadrian return JNI_ERR; 4605227364Sadrian } 4606227364Sadrian 4607227364Sadrian // For 64kbps there will be a 64kb page size, which makes 4608227364Sadrian // the usable default stack size quite a bit less. Increase the 4609227364Sadrian // stack for 64kb (or any > than 8kb) pages, this increases 4610240639Sadrian // virtual memory fragmentation (since we're not creating the 4611240639Sadrian // stack on a power of 2 boundary. The real fix for this 4612240639Sadrian // should be to fix the guard page mechanism. 4613240639Sadrian 4614240639Sadrian if (vm_page_size() > 8*K) { 4615240639Sadrian threadStackSizeInBytes = (threadStackSizeInBytes != 0) 4616240639Sadrian ? threadStackSizeInBytes + 4617240639Sadrian ((StackYellowPages + StackRedPages) * vm_page_size()) 4618240639Sadrian : 0; 4619240639Sadrian ThreadStackSize = threadStackSizeInBytes/K; 4620240639Sadrian } 4621240677Sadrian 4622240677Sadrian // Make the stack size a multiple of the page size so that 4623240639Sadrian // the yellow/red zones can be guarded. 4624240639Sadrian JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes, 4625240639Sadrian vm_page_size())); 4626240639Sadrian 4627240639Sadrian Solaris::libthread_init(); 4628240639Sadrian 4629240639Sadrian if (UseNUMA) { 4630240639Sadrian if (!Solaris::liblgrp_init()) { 4631240639Sadrian UseNUMA = false; 4632240639Sadrian } else { 4633240639Sadrian size_t lgrp_limit = os::numa_get_groups_num(); 4634240639Sadrian int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit, mtInternal); 4635240639Sadrian size_t lgrp_num = os::numa_get_leaf_groups(lgrp_ids, lgrp_limit); 4636240639Sadrian FREE_C_HEAP_ARRAY(int, lgrp_ids, mtInternal); 4637240639Sadrian if (lgrp_num < 2) { 4638240639Sadrian // There's only one locality group, disable NUMA. 4639240639Sadrian UseNUMA = false; 4640240639Sadrian } 4641240639Sadrian } 4642240639Sadrian if (!UseNUMA && ForceNUMA) { 4643240639Sadrian UseNUMA = true; 4644240639Sadrian } 4645240639Sadrian } 4646240639Sadrian 4647240639Sadrian Solaris::signal_sets_init(); 4648240639Sadrian Solaris::init_signal_mem(); 4649240639Sadrian Solaris::install_signal_handlers(); 4650240639Sadrian 4651240639Sadrian if (libjsigversion < JSIG_VERSION_1_4_1) { 4652240639Sadrian Maxlibjsigsigs = OLDMAXSIGNUM; 4653240639Sadrian } 4654240639Sadrian 4655240639Sadrian // initialize synchronization primitives to use either thread or 4656240639Sadrian // lwp synchronization (controlled by UseLWPSynchronization) 4657240639Sadrian Solaris::synchronization_init(); 4658243786Sadrian 4659240639Sadrian if (MaxFDLimit) { 4660240639Sadrian // set the number of file descriptors to max. print out error 4661240639Sadrian // if getrlimit/setrlimit fails but continue regardless. 4662240639Sadrian struct rlimit nbr_files; 4663240639Sadrian int status = getrlimit(RLIMIT_NOFILE, &nbr_files); 4664240639Sadrian if (status != 0) { 4665240639Sadrian if (PrintMiscellaneous && (Verbose || WizardMode)) 4666240639Sadrian perror("os::init_2 getrlimit failed"); 4667240639Sadrian } else { 4668240639Sadrian nbr_files.rlim_cur = nbr_files.rlim_max; 4669240639Sadrian status = setrlimit(RLIMIT_NOFILE, &nbr_files); 4670227364Sadrian if (status != 0) { 4671227364Sadrian if (PrintMiscellaneous && (Verbose || WizardMode)) 4672227364Sadrian perror("os::init_2 setrlimit failed"); 4673235461Sadrian } 4674227364Sadrian } 4675235461Sadrian } 4676240677Sadrian 4677243786Sadrian // Calculate theoretical max. size of Threads to guard gainst 4678229949Sadrian // artifical out-of-memory situations, where all available address- 4679229949Sadrian // space has been reserved by thread stacks. Default stack size is 1Mb. 4680227364Sadrian size_t pre_thread_stack_size = (JavaThread::stack_size_at_create()) ? 4681227364Sadrian JavaThread::stack_size_at_create() : (1*K*K); 4682227364Sadrian assert(pre_thread_stack_size != 0, "Must have a stack"); 4683227364Sadrian // Solaris has a maximum of 4Gb of user programs. Calculate the thread limit when 4684227364Sadrian // we should start doing Virtual Memory banging. Currently when the threads will 4685227364Sadrian // have used all but 200Mb of space. 4686227364Sadrian size_t max_address_space = ((unsigned int)4 * K * K * K) - (200 * K * K); 4687227364Sadrian Solaris::_os_thread_limit = max_address_space / pre_thread_stack_size; 4688227364Sadrian 4689227364Sadrian // at-exit methods are called in the reverse order of their registration. 4690227364Sadrian // In Solaris 7 and earlier, atexit functions are called on return from 4691227364Sadrian // main or as a result of a call to exit(3C). There can be only 32 of 4692227364Sadrian // these functions registered and atexit() does not set errno. In Solaris 4693227364Sadrian // 8 and later, there is no limit to the number of functions registered 4694227364Sadrian // and atexit() sets errno. In addition, in Solaris 8 and later, atexit 4695227364Sadrian // functions are called upon dlclose(3DL) in addition to return from main 4696233908Sadrian // and exit(3C). 4697240639Sadrian 4698240639Sadrian if (PerfAllowAtExitRegistration) { 4699240639Sadrian // only register atexit functions if PerfAllowAtExitRegistration is set. 4700240639Sadrian // atexit functions can be delayed until process exit time, which 4701240639Sadrian // can be problematic for embedded VM situations. Embedded VMs should 4702240639Sadrian // call DestroyJavaVM() to assure that VM resources are released. 4703240639Sadrian 4704240639Sadrian // note: perfMemory_exit_helper atexit function may be removed in 4705240639Sadrian // the future if the appropriate cleanup code can be added to the 4706240639Sadrian // VM_Exit VMOperation's doit method. 4707240639Sadrian if (atexit(perfMemory_exit_helper) != 0) { 4708240639Sadrian warning("os::init2 atexit(perfMemory_exit_helper) failed"); 4709240639Sadrian } 4710233908Sadrian } 4711233908Sadrian 4712233908Sadrian // Init pset_loadavg function pointer 4713233908Sadrian init_pset_getloadavg_ptr(); 4714233908Sadrian 4715243786Sadrian return JNI_OK; 4716227364Sadrian} 4717227364Sadrian 4718227364Sadrianvoid os::init_3(void) { 4719227364Sadrian return; 4720227364Sadrian} 4721227364Sadrian 4722227364Sadrian// Mark the polling page as unreadable 4723227364Sadrianvoid os::make_polling_page_unreadable(void) { 4724227364Sadrian if (mprotect((char *)_polling_page, page_size, PROT_NONE) != 0) 4725227364Sadrian fatal("Could not disable polling page"); 4726227364Sadrian}; 4727227364Sadrian 4728227364Sadrian// Mark the polling page as readable 4729227364Sadrianvoid os::make_polling_page_readable(void) { 4730227364Sadrian if (mprotect((char *)_polling_page, page_size, PROT_READ) != 0) 4731227364Sadrian fatal("Could not enable polling page"); 4732227364Sadrian}; 4733227364Sadrian 4734227364Sadrian// OS interface. 4735227364Sadrian 4736227364Sadrianbool os::check_heap(bool force) { return true; } 4737227364Sadrian 4738227364Sadriantypedef int (*vsnprintf_t)(char* buf, size_t count, const char* fmt, va_list argptr); 4739227364Sadrianstatic vsnprintf_t sol_vsnprintf = NULL; 4740227364Sadrian 4741227364Sadrianint local_vsnprintf(char* buf, size_t count, const char* fmt, va_list argptr) { 4742227364Sadrian if (!sol_vsnprintf) { 4743227364Sadrian //search for the named symbol in the objects that were loaded after libjvm 4744227364Sadrian void* where = RTLD_NEXT; 4745227364Sadrian if ((sol_vsnprintf = CAST_TO_FN_PTR(vsnprintf_t, dlsym(where, "__vsnprintf"))) == NULL) 4746243786Sadrian sol_vsnprintf = CAST_TO_FN_PTR(vsnprintf_t, dlsym(where, "vsnprintf")); 4747227364Sadrian if (!sol_vsnprintf){ 4748227364Sadrian //search for the named symbol in the objects that were loaded before libjvm 4749227364Sadrian where = RTLD_DEFAULT; 4750227364Sadrian if ((sol_vsnprintf = CAST_TO_FN_PTR(vsnprintf_t, dlsym(where, "__vsnprintf"))) == NULL) 4751227364Sadrian sol_vsnprintf = CAST_TO_FN_PTR(vsnprintf_t, dlsym(where, "vsnprintf")); 4752227364Sadrian assert(sol_vsnprintf != NULL, "vsnprintf not found"); 4753227364Sadrian } 4754227364Sadrian } 4755227364Sadrian return (*sol_vsnprintf)(buf, count, fmt, argptr); 4756227364Sadrian} 4757227364Sadrian 4758227364Sadrian 4759227364Sadrian// Is a (classpath) directory empty? 4760227364Sadrianbool os::dir_is_empty(const char* path) { 4761227364Sadrian DIR *dir = NULL; 4762227364Sadrian struct dirent *ptr; 4763227364Sadrian 4764227364Sadrian dir = opendir(path); 4765227364Sadrian if (dir == NULL) return true; 4766227364Sadrian 4767227364Sadrian /* Scan the directory */ 4768241336Sadrian bool result = true; 4769227364Sadrian char buf[sizeof(struct dirent) + MAX_PATH]; 4770227364Sadrian struct dirent *dbuf = (struct dirent *) buf; 4771227364Sadrian while (result && (ptr = readdir(dir, dbuf)) != NULL) { 4772227364Sadrian if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) { 4773227364Sadrian result = false; 4774227364Sadrian } 4775227364Sadrian } 4776227364Sadrian closedir(dir); 4777227364Sadrian return result; 4778229949Sadrian} 4779229949Sadrian 4780227364Sadrian// This code originates from JDK's sysOpen and open64_w 4781241336Sadrian// from src/solaris/hpi/src/system_md.c 4782240180Sadrian 4783240180Sadrian#ifndef O_DELETE 4784240180Sadrian#define O_DELETE 0x10000 4785240180Sadrian#endif 4786240180Sadrian 4787240180Sadrian// Open a file. Unlink the file immediately after open returns 4788240180Sadrian// if the specified oflag has the O_DELETE flag set. 4789240180Sadrian// O_DELETE is used only in j2se/src/share/native/java/util/zip/ZipFile.c 4790240180Sadrian 4791240180Sadrianint os::open(const char *path, int oflag, int mode) { 4792240180Sadrian if (strlen(path) > MAX_PATH - 1) { 4793240180Sadrian errno = ENAMETOOLONG; 4794240180Sadrian return -1; 4795240180Sadrian } 4796227364Sadrian int fd; 4797240180Sadrian int o_delete = (oflag & O_DELETE); 4798240180Sadrian oflag = oflag & ~O_DELETE; 4799240724Sadrian 4800240724Sadrian fd = ::open64(path, oflag, mode); 4801240724Sadrian if (fd == -1) return -1; 4802227364Sadrian 4803233989Sadrian //If the open succeeded, the file might still be a directory 4804233989Sadrian { 4805233989Sadrian struct stat64 buf64; 4806227364Sadrian int ret = ::fstat64(fd, &buf64); 4807227364Sadrian int st_mode = buf64.st_mode; 4808227364Sadrian 4809227364Sadrian if (ret != -1) { 4810227364Sadrian if ((st_mode & S_IFMT) == S_IFDIR) { 4811227364Sadrian errno = EISDIR; 4812227364Sadrian ::close(fd); 4813227364Sadrian return -1; 4814227364Sadrian } 4815227364Sadrian } else { 4816227364Sadrian ::close(fd); 4817227364Sadrian return -1; 4818227364Sadrian } 4819227364Sadrian } 4820227364Sadrian /* 4821227364Sadrian * 32-bit Solaris systems suffer from: 4822227364Sadrian * 4823227364Sadrian * - an historical default soft limit of 256 per-process file 4824227364Sadrian * descriptors that is too low for many Java programs. 4825227364Sadrian * 4826227364Sadrian * - a design flaw where file descriptors created using stdio 4827227364Sadrian * fopen must be less than 256, _even_ when the first limit above 4828227364Sadrian * has been raised. This can cause calls to fopen (but not calls to 4829233989Sadrian * open, for example) to fail mysteriously, perhaps in 3rd party 4830233989Sadrian * native code (although the JDK itself uses fopen). One can hardly 4831233989Sadrian * criticize them for using this most standard of all functions. 4832233989Sadrian * 4833233989Sadrian * We attempt to make everything work anyways by: 4834227364Sadrian * 4835227364Sadrian * - raising the soft limit on per-process file descriptors beyond 4836227364Sadrian * 256 4837227364Sadrian * 4838227364Sadrian * - As of Solaris 10u4, we can request that Solaris raise the 256 4839227364Sadrian * stdio fopen limit by calling function enable_extended_FILE_stdio. 4840227364Sadrian * This is done in init_2 and recorded in enabled_extended_FILE_stdio 4841227364Sadrian * 4842227364Sadrian * - If we are stuck on an old (pre 10u4) Solaris system, we can 4843227364Sadrian * workaround the bug by remapping non-stdio file descriptors below 4844227364Sadrian * 256 to ones beyond 256, which is done below. 4845227364Sadrian * 4846227364Sadrian * See: 4847227364Sadrian * 1085341: 32-bit stdio routines should support file descriptors >255 4848227364Sadrian * 6533291: Work around 32-bit Solaris stdio limit of 256 open files 4849227364Sadrian * 6431278: Netbeans crash on 32 bit Solaris: need to call 4850227364Sadrian * enable_extended_FILE_stdio() in VM initialisation 4851227364Sadrian * Giri Mandalika's blog 4852227364Sadrian * http://technopark02.blogspot.com/2005_05_01_archive.html 4853233989Sadrian */ 4854233989Sadrian#ifndef _LP64 4855233989Sadrian if ((!enabled_extended_FILE_stdio) && fd < 256) { 4856227364Sadrian int newfd = ::fcntl(fd, F_DUPFD, 256); 4857227364Sadrian if (newfd != -1) { 4858227364Sadrian ::close(fd); 4859227364Sadrian fd = newfd; 4860227364Sadrian } 4861227364Sadrian } 4862227364Sadrian#endif // 32-bit Solaris 4863227364Sadrian /* 4864240724Sadrian * All file descriptors that are opened in the JVM and not 4865240724Sadrian * specifically destined for a subprocess should have the 4866240724Sadrian * close-on-exec flag set. If we don't set it, then careless 3rd 4867240724Sadrian * party native code might fork and exec without closing all 4868227364Sadrian * appropriate file descriptors (e.g. as we do in closeDescriptors in 4869240255Sadrian * UNIXProcess.c), and this in turn might: 4870227364Sadrian * 4871227364Sadrian * - cause end-of-file to fail to be detected on some file 4872227364Sadrian * descriptors, resulting in mysterious hangs, or 4873227364Sadrian * 4874227364Sadrian * - might cause an fopen in the subprocess to fail on a system 4875227364Sadrian * suffering from bug 1085341. 4876227364Sadrian * 4877227364Sadrian * (Yes, the default setting of the close-on-exec flag is a Unix 4878229949Sadrian * design flaw) 4879229949Sadrian * 4880227364Sadrian * See: 4881227364Sadrian * 1085341: 32-bit stdio routines should support file descriptors >255 4882227364Sadrian * 4843136: (process) pipe file descriptor from Runtime.exec not being closed 4883227364Sadrian * 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9 4884227364Sadrian */ 4885227364Sadrian#ifdef FD_CLOEXEC 4886240724Sadrian { 4887240724Sadrian int flags = ::fcntl(fd, F_GETFD); 4888240724Sadrian if (flags != -1) 4889227364Sadrian ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC); 4890233989Sadrian } 4891233989Sadrian#endif 4892233989Sadrian 4893233989Sadrian if (o_delete != 0) { 4894233989Sadrian ::unlink(path); 4895233989Sadrian } 4896227364Sadrian return fd; 4897227364Sadrian} 4898227364Sadrian 4899227364Sadrian// create binary file, rewriting existing file if required 4900227364Sadrianint os::create_binary_file(const char* path, bool rewrite_existing) { 4901227364Sadrian int oflags = O_WRONLY | O_CREAT; 4902227364Sadrian if (!rewrite_existing) { 4903227364Sadrian oflags |= O_EXCL; 4904227364Sadrian } 4905227364Sadrian return ::open64(path, oflags, S_IREAD | S_IWRITE); 4906227364Sadrian} 4907227364Sadrian 4908227364Sadrian// return current position of file pointer 4909227364Sadrianjlong os::current_file_offset(int fd) { 4910227364Sadrian return (jlong)::lseek64(fd, (off64_t)0, SEEK_CUR); 4911227364Sadrian} 4912227364Sadrian 4913227364Sadrian// move file pointer to the specified offset 4914227364Sadrianjlong os::seek_to_file_offset(int fd, jlong offset) { 4915227364Sadrian return (jlong)::lseek64(fd, (off64_t)offset, SEEK_SET); 4916227364Sadrian} 4917227364Sadrian 4918227364Sadrianjlong os::lseek(int fd, jlong offset, int whence) { 4919227364Sadrian return (jlong) ::lseek64(fd, offset, whence); 4920227364Sadrian} 4921227364Sadrian 4922227364Sadrianchar * os::native_path(char *path) { 4923227364Sadrian return path; 4924227364Sadrian} 4925227364Sadrian 4926227364Sadrianint os::ftruncate(int fd, jlong length) { 4927227364Sadrian return ::ftruncate64(fd, length); 4928227364Sadrian} 4929227364Sadrian 4930227364Sadrianint os::fsync(int fd) { 4931227364Sadrian RESTARTABLE_RETURN_INT(::fsync(fd)); 4932227364Sadrian} 4933227364Sadrian 4934227364Sadrianint os::available(int fd, jlong *bytes) { 4935227364Sadrian assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, 4936227364Sadrian "Assumed _thread_in_native"); 4937227364Sadrian jlong cur, end; 4938227364Sadrian int mode; 4939227364Sadrian struct stat64 buf64; 4940227364Sadrian 4941227364Sadrian if (::fstat64(fd, &buf64) >= 0) { 4942227364Sadrian mode = buf64.st_mode; 4943227364Sadrian if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) { 4944227364Sadrian int n,ioctl_return; 4945227364Sadrian 4946227364Sadrian RESTARTABLE(::ioctl(fd, FIONREAD, &n), ioctl_return); 4947227364Sadrian if (ioctl_return>= 0) { 4948227364Sadrian *bytes = n; 4949227364Sadrian return 1; 4950243786Sadrian } 4951227364Sadrian } 4952227364Sadrian } 4953227364Sadrian if ((cur = ::lseek64(fd, 0L, SEEK_CUR)) == -1) { 4954227364Sadrian return 0; 4955227364Sadrian } else if ((end = ::lseek64(fd, 0L, SEEK_END)) == -1) { 4956227364Sadrian return 0; 4957227364Sadrian } else if (::lseek64(fd, cur, SEEK_SET) == -1) { 4958227364Sadrian return 0; 4959227364Sadrian } 4960227364Sadrian *bytes = end - cur; 4961227364Sadrian return 1; 4962227364Sadrian} 4963227364Sadrian 4964227364Sadrian// Map a block of memory. 4965227364Sadrianchar* os::pd_map_memory(int fd, const char* file_name, size_t file_offset, 4966227364Sadrian char *addr, size_t bytes, bool read_only, 4967227364Sadrian bool allow_exec) { 4968227364Sadrian int prot; 4969241336Sadrian int flags; 4970227364Sadrian 4971227364Sadrian if (read_only) { 4972227364Sadrian prot = PROT_READ; 4973227364Sadrian flags = MAP_SHARED; 4974241336Sadrian } else { 4975227364Sadrian prot = PROT_READ | PROT_WRITE; 4976227364Sadrian flags = MAP_PRIVATE; 4977227364Sadrian } 4978227364Sadrian 4979227364Sadrian if (allow_exec) { 4980227364Sadrian prot |= PROT_EXEC; 4981227364Sadrian } 4982227364Sadrian 4983227364Sadrian if (addr != NULL) { 4984227364Sadrian flags |= MAP_FIXED; 4985240883Sadrian } 4986240883Sadrian 4987240883Sadrian char* mapped_address = (char*)mmap(addr, (size_t)bytes, prot, flags, 4988240883Sadrian fd, file_offset); 4989240883Sadrian if (mapped_address == MAP_FAILED) { 4990240883Sadrian return NULL; 4991240724Sadrian } 4992240724Sadrian return mapped_address; 4993240724Sadrian} 4994227364Sadrian 4995227364Sadrian 4996233989Sadrian// Remap a block of memory. 4997233989Sadrianchar* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset, 4998233989Sadrian char *addr, size_t bytes, bool read_only, 4999227364Sadrian bool allow_exec) { 5000227364Sadrian // same as map_memory() on this OS 5001227364Sadrian return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only, 5002227364Sadrian allow_exec); 5003227364Sadrian} 5004227364Sadrian 5005227364Sadrian 5006227364Sadrian// Unmap a block of memory. 5007227364Sadrianbool os::pd_unmap_memory(char* addr, size_t bytes) { 5008227364Sadrian return munmap(addr, bytes) == 0; 5009227364Sadrian} 5010227364Sadrian 5011227364Sadrianvoid os::pause() { 5012227364Sadrian char filename[MAX_PATH]; 5013227364Sadrian if (PauseAtStartupFile && PauseAtStartupFile[0]) { 5014227364Sadrian jio_snprintf(filename, MAX_PATH, PauseAtStartupFile); 5015227364Sadrian } else { 5016227364Sadrian jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id()); 5017227364Sadrian } 5018227364Sadrian 5019227364Sadrian int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666); 5020227364Sadrian if (fd != -1) { 5021227364Sadrian struct stat buf; 5022227364Sadrian ::close(fd); 5023227364Sadrian while (::stat(filename, &buf) == 0) { 5024227364Sadrian (void)::poll(NULL, 0, 100); 5025227364Sadrian } 5026227364Sadrian } else { 5027243786Sadrian jio_fprintf(stderr, 5028227364Sadrian "Could not open pause file '%s', continuing immediately.\n", filename); 5029227364Sadrian } 5030227364Sadrian} 5031227364Sadrian 5032227364Sadrian#ifndef PRODUCT 5033227364Sadrian#ifdef INTERPOSE_ON_SYSTEM_SYNCH_FUNCTIONS 5034227364Sadrian// Turn this on if you need to trace synch operations. 5035227364Sadrian// Set RECORD_SYNCH_LIMIT to a large-enough value, 5036227364Sadrian// and call record_synch_enable and record_synch_disable 5037227364Sadrian// around the computation of interest. 5038227364Sadrian 5039227364Sadrianvoid record_synch(char* name, bool returning); // defined below 5040227364Sadrian 5041227364Sadrianclass RecordSynch { 5042227364Sadrian char* _name; 5043227364Sadrian public: 5044227364Sadrian RecordSynch(char* name) :_name(name) 5045227364Sadrian { record_synch(_name, false); } 5046227364Sadrian ~RecordSynch() { record_synch(_name, true); } 5047227364Sadrian}; 5048227364Sadrian 5049227364Sadrian#define CHECK_SYNCH_OP(ret, name, params, args, inner) \ 5050227364Sadrianextern "C" ret name params { \ 5051227364Sadrian typedef ret name##_t params; \ 5052227364Sadrian static name##_t* implem = NULL; \ 5053227364Sadrian static int callcount = 0; \ 5054227364Sadrian if (implem == NULL) { \ 5055227364Sadrian implem = (name##_t*) dlsym(RTLD_NEXT, #name); \ 5056227364Sadrian if (implem == NULL) fatal(dlerror()); \ 5057227364Sadrian } \ 5058227364Sadrian ++callcount; \ 5059227364Sadrian RecordSynch _rs(#name); \ 5060227364Sadrian inner; \ 5061227364Sadrian return implem args; \ 5062227364Sadrian} 5063227364Sadrian// in dbx, examine callcounts this way: 5064227364Sadrian// for n in $(eval whereis callcount | awk '{print $2}'); do print $n; done 5065227364Sadrian 5066227364Sadrian#define CHECK_POINTER_OK(p) \ 5067227364Sadrian (!Universe::is_fully_initialized() || !Universe::is_reserved_heap((oop)(p))) 5068227364Sadrian#define CHECK_MU \ 5069227364Sadrian if (!CHECK_POINTER_OK(mu)) fatal("Mutex must be in C heap only."); 5070227364Sadrian#define CHECK_CV \ 5071227364Sadrian if (!CHECK_POINTER_OK(cv)) fatal("Condvar must be in C heap only."); 5072227364Sadrian#define CHECK_P(p) \ 5073227364Sadrian if (!CHECK_POINTER_OK(p)) fatal(false, "Pointer must be in C heap only."); 5074227364Sadrian 5075227364Sadrian#define CHECK_MUTEX(mutex_op) \ 5076227364SadrianCHECK_SYNCH_OP(int, mutex_op, (mutex_t *mu), (mu), CHECK_MU); 5077227364Sadrian 5078227364SadrianCHECK_MUTEX( mutex_lock) 5079227364SadrianCHECK_MUTEX( _mutex_lock) 5080227364SadrianCHECK_MUTEX( mutex_unlock) 5081227364SadrianCHECK_MUTEX(_mutex_unlock) 5082227364SadrianCHECK_MUTEX( mutex_trylock) 5083227364SadrianCHECK_MUTEX(_mutex_trylock) 5084227364Sadrian 5085227364Sadrian#define CHECK_COND(cond_op) \ 5086227364SadrianCHECK_SYNCH_OP(int, cond_op, (cond_t *cv, mutex_t *mu), (cv, mu), CHECK_MU;CHECK_CV); 5087227364Sadrian 5088227364SadrianCHECK_COND( cond_wait); 5089227364SadrianCHECK_COND(_cond_wait); 5090227364SadrianCHECK_COND(_cond_wait_cancel); 5091227364Sadrian 5092234324Sadrian#define CHECK_COND2(cond_op) \ 5093227364SadrianCHECK_SYNCH_OP(int, cond_op, (cond_t *cv, mutex_t *mu, timestruc_t* ts), (cv, mu, ts), CHECK_MU;CHECK_CV); 5094227364Sadrian 5095227364SadrianCHECK_COND2( cond_timedwait); 5096227364SadrianCHECK_COND2(_cond_timedwait); 5097227364SadrianCHECK_COND2(_cond_timedwait_cancel); 5098227364Sadrian 5099227364Sadrian// do the _lwp_* versions too 5100227364Sadrian#define mutex_t lwp_mutex_t 5101227364Sadrian#define cond_t lwp_cond_t 5102227364SadrianCHECK_MUTEX( _lwp_mutex_lock) 5103227364SadrianCHECK_MUTEX( _lwp_mutex_unlock) 5104227364SadrianCHECK_MUTEX( _lwp_mutex_trylock) 5105227364SadrianCHECK_MUTEX( __lwp_mutex_lock) 5106227364SadrianCHECK_MUTEX( __lwp_mutex_unlock) 5107227364SadrianCHECK_MUTEX( __lwp_mutex_trylock) 5108227364SadrianCHECK_MUTEX(___lwp_mutex_lock) 5109227364SadrianCHECK_MUTEX(___lwp_mutex_unlock) 5110227364Sadrian 5111227364SadrianCHECK_COND( _lwp_cond_wait); 5112227364SadrianCHECK_COND( __lwp_cond_wait); 5113227364SadrianCHECK_COND(___lwp_cond_wait); 5114227364Sadrian 5115227364SadrianCHECK_COND2( _lwp_cond_timedwait); 5116227364SadrianCHECK_COND2( __lwp_cond_timedwait); 5117227364Sadrian#undef mutex_t 5118227364Sadrian#undef cond_t 5119227364Sadrian 5120227364SadrianCHECK_SYNCH_OP(int, _lwp_suspend2, (int lwp, int *n), (lwp, n), 0); 5121227364SadrianCHECK_SYNCH_OP(int,__lwp_suspend2, (int lwp, int *n), (lwp, n), 0); 5122227364SadrianCHECK_SYNCH_OP(int, _lwp_kill, (int lwp, int n), (lwp, n), 0); 5123227364SadrianCHECK_SYNCH_OP(int,__lwp_kill, (int lwp, int n), (lwp, n), 0); 5124227364SadrianCHECK_SYNCH_OP(int, _lwp_sema_wait, (lwp_sema_t* p), (p), CHECK_P(p)); 5125227364SadrianCHECK_SYNCH_OP(int,__lwp_sema_wait, (lwp_sema_t* p), (p), CHECK_P(p)); 5126227364SadrianCHECK_SYNCH_OP(int, _lwp_cond_broadcast, (lwp_cond_t* cv), (cv), CHECK_CV); 5127227364SadrianCHECK_SYNCH_OP(int,__lwp_cond_broadcast, (lwp_cond_t* cv), (cv), CHECK_CV); 5128227364Sadrian 5129227364Sadrian 5130227364Sadrian// recording machinery: 5131227364Sadrian 5132227364Sadrianenum { RECORD_SYNCH_LIMIT = 200 }; 5133227364Sadrianchar* record_synch_name[RECORD_SYNCH_LIMIT]; 5134227364Sadrianvoid* record_synch_arg0ptr[RECORD_SYNCH_LIMIT]; 5135227364Sadrianbool record_synch_returning[RECORD_SYNCH_LIMIT]; 5136227364Sadrianthread_t record_synch_thread[RECORD_SYNCH_LIMIT]; 5137227364Sadrianint record_synch_count = 0; 5138227364Sadrianbool record_synch_enabled = false; 5139227364Sadrian 5140227364Sadrian// in dbx, examine recorded data this way: 5141227364Sadrian// for n in name arg0ptr returning thread; do print record_synch_$n[0..record_synch_count-1]; done 5142227364Sadrian 5143227364Sadrianvoid record_synch(char* name, bool returning) { 5144227364Sadrian if (record_synch_enabled) { 5145227364Sadrian if (record_synch_count < RECORD_SYNCH_LIMIT) { 5146227364Sadrian record_synch_name[record_synch_count] = name; 5147227364Sadrian record_synch_returning[record_synch_count] = returning; 5148227364Sadrian record_synch_thread[record_synch_count] = thr_self(); 5149227364Sadrian record_synch_arg0ptr[record_synch_count] = &name; 5150234324Sadrian record_synch_count++; 5151227364Sadrian } 5152227364Sadrian // put more checking code here: 5153227364Sadrian // ... 5154227364Sadrian } 5155227364Sadrian} 5156227364Sadrian 5157227364Sadrianvoid record_synch_enable() { 5158227364Sadrian // start collecting trace data, if not already doing so 5159227364Sadrian if (!record_synch_enabled) record_synch_count = 0; 5160227364Sadrian record_synch_enabled = true; 5161227364Sadrian} 5162227364Sadrian 5163227364Sadrianvoid record_synch_disable() { 5164227364Sadrian // stop collecting trace data 5165227364Sadrian record_synch_enabled = false; 5166227364Sadrian} 5167227364Sadrian 5168227364Sadrian#endif // INTERPOSE_ON_SYSTEM_SYNCH_FUNCTIONS 5169227364Sadrian#endif // PRODUCT 5170227364Sadrian 5171227364Sadrianconst intptr_t thr_time_off = (intptr_t)(&((prusage_t *)(NULL))->pr_utime); 5172227364Sadrianconst intptr_t thr_time_size = (intptr_t)(&((prusage_t *)(NULL))->pr_ttime) - 5173227364Sadrian (intptr_t)(&((prusage_t *)(NULL))->pr_utime); 5174227364Sadrian 5175227364Sadrian 5176227364Sadrian// JVMTI & JVM monitoring and management support 5177243786Sadrian// The thread_cpu_time() and current_thread_cpu_time() are only 5178235774Sadrian// supported if is_thread_cpu_time_supported() returns true. 5179235774Sadrian// They are not supported on Solaris T1. 5180235774Sadrian 5181235774Sadrian// current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool) 5182235774Sadrian// are used by JVM M&M and JVMTI to get user+sys or user CPU time 5183235774Sadrian// of a thread. 5184235774Sadrian// 5185235774Sadrian// current_thread_cpu_time() and thread_cpu_time(Thread *) 5186235774Sadrian// returns the fast estimate available on the platform. 5187243786Sadrian 5188227364Sadrian// hrtime_t gethrvtime() return value includes 5189227364Sadrian// user time but does not include system time 5190227364Sadrianjlong os::current_thread_cpu_time() { 5191227364Sadrian return (jlong) gethrvtime(); 5192227364Sadrian} 5193227364Sadrian 5194227364Sadrianjlong os::thread_cpu_time(Thread *thread) { 5195227364Sadrian // return user level CPU time only to be consistent with 5196227364Sadrian // what current_thread_cpu_time returns. 5197227364Sadrian // thread_cpu_time_info() must be changed if this changes 5198227364Sadrian return os::thread_cpu_time(thread, false /* user time only */); 5199227364Sadrian} 5200227364Sadrian 5201227364Sadrianjlong os::current_thread_cpu_time(bool user_sys_cpu_time) { 5202227364Sadrian if (user_sys_cpu_time) { 5203227364Sadrian return os::thread_cpu_time(Thread::current(), user_sys_cpu_time); 5204227364Sadrian } else { 5205227364Sadrian return os::current_thread_cpu_time(); 5206227364Sadrian } 5207227364Sadrian} 5208227364Sadrian 5209227364Sadrianjlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) { 5210227364Sadrian char proc_name[64]; 5211227364Sadrian int count; 5212227364Sadrian prusage_t prusage; 5213227364Sadrian jlong lwp_time; 5214227364Sadrian int fd; 5215227364Sadrian 5216227364Sadrian sprintf(proc_name, "/proc/%d/lwp/%d/lwpusage", 5217227364Sadrian getpid(), 5218227364Sadrian thread->osthread()->lwp_id()); 5219227364Sadrian fd = ::open(proc_name, O_RDONLY); 5220227364Sadrian if (fd == -1) return -1; 5221227364Sadrian 5222227364Sadrian do { 5223227364Sadrian count = ::pread(fd, 5224227364Sadrian (void *)&prusage.pr_utime, 5225234324Sadrian thr_time_size, 5226227364Sadrian thr_time_off); 5227227364Sadrian } while (count < 0 && errno == EINTR); 5228227364Sadrian ::close(fd); 5229227364Sadrian if (count < 0) return -1; 5230227364Sadrian 5231227364Sadrian if (user_sys_cpu_time) { 5232227364Sadrian // user + system CPU time 5233227364Sadrian lwp_time = (((jlong)prusage.pr_stime.tv_sec + 5234227364Sadrian (jlong)prusage.pr_utime.tv_sec) * (jlong)1000000000) + 5235227364Sadrian (jlong)prusage.pr_stime.tv_nsec + 5236227364Sadrian (jlong)prusage.pr_utime.tv_nsec; 5237227364Sadrian } else { 5238227364Sadrian // user level CPU time only 5239227364Sadrian lwp_time = ((jlong)prusage.pr_utime.tv_sec * (jlong)1000000000) + 5240227364Sadrian (jlong)prusage.pr_utime.tv_nsec; 5241227364Sadrian } 5242227364Sadrian 5243227364Sadrian return (lwp_time); 5244227364Sadrian} 5245227364Sadrian 5246243786Sadrianvoid os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) { 5247235774Sadrian info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits 5248227364Sadrian info_ptr->may_skip_backward = false; // elapsed time not wall time 5249227364Sadrian info_ptr->may_skip_forward = false; // elapsed time not wall time 5250227364Sadrian info_ptr->kind = JVMTI_TIMER_USER_CPU; // only user time is returned 5251227364Sadrian} 5252227364Sadrian 5253227364Sadrianvoid os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) { 5254227364Sadrian info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits 5255243786Sadrian info_ptr->may_skip_backward = false; // elapsed time not wall time 5256227364Sadrian info_ptr->may_skip_forward = false; // elapsed time not wall time 5257227364Sadrian info_ptr->kind = JVMTI_TIMER_USER_CPU; // only user time is returned 5258227364Sadrian} 5259227364Sadrian 5260227364Sadrianbool os::is_thread_cpu_time_supported() { 5261227364Sadrian return true; 5262237593Sadrian} 5263237593Sadrian 5264237593Sadrian// System loadavg support. Returns -1 if load average cannot be obtained. 5265227364Sadrian// Return the load average for our processor set if the primitive exists 5266227364Sadrian// (Solaris 9 and later). Otherwise just return system wide loadavg. 5267227364Sadrianint os::loadavg(double loadavg[], int nelem) { 5268227364Sadrian if (pset_getloadavg_ptr != NULL) { 5269227364Sadrian return (*pset_getloadavg_ptr)(PS_MYID, loadavg, nelem); 5270234324Sadrian } else { 5271227364Sadrian return ::getloadavg(loadavg, nelem); 5272227364Sadrian } 5273227364Sadrian} 5274227364Sadrian 5275227364Sadrian//--------------------------------------------------------------------------------- 5276237593Sadrian 5277237593Sadrianbool os::find(address addr, outputStream* st) { 5278237593Sadrian Dl_info dlinfo; 5279237593Sadrian memset(&dlinfo, 0, sizeof(dlinfo)); 5280243786Sadrian if (dladdr(addr, &dlinfo) != 0) { 5281227364Sadrian st->print(PTR_FORMAT ": ", addr); 5282237593Sadrian if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) { 5283237593Sadrian st->print("%s+%#lx", dlinfo.dli_sname, addr-(intptr_t)dlinfo.dli_saddr); 5284237593Sadrian } else if (dlinfo.dli_fbase != NULL) 5285237593Sadrian st->print("<offset %#lx>", addr-(intptr_t)dlinfo.dli_fbase); 5286237593Sadrian else 5287237593Sadrian st->print("<absolute address>"); 5288237593Sadrian if (dlinfo.dli_fname != NULL) { 5289237593Sadrian st->print(" in %s", dlinfo.dli_fname); 5290237593Sadrian } 5291243786Sadrian if (dlinfo.dli_fbase != NULL) { 5292227364Sadrian st->print(" at " PTR_FORMAT, dlinfo.dli_fbase); 5293227364Sadrian } 5294227364Sadrian st->cr(); 5295227364Sadrian 5296227364Sadrian if (Verbose) { 5297235749Sadrian // decode some bytes around the PC 5298227364Sadrian address begin = clamp_address_in_page(addr-40, addr, os::vm_page_size()); 5299227364Sadrian address end = clamp_address_in_page(addr+40, addr, os::vm_page_size()); 5300227364Sadrian address lowest = (address) dlinfo.dli_sname; 5301235749Sadrian if (!lowest) lowest = (address) dlinfo.dli_fbase; 5302227364Sadrian if (begin < lowest) begin = lowest; 5303227364Sadrian Dl_info dlinfo2; 5304227364Sadrian if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr 5305227364Sadrian && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin) 5306227364Sadrian end = (address) dlinfo2.dli_saddr; 5307227364Sadrian Disassembler::decode(begin, end, st); 5308227364Sadrian } 5309227364Sadrian return true; 5310227364Sadrian } 5311227364Sadrian return false; 5312227364Sadrian} 5313227364Sadrian 5314227364Sadrian// Following function has been added to support HotSparc's libjvm.so running 5315227364Sadrian// under Solaris production JDK 1.2.2 / 1.3.0. These came from 5316227364Sadrian// src/solaris/hpi/native_threads in the EVM codebase. 5317227364Sadrian// 5318227364Sadrian// NOTE: This is no longer needed in the 1.3.1 and 1.4 production release 5319234324Sadrian// libraries and should thus be removed. We will leave it behind for a while 5320227364Sadrian// until we no longer want to able to run on top of 1.3.0 Solaris production 5321227364Sadrian// JDK. See 4341971. 5322227364Sadrian 5323227364Sadrian#define STACK_SLACK 0x800 5324235491Sadrian 5325235676Sadrianextern "C" { 5326235491Sadrian intptr_t sysThreadAvailableStackWithSlack() { 5327235676Sadrian stack_t st; 5328235676Sadrian intptr_t retval, stack_top; 5329235676Sadrian retval = thr_stksegment(&st); 5330235676Sadrian assert(retval == 0, "incorrect return value from thr_stksegment"); 5331235491Sadrian assert((address)&st < (address)st.ss_sp, "Invalid stack base returned"); 5332235491Sadrian assert((address)&st > (address)st.ss_sp-st.ss_size, "Invalid stack size returned"); 5333227364Sadrian stack_top=(intptr_t)st.ss_sp-st.ss_size; 5334227364Sadrian return ((intptr_t)&stack_top - stack_top - STACK_SLACK); 5335227364Sadrian } 5336227364Sadrian} 5337227364Sadrian 5338227364Sadrian// ObjectMonitor park-unpark infrastructure ... 5339227364Sadrian// 5340227364Sadrian// We implement Solaris and Linux PlatformEvents with the 5341227364Sadrian// obvious condvar-mutex-flag triple. 5342240721Sadrian// Another alternative that works quite well is pipes: 5343240721Sadrian// Each PlatformEvent consists of a pipe-pair. 5344240721Sadrian// The thread associated with the PlatformEvent 5345227364Sadrian// calls park(), which reads from the input end of the pipe. 5346227364Sadrian// Unpark() writes into the other end of the pipe. 5347243786Sadrian// The write-side of the pipe must be set NDELAY. 5348240721Sadrian// Unfortunately pipes consume a large # of handles. 5349240721Sadrian// Native solaris lwp_park() and lwp_unpark() work nicely, too. 5350240721Sadrian// Using pipes for the 1st few threads might be workable, however. 5351240721Sadrian// 5352240721Sadrian// park() is permitted to return spuriously. 5353240721Sadrian// Callers of park() should wrap the call to park() in 5354240721Sadrian// an appropriate loop. A litmus test for the correct 5355243786Sadrian// usage of park is the following: if park() were modified 5356227364Sadrian// to immediately return 0 your code should still work, 5357227364Sadrian// albeit degenerating to a spin loop. 5358227364Sadrian// 5359227364Sadrian// An interesting optimization for park() is to use a trylock() 5360227364Sadrian// to attempt to acquire the mutex. If the trylock() fails 5361227364Sadrian// then we know that a concurrent unpark() operation is in-progress. 5362227364Sadrian// in that case the park() code could simply set _count to 0 5363227364Sadrian// and return immediately. The subsequent park() operation *might* 5364227364Sadrian// return immediately. That's harmless as the caller of park() is 5365227364Sadrian// expected to loop. By using trylock() we will have avoided a 5366227364Sadrian// avoided a context switch caused by contention on the per-thread mutex. 5367227364Sadrian// 5368234324Sadrian// TODO-FIXME: 5369227364Sadrian// 1. Reconcile Doug's JSR166 j.u.c park-unpark with the 5370227364Sadrian// objectmonitor implementation. 5371227364Sadrian// 2. Collapse the JSR166 parker event, and the 5372227364Sadrian// objectmonitor ParkEvent into a single "Event" construct. 5373227364Sadrian// 3. In park() and unpark() add: 5374227364Sadrian// assert (Thread::current() == AssociatedWith). 5375243786Sadrian// 4. add spurious wakeup injection on a -XX:EarlyParkReturn=N switch. 5376235774Sadrian// 1-out-of-N park() operations will return immediately. 5377243786Sadrian// 5378235774Sadrian// _Event transitions in park() 5379227364Sadrian// -1 => -1 : illegal 5380227364Sadrian// 1 => 0 : pass - return immediately 5381227364Sadrian// 0 => -1 : block 5382227364Sadrian// 5383243786Sadrian// _Event serves as a restricted-range semaphore. 5384227364Sadrian// 5385243786Sadrian// Another possible encoding of _Event would be with 5386227364Sadrian// explicit "PARKED" == 01b and "SIGNALED" == 10b bits. 5387238710Sadrian// 5388241170Sadrian// TODO-FIXME: add DTRACE probes for: 5389241170Sadrian// 1. Tx parks 5390241170Sadrian// 2. Ty unparks Tx 5391242271Sadrian// 3. Tx resumes from park 5392241170Sadrian 5393241170Sadrian 5394241170Sadrian// value determined through experimentation 5395241170Sadrian#define ROUNDINGFIX 11 5396241170Sadrian 5397241170Sadrian// utility to compute the abstime argument to timedwait. 5398241170Sadrian// TODO-FIXME: switch from compute_abstime() to unpackTime(). 5399241170Sadrian 5400241170Sadrianstatic timestruc_t* compute_abstime(timestruc_t* abstime, jlong millis) { 5401241170Sadrian // millis is the relative timeout time 5402241170Sadrian // abstime will be the absolute timeout time 5403241170Sadrian if (millis < 0) millis = 0; 5404241170Sadrian struct timeval now; 5405241170Sadrian int status = gettimeofday(&now, NULL); 5406241170Sadrian assert(status == 0, "gettimeofday"); 5407241170Sadrian jlong seconds = millis / 1000; 5408241170Sadrian jlong max_wait_period; 5409241170Sadrian 5410241170Sadrian if (UseLWPSynchronization) { 5411241170Sadrian // forward port of fix for 4275818 (not sleeping long enough) 5412241170Sadrian // There was a bug in Solaris 6, 7 and pre-patch 5 of 8 where 5413241170Sadrian // _lwp_cond_timedwait() used a round_down algorithm rather 5414241170Sadrian // than a round_up. For millis less than our roundfactor 5415241170Sadrian // it rounded down to 0 which doesn't meet the spec. 5416241170Sadrian // For millis > roundfactor we may return a bit sooner, but 5417241170Sadrian // since we can not accurately identify the patch level and 5418241170Sadrian // this has already been fixed in Solaris 9 and 8 we will 5419241170Sadrian // leave it alone rather than always rounding down. 5420241170Sadrian 5421241170Sadrian if (millis > 0 && millis < ROUNDINGFIX) millis = ROUNDINGFIX; 5422241170Sadrian // It appears that when we go directly through Solaris _lwp_cond_timedwait() 5423241170Sadrian // the acceptable max time threshold is smaller than for libthread on 2.5.1 and 2.6 5424241170Sadrian max_wait_period = 21000000; 5425241170Sadrian } else { 5426241170Sadrian max_wait_period = 50000000; 5427241170Sadrian } 5428241170Sadrian millis %= 1000; 5429241170Sadrian if (seconds > max_wait_period) { // see man cond_timedwait(3T) 5430241170Sadrian seconds = max_wait_period; 5431241170Sadrian } 5432241170Sadrian abstime->tv_sec = now.tv_sec + seconds; 5433241170Sadrian long usec = now.tv_usec + millis * 1000; 5434241170Sadrian if (usec >= 1000000) { 5435241170Sadrian abstime->tv_sec += 1; 5436241170Sadrian usec -= 1000000; 5437241170Sadrian } 5438241170Sadrian abstime->tv_nsec = usec * 1000; 5439241170Sadrian return abstime; 5440241170Sadrian} 5441241170Sadrian 5442241170Sadrian// Test-and-clear _Event, always leaves _Event set to 0, returns immediately. 5443241170Sadrian// Conceptually TryPark() should be equivalent to park(0). 5444241170Sadrian 5445241170Sadrianint os::PlatformEvent::TryPark() { 5446241170Sadrian for (;;) { 5447241170Sadrian const int v = _Event; 5448241170Sadrian guarantee((v == 0) || (v == 1), "invariant"); 5449241170Sadrian if (Atomic::cmpxchg(0, &_Event, v) == v) return v; 5450241170Sadrian } 5451241170Sadrian} 5452241170Sadrian 5453243786Sadrianvoid os::PlatformEvent::park() { // AKA: down() 5454241170Sadrian // Invariant: Only the thread associated with the Event/PlatformEvent 5455241170Sadrian // may call park(). 5456241170Sadrian int v; 5457241170Sadrian for (;;) { 5458241170Sadrian v = _Event; 5459241170Sadrian if (Atomic::cmpxchg(v-1, &_Event, v) == v) break; 5460243786Sadrian } 5461241170Sadrian guarantee(v >= 0, "invariant"); 5462241170Sadrian if (v == 0) { 5463241170Sadrian // Do this the hard way by blocking ... 5464241170Sadrian // See http://monaco.sfbay/detail.jsf?cr=5094058. 5465241170Sadrian // TODO-FIXME: for Solaris SPARC set fprs.FEF=0 prior to parking. 5466241170Sadrian // Only for SPARC >= V8PlusA 5467241170Sadrian#if defined(__sparc) && defined(COMPILER2) 5468241170Sadrian if (ClearFPUAtPark) { _mark_fpu_nosave(); } 5469241170Sadrian#endif 5470243786Sadrian int status = os::Solaris::mutex_lock(_mutex); 5471241170Sadrian assert_status(status == 0, status, "mutex_lock"); 5472241170Sadrian guarantee(_nParked == 0, "invariant"); 5473241170Sadrian ++_nParked; 5474241170Sadrian while (_Event < 0) { 5475241170Sadrian // for some reason, under 2.7 lwp_cond_wait() may return ETIME ... 5476241170Sadrian // Treat this the same as if the wait was interrupted 5477243786Sadrian // With usr/lib/lwp going to kernel, always handle ETIME 5478241170Sadrian status = os::Solaris::cond_wait(_cond, _mutex); 5479241170Sadrian if (status == ETIME) status = EINTR; 5480241170Sadrian assert_status(status == 0 || status == EINTR, status, "cond_wait"); 5481241170Sadrian } 5482241170Sadrian --_nParked; 5483241170Sadrian _Event = 0; 5484241170Sadrian status = os::Solaris::mutex_unlock(_mutex); 5485241170Sadrian assert_status(status == 0, status, "mutex_unlock"); 5486241170Sadrian // Paranoia to ensure our locked and lock-free paths interact 5487241170Sadrian // correctly with each other. 5488241170Sadrian OrderAccess::fence(); 5489241170Sadrian } 5490241170Sadrian} 5491241170Sadrian 5492241170Sadrianint os::PlatformEvent::park(jlong millis) { 5493241170Sadrian guarantee(_nParked == 0, "invariant"); 5494241170Sadrian int v; 5495241170Sadrian for (;;) { 5496241170Sadrian v = _Event; 5497241170Sadrian if (Atomic::cmpxchg(v-1, &_Event, v) == v) break; 5498241170Sadrian } 5499241170Sadrian guarantee(v >= 0, "invariant"); 5500241170Sadrian if (v != 0) return OS_OK; 5501241170Sadrian 5502241170Sadrian int ret = OS_TIMEOUT; 5503241170Sadrian timestruc_t abst; 5504241170Sadrian compute_abstime(&abst, millis); 5505241170Sadrian 5506241170Sadrian // See http://monaco.sfbay/detail.jsf?cr=5094058. 5507241170Sadrian // For Solaris SPARC set fprs.FEF=0 prior to parking. 5508241170Sadrian // Only for SPARC >= V8PlusA 5509241170Sadrian#if defined(__sparc) && defined(COMPILER2) 5510241170Sadrian if (ClearFPUAtPark) { _mark_fpu_nosave(); } 5511241170Sadrian#endif 5512241170Sadrian int status = os::Solaris::mutex_lock(_mutex); 5513241170Sadrian assert_status(status == 0, status, "mutex_lock"); 5514241170Sadrian guarantee(_nParked == 0, "invariant"); 5515243786Sadrian ++_nParked; 5516241170Sadrian while (_Event < 0) { 5517241170Sadrian int status = os::Solaris::cond_timedwait(_cond, _mutex, &abst); 5518241170Sadrian assert_status(status == 0 || status == EINTR || 5519241170Sadrian status == ETIME || status == ETIMEDOUT, 5520241170Sadrian status, "cond_timedwait"); 5521241170Sadrian if (!FilterSpuriousWakeups) break; // previous semantics 5522243786Sadrian if (status == ETIME || status == ETIMEDOUT) break; 5523241170Sadrian // We consume and ignore EINTR and spurious wakeups. 5524241170Sadrian } 5525241170Sadrian --_nParked; 5526238710Sadrian if (_Event >= 0) ret = OS_OK; 5527238710Sadrian _Event = 0; 5528238710Sadrian status = os::Solaris::mutex_unlock(_mutex); 5529238710Sadrian assert_status(status == 0, status, "mutex_unlock"); 5530238710Sadrian // Paranoia to ensure our locked and lock-free paths interact 5531238710Sadrian // correctly with each other. 5532238710Sadrian OrderAccess::fence(); 5533238710Sadrian return ret; 5534238710Sadrian} 5535238710Sadrian 5536238710Sadrianvoid os::PlatformEvent::unpark() { 5537238710Sadrian // Transitions for _Event: 5538238710Sadrian // 0 :=> 1 5539238710Sadrian // 1 :=> 1 5540238710Sadrian // -1 :=> either 0 or 1; must signal target thread 5541238710Sadrian // That is, we can safely transition _Event from -1 to either 5542238710Sadrian // 0 or 1. Forcing 1 is slightly more efficient for back-to-back 5543238710Sadrian // unpark() calls. 5544238729Sadrian // See also: "Semaphores in Plan 9" by Mullender & Cox 5545238729Sadrian // 5546238729Sadrian // Note: Forcing a transition from "-1" to "1" on an unpark() means 5547238729Sadrian // that it will take two back-to-back park() calls for the owning 5548238729Sadrian // thread to block. This has the benefit of forcing a spurious return 5549243162Sadrian // from the first park() call after an unpark() call which will help 5550238729Sadrian // shake out uses of park() and unpark() without condition variables. 5551238710Sadrian 5552238710Sadrian if (Atomic::xchg(1, &_Event) >= 0) return; 5553238710Sadrian 5554238931Sadrian // If the thread associated with the event was parked, wake it. 5555238930Sadrian // Wait for the thread assoc with the PlatformEvent to vacate. 5556238930Sadrian int status = os::Solaris::mutex_lock(_mutex); 5557238930Sadrian assert_status(status == 0, status, "mutex_lock"); 5558239204Sadrian int AnyWaiters = _nParked; 5559239204Sadrian status = os::Solaris::mutex_unlock(_mutex); 5560238710Sadrian assert_status(status == 0, status, "mutex_unlock"); 5561 guarantee(AnyWaiters == 0 || AnyWaiters == 1, "invariant"); 5562 if (AnyWaiters != 0) { 5563 // We intentional signal *after* dropping the lock 5564 // to avoid a common class of futile wakeups. 5565 status = os::Solaris::cond_signal(_cond); 5566 assert_status(status == 0, status, "cond_signal"); 5567 } 5568} 5569 5570// JSR166 5571// ------------------------------------------------------- 5572 5573/* 5574 * The solaris and linux implementations of park/unpark are fairly 5575 * conservative for now, but can be improved. They currently use a 5576 * mutex/condvar pair, plus _counter. 5577 * Park decrements _counter if > 0, else does a condvar wait. Unpark 5578 * sets count to 1 and signals condvar. Only one thread ever waits 5579 * on the condvar. Contention seen when trying to park implies that someone 5580 * is unparking you, so don't wait. And spurious returns are fine, so there 5581 * is no need to track notifications. 5582 */ 5583 5584#define MAX_SECS 100000000 5585/* 5586 * This code is common to linux and solaris and will be moved to a 5587 * common place in dolphin. 5588 * 5589 * The passed in time value is either a relative time in nanoseconds 5590 * or an absolute time in milliseconds. Either way it has to be unpacked 5591 * into suitable seconds and nanoseconds components and stored in the 5592 * given timespec structure. 5593 * Given time is a 64-bit value and the time_t used in the timespec is only 5594 * a signed-32-bit value (except on 64-bit Linux) we have to watch for 5595 * overflow if times way in the future are given. Further on Solaris versions 5596 * prior to 10 there is a restriction (see cond_timedwait) that the specified 5597 * number of seconds, in abstime, is less than current_time + 100,000,000. 5598 * As it will be 28 years before "now + 100000000" will overflow we can 5599 * ignore overflow and just impose a hard-limit on seconds using the value 5600 * of "now + 100,000,000". This places a limit on the timeout of about 3.17 5601 * years from "now". 5602 */ 5603static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) { 5604 assert(time > 0, "convertTime"); 5605 5606 struct timeval now; 5607 int status = gettimeofday(&now, NULL); 5608 assert(status == 0, "gettimeofday"); 5609 5610 time_t max_secs = now.tv_sec + MAX_SECS; 5611 5612 if (isAbsolute) { 5613 jlong secs = time / 1000; 5614 if (secs > max_secs) { 5615 absTime->tv_sec = max_secs; 5616 } 5617 else { 5618 absTime->tv_sec = secs; 5619 } 5620 absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC; 5621 } 5622 else { 5623 jlong secs = time / NANOSECS_PER_SEC; 5624 if (secs >= MAX_SECS) { 5625 absTime->tv_sec = max_secs; 5626 absTime->tv_nsec = 0; 5627 } 5628 else { 5629 absTime->tv_sec = now.tv_sec + secs; 5630 absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000; 5631 if (absTime->tv_nsec >= NANOSECS_PER_SEC) { 5632 absTime->tv_nsec -= NANOSECS_PER_SEC; 5633 ++absTime->tv_sec; // note: this must be <= max_secs 5634 } 5635 } 5636 } 5637 assert(absTime->tv_sec >= 0, "tv_sec < 0"); 5638 assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs"); 5639 assert(absTime->tv_nsec >= 0, "tv_nsec < 0"); 5640 assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec"); 5641} 5642 5643void Parker::park(bool isAbsolute, jlong time) { 5644 // Ideally we'd do something useful while spinning, such 5645 // as calling unpackTime(). 5646 5647 // Optional fast-path check: 5648 // Return immediately if a permit is available. 5649 // We depend on Atomic::xchg() having full barrier semantics 5650 // since we are doing a lock-free update to _counter. 5651 if (Atomic::xchg(0, &_counter) > 0) return; 5652 5653 // Optional fast-exit: Check interrupt before trying to wait 5654 Thread* thread = Thread::current(); 5655 assert(thread->is_Java_thread(), "Must be JavaThread"); 5656 JavaThread *jt = (JavaThread *)thread; 5657 if (Thread::is_interrupted(thread, false)) { 5658 return; 5659 } 5660 5661 // First, demultiplex/decode time arguments 5662 timespec absTime; 5663 if (time < 0 || (isAbsolute && time == 0)) { // don't wait at all 5664 return; 5665 } 5666 if (time > 0) { 5667 // Warning: this code might be exposed to the old Solaris time 5668 // round-down bugs. Grep "roundingFix" for details. 5669 unpackTime(&absTime, isAbsolute, time); 5670 } 5671 5672 // Enter safepoint region 5673 // Beware of deadlocks such as 6317397. 5674 // The per-thread Parker:: _mutex is a classic leaf-lock. 5675 // In particular a thread must never block on the Threads_lock while 5676 // holding the Parker:: mutex. If safepoints are pending both the 5677 // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock. 5678 ThreadBlockInVM tbivm(jt); 5679 5680 // Don't wait if cannot get lock since interference arises from 5681 // unblocking. Also. check interrupt before trying wait 5682 if (Thread::is_interrupted(thread, false) || 5683 os::Solaris::mutex_trylock(_mutex) != 0) { 5684 return; 5685 } 5686 5687 int status; 5688 5689 if (_counter > 0) { // no wait needed 5690 _counter = 0; 5691 status = os::Solaris::mutex_unlock(_mutex); 5692 assert(status == 0, "invariant"); 5693 // Paranoia to ensure our locked and lock-free paths interact 5694 // correctly with each other and Java-level accesses. 5695 OrderAccess::fence(); 5696 return; 5697 } 5698 5699#ifdef ASSERT 5700 // Don't catch signals while blocked; let the running threads have the signals. 5701 // (This allows a debugger to break into the running thread.) 5702 sigset_t oldsigs; 5703 sigset_t* allowdebug_blocked = os::Solaris::allowdebug_blocked_signals(); 5704 thr_sigsetmask(SIG_BLOCK, allowdebug_blocked, &oldsigs); 5705#endif 5706 5707 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */); 5708 jt->set_suspend_equivalent(); 5709 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self() 5710 5711 // Do this the hard way by blocking ... 5712 // See http://monaco.sfbay/detail.jsf?cr=5094058. 5713 // TODO-FIXME: for Solaris SPARC set fprs.FEF=0 prior to parking. 5714 // Only for SPARC >= V8PlusA 5715#if defined(__sparc) && defined(COMPILER2) 5716 if (ClearFPUAtPark) { _mark_fpu_nosave(); } 5717#endif 5718 5719 if (time == 0) { 5720 status = os::Solaris::cond_wait(_cond, _mutex); 5721 } else { 5722 status = os::Solaris::cond_timedwait (_cond, _mutex, &absTime); 5723 } 5724 // Note that an untimed cond_wait() can sometimes return ETIME on older 5725 // versions of the Solaris. 5726 assert_status(status == 0 || status == EINTR || 5727 status == ETIME || status == ETIMEDOUT, 5728 status, "cond_timedwait"); 5729 5730#ifdef ASSERT 5731 thr_sigsetmask(SIG_SETMASK, &oldsigs, NULL); 5732#endif 5733 _counter = 0; 5734 status = os::Solaris::mutex_unlock(_mutex); 5735 assert_status(status == 0, status, "mutex_unlock"); 5736 // Paranoia to ensure our locked and lock-free paths interact 5737 // correctly with each other and Java-level accesses. 5738 OrderAccess::fence(); 5739 5740 // If externally suspended while waiting, re-suspend 5741 if (jt->handle_special_suspend_equivalent_condition()) { 5742 jt->java_suspend_self(); 5743 } 5744} 5745 5746void Parker::unpark() { 5747 int s, status; 5748 status = os::Solaris::mutex_lock(_mutex); 5749 assert(status == 0, "invariant"); 5750 s = _counter; 5751 _counter = 1; 5752 status = os::Solaris::mutex_unlock(_mutex); 5753 assert(status == 0, "invariant"); 5754 5755 if (s < 1) { 5756 status = os::Solaris::cond_signal(_cond); 5757 assert(status == 0, "invariant"); 5758 } 5759} 5760 5761extern char** environ; 5762 5763// Run the specified command in a separate process. Return its exit value, 5764// or -1 on failure (e.g. can't fork a new process). 5765// Unlike system(), this function can be called from signal handler. It 5766// doesn't block SIGINT et al. 5767int os::fork_and_exec(char* cmd) { 5768 char * argv[4]; 5769 argv[0] = (char *)"sh"; 5770 argv[1] = (char *)"-c"; 5771 argv[2] = cmd; 5772 argv[3] = NULL; 5773 5774 // fork is async-safe, fork1 is not so can't use in signal handler 5775 pid_t pid; 5776 Thread* t = ThreadLocalStorage::get_thread_slow(); 5777 if (t != NULL && t->is_inside_signal_handler()) { 5778 pid = fork(); 5779 } else { 5780 pid = fork1(); 5781 } 5782 5783 if (pid < 0) { 5784 // fork failed 5785 warning("fork failed: %s", strerror(errno)); 5786 return -1; 5787 5788 } else if (pid == 0) { 5789 // child process 5790 5791 // try to be consistent with system(), which uses "/usr/bin/sh" on Solaris 5792 execve("/usr/bin/sh", argv, environ); 5793 5794 // execve failed 5795 _exit(-1); 5796 5797 } else { 5798 // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't 5799 // care about the actual exit code, for now. 5800 5801 int status; 5802 5803 // Wait for the child process to exit. This returns immediately if 5804 // the child has already exited. */ 5805 while (waitpid(pid, &status, 0) < 0) { 5806 switch (errno) { 5807 case ECHILD: return 0; 5808 case EINTR: break; 5809 default: return -1; 5810 } 5811 } 5812 5813 if (WIFEXITED(status)) { 5814 // The child exited normally; get its exit code. 5815 return WEXITSTATUS(status); 5816 } else if (WIFSIGNALED(status)) { 5817 // The child exited because of a signal 5818 // The best value to return is 0x80 + signal number, 5819 // because that is what all Unix shells do, and because 5820 // it allows callers to distinguish between process exit and 5821 // process death by signal. 5822 return 0x80 + WTERMSIG(status); 5823 } else { 5824 // Unknown exit code; pass it through 5825 return status; 5826 } 5827 } 5828} 5829 5830// is_headless_jre() 5831// 5832// Test for the existence of xawt/libmawt.so or libawt_xawt.so 5833// in order to report if we are running in a headless jre 5834// 5835// Since JDK8 xawt/libmawt.so was moved into the same directory 5836// as libawt.so, and renamed libawt_xawt.so 5837// 5838bool os::is_headless_jre() { 5839 struct stat statbuf; 5840 char buf[MAXPATHLEN]; 5841 char libmawtpath[MAXPATHLEN]; 5842 const char *xawtstr = "/xawt/libmawt.so"; 5843 const char *new_xawtstr = "/libawt_xawt.so"; 5844 char *p; 5845 5846 // Get path to libjvm.so 5847 os::jvm_path(buf, sizeof(buf)); 5848 5849 // Get rid of libjvm.so 5850 p = strrchr(buf, '/'); 5851 if (p == NULL) return false; 5852 else *p = '\0'; 5853 5854 // Get rid of client or server 5855 p = strrchr(buf, '/'); 5856 if (p == NULL) return false; 5857 else *p = '\0'; 5858 5859 // check xawt/libmawt.so 5860 strcpy(libmawtpath, buf); 5861 strcat(libmawtpath, xawtstr); 5862 if (::stat(libmawtpath, &statbuf) == 0) return false; 5863 5864 // check libawt_xawt.so 5865 strcpy(libmawtpath, buf); 5866 strcat(libmawtpath, new_xawtstr); 5867 if (::stat(libmawtpath, &statbuf) == 0) return false; 5868 5869 return true; 5870} 5871 5872size_t os::write(int fd, const void *buf, unsigned int nBytes) { 5873 size_t res; 5874 assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, 5875 "Assumed _thread_in_native"); 5876 RESTARTABLE((size_t) ::write(fd, buf, (size_t) nBytes), res); 5877 return res; 5878} 5879 5880int os::close(int fd) { 5881 return ::close(fd); 5882} 5883 5884int os::socket_close(int fd) { 5885 return ::close(fd); 5886} 5887 5888int os::recv(int fd, char* buf, size_t nBytes, uint flags) { 5889 assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, 5890 "Assumed _thread_in_native"); 5891 RESTARTABLE_RETURN_INT((int)::recv(fd, buf, nBytes, flags)); 5892} 5893 5894int os::send(int fd, char* buf, size_t nBytes, uint flags) { 5895 assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, 5896 "Assumed _thread_in_native"); 5897 RESTARTABLE_RETURN_INT((int)::send(fd, buf, nBytes, flags)); 5898} 5899 5900int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) { 5901 RESTARTABLE_RETURN_INT((int)::send(fd, buf, nBytes, flags)); 5902} 5903 5904// As both poll and select can be interrupted by signals, we have to be 5905// prepared to restart the system call after updating the timeout, unless 5906// a poll() is done with timeout == -1, in which case we repeat with this 5907// "wait forever" value. 5908 5909int os::timeout(int fd, long timeout) { 5910 int res; 5911 struct timeval t; 5912 julong prevtime, newtime; 5913 static const char* aNull = 0; 5914 struct pollfd pfd; 5915 pfd.fd = fd; 5916 pfd.events = POLLIN; 5917 5918 assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, 5919 "Assumed _thread_in_native"); 5920 5921 gettimeofday(&t, &aNull); 5922 prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000; 5923 5924 for (;;) { 5925 res = ::poll(&pfd, 1, timeout); 5926 if (res == OS_ERR && errno == EINTR) { 5927 if (timeout != -1) { 5928 gettimeofday(&t, &aNull); 5929 newtime = ((julong)t.tv_sec * 1000) + t.tv_usec /1000; 5930 timeout -= newtime - prevtime; 5931 if (timeout <= 0) 5932 return OS_OK; 5933 prevtime = newtime; 5934 } 5935 } else return res; 5936 } 5937} 5938 5939int os::connect(int fd, struct sockaddr *him, socklen_t len) { 5940 int _result; 5941 _result = ::connect(fd, him, len); 5942 5943 // On Solaris, when a connect() call is interrupted, the connection 5944 // can be established asynchronously (see 6343810). Subsequent calls 5945 // to connect() must check the errno value which has the semantic 5946 // described below (copied from the connect() man page). Handling 5947 // of asynchronously established connections is required for both 5948 // blocking and non-blocking sockets. 5949 // EINTR The connection attempt was interrupted 5950 // before any data arrived by the delivery of 5951 // a signal. The connection, however, will be 5952 // established asynchronously. 5953 // 5954 // EINPROGRESS The socket is non-blocking, and the connec- 5955 // tion cannot be completed immediately. 5956 // 5957 // EALREADY The socket is non-blocking, and a previous 5958 // connection attempt has not yet been com- 5959 // pleted. 5960 // 5961 // EISCONN The socket is already connected. 5962 if (_result == OS_ERR && errno == EINTR) { 5963 /* restarting a connect() changes its errno semantics */ 5964 RESTARTABLE(::connect(fd, him, len), _result); 5965 /* undo these changes */ 5966 if (_result == OS_ERR) { 5967 if (errno == EALREADY) { 5968 errno = EINPROGRESS; /* fall through */ 5969 } else if (errno == EISCONN) { 5970 errno = 0; 5971 return OS_OK; 5972 } 5973 } 5974 } 5975 return _result; 5976 } 5977 5978int os::accept(int fd, struct sockaddr* him, socklen_t* len) { 5979 if (fd < 0) { 5980 return OS_ERR; 5981 } 5982 assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, 5983 "Assumed _thread_in_native"); 5984 RESTARTABLE_RETURN_INT((int)::accept(fd, him, len)); 5985} 5986 5987int os::recvfrom(int fd, char* buf, size_t nBytes, uint flags, 5988 sockaddr* from, socklen_t* fromlen) { 5989 assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, 5990 "Assumed _thread_in_native"); 5991 RESTARTABLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes, flags, from, fromlen)); 5992} 5993 5994int os::sendto(int fd, char* buf, size_t len, uint flags, 5995 struct sockaddr* to, socklen_t tolen) { 5996 assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, 5997 "Assumed _thread_in_native"); 5998 RESTARTABLE_RETURN_INT((int)::sendto(fd, buf, len, flags, to, tolen)); 5999} 6000 6001int os::socket_available(int fd, jint *pbytes) { 6002 if (fd < 0) { 6003 return OS_OK; 6004 } 6005 int ret; 6006 RESTARTABLE(::ioctl(fd, FIONREAD, pbytes), ret); 6007 // note: ioctl can return 0 when successful, JVM_SocketAvailable 6008 // is expected to return 0 on failure and 1 on success to the jdk. 6009 return (ret == OS_ERR) ? 0 : 1; 6010} 6011 6012int os::bind(int fd, struct sockaddr* him, socklen_t len) { 6013 assert(((JavaThread*)Thread::current())->thread_state() == _thread_in_native, 6014 "Assumed _thread_in_native"); 6015 return ::bind(fd, him, len); 6016} 6017 6018// Get the default path to the core file 6019// Returns the length of the string 6020int os::get_core_path(char* buffer, size_t bufferSize) { 6021 const char* p = get_current_directory(buffer, bufferSize); 6022 6023 if (p == NULL) { 6024 assert(p != NULL, "failed to get current directory"); 6025 return 0; 6026 } 6027 6028 return strlen(buffer); 6029} 6030 6031#ifndef PRODUCT 6032void TestReserveMemorySpecial_test() { 6033 // No tests available for this platform 6034} 6035#endif 6036