os_solaris.cpp revision 79:82db0859acbe
154359Sroberto/*
254359Sroberto * Copyright 1997-2007 Sun Microsystems, Inc.  All Rights Reserved.
354359Sroberto * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
454359Sroberto *
554359Sroberto * This code is free software; you can redistribute it and/or modify it
654359Sroberto * under the terms of the GNU General Public License version 2 only, as
754359Sroberto * published by the Free Software Foundation.
854359Sroberto *
954359Sroberto * This code is distributed in the hope that it will be useful, but WITHOUT
1054359Sroberto * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
1154359Sroberto * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12132451Sroberto * version 2 for more details (a copy is included in the LICENSE file that
13132451Sroberto * accompanied this code).
14132451Sroberto *
1582498Sroberto * You should have received a copy of the GNU General Public License version
1654359Sroberto * 2 along with this work; if not, write to the Free Software Foundation,
1754359Sroberto * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
1854359Sroberto *
1954359Sroberto * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
2054359Sroberto * CA 95054 USA or visit www.sun.com if you need additional information or
2154359Sroberto * have any questions.
2254359Sroberto *
2354359Sroberto */
2454359Sroberto
2554359Sroberto// do not include  precompiled  header file
2654359Sroberto# include "incls/_os_solaris.cpp.incl"
2754359Sroberto
2854359Sroberto// put OS-includes here
2954359Sroberto# include <dlfcn.h>
3054359Sroberto# include <errno.h>
3182498Sroberto# include <link.h>
32132451Sroberto# include <poll.h>
33132451Sroberto# include <pthread.h>
34132451Sroberto# include <pwd.h>
35132451Sroberto# include <schedctl.h>
36132451Sroberto# include <setjmp.h>
37132451Sroberto# include <signal.h>
3882498Sroberto# include <stdio.h>
39132451Sroberto# include <alloca.h>
40132451Sroberto# include <sys/filio.h>
41132451Sroberto# include <sys/ipc.h>
4282498Sroberto# include <sys/lwp.h>
43182007Sroberto# include <sys/machelf.h>     // for elf Sym structure used by dladdr1
44182007Sroberto# include <sys/mman.h>
45182007Sroberto# include <sys/processor.h>
46182007Sroberto# include <sys/procset.h>
47182007Sroberto# include <sys/pset.h>
48182007Sroberto# include <sys/resource.h>
49182007Sroberto# include <sys/shm.h>
50182007Sroberto# include <sys/socket.h>
51182007Sroberto# include <sys/stat.h>
52182007Sroberto# include <sys/systeminfo.h>
53182007Sroberto# include <sys/time.h>
5454359Sroberto# include <sys/times.h>
55182007Sroberto# include <sys/types.h>
56182007Sroberto# include <sys/wait.h>
57182007Sroberto# include <sys/utsname.h>
58182007Sroberto# include <thread.h>
59182007Sroberto# include <unistd.h>
60182007Sroberto# include <sys/priocntl.h>
61182007Sroberto# include <sys/rtpriocntl.h>
62182007Sroberto# include <sys/tspriocntl.h>
63182007Sroberto# include <sys/iapriocntl.h>
64182007Sroberto# include <sys/loadavg.h>
65182007Sroberto# include <string.h>
66182007Sroberto
67182007Sroberto# define _STRUCTURED_PROC 1  //  this gets us the new structured proc interfaces of 5.6 & later
68182007Sroberto# include <sys/procfs.h>     //  see comment in <sys/procfs.h>
69182007Sroberto
70182007Sroberto#define MAX_PATH (2 * K)
71182007Sroberto
72182007Sroberto// for timer info max values which include all bits
7354359Sroberto#define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
7482498Sroberto
7582498Sroberto#ifdef _GNU_SOURCE
7654359Sroberto// See bug #6514594
7754359Srobertoextern "C" int madvise(caddr_t, size_t, int);
7882498Srobertoextern "C"  int memcntl(caddr_t addr, size_t len, int cmd, caddr_t  arg,
7982498Sroberto     int attr, int mask);
8054359Sroberto#endif //_GNU_SOURCE
8154359Sroberto
8254359Sroberto/*
8382498Sroberto  MPSS Changes Start.
8482498Sroberto  The JVM binary needs to be built and run on pre-Solaris 9
8582498Sroberto  systems, but the constants needed by MPSS are only in Solaris 9
8682498Sroberto  header files.  They are textually replicated here to allow
8754359Sroberto  building on earlier systems.  Once building on Solaris 8 is
8854359Sroberto  no longer a requirement, these #defines can be replaced by ordinary
8954359Sroberto  system .h inclusion.
9054359Sroberto
9154359Sroberto  In earlier versions of the  JDK and Solaris, we used ISM for large pages.
9254359Sroberto  But ISM requires shared memory to achieve this and thus has many caveats.
9382498Sroberto  MPSS is a fully transparent and is a cleaner way to get large pages.
9454359Sroberto  Although we still require keeping ISM for backward compatiblitiy as well as
9554359Sroberto  giving the opportunity to use large pages on older systems it is
9654359Sroberto  recommended that MPSS be used for Solaris 9 and above.
9754359Sroberto
9854359Sroberto*/
9954359Sroberto
10054359Sroberto#ifndef MC_HAT_ADVISE
10154359Sroberto
10254359Srobertostruct memcntl_mha {
10356746Sroberto  uint_t          mha_cmd;        /* command(s) */
10456746Sroberto  uint_t          mha_flags;
10556746Sroberto  size_t          mha_pagesize;
10682498Sroberto};
10756746Sroberto#define MC_HAT_ADVISE   7       /* advise hat map size */
10882498Sroberto#define MHA_MAPSIZE_VA  0x1     /* set preferred page size */
10982498Sroberto#define MAP_ALIGN       0x200   /* addr specifies alignment */
11056746Sroberto
11156746Sroberto#endif
11254359Sroberto// MPSS Changes End.
11354359Sroberto
11454359Sroberto
11554359Sroberto// Here are some liblgrp types from sys/lgrp_user.h to be able to
116182007Sroberto// compile on older systems without this header file.
11754359Sroberto
11882498Sroberto#ifndef MADV_ACCESS_LWP
11982498Sroberto# define  MADV_ACCESS_LWP         7       /* next LWP to access heavily */
12082498Sroberto#endif
12182498Sroberto#ifndef MADV_ACCESS_MANY
12282498Sroberto# define  MADV_ACCESS_MANY        8       /* many processes to access heavily */
12382498Sroberto#endif
12454359Sroberto
12554359Sroberto// Some more macros from sys/mman.h that are not present in Solaris 8.
12654359Sroberto
12756746Sroberto#ifndef MAX_MEMINFO_CNT
12856746Sroberto/*
12956746Sroberto * info_req request type definitions for meminfo
13056746Sroberto * request types starting with MEMINFO_V are used for Virtual addresses
13156746Sroberto * and should not be mixed with MEMINFO_PLGRP which is targeted for Physical
132182007Sroberto * addresses
13356746Sroberto */
13456746Sroberto# define MEMINFO_SHIFT           16
13554359Sroberto# define MEMINFO_MASK            (0xFF << MEMINFO_SHIFT)
13654359Sroberto# define MEMINFO_VPHYSICAL       (0x01 << MEMINFO_SHIFT) /* get physical addr */
137182007Sroberto# define MEMINFO_VLGRP           (0x02 << MEMINFO_SHIFT) /* get lgroup */
13854359Sroberto# define MEMINFO_VPAGESIZE       (0x03 << MEMINFO_SHIFT) /* size of phys page */
13954359Sroberto# define MEMINFO_VREPLCNT        (0x04 << MEMINFO_SHIFT) /* no. of replica */
14056746Sroberto# define MEMINFO_VREPL           (0x05 << MEMINFO_SHIFT) /* physical replica */
14156746Sroberto# define MEMINFO_VREPL_LGRP      (0x06 << MEMINFO_SHIFT) /* lgrp of replica */
14256746Sroberto# define MEMINFO_PLGRP           (0x07 << MEMINFO_SHIFT) /* lgroup for paddr */
14356746Sroberto
14454359Sroberto/* maximum number of addresses meminfo() can process at a time */
14554359Sroberto# define MAX_MEMINFO_CNT 256
146132451Sroberto
147132451Sroberto/* maximum number of request types */
148132451Sroberto# define MAX_MEMINFO_REQ 31
14954359Sroberto#endif
15054359Sroberto
15182498Sroberto// see thr_setprio(3T) for the basis of these numbers
15254359Sroberto#define MinimumPriority 0
15354359Sroberto#define NormalPriority  64
15454359Sroberto#define MaximumPriority 127
15554359Sroberto
15654359Sroberto// Values for ThreadPriorityPolicy == 1
15754359Srobertoint prio_policy1[MaxPriority+1] = { -99999, 0, 16, 32, 48, 64,
15882498Sroberto                                        80, 96, 112, 124, 127 };
15954359Sroberto
16054359Sroberto// System parameters used internally
16154359Srobertostatic clock_t clock_tics_per_sec = 100;
16254359Sroberto
16354359Sroberto// For diagnostics to print a message once. see run_periodic_checks
164132451Srobertostatic bool check_addr0_done = false;
165132451Srobertostatic sigset_t check_signal_done;
166132451Srobertostatic bool check_signals = true;
167132451Sroberto
168132451Srobertoaddress os::Solaris::handler_start;  // start pc of thr_sighndlrinfo
169132451Srobertoaddress os::Solaris::handler_end;    // end pc of thr_sighndlrinfo
170132451Sroberto
171132451Srobertoaddress os::Solaris::_main_stack_base = NULL;  // 4352906 workaround
17282498Sroberto
17382498Sroberto
17482498Sroberto// "default" initializers for missing libc APIs
17582498Srobertoextern "C" {
17682498Sroberto  static int lwp_mutex_init(mutex_t *mx, int scope, void *arg) { memset(mx, 0, sizeof(mutex_t)); return 0; }
17782498Sroberto  static int lwp_mutex_destroy(mutex_t *mx)                 { return 0; }
17882498Sroberto
17982498Sroberto  static int lwp_cond_init(cond_t *cv, int scope, void *arg){ memset(cv, 0, sizeof(cond_t)); return 0; }
18082498Sroberto  static int lwp_cond_destroy(cond_t *cv)                   { return 0; }
18182498Sroberto}
18282498Sroberto
18382498Sroberto// "default" initializers for pthread-based synchronization
18482498Srobertoextern "C" {
18582498Sroberto  static int pthread_mutex_default_init(mutex_t *mx, int scope, void *arg) { memset(mx, 0, sizeof(mutex_t)); return 0; }
18682498Sroberto  static int pthread_cond_default_init(cond_t *cv, int scope, void *arg){ memset(cv, 0, sizeof(cond_t)); return 0; }
18782498Sroberto}
18882498Sroberto
18982498Sroberto// Thread Local Storage
19082498Sroberto// This is common to all Solaris platforms so it is defined here,
19182498Sroberto// in this common file.
19282498Sroberto// The declarations are in the os_cpu threadLS*.hpp files.
19382498Sroberto//
19482498Sroberto// Static member initialization for TLS
19582498SrobertoThread* ThreadLocalStorage::_get_thread_cache[ThreadLocalStorage::_pd_cache_size] = {NULL};
19682498Sroberto
19782498Sroberto#ifndef PRODUCT
19882498Sroberto#define _PCT(n,d)       ((100.0*(double)(n))/(double)(d))
19982498Sroberto
20082498Srobertoint ThreadLocalStorage::_tcacheHit = 0;
20182498Srobertoint ThreadLocalStorage::_tcacheMiss = 0;
20282498Sroberto
20382498Srobertovoid ThreadLocalStorage::print_statistics() {
20482498Sroberto  int total = _tcacheMiss+_tcacheHit;
20582498Sroberto  tty->print_cr("Thread cache hits %d misses %d total %d percent %f\n",
20682498Sroberto                _tcacheHit, _tcacheMiss, total, _PCT(_tcacheHit, total));
20782498Sroberto}
20882498Sroberto#undef _PCT
20982498Sroberto#endif // PRODUCT
21082498Sroberto
21182498SrobertoThread* ThreadLocalStorage::get_thread_via_cache_slowly(uintptr_t raw_id,
21282498Sroberto                                                        int index) {
21382498Sroberto  Thread *thread = get_thread_slow();
21482498Sroberto  if (thread != NULL) {
21554359Sroberto    address sp = os::current_stack_pointer();
21654359Sroberto    guarantee(thread->_stack_base == NULL ||
21782498Sroberto              (sp <= thread->_stack_base &&
21882498Sroberto                 sp >= thread->_stack_base - thread->_stack_size) ||
21982498Sroberto               is_error_reported(),
22054359Sroberto              "sp must be inside of selected thread stack");
22154359Sroberto
222132451Sroberto    thread->_self_raw_id = raw_id;  // mark for quick retrieval
22354359Sroberto    _get_thread_cache[ index ] = thread;
22454359Sroberto  }
22554359Sroberto  return thread;
22682498Sroberto}
22754359Sroberto
228132451Sroberto
22954359Srobertostatic const double all_zero[ sizeof(Thread) / sizeof(double) + 1 ] = {0};
23054359Sroberto#define NO_CACHED_THREAD ((Thread*)all_zero)
23154359Sroberto
23282498Srobertovoid ThreadLocalStorage::pd_set_thread(Thread* thread) {
23354359Sroberto
23454359Sroberto  // Store the new value before updating the cache to prevent a race
23582498Sroberto  // between get_thread_via_cache_slowly() and this store operation.
23682498Sroberto  os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
23782498Sroberto
23882498Sroberto  // Update thread cache with new thread if setting on thread create,
23982498Sroberto  // or NO_CACHED_THREAD (zeroed) thread if resetting thread on exit.
24082498Sroberto  uintptr_t raw = pd_raw_thread_id();
24182498Sroberto  int ix = pd_cache_index(raw);
24282498Sroberto  _get_thread_cache[ix] = thread == NULL ? NO_CACHED_THREAD : thread;
243132451Sroberto}
244132451Sroberto
24582498Srobertovoid ThreadLocalStorage::pd_init() {
24654359Sroberto  for (int i = 0; i < _pd_cache_size; i++) {
24754359Sroberto    _get_thread_cache[i] = NO_CACHED_THREAD;
24854359Sroberto  }
24982498Sroberto}
25054359Sroberto
25182498Sroberto// Invalidate all the caches (happens to be the same as pd_init).
25254359Srobertovoid ThreadLocalStorage::pd_invalidate_all() { pd_init(); }
25382498Sroberto
25482498Sroberto#undef NO_CACHED_THREAD
25582498Sroberto
25682498Sroberto// END Thread Local Storage
25782498Sroberto
258182007Srobertostatic inline size_t adjust_stack_size(address base, size_t size) {
259132451Sroberto  if ((ssize_t)size < 0) {
26082498Sroberto    // 4759953: Compensate for ridiculous stack size.
261132451Sroberto    size = max_intx;
262132451Sroberto  }
263132451Sroberto  if (size > (size_t)base) {
264132451Sroberto    // 4812466: Make sure size doesn't allow the stack to wrap the address space.
265132451Sroberto    size = (size_t)base;
266182007Sroberto  }
267182007Sroberto  return size;
268132451Sroberto}
269132451Sroberto
27082498Srobertostatic inline stack_t get_stack_info() {
27182498Sroberto  stack_t st;
27282498Sroberto  int retval = thr_stksegment(&st);
27382498Sroberto  st.ss_size = adjust_stack_size((address)st.ss_sp, st.ss_size);
274132451Sroberto  assert(retval == 0, "incorrect return value from thr_stksegment");
27554359Sroberto  assert((address)&st < (address)st.ss_sp, "Invalid stack base returned");
27654359Sroberto  assert((address)&st > (address)st.ss_sp-st.ss_size, "Invalid stack size returned");
277132451Sroberto  return st;
278132451Sroberto}
27954359Sroberto
280132451Srobertoaddress os::current_stack_base() {
281132451Sroberto  int r = thr_main() ;
282132451Sroberto  guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ;
283132451Sroberto  bool is_primordial_thread = r;
284132451Sroberto
28582498Sroberto  // Workaround 4352906, avoid calls to thr_stksegment by
28654359Sroberto  // thr_main after the first one (it looks like we trash
28754359Sroberto  // some data, causing the value for ss_sp to be incorrect).
288132451Sroberto  if (!is_primordial_thread || os::Solaris::_main_stack_base == NULL) {
289132451Sroberto    stack_t st = get_stack_info();
290132451Sroberto    if (is_primordial_thread) {
291182007Sroberto      // cache initial value of stack base
292132451Sroberto      os::Solaris::_main_stack_base = (address)st.ss_sp;
293132451Sroberto    }
294132451Sroberto    return (address)st.ss_sp;
29582498Sroberto  } else {
296132451Sroberto    guarantee(os::Solaris::_main_stack_base != NULL, "Attempt to use null cached stack base");
29754359Sroberto    return os::Solaris::_main_stack_base;
29854359Sroberto  }
29954359Sroberto}
30054359Sroberto
30154359Srobertosize_t os::current_stack_size() {
302132451Sroberto  size_t size;
303132451Sroberto
304132451Sroberto  int r = thr_main() ;
305132451Sroberto  guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ;
306132451Sroberto  if(!r) {
307132451Sroberto    size = get_stack_info().ss_size;
308132451Sroberto  } else {
309132451Sroberto    struct rlimit limits;
310132451Sroberto    getrlimit(RLIMIT_STACK, &limits);
31154359Sroberto    size = adjust_stack_size(os::Solaris::_main_stack_base, (size_t)limits.rlim_cur);
312132451Sroberto  }
313132451Sroberto  // base may not be page aligned
314132451Sroberto  address base = current_stack_base();
315132451Sroberto  address bottom = (address)align_size_up((intptr_t)(base - size), os::vm_page_size());;
316132451Sroberto  return (size_t)(base - bottom);
317132451Sroberto}
318132451Sroberto
319132451Sroberto// interruptible infrastructure
320132451Sroberto
321132451Sroberto// setup_interruptible saves the thread state before going into an
322132451Sroberto// interruptible system call.
323132451Sroberto// The saved state is used to restore the thread to
324132451Sroberto// its former state whether or not an interrupt is received.
325132451Sroberto// Used by classloader os::read
326132451Sroberto// hpi calls skip this layer and stay in _thread_in_native
327132451Sroberto
328132451Srobertovoid os::Solaris::setup_interruptible(JavaThread* thread) {
329132451Sroberto
33082498Sroberto  JavaThreadState thread_state = thread->thread_state();
331132451Sroberto
332132451Sroberto  assert(thread_state != _thread_blocked, "Coming from the wrong thread");
33382498Sroberto  assert(thread_state != _thread_in_native, "Native threads skip setup_interruptible");
33482498Sroberto  OSThread* osthread = thread->osthread();
33582498Sroberto  osthread->set_saved_interrupt_thread_state(thread_state);
33682498Sroberto  thread->frame_anchor()->make_walkable(thread);
33782498Sroberto  ThreadStateTransition::transition(thread, thread_state, _thread_blocked);
338132451Sroberto}
33982498Sroberto
340132451Sroberto// Version of setup_interruptible() for threads that are already in
34182498Sroberto// _thread_blocked. Used by os_sleep().
34282498Srobertovoid os::Solaris::setup_interruptible_already_blocked(JavaThread* thread) {
34382498Sroberto  thread->frame_anchor()->make_walkable(thread);
34482498Sroberto}
34582498Sroberto
34682498SrobertoJavaThread* os::Solaris::setup_interruptible() {
347132451Sroberto  JavaThread* thread = (JavaThread*)ThreadLocalStorage::thread();
348132451Sroberto  setup_interruptible(thread);
34982498Sroberto  return thread;
35082498Sroberto}
35154359Sroberto
35254359Srobertovoid os::Solaris::try_enable_extended_io() {
35354359Sroberto  typedef int (*enable_extended_FILE_stdio_t)(int, int);
35454359Sroberto
35554359Sroberto  if (!UseExtendedFileIO) {
35654359Sroberto    return;
35754359Sroberto  }
358182007Sroberto
35954359Sroberto  enable_extended_FILE_stdio_t enabler =
36054359Sroberto    (enable_extended_FILE_stdio_t) dlsym(RTLD_DEFAULT,
36154359Sroberto                                         "enable_extended_FILE_stdio");
36254359Sroberto  if (enabler) {
36354359Sroberto    enabler(-1, -1);
36482498Sroberto  }
36554359Sroberto}
36654359Sroberto
36756746Sroberto
36854359Sroberto#ifdef ASSERT
36954359Sroberto
37082498SrobertoJavaThread* os::Solaris::setup_interruptible_native() {
37154359Sroberto  JavaThread* thread = (JavaThread*)ThreadLocalStorage::thread();
37256746Sroberto  JavaThreadState thread_state = thread->thread_state();
37354359Sroberto  assert(thread_state == _thread_in_native, "Assumed thread_in_native");
37482498Sroberto  return thread;
37582498Sroberto}
37682498Sroberto
37782498Srobertovoid os::Solaris::cleanup_interruptible_native(JavaThread* thread) {
378132451Sroberto  JavaThreadState thread_state = thread->thread_state();
379132451Sroberto  assert(thread_state == _thread_in_native, "Assumed thread_in_native");
380132451Sroberto}
38182498Sroberto#endif
38282498Sroberto
383132451Sroberto// cleanup_interruptible reverses the effects of setup_interruptible
384132451Sroberto// setup_interruptible_already_blocked() does not need any cleanup.
385132451Sroberto
386132451Srobertovoid os::Solaris::cleanup_interruptible(JavaThread* thread) {
38782498Sroberto  OSThread* osthread = thread->osthread();
38882498Sroberto
38982498Sroberto  ThreadStateTransition::transition(thread, _thread_blocked, osthread->saved_interrupt_thread_state());
39082498Sroberto}
39182498Sroberto
39282498Sroberto// I/O interruption related counters called in _INTERRUPTIBLE
39382498Sroberto
39482498Srobertovoid os::Solaris::bump_interrupted_before_count() {
39582498Sroberto  RuntimeService::record_interrupted_before_count();
396132451Sroberto}
39782498Sroberto
39882498Srobertovoid os::Solaris::bump_interrupted_during_count() {
39982498Sroberto  RuntimeService::record_interrupted_during_count();
40082498Sroberto}
40182498Sroberto
40282498Srobertostatic int _processors_online = 0;
40382498Sroberto
40482498Sroberto         jint os::Solaris::_os_thread_limit = 0;
40582498Srobertovolatile jint os::Solaris::_os_thread_count = 0;
406132451Sroberto
407132451Srobertojulong os::available_memory() {
408132451Sroberto  return Solaris::available_memory();
409182007Sroberto}
410132451Sroberto
41182498Srobertojulong os::Solaris::available_memory() {
41282498Sroberto  return (julong)sysconf(_SC_AVPHYS_PAGES) * os::vm_page_size();
41382498Sroberto}
41482498Sroberto
41554359Srobertojulong os::Solaris::_physical_memory = 0;
41654359Sroberto
41754359Srobertojulong os::physical_memory() {
418132451Sroberto   return Solaris::physical_memory();
419132451Sroberto}
420132451Sroberto
421132451Srobertojulong os::allocatable_physical_memory(julong size) {
422132451Sroberto#ifdef _LP64
423132451Sroberto   return size;
424132451Sroberto#else
425132451Sroberto   julong result = MIN2(size, (julong)3835*M);
426132451Sroberto   if (!is_allocatable(result)) {
427132451Sroberto     // Memory allocations will be aligned but the alignment
428132451Sroberto     // is not known at this point.  Alignments will
429132451Sroberto     // be at most to LargePageSizeInBytes.  Protect
430132451Sroberto     // allocations from alignments up to illegal
431132451Sroberto     // values. If at this point 2G is illegal.
432132451Sroberto     julong reasonable_size = (julong)2*G - 2 * LargePageSizeInBytes;
433132451Sroberto     result =  MIN2(size, reasonable_size);
434132451Sroberto   }
435132451Sroberto   return result;
436132451Sroberto#endif
437132451Sroberto}
438132451Sroberto
439132451Srobertostatic hrtime_t first_hrtime = 0;
440132451Srobertostatic const hrtime_t hrtime_hz = 1000*1000*1000;
441132451Srobertoconst int LOCK_BUSY = 1;
442132451Srobertoconst int LOCK_FREE = 0;
443132451Srobertoconst int LOCK_INVALID = -1;
444132451Srobertostatic volatile hrtime_t max_hrtime = 0;
445132451Srobertostatic volatile int max_hrtime_lock = LOCK_FREE;     // Update counter with LSB as lock-in-progress
446132451Sroberto
447132451Sroberto
448132451Srobertovoid os::Solaris::initialize_system_info() {
449132451Sroberto  _processor_count = sysconf(_SC_NPROCESSORS_CONF);
450182007Sroberto  _processors_online = sysconf (_SC_NPROCESSORS_ONLN);
451182007Sroberto  _physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE);
452132451Sroberto}
453132451Sroberto
454132451Srobertoint os::active_processor_count() {
455132451Sroberto  int online_cpus = sysconf(_SC_NPROCESSORS_ONLN);
456132451Sroberto  pid_t pid = getpid();
457132451Sroberto  psetid_t pset = PS_NONE;
458132451Sroberto  // Are we running in a processor set?
459132451Sroberto  if (pset_bind(PS_QUERY, P_PID, pid, &pset) == 0) {
460182007Sroberto    if (pset != PS_NONE) {
461182007Sroberto      uint_t pset_cpus;
462132451Sroberto      // Query number of cpus in processor set
463132451Sroberto      if (pset_info(pset, NULL, &pset_cpus, NULL) == 0) {
464132451Sroberto        assert(pset_cpus > 0 && pset_cpus <= online_cpus, "sanity check");
465132451Sroberto        _processors_online = pset_cpus;
466132451Sroberto        return pset_cpus;
467132451Sroberto      }
468132451Sroberto    }
469132451Sroberto  }
470132451Sroberto  // Otherwise return number of online cpus
471132451Sroberto  return online_cpus;
472132451Sroberto}
473132451Sroberto
474132451Srobertostatic bool find_processors_in_pset(psetid_t        pset,
475132451Sroberto                                    processorid_t** id_array,
476132451Sroberto                                    uint_t*         id_length) {
477132451Sroberto  bool result = false;
478132451Sroberto  // Find the number of processors in the processor set.
479132451Sroberto  if (pset_info(pset, NULL, id_length, NULL) == 0) {
480132451Sroberto    // Make up an array to hold their ids.
48154359Sroberto    *id_array = NEW_C_HEAP_ARRAY(processorid_t, *id_length);
482132451Sroberto    // Fill in the array with their processor ids.
483132451Sroberto    if (pset_info(pset, NULL, id_length, *id_array) == 0) {
484132451Sroberto      result = true;
485132451Sroberto    }
486132451Sroberto  }
487132451Sroberto  return result;
48854359Sroberto}
48954359Sroberto
490132451Sroberto// Callers of find_processors_online() must tolerate imprecise results --
491132451Sroberto// the system configuration can change asynchronously because of DR
49282498Sroberto// or explicit psradm operations.
493182007Sroberto//
494182007Sroberto// We also need to take care that the loop (below) terminates as the
49554359Sroberto// number of processors online can change between the _SC_NPROCESSORS_ONLN
49654359Sroberto// request and the loop that builds the list of processor ids.   Unfortunately
49754359Sroberto// there's no reliable way to determine the maximum valid processor id,
49854359Sroberto// so we use a manifest constant, MAX_PROCESSOR_ID, instead.  See p_online
49954359Sroberto// man pages, which claim the processor id set is "sparse, but
50054359Sroberto// not too sparse".  MAX_PROCESSOR_ID is used to ensure that we eventually
50154359Sroberto// exit the loop.
50254359Sroberto//
50354359Sroberto// In the future we'll be able to use sysconf(_SC_CPUID_MAX), but that's
50482498Sroberto// not available on S8.0.
50554359Sroberto
50654359Srobertostatic bool find_processors_online(processorid_t** id_array,
50754359Sroberto                                   uint*           id_length) {
50854359Sroberto  const processorid_t MAX_PROCESSOR_ID = 100000 ;
50954359Sroberto  // Find the number of processors online.
51054359Sroberto  *id_length = sysconf(_SC_NPROCESSORS_ONLN);
51154359Sroberto  // Make up an array to hold their ids.
51254359Sroberto  *id_array = NEW_C_HEAP_ARRAY(processorid_t, *id_length);
51354359Sroberto  // Processors need not be numbered consecutively.
51454359Sroberto  long found = 0;
51554359Sroberto  processorid_t next = 0;
51654359Sroberto  while (found < *id_length && next < MAX_PROCESSOR_ID) {
51754359Sroberto    processor_info_t info;
51854359Sroberto    if (processor_info(next, &info) == 0) {
51954359Sroberto      // NB, PI_NOINTR processors are effectively online ...
52056746Sroberto      if (info.pi_state == P_ONLINE || info.pi_state == P_NOINTR) {
52154359Sroberto        (*id_array)[found] = next;
52254359Sroberto        found += 1;
52354359Sroberto      }
52482498Sroberto    }
52554359Sroberto    next += 1;
52654359Sroberto  }
52754359Sroberto  if (found < *id_length) {
52854359Sroberto      // The loop above didn't identify the expected number of processors.
52954359Sroberto      // We could always retry the operation, calling sysconf(_SC_NPROCESSORS_ONLN)
53054359Sroberto      // and re-running the loop, above, but there's no guarantee of progress
531182007Sroberto      // if the system configuration is in flux.  Instead, we just return what
53254359Sroberto      // we've got.  Note that in the worst case find_processors_online() could
53354359Sroberto      // return an empty set.  (As a fall-back in the case of the empty set we
534182007Sroberto      // could just return the ID of the current processor).
535182007Sroberto      *id_length = found ;
53654359Sroberto  }
53754359Sroberto
53854359Sroberto  return true;
539132451Sroberto}
540132451Sroberto
541132451Srobertostatic bool assign_distribution(processorid_t* id_array,
542132451Sroberto                                uint           id_length,
543132451Sroberto                                uint*          distribution,
544132451Sroberto                                uint           distribution_length) {
545132451Sroberto  // We assume we can assign processorid_t's to uint's.
546132451Sroberto  assert(sizeof(processorid_t) == sizeof(uint),
547132451Sroberto         "can't convert processorid_t to uint");
54854359Sroberto  // Quick check to see if we won't succeed.
54954359Sroberto  if (id_length < distribution_length) {
55082498Sroberto    return false;
55182498Sroberto  }
55282498Sroberto  // Assign processor ids to the distribution.
55382498Sroberto  // Try to shuffle processors to distribute work across boards,
554132451Sroberto  // assuming 4 processors per board.
555132451Sroberto  const uint processors_per_board = ProcessDistributionStride;
55682498Sroberto  // Find the maximum processor id.
55754359Sroberto  processorid_t max_id = 0;
55882498Sroberto  for (uint m = 0; m < id_length; m += 1) {
559132451Sroberto    max_id = MAX2(max_id, id_array[m]);
560132451Sroberto  }
56182498Sroberto  // The next id, to limit loops.
56282498Sroberto  const processorid_t limit_id = max_id + 1;
56382498Sroberto  // Make up markers for available processors.
564132451Sroberto  bool* available_id = NEW_C_HEAP_ARRAY(bool, limit_id);
565132451Sroberto  for (uint c = 0; c < limit_id; c += 1) {
56654359Sroberto    available_id[c] = false;
56782498Sroberto  }
56882498Sroberto  for (uint a = 0; a < id_length; a += 1) {
56982498Sroberto    available_id[id_array[a]] = true;
57082498Sroberto  }
57182498Sroberto  // Step by "boards", then by "slot", copying to "assigned".
57282498Sroberto  // NEEDS_CLEANUP: The assignment of processors should be stateful,
573182007Sroberto  //                remembering which processors have been assigned by
574182007Sroberto  //                previous calls, etc., so as to distribute several
57554359Sroberto  //                independent calls of this method.  What we'd like is
576182007Sroberto  //                It would be nice to have an API that let us ask
577182007Sroberto  //                how many processes are bound to a processor,
578182007Sroberto  //                but we don't have that, either.
57954359Sroberto  //                In the short term, "board" is static so that
580182007Sroberto  //                subsequent distributions don't all start at board 0.
581182007Sroberto  static uint board = 0;
582182007Sroberto  uint assigned = 0;
583182007Sroberto  // Until we've found enough processors ....
584182007Sroberto  while (assigned < distribution_length) {
585182007Sroberto    // ... find the next available processor in the board.
586182007Sroberto    for (uint slot = 0; slot < processors_per_board; slot += 1) {
587182007Sroberto      uint try_id = board * processors_per_board + slot;
588182007Sroberto      if ((try_id < limit_id) && (available_id[try_id] == true)) {
589182007Sroberto        distribution[assigned] = try_id;
590182007Sroberto        available_id[try_id] = false;
591182007Sroberto        assigned += 1;
592182007Sroberto        break;
593182007Sroberto      }
594182007Sroberto    }
595182007Sroberto    board += 1;
596182007Sroberto    if (board * processors_per_board + 0 >= limit_id) {
597182007Sroberto      board = 0;
598182007Sroberto    }
599182007Sroberto  }
600182007Sroberto  if (available_id != NULL) {
601182007Sroberto    FREE_C_HEAP_ARRAY(bool, available_id);
602182007Sroberto  }
60354359Sroberto  return true;
60454359Sroberto}
605182007Sroberto
606182007Srobertobool os::distribute_processes(uint length, uint* distribution) {
607182007Sroberto  bool result = false;
608182007Sroberto  // Find the processor id's of all the available CPUs.
609182007Sroberto  processorid_t* id_array  = NULL;
610132451Sroberto  uint           id_length = 0;
611182007Sroberto  // There are some races between querying information and using it,
612182007Sroberto  // since processor sets can change dynamically.
613182007Sroberto  psetid_t pset = PS_NONE;
614182007Sroberto  // Are we running in a processor set?
615132451Sroberto  if ((pset_bind(PS_QUERY, P_PID, P_MYID, &pset) == 0) && pset != PS_NONE) {
616132451Sroberto    result = find_processors_in_pset(pset, &id_array, &id_length);
617182007Sroberto  } else {
618182007Sroberto    result = find_processors_online(&id_array, &id_length);
619182007Sroberto  }
620182007Sroberto  if (result == true) {
621182007Sroberto    if (id_length >= length) {
622182007Sroberto      result = assign_distribution(id_array, id_length, distribution, length);
623182007Sroberto    } else {
624182007Sroberto      result = false;
625182007Sroberto    }
626182007Sroberto  }
627182007Sroberto  if (id_array != NULL) {
628182007Sroberto    FREE_C_HEAP_ARRAY(processorid_t, id_array);
629182007Sroberto  }
630182007Sroberto  return result;
631182007Sroberto}
632182007Sroberto
633182007Srobertobool os::bind_to_processor(uint processor_id) {
634182007Sroberto  // We assume that a processorid_t can be stored in a uint.
635182007Sroberto  assert(sizeof(uint) == sizeof(processorid_t),
636182007Sroberto         "can't convert uint to processorid_t");
637182007Sroberto  int bind_result =
638182007Sroberto    processor_bind(P_LWPID,                       // bind LWP.
639182007Sroberto                   P_MYID,                        // bind current LWP.
640182007Sroberto                   (processorid_t) processor_id,  // id.
641182007Sroberto                   NULL);                         // don't return old binding.
642182007Sroberto  return (bind_result == 0);
643182007Sroberto}
644132451Sroberto
645132451Srobertobool os::getenv(const char* name, char* buffer, int len) {
646132451Sroberto  char* val = ::getenv( name );
647132451Sroberto  if ( val == NULL
648132451Sroberto  ||   strlen(val) + 1  >  len ) {
649132451Sroberto    if (len > 0)  buffer[0] = 0; // return a null string
650132451Sroberto    return false;
651132451Sroberto  }
652182007Sroberto  strcpy( buffer, val );
653132451Sroberto  return true;
654132451Sroberto}
655132451Sroberto
656132451Sroberto
657132451Sroberto// Return true if user is running as root.
658132451Sroberto
659132451Srobertobool os::have_special_privileges() {
660132451Sroberto  static bool init = false;
661132451Sroberto  static bool privileges = false;
662132451Sroberto  if (!init) {
663132451Sroberto    privileges = (getuid() != geteuid()) || (getgid() != getegid());
664132451Sroberto    init = true;
665132451Sroberto  }
666132451Sroberto  return privileges;
667132451Sroberto}
668132451Sroberto
669132451Sroberto
670132451Srobertostatic char* get_property(char* name, char* buffer, int buffer_size) {
671132451Sroberto  if (os::getenv(name, buffer, buffer_size)) {
672132451Sroberto    return buffer;
673132451Sroberto  }
674132451Sroberto  static char empty[] = "";
675132451Sroberto  return empty;
676132451Sroberto}
677132451Sroberto
678132451Sroberto
679132451Srobertovoid os::init_system_properties_values() {
680132451Sroberto  char arch[12];
681132451Sroberto  sysinfo(SI_ARCHITECTURE, arch, sizeof(arch));
682132451Sroberto
683132451Sroberto  // The next steps are taken in the product version:
684132451Sroberto  //
685132451Sroberto  // Obtain the JAVA_HOME value from the location of libjvm[_g].so.
686132451Sroberto  // This library should be located at:
687132451Sroberto  // <JAVA_HOME>/jre/lib/<arch>/{client|server}/libjvm[_g].so.
688132451Sroberto  //
689132451Sroberto  // If "/jre/lib/" appears at the right place in the path, then we
690132451Sroberto  // assume libjvm[_g].so is installed in a JDK and we use this path.
691132451Sroberto  //
692132451Sroberto  // Otherwise exit with message: "Could not create the Java virtual machine."
693132451Sroberto  //
694132451Sroberto  // The following extra steps are taken in the debugging version:
695132451Sroberto  //
696132451Sroberto  // If "/jre/lib/" does NOT appear at the right place in the path
697132451Sroberto  // instead of exit check for $JAVA_HOME environment variable.
698132451Sroberto  //
699132451Sroberto  // If it is defined and we are able to locate $JAVA_HOME/jre/lib/<arch>,
700132451Sroberto  // then we append a fake suffix "hotspot/libjvm[_g].so" to this path so
701132451Sroberto  // it looks like libjvm[_g].so is installed there
702132451Sroberto  // <JAVA_HOME>/jre/lib/<arch>/hotspot/libjvm[_g].so.
703132451Sroberto  //
704182007Sroberto  // Otherwise exit.
705182007Sroberto  //
706132451Sroberto  // Important note: if the location of libjvm.so changes this
707182007Sroberto  // code needs to be changed accordingly.
708182007Sroberto
709182007Sroberto  // The next few definitions allow the code to be verbatim:
710182007Sroberto#define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n))
711132451Sroberto#define free(p) FREE_C_HEAP_ARRAY(char, p)
712132451Sroberto#define getenv(n) ::getenv(n)
713182007Sroberto
714132451Sroberto#define EXTENSIONS_DIR  "/lib/ext"
715132451Sroberto#define ENDORSED_DIR    "/lib/endorsed"
716132451Sroberto#define COMMON_DIR      "/usr/jdk/packages"
717132451Sroberto
718132451Sroberto  {
719132451Sroberto    /* sysclasspath, java_home, dll_dir */
720132451Sroberto    {
721132451Sroberto        char *home_path;
722132451Sroberto        char *dll_path;
723132451Sroberto        char *pslash;
724132451Sroberto        char buf[MAXPATHLEN];
725132451Sroberto        os::jvm_path(buf, sizeof(buf));
726132451Sroberto
727132451Sroberto        // Found the full path to libjvm.so.
728132451Sroberto        // Now cut the path to <java_home>/jre if we can.
729132451Sroberto        *(strrchr(buf, '/')) = '\0';  /* get rid of /libjvm.so */
730132451Sroberto        pslash = strrchr(buf, '/');
731132451Sroberto        if (pslash != NULL)
732132451Sroberto            *pslash = '\0';           /* get rid of /{client|server|hotspot} */
733132451Sroberto        dll_path = malloc(strlen(buf) + 1);
734132451Sroberto        if (dll_path == NULL)
735132451Sroberto            return;
736132451Sroberto        strcpy(dll_path, buf);
737132451Sroberto        Arguments::set_dll_dir(dll_path);
738132451Sroberto
739132451Sroberto        if (pslash != NULL) {
740132451Sroberto            pslash = strrchr(buf, '/');
741132451Sroberto            if (pslash != NULL) {
742132451Sroberto                *pslash = '\0';       /* get rid of /<arch> */
743132451Sroberto                pslash = strrchr(buf, '/');
744132451Sroberto                if (pslash != NULL)
745132451Sroberto                    *pslash = '\0';   /* get rid of /lib */
746132451Sroberto            }
747132451Sroberto        }
748132451Sroberto
749132451Sroberto        home_path = malloc(strlen(buf) + 1);
750132451Sroberto        if (home_path == NULL)
751132451Sroberto            return;
752132451Sroberto        strcpy(home_path, buf);
753132451Sroberto        Arguments::set_java_home(home_path);
754132451Sroberto
755132451Sroberto        if (!set_boot_path('/', ':'))
756132451Sroberto            return;
757132451Sroberto    }
758132451Sroberto
759132451Sroberto    /*
760132451Sroberto     * Where to look for native libraries
761132451Sroberto     */
762132451Sroberto    {
763132451Sroberto      // Use dlinfo() to determine the correct java.library.path.
764132451Sroberto      //
765132451Sroberto      // If we're launched by the Java launcher, and the user
766132451Sroberto      // does not set java.library.path explicitly on the commandline,
767182007Sroberto      // the Java launcher sets LD_LIBRARY_PATH for us and unsets
768182007Sroberto      // LD_LIBRARY_PATH_32 and LD_LIBRARY_PATH_64.  In this case
769132451Sroberto      // dlinfo returns LD_LIBRARY_PATH + crle settings (including
770182007Sroberto      // /usr/lib), which is exactly what we want.
771182007Sroberto      //
77256746Sroberto      // If the user does set java.library.path, it completely
77356746Sroberto      // overwrites this setting, and always has.
77456746Sroberto      //
77556746Sroberto      // If we're not launched by the Java launcher, we may
776182007Sroberto      // get here with any/all of the LD_LIBRARY_PATH[_32|64]
77756746Sroberto      // settings.  Again, dlinfo does exactly what we want.
77856746Sroberto
77956746Sroberto      Dl_serinfo     _info, *info = &_info;
78056746Sroberto      Dl_serpath     *path;
78182498Sroberto      char*          library_path;
78256746Sroberto      char           *common_path;
78356746Sroberto      int            i;
784182007Sroberto
785182007Sroberto      // determine search path count and required buffer size
786182007Sroberto      if (dlinfo(RTLD_SELF, RTLD_DI_SERINFOSIZE, (void *)info) == -1) {
787182007Sroberto        vm_exit_during_initialization("dlinfo SERINFOSIZE request", dlerror());
78854359Sroberto      }
789182007Sroberto
790182007Sroberto      // allocate new buffer and initialize
791182007Sroberto      info = (Dl_serinfo*)malloc(_info.dls_size);
79254359Sroberto      if (info == NULL) {
793182007Sroberto        vm_exit_out_of_memory(_info.dls_size,
794182007Sroberto                              "init_system_properties_values info");
79556746Sroberto      }
796182007Sroberto      info->dls_size = _info.dls_size;
797182007Sroberto      info->dls_cnt = _info.dls_cnt;
798182007Sroberto
799182007Sroberto      // obtain search path information
800182007Sroberto      if (dlinfo(RTLD_SELF, RTLD_DI_SERINFO, (void *)info) == -1) {
801182007Sroberto        free(info);
802182007Sroberto        vm_exit_during_initialization("dlinfo SERINFO request", dlerror());
803182007Sroberto      }
804182007Sroberto
805182007Sroberto      path = &info->dls_serpath[0];
806182007Sroberto
807182007Sroberto      // Note: Due to a legacy implementation, most of the library path
808182007Sroberto      // is set in the launcher.  This was to accomodate linking restrictions
809182007Sroberto      // on legacy Solaris implementations (which are no longer supported).
810182007Sroberto      // Eventually, all the library path setting will be done here.
811182007Sroberto      //
81254359Sroberto      // However, to prevent the proliferation of improperly built native
813182007Sroberto      // libraries, the new path component /usr/jdk/packages is added here.
81454359Sroberto
81554359Sroberto      // Determine the actual CPU architecture.
81656746Sroberto      char cpu_arch[12];
817132451Sroberto      sysinfo(SI_ARCHITECTURE, cpu_arch, sizeof(cpu_arch));
81882498Sroberto#ifdef _LP64
819132451Sroberto      // If we are a 64-bit vm, perform the following translations:
820132451Sroberto      //   sparc   -> sparcv9
82182498Sroberto      //   i386    -> amd64
822182007Sroberto      if (strcmp(cpu_arch, "sparc") == 0)
823182007Sroberto        strcat(cpu_arch, "v9");
824132451Sroberto      else if (strcmp(cpu_arch, "i386") == 0)
825132451Sroberto        strcpy(cpu_arch, "amd64");
826132451Sroberto#endif
827132451Sroberto
82882498Sroberto      // Construct the invariant part of ld_library_path. Note that the
829182007Sroberto      // space for the colon and the trailing null are provided by the
830182007Sroberto      // nulls included by the sizeof operator.
831182007Sroberto      size_t bufsize = sizeof(COMMON_DIR) + sizeof("/lib/") + strlen(cpu_arch);
832182007Sroberto      common_path = malloc(bufsize);
833182007Sroberto      if (common_path == NULL) {
834182007Sroberto        free(info);
835182007Sroberto        vm_exit_out_of_memory(bufsize,
83656746Sroberto                              "init_system_properties_values common_path");
837182007Sroberto      }
83854359Sroberto      sprintf(common_path, COMMON_DIR "/lib/%s", cpu_arch);
839132451Sroberto
840132451Sroberto      // struct size is more than sufficient for the path components obtained
84156746Sroberto      // through the dlinfo() call, so only add additional space for the path
842132451Sroberto      // components explicitly added here.
843132451Sroberto      bufsize = info->dls_size + strlen(common_path);
844132451Sroberto      library_path = malloc(bufsize);
845132451Sroberto      if (library_path == NULL) {
846132451Sroberto        free(info);
847132451Sroberto        free(common_path);
848132451Sroberto        vm_exit_out_of_memory(bufsize,
849132451Sroberto                              "init_system_properties_values library_path");
850132451Sroberto      }
851182007Sroberto      library_path[0] = '\0';
852182007Sroberto
853132451Sroberto      // Construct the desired Java library path from the linker's library
854132451Sroberto      // search path.
855132451Sroberto      //
856132451Sroberto      // For compatibility, it is optimal that we insert the additional path
857132451Sroberto      // components specific to the Java VM after those components specified
858132451Sroberto      // in LD_LIBRARY_PATH (if any) but before those added by the ld.so
859132451Sroberto      // infrastructure.
860132451Sroberto      if (info->dls_cnt == 0) { // Not sure this can happen, but allow for it
861132451Sroberto        strcpy(library_path, common_path);
862132451Sroberto      } else {
863132451Sroberto        int inserted = 0;
864182007Sroberto        for (i = 0; i < info->dls_cnt; i++, path++) {
865132451Sroberto          uint_t flags = path->dls_flags & LA_SER_MASK;
866182007Sroberto          if (((flags & LA_SER_LIBPATH) == 0) && !inserted) {
867132451Sroberto            strcat(library_path, common_path);
868132451Sroberto            strcat(library_path, os::path_separator());
869132451Sroberto            inserted = 1;
870182007Sroberto          }
871182007Sroberto          strcat(library_path, path->dls_name);
872182007Sroberto          strcat(library_path, os::path_separator());
873182007Sroberto        }
874182007Sroberto        // eliminate trailing path separator
875182007Sroberto        library_path[strlen(library_path)-1] = '\0';
876132451Sroberto      }
877132451Sroberto
87854359Sroberto      // happens before argument parsing - can't use a trace flag
87954359Sroberto      // tty->print_raw("init_system_properties_values: native lib path: ");
880132451Sroberto      // tty->print_raw_cr(library_path);
881132451Sroberto
882132451Sroberto      // callee copies into its own buffer
883182007Sroberto      Arguments::set_library_path(library_path);
884182007Sroberto
885182007Sroberto      free(common_path);
886182007Sroberto      free(library_path);
887132451Sroberto      free(info);
888132451Sroberto    }
889132451Sroberto
890132451Sroberto    /*
891132451Sroberto     * Extensions directories.
892132451Sroberto     *
893132451Sroberto     * Note that the space for the colon and the trailing null are provided
894132451Sroberto     * by the nulls included by the sizeof operator (so actually one byte more
895132451Sroberto     * than necessary is allocated).
896132451Sroberto     */
897132451Sroberto    {
898132451Sroberto        char *buf = (char *) malloc(strlen(Arguments::get_java_home()) +
899132451Sroberto            sizeof(EXTENSIONS_DIR) + sizeof(COMMON_DIR) +
900132451Sroberto            sizeof(EXTENSIONS_DIR));
901132451Sroberto        sprintf(buf, "%s" EXTENSIONS_DIR ":" COMMON_DIR EXTENSIONS_DIR,
902132451Sroberto            Arguments::get_java_home());
903132451Sroberto        Arguments::set_ext_dirs(buf);
904132451Sroberto    }
905132451Sroberto
906132451Sroberto    /* Endorsed standards default directory. */
907132451Sroberto    {
908132451Sroberto        char * buf = malloc(strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR));
909132451Sroberto        sprintf(buf, "%s" ENDORSED_DIR, Arguments::get_java_home());
910132451Sroberto        Arguments::set_endorsed_dirs(buf);
911132451Sroberto    }
912132451Sroberto  }
913132451Sroberto
914132451Sroberto#undef malloc
915132451Sroberto#undef free
916132451Sroberto#undef getenv
917132451Sroberto#undef EXTENSIONS_DIR
918182007Sroberto#undef ENDORSED_DIR
919132451Sroberto#undef COMMON_DIR
920182007Sroberto
921182007Sroberto}
922182007Sroberto
923132451Srobertovoid os::breakpoint() {
924132451Sroberto  BREAKPOINT;
925132451Sroberto}
926132451Sroberto
927132451Srobertobool os::obsolete_option(const JavaVMOption *option)
928132451Sroberto{
929132451Sroberto  if (!strncmp(option->optionString, "-Xt", 3)) {
930132451Sroberto    return true;
931132451Sroberto  } else if (!strncmp(option->optionString, "-Xtm", 4)) {
932132451Sroberto    return true;
933132451Sroberto  } else if (!strncmp(option->optionString, "-Xverifyheap", 12)) {
934132451Sroberto    return true;
935132451Sroberto  } else if (!strncmp(option->optionString, "-Xmaxjitcodesize", 16)) {
936132451Sroberto    return true;
937132451Sroberto  }
938132451Sroberto  return false;
939132451Sroberto}
940132451Sroberto
941132451Srobertobool os::Solaris::valid_stack_address(Thread* thread, address sp) {
942132451Sroberto  address  stackStart  = (address)thread->stack_base();
943132451Sroberto  address  stackEnd    = (address)(stackStart - (address)thread->stack_size());
944132451Sroberto  if (sp < stackStart && sp >= stackEnd ) return true;
945132451Sroberto  return false;
946132451Sroberto}
947132451Sroberto
948132451Srobertoextern "C" void breakpoint() {
949132451Sroberto  // use debugger to set breakpoint here
950132451Sroberto}
951132451Sroberto
952132451Sroberto// Returns an estimate of the current stack pointer. Result must be guaranteed to
953132451Sroberto// point into the calling threads stack, and be no lower than the current stack
954132451Sroberto// pointer.
955132451Srobertoaddress os::current_stack_pointer() {
956132451Sroberto  volatile int dummy;
957182007Sroberto  address sp = (address)&dummy + 8;     // %%%% need to confirm if this is right
958182007Sroberto  return sp;
959182007Sroberto}
960182007Sroberto
96154359Srobertostatic thread_t main_thread;
96254359Sroberto
963132451Sroberto// Thread start routine for all new Java threads
964182007Srobertoextern "C" void* java_start(void* thread_addr) {
965182007Sroberto  // Try to randomize the cache line index of hot stack frames.
966182007Sroberto  // This helps when threads of the same stack traces evict each other's
967182007Sroberto  // cache lines. The threads can be either from the same JVM instance, or
968182007Sroberto  // from different JVM instances. The benefit is especially true for
96954359Sroberto  // processors with hyperthreading technology.
970182007Sroberto  static int counter = 0;
971182007Sroberto  int pid = os::current_process_id();
972132451Sroberto  alloca(((pid ^ counter++) & 7) * 128);
973132451Sroberto
974132451Sroberto  int prio;
975132451Sroberto  Thread* thread = (Thread*)thread_addr;
976132451Sroberto  OSThread* osthr = thread->osthread();
977132451Sroberto
978132451Sroberto  osthr->set_lwp_id( _lwp_self() );  // Store lwp in case we are bound
979132451Sroberto  thread->_schedctl = (void *) schedctl_init () ;
980182007Sroberto
981132451Sroberto  if (UseNUMA) {
982132451Sroberto    int lgrp_id = os::numa_get_group_id();
983132451Sroberto    if (lgrp_id != -1) {
984132451Sroberto      thread->set_lgrp_id(lgrp_id);
985132451Sroberto    }
986132451Sroberto  }
987132451Sroberto
988132451Sroberto  // If the creator called set priority before we started,
989132451Sroberto  // we need to call set priority now that we have an lwp.
990132451Sroberto  // Get the priority from libthread and set the priority
991132451Sroberto  // for the new Solaris lwp.
992132451Sroberto  if ( osthr->thread_id() != -1 ) {
993132451Sroberto    if ( UseThreadPriorities ) {
994132451Sroberto      thr_getprio(osthr->thread_id(), &prio);
995132451Sroberto      if (ThreadPriorityVerbose) {
996132451Sroberto        tty->print_cr("Starting Thread " INTPTR_FORMAT ", LWP is " INTPTR_FORMAT ", setting priority: %d\n",
997132451Sroberto                      osthr->thread_id(), osthr->lwp_id(), prio );
998182007Sroberto      }
999182007Sroberto      os::set_native_priority(thread, prio);
1000132451Sroberto    }
100154359Sroberto  } else if (ThreadPriorityVerbose) {
1002132451Sroberto    warning("Can't set priority in _start routine, thread id hasn't been set\n");
100354359Sroberto  }
100456746Sroberto
100556746Sroberto  assert(osthr->get_state() == RUNNABLE, "invalid os thread state");
100654359Sroberto
100754359Sroberto  // initialize signal mask for this thread
100854359Sroberto  os::Solaris::hotspot_sigmask(thread);
100982498Sroberto
101054359Sroberto  thread->run();
101154359Sroberto
101254359Sroberto  // One less thread is executing
101354359Sroberto  // When the VMThread gets here, the main thread may have already exited
101454359Sroberto  // which frees the CodeHeap containing the Atomic::dec code
101554359Sroberto  if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) {
101682498Sroberto    Atomic::dec(&os::Solaris::_os_thread_count);
101782498Sroberto  }
101882498Sroberto
101982498Sroberto  if (UseDetachedThreads) {
102082498Sroberto    thr_exit(NULL);
102182498Sroberto    ShouldNotReachHere();
102282498Sroberto  }
102354359Sroberto  return NULL;
102482498Sroberto}
102554359Sroberto
102654359Srobertostatic OSThread* create_os_thread(Thread* thread, thread_t thread_id) {
102754359Sroberto  // Allocate the OSThread object
102854359Sroberto  OSThread* osthread = new OSThread(NULL, NULL);
102954359Sroberto  if (osthread == NULL) return NULL;
103054359Sroberto
103154359Sroberto  // Store info on the Solaris thread into the OSThread
103254359Sroberto  osthread->set_thread_id(thread_id);
103354359Sroberto  osthread->set_lwp_id(_lwp_self());
103454359Sroberto  thread->_schedctl = (void *) schedctl_init () ;
103554359Sroberto
103654359Sroberto  if (UseNUMA) {
103754359Sroberto    int lgrp_id = os::numa_get_group_id();
103854359Sroberto    if (lgrp_id != -1) {
103954359Sroberto      thread->set_lgrp_id(lgrp_id);
104054359Sroberto    }
104154359Sroberto  }
104254359Sroberto
104354359Sroberto  if ( ThreadPriorityVerbose ) {
104454359Sroberto    tty->print_cr("In create_os_thread, Thread " INTPTR_FORMAT ", LWP is " INTPTR_FORMAT "\n",
104554359Sroberto                  osthread->thread_id(), osthread->lwp_id() );
104654359Sroberto  }
104754359Sroberto
104854359Sroberto  // Initial thread state is INITIALIZED, not SUSPENDED
1049132451Sroberto  osthread->set_state(INITIALIZED);
1050132451Sroberto
105154359Sroberto  return osthread;
105254359Sroberto}
105354359Sroberto
105454359Srobertovoid os::Solaris::hotspot_sigmask(Thread* thread) {
105554359Sroberto
105654359Sroberto  //Save caller's signal mask
105754359Sroberto  sigset_t sigmask;
105854359Sroberto  thr_sigsetmask(SIG_SETMASK, NULL, &sigmask);
105954359Sroberto  OSThread *osthread = thread->osthread();
106054359Sroberto  osthread->set_caller_sigmask(sigmask);
106154359Sroberto
106254359Sroberto  thr_sigsetmask(SIG_UNBLOCK, os::Solaris::unblocked_signals(), NULL);
106354359Sroberto  if (!ReduceSignalUsage) {
106454359Sroberto    if (thread->is_VM_thread()) {
106554359Sroberto      // Only the VM thread handles BREAK_SIGNAL ...
106654359Sroberto      thr_sigsetmask(SIG_UNBLOCK, vm_signals(), NULL);
106754359Sroberto    } else {
106882498Sroberto      // ... all other threads block BREAK_SIGNAL
106982498Sroberto      assert(!sigismember(vm_signals(), SIGINT), "SIGINT should not be blocked");
107082498Sroberto      thr_sigsetmask(SIG_BLOCK, vm_signals(), NULL);
1071132451Sroberto    }
107282498Sroberto  }
107354359Sroberto}
107482498Sroberto
107554359Srobertobool os::create_attached_thread(JavaThread* thread) {
107654359Sroberto#ifdef ASSERT
107782498Sroberto  thread->verify_not_published();
107882498Sroberto#endif
107982498Sroberto  OSThread* osthread = create_os_thread(thread, thr_self());
108082498Sroberto  if (osthread == NULL) {
108182498Sroberto     return false;
108282498Sroberto  }
108354359Sroberto
108454359Sroberto  // Initial thread state is RUNNABLE
108554359Sroberto  osthread->set_state(RUNNABLE);
108654359Sroberto  thread->set_osthread(osthread);
108754359Sroberto
108882498Sroberto  // initialize signal mask for this thread
108954359Sroberto  // and save the caller's signal mask
109054359Sroberto  os::Solaris::hotspot_sigmask(thread);
1091132451Sroberto
1092132451Sroberto  return true;
109354359Sroberto}
1094132451Sroberto
1095132451Srobertobool os::create_main_thread(JavaThread* thread) {
1096132451Sroberto#ifdef ASSERT
1097132451Sroberto  thread->verify_not_published();
1098132451Sroberto#endif
1099132451Sroberto  if (_starting_thread == NULL) {
1100132451Sroberto    _starting_thread = create_os_thread(thread, main_thread);
110182498Sroberto     if (_starting_thread == NULL) {
110282498Sroberto        return false;
1103132451Sroberto     }
1104132451Sroberto  }
1105132451Sroberto
1106132451Sroberto  // The primodial thread is runnable from the start
1107132451Sroberto  _starting_thread->set_state(RUNNABLE);
1108132451Sroberto
110982498Sroberto  thread->set_osthread(_starting_thread);
111082498Sroberto
111182498Sroberto  // initialize signal mask for this thread
1112132451Sroberto  // and save the caller's signal mask
111382498Sroberto  os::Solaris::hotspot_sigmask(thread);
111482498Sroberto
111582498Sroberto  return true;
1116132451Sroberto}
1117132451Sroberto
1118132451Sroberto// _T2_libthread is true if we believe we are running with the newer
1119132451Sroberto// SunSoft lwp/libthread.so (2.8 patch, 2.9 default)
1120132451Srobertobool os::Solaris::_T2_libthread = false;
112154359Sroberto
112254359Srobertobool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
112354359Sroberto  // Allocate the OSThread object
112454359Sroberto  OSThread* osthread = new OSThread(NULL, NULL);
112554359Sroberto  if (osthread == NULL) {
112654359Sroberto    return false;
112754359Sroberto  }
112854359Sroberto
112954359Sroberto  if ( ThreadPriorityVerbose ) {
1130182007Sroberto    char *thrtyp;
1131182007Sroberto    switch ( thr_type ) {
1132132451Sroberto      case vm_thread:
113354359Sroberto        thrtyp = (char *)"vm";
113454359Sroberto        break;
1135182007Sroberto      case cgc_thread:
1136182007Sroberto        thrtyp = (char *)"cgc";
1137182007Sroberto        break;
1138182007Sroberto      case pgc_thread:
1139182007Sroberto        thrtyp = (char *)"pgc";
1140182007Sroberto        break;
1141182007Sroberto      case java_thread:
1142182007Sroberto        thrtyp = (char *)"java";
1143182007Sroberto        break;
1144182007Sroberto      case compiler_thread:
1145182007Sroberto        thrtyp = (char *)"compiler";
1146182007Sroberto        break;
114782498Sroberto      case watcher_thread:
114854359Sroberto        thrtyp = (char *)"watcher";
1149182007Sroberto        break;
1150182007Sroberto      default:
1151182007Sroberto        thrtyp = (char *)"unknown";
1152182007Sroberto        break;
1153182007Sroberto    }
1154132451Sroberto    tty->print_cr("In create_thread, creating a %s thread\n", thrtyp);
115554359Sroberto  }
115654359Sroberto
115756746Sroberto  // Calculate stack size if it's not specified by caller.
115856746Sroberto  if (stack_size == 0) {
115956746Sroberto    // The default stack size 1M (2M for LP64).
116054359Sroberto    stack_size = (BytesPerWord >> 2) * K * K;
116182498Sroberto
116256746Sroberto    switch (thr_type) {
116356746Sroberto    case os::java_thread:
116456746Sroberto      // Java threads use ThreadStackSize which default value can be changed with the flag -Xss
116556746Sroberto      if (JavaThread::stack_size_at_create() > 0) stack_size = JavaThread::stack_size_at_create();
116656746Sroberto      break;
116756746Sroberto    case os::compiler_thread:
116856746Sroberto      if (CompilerThreadStackSize > 0) {
116956746Sroberto        stack_size = (size_t)(CompilerThreadStackSize * K);
117056746Sroberto        break;
117156746Sroberto      } // else fall through:
117256746Sroberto        // use VMThreadStackSize if CompilerThreadStackSize is not defined
117356746Sroberto    case os::vm_thread:
117456746Sroberto    case os::pgc_thread:
117556746Sroberto    case os::cgc_thread:
117682498Sroberto    case os::watcher_thread:
117756746Sroberto      if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);
117882498Sroberto      break;
117982498Sroberto    }
118082498Sroberto  }
118182498Sroberto  stack_size = MAX2(stack_size, os::Solaris::min_stack_allowed);
118282498Sroberto
118356746Sroberto  // Initial state is ALLOCATED but not INITIALIZED
118456746Sroberto  osthread->set_state(ALLOCATED);
118582498Sroberto
118682498Sroberto  if (os::Solaris::_os_thread_count > os::Solaris::_os_thread_limit) {
118782498Sroberto    // We got lots of threads. Check if we still have some address space left.
118856746Sroberto    // Need to be at least 5Mb of unreserved address space. We do check by
118956746Sroberto    // trying to reserve some.
119082498Sroberto    const size_t VirtualMemoryBangSize = 20*K*K;
119182498Sroberto    char* mem = os::reserve_memory(VirtualMemoryBangSize);
119282498Sroberto    if (mem == NULL) {
119382498Sroberto      delete osthread;
119456746Sroberto      return false;
119556746Sroberto    } else {
119656746Sroberto      // Release the memory again
119756746Sroberto      os::release_memory(mem, VirtualMemoryBangSize);
119856746Sroberto    }
119956746Sroberto  }
120056746Sroberto
120156746Sroberto  // Setup osthread because the child thread may need it.
120282498Sroberto  thread->set_osthread(osthread);
120354359Sroberto
120456746Sroberto  // Create the Solaris thread
120554359Sroberto  // explicit THR_BOUND for T2_libthread case in case
120654359Sroberto  // that assumption is not accurate, but our alternate signal stack
120754359Sroberto  // handling is based on it which must have bound threads
120854359Sroberto  thread_t tid = 0;
120954359Sroberto  long     flags = (UseDetachedThreads ? THR_DETACHED : 0) | THR_SUSPENDED
121054359Sroberto                   | ((UseBoundThreads || os::Solaris::T2_libthread() ||
121154359Sroberto                       (thr_type == vm_thread) ||
121282498Sroberto                       (thr_type == cgc_thread) ||
121354359Sroberto                       (thr_type == pgc_thread) ||
121456746Sroberto                       (thr_type == compiler_thread && BackgroundCompilation)) ?
121554359Sroberto                      THR_BOUND : 0);
121654359Sroberto  int      status;
121754359Sroberto
121854359Sroberto  // 4376845 -- libthread/kernel don't provide enough LWPs to utilize all CPUs.
121954359Sroberto  //
122054359Sroberto  // On multiprocessors systems, libthread sometimes under-provisions our
122154359Sroberto  // process with LWPs.  On a 30-way systems, for instance, we could have
122282498Sroberto  // 50 user-level threads in ready state and only 2 or 3 LWPs assigned
122354359Sroberto  // to our process.  This can result in under utilization of PEs.
122454359Sroberto  // I suspect the problem is related to libthread's LWP
122556746Sroberto  // pool management and to the kernel's SIGBLOCKING "last LWP parked"
122654359Sroberto  // upcall policy.
122754359Sroberto  //
122854359Sroberto  // The following code is palliative -- it attempts to ensure that our
122954359Sroberto  // process has sufficient LWPs to take advantage of multiple PEs.
123082498Sroberto  // Proper long-term cures include using user-level threads bound to LWPs
123154359Sroberto  // (THR_BOUND) or using LWP-based synchronization.  Note that there is a
123254359Sroberto  // slight timing window with respect to sampling _os_thread_count, but
123356746Sroberto  // the race is benign.  Also, we should periodically recompute
123454359Sroberto  // _processors_online as the min of SC_NPROCESSORS_ONLN and the
123554359Sroberto  // the number of PEs in our partition.  You might be tempted to use
123654359Sroberto  // THR_NEW_LWP here, but I'd recommend against it as that could
123754359Sroberto  // result in undesirable growth of the libthread's LWP pool.
123854359Sroberto  // The fix below isn't sufficient; for instance, it doesn't take into count
123954359Sroberto  // LWPs parked on IO.  It does, however, help certain CPU-bound benchmarks.
124054359Sroberto  //
124154359Sroberto  // Some pathologies this scheme doesn't handle:
124254359Sroberto  // *  Threads can block, releasing the LWPs.  The LWPs can age out.
124354359Sroberto  //    When a large number of threads become ready again there aren't
124482498Sroberto  //    enough LWPs available to service them.  This can occur when the
124582498Sroberto  //    number of ready threads oscillates.
124682498Sroberto  // *  LWPs/Threads park on IO, thus taking the LWP out of circulation.
124782498Sroberto  //
124882498Sroberto  // Finally, we should call thr_setconcurrency() periodically to refresh
124982498Sroberto  // the LWP pool and thwart the LWP age-out mechanism.
125054359Sroberto  // The "+3" term provides a little slop -- we want to slightly overprovision.
125154359Sroberto
125256746Sroberto  if (AdjustConcurrency && os::Solaris::_os_thread_count < (_processors_online+3)) {
125354359Sroberto    if (!(flags & THR_BOUND)) {
125454359Sroberto      thr_setconcurrency (os::Solaris::_os_thread_count);       // avoid starvation
125554359Sroberto    }
125654359Sroberto  }
125754359Sroberto  // Although this doesn't hurt, we should warn of undefined behavior
125854359Sroberto  // when using unbound T1 threads with schedctl().  This should never
125954359Sroberto  // happen, as the compiler and VM threads are always created bound
126054359Sroberto  DEBUG_ONLY(
126154359Sroberto      if ((VMThreadHintNoPreempt || CompilerThreadHintNoPreempt) &&
126254359Sroberto          (!os::Solaris::T2_libthread() && (!(flags & THR_BOUND))) &&
126382498Sroberto          ((thr_type == vm_thread) || (thr_type == cgc_thread) ||
126482498Sroberto           (thr_type == pgc_thread) || (thr_type == compiler_thread && BackgroundCompilation))) {
126582498Sroberto         warning("schedctl behavior undefined when Compiler/VM/GC Threads are Unbound");
126682498Sroberto      }
126782498Sroberto  );
126882498Sroberto
126956746Sroberto
127054359Sroberto  // Mark that we don't have an lwp or thread id yet.
127154359Sroberto  // In case we attempt to set the priority before the thread starts.
127282498Sroberto  osthread->set_lwp_id(-1);
127354359Sroberto  osthread->set_thread_id(-1);
127482498Sroberto
127554359Sroberto  status = thr_create(NULL, stack_size, java_start, thread, flags, &tid);
1276132451Sroberto  if (status != 0) {
1277132451Sroberto    if (PrintMiscellaneous && (Verbose || WizardMode)) {
127882498Sroberto      perror("os::create_thread");
127982498Sroberto    }
128082498Sroberto    thread->set_osthread(NULL);
128182498Sroberto    // Need to clean up stuff we've allocated so far
128282498Sroberto    delete osthread;
128382498Sroberto    return false;
128482498Sroberto  }
1285132451Sroberto
128682498Sroberto  Atomic::inc(&os::Solaris::_os_thread_count);
1287132451Sroberto
128882498Sroberto  // Store info on the Solaris thread into the OSThread
1289132451Sroberto  osthread->set_thread_id(tid);
1290132451Sroberto
1291132451Sroberto  // Remember that we created this thread so we can set priority on it
1292132451Sroberto  osthread->set_vm_created();
1293132451Sroberto
129454359Sroberto  // Set the default thread priority otherwise use NormalPriority
129554359Sroberto
129654359Sroberto  if ( UseThreadPriorities ) {
129754359Sroberto     thr_setprio(tid, (DefaultThreadPriority == -1) ?
129854359Sroberto                        java_to_os_priority[NormPriority] :
129954359Sroberto                        DefaultThreadPriority);
130054359Sroberto  }
130154359Sroberto
130254359Sroberto  // Initial thread state is INITIALIZED, not SUSPENDED
130354359Sroberto  osthread->set_state(INITIALIZED);
1304132451Sroberto
1305182007Sroberto  // The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain
130654359Sroberto  return true;
130782498Sroberto}
130882498Sroberto
130982498Sroberto/* defined for >= Solaris 10. This allows builds on earlier versions
131082498Sroberto *  of Solaris to take advantage of the newly reserved Solaris JVM signals
131182498Sroberto *  With SIGJVM1, SIGJVM2, INTERRUPT_SIGNAL is SIGJVM1, ASYNC_SIGNAL is SIGJVM2
131254359Sroberto *  and -XX:+UseAltSigs does nothing since these should have no conflict
131382498Sroberto */
131482498Sroberto#if !defined(SIGJVM1)
131582498Sroberto#define SIGJVM1 39
131682498Sroberto#define SIGJVM2 40
131754359Sroberto#endif
131854359Sroberto
131954359Srobertodebug_only(static bool signal_sets_initialized = false);
132054359Srobertostatic sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs;
132154359Srobertoint os::Solaris::_SIGinterrupt = INTERRUPT_SIGNAL;
1322132451Srobertoint os::Solaris::_SIGasync = ASYNC_SIGNAL;
132354359Sroberto
132482498Srobertobool os::Solaris::is_sig_ignored(int sig) {
132554359Sroberto      struct sigaction oact;
132654359Sroberto      sigaction(sig, (struct sigaction*)NULL, &oact);
132754359Sroberto      void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*,  oact.sa_sigaction)
132854359Sroberto                                     : CAST_FROM_FN_PTR(void*,  oact.sa_handler);
132954359Sroberto      if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN))
133082498Sroberto           return true;
133154359Sroberto      else
133254359Sroberto           return false;
133354359Sroberto}
133454359Sroberto
133554359Sroberto// Note: SIGRTMIN is a macro that calls sysconf() so it will
133654359Sroberto// dynamically detect SIGRTMIN value for the system at runtime, not buildtime
133754359Srobertostatic bool isJVM1available() {
133854359Sroberto  return SIGJVM1 < SIGRTMIN;
133954359Sroberto}
134054359Sroberto
134154359Srobertovoid os::Solaris::signal_sets_init() {
134254359Sroberto  // Should also have an assertion stating we are still single-threaded.
134354359Sroberto  assert(!signal_sets_initialized, "Already initialized");
134454359Sroberto  // Fill in signals that are necessarily unblocked for all threads in
134554359Sroberto  // the VM. Currently, we unblock the following signals:
134654359Sroberto  // SHUTDOWN{1,2,3}_SIGNAL: for shutdown hooks support (unless over-ridden
134754359Sroberto  //                         by -Xrs (=ReduceSignalUsage));
134854359Sroberto  // BREAK_SIGNAL which is unblocked only by the VM thread and blocked by all
134954359Sroberto  // other threads. The "ReduceSignalUsage" boolean tells us not to alter
135054359Sroberto  // the dispositions or masks wrt these signals.
135154359Sroberto  // Programs embedding the VM that want to use the above signals for their
135254359Sroberto  // own purposes must, at this time, use the "-Xrs" option to prevent
135354359Sroberto  // interference with shutdown hooks and BREAK_SIGNAL thread dumping.
135454359Sroberto  // (See bug 4345157, and other related bugs).
135554359Sroberto  // In reality, though, unblocking these signals is really a nop, since
135654359Sroberto  // these signals are not blocked by default.
135754359Sroberto  sigemptyset(&unblocked_sigs);
135854359Sroberto  sigemptyset(&allowdebug_blocked_sigs);
135954359Sroberto  sigaddset(&unblocked_sigs, SIGILL);
136054359Sroberto  sigaddset(&unblocked_sigs, SIGSEGV);
136154359Sroberto  sigaddset(&unblocked_sigs, SIGBUS);
136254359Sroberto  sigaddset(&unblocked_sigs, SIGFPE);
136354359Sroberto
136454359Sroberto  if (isJVM1available) {
136554359Sroberto    os::Solaris::set_SIGinterrupt(SIGJVM1);
136682498Sroberto    os::Solaris::set_SIGasync(SIGJVM2);
136754359Sroberto  } else if (UseAltSigs) {
136854359Sroberto    os::Solaris::set_SIGinterrupt(ALT_INTERRUPT_SIGNAL);
136954359Sroberto    os::Solaris::set_SIGasync(ALT_ASYNC_SIGNAL);
137054359Sroberto  } else {
137154359Sroberto    os::Solaris::set_SIGinterrupt(INTERRUPT_SIGNAL);
1372132451Sroberto    os::Solaris::set_SIGasync(ASYNC_SIGNAL);
137356746Sroberto  }
137454359Sroberto
137554359Sroberto  sigaddset(&unblocked_sigs, os::Solaris::SIGinterrupt());
137654359Sroberto  sigaddset(&unblocked_sigs, os::Solaris::SIGasync());
137754359Sroberto
137854359Sroberto  if (!ReduceSignalUsage) {
137954359Sroberto   if (!os::Solaris::is_sig_ignored(SHUTDOWN1_SIGNAL)) {
138054359Sroberto      sigaddset(&unblocked_sigs, SHUTDOWN1_SIGNAL);
1381182007Sroberto      sigaddset(&allowdebug_blocked_sigs, SHUTDOWN1_SIGNAL);
138254359Sroberto   }
138382498Sroberto   if (!os::Solaris::is_sig_ignored(SHUTDOWN2_SIGNAL)) {
1384182007Sroberto      sigaddset(&unblocked_sigs, SHUTDOWN2_SIGNAL);
138554359Sroberto      sigaddset(&allowdebug_blocked_sigs, SHUTDOWN2_SIGNAL);
138682498Sroberto   }
138754359Sroberto   if (!os::Solaris::is_sig_ignored(SHUTDOWN3_SIGNAL)) {
138882498Sroberto      sigaddset(&unblocked_sigs, SHUTDOWN3_SIGNAL);
138954359Sroberto      sigaddset(&allowdebug_blocked_sigs, SHUTDOWN3_SIGNAL);
139054359Sroberto   }
139154359Sroberto  }
139254359Sroberto  // Fill in signals that are blocked by all but the VM thread.
139354359Sroberto  sigemptyset(&vm_sigs);
139482498Sroberto  if (!ReduceSignalUsage)
139554359Sroberto    sigaddset(&vm_sigs, BREAK_SIGNAL);
139682498Sroberto  debug_only(signal_sets_initialized = true);
1397182007Sroberto
139882498Sroberto  // For diagnostics only used in run_periodic_checks
139982498Sroberto  sigemptyset(&check_signal_done);
1400182007Sroberto}
140182498Sroberto
140282498Sroberto// These are signals that are unblocked while a thread is running Java.
140382498Sroberto// (For some reason, they get blocked by default.)
140482498Srobertosigset_t* os::Solaris::unblocked_signals() {
140582498Sroberto  assert(signal_sets_initialized, "Not initialized");
140654359Sroberto  return &unblocked_sigs;
140754359Sroberto}
140854359Sroberto
140982498Sroberto// These are the signals that are blocked while a (non-VM) thread is
141054359Sroberto// running Java. Only the VM thread handles these signals.
141154359Srobertosigset_t* os::Solaris::vm_signals() {
141254359Sroberto  assert(signal_sets_initialized, "Not initialized");
141354359Sroberto  return &vm_sigs;
141454359Sroberto}
141554359Sroberto
141682498Sroberto// These are signals that are blocked during cond_wait to allow debugger in
141754359Srobertosigset_t* os::Solaris::allowdebug_blocked_signals() {
141882498Sroberto  assert(signal_sets_initialized, "Not initialized");
1419182007Sroberto  return &allowdebug_blocked_sigs;
142082498Sroberto}
142182498Sroberto
1422182007Sroberto// First crack at OS-specific initialization, from inside the new thread.
142382498Srobertovoid os::initialize_thread() {
1424132451Sroberto  int r = thr_main() ;
142582498Sroberto  guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ;
142682498Sroberto  if (r) {
142782498Sroberto    JavaThread* jt = (JavaThread *)Thread::current();
142882498Sroberto    assert(jt != NULL,"Sanity check");
142982498Sroberto    size_t stack_size;
143082498Sroberto    address base = jt->stack_base();
143182498Sroberto    if (Arguments::created_by_java_launcher()) {
143282498Sroberto      // Use 2MB to allow for Solaris 7 64 bit mode.
1433182007Sroberto      stack_size = JavaThread::stack_size_at_create() == 0
1434182007Sroberto        ? 2048*K : JavaThread::stack_size_at_create();
1435182007Sroberto
1436132451Sroberto      // There are rare cases when we may have already used more than
143782498Sroberto      // the basic stack size allotment before this method is invoked.
143882498Sroberto      // Attempt to allow for a normally sized java_stack.
143982498Sroberto      size_t current_stack_offset = (size_t)(base - (address)&stack_size);
144082498Sroberto      stack_size += ReservedSpace::page_align_size_down(current_stack_offset);
144182498Sroberto    } else {
1442182007Sroberto      // 6269555: If we were not created by a Java launcher, i.e. if we are
144354359Sroberto      // running embedded in a native application, treat the primordial thread
144454359Sroberto      // as much like a native attached thread as possible.  This means using
144554359Sroberto      // the current stack size from thr_stksegment(), unless it is too large
144682498Sroberto      // to reliably setup guard pages.  A reasonable max size is 8MB.
144754359Sroberto      size_t current_size = current_stack_size();
144854359Sroberto      // This should never happen, but just in case....
144954359Sroberto      if (current_size == 0) current_size = 2 * K * K;
145054359Sroberto      stack_size = current_size > (8 * K * K) ? (8 * K * K) : current_size;
145154359Sroberto    }
145254359Sroberto    address bottom = (address)align_size_up((intptr_t)(base - stack_size), os::vm_page_size());;
145354359Sroberto    stack_size = (size_t)(base - bottom);
1454132451Sroberto
1455132451Sroberto    assert(stack_size > 0, "Stack size calculation problem");
1456132451Sroberto
1457132451Sroberto    if (stack_size > jt->stack_size()) {
145854359Sroberto      NOT_PRODUCT(
145954359Sroberto        struct rlimit limits;
1460132451Sroberto        getrlimit(RLIMIT_STACK, &limits);
1461182007Sroberto        size_t size = adjust_stack_size(base, (size_t)limits.rlim_cur);
1462132451Sroberto        assert(size >= jt->stack_size(), "Stack size problem in main thread");
1463132451Sroberto      )
1464132451Sroberto      tty->print_cr(
1465132451Sroberto        "Stack size of %d Kb exceeds current limit of %d Kb.\n"
1466132451Sroberto        "(Stack sizes are rounded up to a multiple of the system page size.)\n"
1467132451Sroberto        "See limit(1) to increase the stack size limit.",
1468132451Sroberto        stack_size / K, jt->stack_size() / K);
1469132451Sroberto      vm_exit(1);
1470182007Sroberto    }
1471132451Sroberto    assert(jt->stack_size() >= stack_size,
1472132451Sroberto          "Attempt to map more stack than was allocated");
1473132451Sroberto    jt->set_stack_size(stack_size);
147454359Sroberto  }
1475132451Sroberto
1476132451Sroberto   // 5/22/01: Right now alternate signal stacks do not handle
1477132451Sroberto   // throwing stack overflow exceptions, see bug 4463178
1478132451Sroberto   // Until a fix is found for this, T2 will NOT imply alternate signal
1479132451Sroberto   // stacks.
1480132451Sroberto   // If using T2 libthread threads, install an alternate signal stack.
1481132451Sroberto   // Because alternate stacks associate with LWPs on Solaris,
1482132451Sroberto   // see sigaltstack(2), if using UNBOUND threads, or if UseBoundThreads
1483132451Sroberto   // we prefer to explicitly stack bang.
1484132451Sroberto   // If not using T2 libthread, but using UseBoundThreads any threads
1485132451Sroberto   // (primordial thread, jni_attachCurrentThread) we do not create,
1486132451Sroberto   // probably are not bound, therefore they can not have an alternate
1487132451Sroberto   // signal stack. Since our stack banging code is generated and
1488132451Sroberto   // is shared across threads, all threads must be bound to allow
1489132451Sroberto   // using alternate signal stacks.  The alternative is to interpose
1490132451Sroberto   // on _lwp_create to associate an alt sig stack with each LWP,
1491132451Sroberto   // and this could be a problem when the JVM is embedded.
1492132451Sroberto   // We would prefer to use alternate signal stacks with T2
1493132451Sroberto   // Since there is currently no accurate way to detect T2
1494132451Sroberto   // we do not. Assuming T2 when running T1 causes sig 11s or assertions
1495182007Sroberto   // on installing alternate signal stacks
1496182007Sroberto
1497182007Sroberto
1498182007Sroberto   // 05/09/03: removed alternate signal stack support for Solaris
1499182007Sroberto   // The alternate signal stack mechanism is no longer needed to
1500182007Sroberto   // handle stack overflow. This is now handled by allocating
1501182007Sroberto   // guard pages (red zone) and stackbanging.
1502182007Sroberto   // Initially the alternate signal stack mechanism was removed because
1503182007Sroberto   // it did not work with T1 llibthread. Alternate
1504182007Sroberto   // signal stacks MUST have all threads bound to lwps. Applications
1505182007Sroberto   // can create their own threads and attach them without their being
1506132451Sroberto   // bound under T1. This is frequently the case for the primordial thread.
1507132451Sroberto   // If we were ever to reenable this mechanism we would need to
1508132451Sroberto   // use the dynamic check for T2 libthread.
1509132451Sroberto
1510132451Sroberto  os::Solaris::init_thread_fpu_state();
1511132451Sroberto}
1512132451Sroberto
1513132451Sroberto
1514132451Sroberto
1515132451Sroberto// Free Solaris resources related to the OSThread
1516132451Srobertovoid os::free_thread(OSThread* osthread) {
1517132451Sroberto  assert(osthread != NULL, "os::free_thread but osthread not set");
1518182007Sroberto
1519132451Sroberto
1520132451Sroberto  // We are told to free resources of the argument thread,
1521182007Sroberto  // but we can only really operate on the current thread.
1522132451Sroberto  // The main thread must take the VMThread down synchronously
1523132451Sroberto  // before the main thread exits and frees up CodeHeap
1524132451Sroberto  guarantee((Thread::current()->osthread() == osthread
1525182007Sroberto     || (osthread == VMThread::vm_thread()->osthread())), "os::free_thread but not current thread");
1526132451Sroberto  if (Thread::current()->osthread() == osthread) {
1527132451Sroberto    // Restore caller's signal mask
1528132451Sroberto    sigset_t sigmask = osthread->caller_sigmask();
1529182007Sroberto    thr_sigsetmask(SIG_SETMASK, &sigmask, NULL);
1530182007Sroberto  }
1531132451Sroberto  delete osthread;
1532132451Sroberto}
1533132451Sroberto
1534132451Srobertovoid os::pd_start_thread(Thread* thread) {
1535132451Sroberto  int status = thr_continue(thread->osthread()->thread_id());
1536132451Sroberto  assert_status(status == 0, status, "thr_continue failed");
1537132451Sroberto}
1538132451Sroberto
1539132451Sroberto
1540132451Srobertointx os::current_thread_id() {
1541182007Sroberto  return (intx)thr_self();
1542132451Sroberto}
1543132451Sroberto
1544182007Srobertostatic pid_t _initial_pid = 0;
1545132451Sroberto
1546132451Srobertoint os::current_process_id() {
1547182007Sroberto  return (int)(_initial_pid ? _initial_pid : getpid());
1548132451Sroberto}
1549132451Sroberto
1550182007Srobertoint os::allocate_thread_local_storage() {
1551182007Sroberto  // %%%       in Win32 this allocates a memory segment pointed to by a
1552132451Sroberto  //           register.  Dan Stein can implement a similar feature in
1553132451Sroberto  //           Solaris.  Alternatively, the VM can do the same thing
1554132451Sroberto  //           explicitly: malloc some storage and keep the pointer in a
1555132451Sroberto  //           register (which is part of the thread's context) (or keep it
1556132451Sroberto  //           in TLS).
1557132451Sroberto  // %%%       In current versions of Solaris, thr_self and TSD can
1558132451Sroberto  //           be accessed via short sequences of displaced indirections.
1559132451Sroberto  //           The value of thr_self is available as %g7(36).
1560132451Sroberto  //           The value of thr_getspecific(k) is stored in %g7(12)(4)(k*4-4),
1561132451Sroberto  //           assuming that the current thread already has a value bound to k.
1562132451Sroberto  //           It may be worth experimenting with such access patterns,
1563132451Sroberto  //           and later having the parameters formally exported from a Solaris
1564132451Sroberto  //           interface.  I think, however, that it will be faster to
1565182007Sroberto  //           maintain the invariant that %g2 always contains the
1566132451Sroberto  //           JavaThread in Java code, and have stubs simply
1567182007Sroberto  //           treat %g2 as a caller-save register, preserving it in a %lN.
1568132451Sroberto  thread_key_t tk;
1569132451Sroberto  if (thr_keycreate( &tk, NULL ) )
1570132451Sroberto    fatal1("os::allocate_thread_local_storage: thr_keycreate failed (%s)", strerror(errno));
1571132451Sroberto  return int(tk);
1572132451Sroberto}
1573132451Sroberto
1574132451Srobertovoid os::free_thread_local_storage(int index) {
1575132451Sroberto  // %%% don't think we need anything here
1576132451Sroberto  // if ( pthread_key_delete((pthread_key_t) tk) )
1577132451Sroberto  //   fatal("os::free_thread_local_storage: pthread_key_delete failed");
1578132451Sroberto}
1579132451Sroberto
1580132451Sroberto#define SMALLINT 32   // libthread allocate for tsd_common is a version specific
1581132451Sroberto                      // small number - point is NO swap space available
1582132451Srobertovoid os::thread_local_storage_at_put(int index, void* value) {
1583182007Sroberto  // %%% this is used only in threadLocalStorage.cpp
1584182007Sroberto  if (thr_setspecific((thread_key_t)index, value)) {
1585132451Sroberto    if (errno == ENOMEM) {
1586132451Sroberto       vm_exit_out_of_memory(SMALLINT, "thr_setspecific: out of swap space");
1587132451Sroberto    } else {
1588132451Sroberto      fatal1("os::thread_local_storage_at_put: thr_setspecific failed (%s)", strerror(errno));
1589132451Sroberto    }
1590132451Sroberto  } else {
1591132451Sroberto      ThreadLocalStorage::set_thread_in_slot ((Thread *) value) ;
1592132451Sroberto  }
1593132451Sroberto}
1594132451Sroberto
1595132451Sroberto// This function could be called before TLS is initialized, for example, when
1596132451Sroberto// VM receives an async signal or when VM causes a fatal error during
1597132451Sroberto// initialization. Return NULL if thr_getspecific() fails.
1598132451Srobertovoid* os::thread_local_storage_at(int index) {
1599132451Sroberto  // %%% this is used only in threadLocalStorage.cpp
1600132451Sroberto  void* r = NULL;
1601132451Sroberto  return thr_getspecific((thread_key_t)index, &r) != 0 ? NULL : r;
1602132451Sroberto}
1603132451Sroberto
1604132451Sroberto
1605132451Srobertoconst int NANOSECS_PER_MILLISECS = 1000000;
1606132451Sroberto// gethrtime can move backwards if read from one cpu and then a different cpu
1607132451Sroberto// getTimeNanos is guaranteed to not move backward on Solaris
1608132451Sroberto// local spinloop created as faster for a CAS on an int than
1609132451Sroberto// a CAS on a 64bit jlong. Also Atomic::cmpxchg for jlong is not
1610132451Sroberto// supported on sparc v8 or pre supports_cx8 intel boxes.
1611132451Sroberto// oldgetTimeNanos for systems which do not support CAS on 64bit jlong
1612132451Sroberto// i.e. sparc v8 and pre supports_cx8 (i486) intel boxes
1613132451Srobertoinline hrtime_t oldgetTimeNanos() {
1614182007Sroberto  int gotlock = LOCK_INVALID;
1615132451Sroberto  hrtime_t newtime = gethrtime();
1616132451Sroberto
1617132451Sroberto  for (;;) {
1618132451Sroberto// grab lock for max_hrtime
1619182007Sroberto    int curlock = max_hrtime_lock;
1620132451Sroberto    if (curlock & LOCK_BUSY)  continue;
1621132451Sroberto    if (gotlock = Atomic::cmpxchg(LOCK_BUSY, &max_hrtime_lock, LOCK_FREE) != LOCK_FREE) continue;
1622132451Sroberto    if (newtime > max_hrtime) {
1623132451Sroberto      max_hrtime = newtime;
1624132451Sroberto    } else {
1625132451Sroberto      newtime = max_hrtime;
1626132451Sroberto    }
1627132451Sroberto    // release lock
1628132451Sroberto    max_hrtime_lock = LOCK_FREE;
1629132451Sroberto    return newtime;
1630132451Sroberto  }
1631132451Sroberto}
1632132451Sroberto// gethrtime can move backwards if read from one cpu and then a different cpu
1633132451Sroberto// getTimeNanos is guaranteed to not move backward on Solaris
1634182007Srobertoinline hrtime_t getTimeNanos() {
1635132451Sroberto  if (VM_Version::supports_cx8()) {
1636132451Sroberto    bool retry = false;
1637132451Sroberto    hrtime_t newtime = gethrtime();
1638132451Sroberto    hrtime_t oldmaxtime = max_hrtime;
1639132451Sroberto    hrtime_t retmaxtime = oldmaxtime;
1640132451Sroberto    while ((newtime > retmaxtime) && (retry == false || retmaxtime != oldmaxtime)) {
1641132451Sroberto      oldmaxtime = retmaxtime;
1642132451Sroberto      retmaxtime = Atomic::cmpxchg(newtime, (volatile jlong *)&max_hrtime, oldmaxtime);
1643132451Sroberto      retry = true;
1644132451Sroberto    }
1645132451Sroberto    return (newtime > retmaxtime) ? newtime : retmaxtime;
1646132451Sroberto  } else {
1647132451Sroberto    return oldgetTimeNanos();
1648132451Sroberto  }
1649132451Sroberto}
1650132451Sroberto
1651132451Sroberto// Time since start-up in seconds to a fine granularity.
1652132451Sroberto// Used by VMSelfDestructTimer and the MemProfiler.
1653132451Srobertodouble os::elapsedTime() {
1654132451Sroberto  return (double)(getTimeNanos() - first_hrtime) / (double)hrtime_hz;
1655132451Sroberto}
1656132451Sroberto
1657182007Srobertojlong os::elapsed_counter() {
1658182007Sroberto  return (jlong)(getTimeNanos() - first_hrtime);
1659182007Sroberto}
1660182007Sroberto
1661182007Srobertojlong os::elapsed_frequency() {
1662182007Sroberto   return hrtime_hz;
1663182007Sroberto}
1664182007Sroberto
1665182007Sroberto// Return the real, user, and system times in seconds from an
1666182007Sroberto// arbitrary fixed point in the past.
1667182007Srobertobool os::getTimesSecs(double* process_real_time,
1668182007Sroberto                  double* process_user_time,
1669182007Sroberto                  double* process_system_time) {
1670182007Sroberto  struct tms ticks;
1671132451Sroberto  clock_t real_ticks = times(&ticks);
1672132451Sroberto
1673132451Sroberto  if (real_ticks == (clock_t) (-1)) {
1674132451Sroberto    return false;
1675132451Sroberto  } else {
1676132451Sroberto    double ticks_per_second = (double) clock_tics_per_sec;
1677182007Sroberto    *process_user_time = ((double) ticks.tms_utime) / ticks_per_second;
1678182007Sroberto    *process_system_time = ((double) ticks.tms_stime) / ticks_per_second;
1679182007Sroberto    // For consistency return the real time from getTimeNanos()
1680182007Sroberto    // converted to seconds.
1681132451Sroberto    *process_real_time = ((double) getTimeNanos()) / ((double) NANOUNITS);
1682132451Sroberto
1683132451Sroberto    return true;
1684132451Sroberto  }
1685182007Sroberto}
1686182007Sroberto
1687182007Sroberto// Used internally for comparisons only
1688182007Sroberto// getTimeMillis guaranteed to not move backwards on Solaris
1689182007Srobertojlong getTimeMillis() {
1690182007Sroberto  jlong nanotime = getTimeNanos();
1691182007Sroberto  return (jlong)(nanotime / NANOSECS_PER_MILLISECS);
1692182007Sroberto}
1693182007Sroberto
1694182007Sroberto// Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
1695182007Srobertojlong os::javaTimeMillis() {
1696182007Sroberto  timeval t;
1697132451Sroberto  if (gettimeofday( &t, NULL) == -1)
1698182007Sroberto    fatal1("os::javaTimeMillis: gettimeofday (%s)", strerror(errno));
1699132451Sroberto  return jlong(t.tv_sec) * 1000  +  jlong(t.tv_usec) / 1000;
1700132451Sroberto}
1701132451Sroberto
1702132451Srobertojlong os::javaTimeNanos() {
1703132451Sroberto  return (jlong)getTimeNanos();
1704132451Sroberto}
1705182007Sroberto
1706182007Srobertovoid os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
1707182007Sroberto  info_ptr->max_value = ALL_64_BITS;      // gethrtime() uses all 64 bits
1708182007Sroberto  info_ptr->may_skip_backward = false;    // not subject to resetting or drifting
1709132451Sroberto  info_ptr->may_skip_forward = false;     // not subject to resetting or drifting
1710132451Sroberto  info_ptr->kind = JVMTI_TIMER_ELAPSED;   // elapsed not CPU time
1711132451Sroberto}
1712132451Sroberto
1713132451Srobertochar * os::local_time_string(char *buf, size_t buflen) {
1714132451Sroberto  struct tm t;
1715182007Sroberto  time_t long_time;
1716132451Sroberto  time(&long_time);
1717132451Sroberto  localtime_r(&long_time, &t);
1718182007Sroberto  jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",
1719132451Sroberto               t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
1720132451Sroberto               t.tm_hour, t.tm_min, t.tm_sec);
1721132451Sroberto  return buf;
1722182007Sroberto}
1723132451Sroberto
1724182007Sroberto// Note: os::shutdown() might be called very early during initialization, or
1725132451Sroberto// called from signal handler. Before adding something to os::shutdown(), make
1726132451Sroberto// sure it is async-safe and can handle partially initialized VM.
1727132451Srobertovoid os::shutdown() {
1728132451Sroberto
1729132451Sroberto  // allow PerfMemory to attempt cleanup of any persistent resources
1730132451Sroberto  perfMemory_exit();
1731132451Sroberto
1732132451Sroberto  // needs to remove object in file system
1733132451Sroberto  AttachListener::abort();
1734132451Sroberto
1735132451Sroberto  // flush buffered output, finish log files
1736182007Sroberto  ostream_abort();
1737132451Sroberto
1738132451Sroberto  // Check for abort hook
1739132451Sroberto  abort_hook_t abort_hook = Arguments::abort_hook();
174054359Sroberto  if (abort_hook != NULL) {
174154359Sroberto    abort_hook();
174254359Sroberto  }
1743132451Sroberto}
174454359Sroberto
1745132451Sroberto// Note: os::abort() might be called very early during initialization, or
174682498Sroberto// called from signal handler. Before adding something to os::abort(), make
174782498Sroberto// sure it is async-safe and can handle partially initialized VM.
174882498Srobertovoid os::abort(bool dump_core) {
174982498Sroberto  os::shutdown();
175054359Sroberto  if (dump_core) {
175154359Sroberto#ifndef PRODUCT
175254359Sroberto    fdStream out(defaultStream::output_fd());
175354359Sroberto    out.print_raw("Current thread is ");
175482498Sroberto    char buf[16];
175554359Sroberto    jio_snprintf(buf, sizeof(buf), UINTX_FORMAT, os::current_thread_id());
175654359Sroberto    out.print_raw_cr(buf);
175754359Sroberto    out.print_raw_cr("Dumping core ...");
175854359Sroberto#endif
175954359Sroberto    ::abort(); // dump core (for debugging)
176054359Sroberto  }
176182498Sroberto
176282498Sroberto  ::exit(1);
176382498Sroberto}
176454359Sroberto
176554359Sroberto// Die immediately, no exit hook, no abort hook, no cleanup.
1766182007Srobertovoid os::die() {
176754359Sroberto  _exit(-1);
1768182007Sroberto}
1769132451Sroberto
1770132451Sroberto// unused
1771132451Srobertovoid os::set_error_file(const char *logfile) {}
1772182007Sroberto
177354359Sroberto// DLL functions
1774182007Sroberto
177582498Srobertoconst char* os::dll_file_extension() { return ".so"; }
177654359Sroberto
177754359Srobertoconst char* os::get_temp_directory() { return "/tmp/"; }
177854359Sroberto
177954359Srobertoconst char* os::get_current_directory(char *buf, int buflen) {
178054359Sroberto  return getcwd(buf, buflen);
178154359Sroberto}
178254359Sroberto
178354359Sroberto// check if addr is inside libjvm[_g].so
178454359Srobertobool os::address_is_in_vm(address addr) {
178554359Sroberto  static address libjvm_base_addr;
178654359Sroberto  Dl_info dlinfo;
178754359Sroberto
178854359Sroberto  if (libjvm_base_addr == NULL) {
178954359Sroberto    dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo);
179054359Sroberto    libjvm_base_addr = (address)dlinfo.dli_fbase;
179154359Sroberto    assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm");
179254359Sroberto  }
179354359Sroberto
179454359Sroberto  if (dladdr((void *)addr, &dlinfo)) {
179554359Sroberto    if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true;
179654359Sroberto  }
1797182007Sroberto
179854359Sroberto  return false;
179954359Sroberto}
180054359Sroberto
180154359Srobertotypedef int (*dladdr1_func_type) (void *, Dl_info *, void **, int);
1802132451Srobertostatic dladdr1_func_type dladdr1_func = NULL;
180382498Sroberto
180456746Srobertobool os::dll_address_to_function_name(address addr, char *buf,
1805132451Sroberto                                      int buflen, int * offset) {
180656746Sroberto  Dl_info dlinfo;
180756746Sroberto
180882498Sroberto  // dladdr1_func was initialized in os::init()
180956746Sroberto  if (dladdr1_func){
181056746Sroberto      // yes, we have dladdr1
1811132451Sroberto
181256746Sroberto      // Support for dladdr1 is checked at runtime; it may be
181356746Sroberto      // available even if the vm is built on a machine that does
181456746Sroberto      // not have dladdr1 support.  Make sure there is a value for
1815132451Sroberto      // RTLD_DL_SYMENT.
181682498Sroberto      #ifndef RTLD_DL_SYMENT
1817132451Sroberto      #define RTLD_DL_SYMENT 1
1818132451Sroberto      #endif
1819132451Sroberto      Sym * info;
1820132451Sroberto      if (dladdr1_func((void *)addr, &dlinfo, (void **)&info,
1821132451Sroberto                       RTLD_DL_SYMENT)) {
1822132451Sroberto          if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
1823132451Sroberto          if (offset) *offset = addr - (address)dlinfo.dli_saddr;
182482498Sroberto
1825132451Sroberto          // check if the returned symbol really covers addr
1826132451Sroberto          return ((char *)dlinfo.dli_saddr + info->st_size > (char *)addr);
1827132451Sroberto      } else {
182854359Sroberto          if (buf) buf[0] = '\0';
1829132451Sroberto          if (offset) *offset  = -1;
1830132451Sroberto          return false;
1831132451Sroberto      }
1832132451Sroberto  } else {
183354359Sroberto      // no, only dladdr is available
1834132451Sroberto      if(dladdr((void *)addr, &dlinfo)) {
1835132451Sroberto          if (buf) jio_snprintf(buf, buflen, dlinfo.dli_sname);
183682498Sroberto          if (offset) *offset = addr - (address)dlinfo.dli_saddr;
1837132451Sroberto          return true;
183856746Sroberto      } else {
183956746Sroberto          if (buf) buf[0] = '\0';
184054359Sroberto          if (offset) *offset  = -1;
1841132451Sroberto          return false;
184254359Sroberto      }
184354359Sroberto  }
184482498Sroberto}
184554359Sroberto
184654359Srobertobool os::dll_address_to_library_name(address addr, char* buf,
1847132451Sroberto                                     int buflen, int* offset) {
1848132451Sroberto  Dl_info dlinfo;
1849132451Sroberto
185054359Sroberto  if (dladdr((void*)addr, &dlinfo)){
1851132451Sroberto     if (buf) jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
1852132451Sroberto     if (offset) *offset = addr - (address)dlinfo.dli_fbase;
185354359Sroberto     return true;
185454359Sroberto  } else {
185554359Sroberto     if (buf) buf[0] = '\0';
185654359Sroberto     if (offset) *offset = -1;
1857132451Sroberto     return false;
1858132451Sroberto  }
1859132451Sroberto}
186054359Sroberto
186182498Sroberto// Prints the names and full paths of all opened dynamic libraries
186254359Sroberto// for current process
1863132451Srobertovoid os::print_dll_info(outputStream * st) {
186454359Sroberto    Dl_info dli;
186554359Sroberto    void *handle;
186682498Sroberto    Link_map *map;
186754359Sroberto    Link_map *p;
186854359Sroberto
1869132451Sroberto    st->print_cr("Dynamic libraries:"); st->flush();
187054359Sroberto
1871132451Sroberto    if (!dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli)) {
1872132451Sroberto        st->print_cr("Error: Cannot print dynamic libraries.");
1873132451Sroberto        return;
1874132451Sroberto    }
1875132451Sroberto    handle = dlopen(dli.dli_fname, RTLD_LAZY);
187654359Sroberto    if (handle == NULL) {
1877132451Sroberto        st->print_cr("Error: Cannot print dynamic libraries.");
1878132451Sroberto        return;
1879132451Sroberto    }
1880132451Sroberto    dlinfo(handle, RTLD_DI_LINKMAP, &map);
188156746Sroberto    if (map == NULL) {
1882132451Sroberto        st->print_cr("Error: Cannot print dynamic libraries.");
188382498Sroberto        return;
188482498Sroberto    }
188582498Sroberto
1886132451Sroberto    while (map->l_prev != NULL)
1887132451Sroberto        map = map->l_prev;
1888132451Sroberto
1889132451Sroberto    while (map != NULL) {
189082498Sroberto        st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name);
1891132451Sroberto        map = map->l_next;
1892132451Sroberto    }
1893132451Sroberto
1894132451Sroberto    dlclose(handle);
1895132451Sroberto}
1896132451Sroberto
1897132451Sroberto  // Loads .dll/.so and
1898132451Sroberto  // in case of error it checks if .dll/.so was built for the
189982498Sroberto  // same architecture as Hotspot is running on
1900132451Sroberto
1901132451Srobertovoid * os::dll_load(const char *filename, char *ebuf, int ebuflen)
190282498Sroberto{
1903132451Sroberto  void * result= ::dlopen(filename, RTLD_LAZY);
190482498Sroberto  if (result != NULL) {
1905132451Sroberto    // Successful loading
190682498Sroberto    return result;
1907132451Sroberto  }
190882498Sroberto
1909132451Sroberto  Elf32_Ehdr elf_head;
191082498Sroberto
191182498Sroberto  // Read system error message into ebuf
191282498Sroberto  // It may or may not be overwritten below
1913132451Sroberto  ::strncpy(ebuf, ::dlerror(), ebuflen-1);
1914132451Sroberto  ebuf[ebuflen-1]='\0';
1915132451Sroberto  int diag_msg_max_length=ebuflen-strlen(ebuf);
191682498Sroberto  char* diag_msg_buf=ebuf+strlen(ebuf);
1917132451Sroberto
1918132451Sroberto  if (diag_msg_max_length==0) {
1919132451Sroberto    // No more space in ebuf for additional diagnostics message
1920132451Sroberto    return NULL;
1921132451Sroberto  }
1922132451Sroberto
1923132451Sroberto
1924132451Sroberto  int file_descriptor= ::open(filename, O_RDONLY | O_NONBLOCK);
192582498Sroberto
1926132451Sroberto  if (file_descriptor < 0) {
1927132451Sroberto    // Can't open library, report dlerror() message
192882498Sroberto    return NULL;
1929132451Sroberto  }
193056746Sroberto
1931132451Sroberto  bool failed_to_read_elf_head=
193254359Sroberto    (sizeof(elf_head)!=
1933132451Sroberto        (::read(file_descriptor, &elf_head,sizeof(elf_head)))) ;
1934132451Sroberto
193582498Sroberto  ::close(file_descriptor);
193682498Sroberto  if (failed_to_read_elf_head) {
193782498Sroberto    // file i/o error - report dlerror() msg
193882498Sroberto    return NULL;
1939132451Sroberto  }
1940132451Sroberto
194182498Sroberto  typedef struct {
1942132451Sroberto    Elf32_Half  code;         // Actual value as defined in elf.h
194382498Sroberto    Elf32_Half  compat_class; // Compatibility of archs at VM's sense
194482498Sroberto    char        elf_class;    // 32 or 64 bit
194582498Sroberto    char        endianess;    // MSB or LSB
194682498Sroberto    char*       name;         // String representation
194782498Sroberto  } arch_t;
1948132451Sroberto
1949132451Sroberto  static const arch_t arch_array[]={
1950132451Sroberto    {EM_386,         EM_386,     ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
195182498Sroberto    {EM_486,         EM_386,     ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
1952132451Sroberto    {EM_IA_64,       EM_IA_64,   ELFCLASS64, ELFDATA2LSB, (char*)"IA 64"},
1953132451Sroberto    {EM_X86_64,      EM_X86_64,  ELFCLASS64, ELFDATA2LSB, (char*)"AMD 64"},
1954132451Sroberto    {EM_SPARC,       EM_SPARC,   ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
1955132451Sroberto    {EM_SPARC32PLUS, EM_SPARC,   ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
1956132451Sroberto    {EM_SPARCV9,     EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"},
1957132451Sroberto    {EM_PPC,         EM_PPC,     ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"},
1958132451Sroberto    {EM_PPC64,       EM_PPC64,   ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"}
195982498Sroberto  };
196082498Sroberto
1961132451Sroberto  #if  (defined IA32)
1962132451Sroberto    static  Elf32_Half running_arch_code=EM_386;
1963132451Sroberto  #elif   (defined AMD64)
1964132451Sroberto    static  Elf32_Half running_arch_code=EM_X86_64;
1965132451Sroberto  #elif  (defined IA64)
1966132451Sroberto    static  Elf32_Half running_arch_code=EM_IA_64;
1967132451Sroberto  #elif  (defined __sparc) && (defined _LP64)
1968132451Sroberto    static  Elf32_Half running_arch_code=EM_SPARCV9;
196982498Sroberto  #elif  (defined __sparc) && (!defined _LP64)
1970132451Sroberto    static  Elf32_Half running_arch_code=EM_SPARC;
1971132451Sroberto  #elif  (defined __powerpc64__)
197282498Sroberto    static  Elf32_Half running_arch_code=EM_PPC64;
1973132451Sroberto  #elif  (defined __powerpc__)
1974132451Sroberto    static  Elf32_Half running_arch_code=EM_PPC;
1975132451Sroberto  #else
1976132451Sroberto    #error Method os::dll_load requires that one of following is defined:\
1977132451Sroberto         IA32, AMD64, IA64, __sparc, __powerpc__
1978132451Sroberto  #endif
1979132451Sroberto
1980132451Sroberto  // Identify compatability class for VM's architecture and library's architecture
1981132451Sroberto  // Obtain string descriptions for architectures
1982132451Sroberto
1983132451Sroberto  arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL};
1984132451Sroberto  int running_arch_index=-1;
1985132451Sroberto
1986132451Sroberto  for (unsigned int i=0 ; i < ARRAY_SIZE(arch_array) ; i++ ) {
1987132451Sroberto    if (running_arch_code == arch_array[i].code) {
1988132451Sroberto      running_arch_index    = i;
1989132451Sroberto    }
1990132451Sroberto    if (lib_arch.code == arch_array[i].code) {
1991132451Sroberto      lib_arch.compat_class = arch_array[i].compat_class;
1992132451Sroberto      lib_arch.name         = arch_array[i].name;
1993132451Sroberto    }
1994132451Sroberto  }
1995132451Sroberto
199682498Sroberto  assert(running_arch_index != -1,
199782498Sroberto    "Didn't find running architecture code (running_arch_code) in arch_array");
1998132451Sroberto  if (running_arch_index == -1) {
1999132451Sroberto    // Even though running architecture detection failed
2000132451Sroberto    // we may still continue with reporting dlerror() message
2001182007Sroberto    return NULL;
2002132451Sroberto  }
2003132451Sroberto
2004182007Sroberto  if (lib_arch.endianess != arch_array[running_arch_index].endianess) {
2005132451Sroberto    ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)");
2006132451Sroberto    return NULL;
200782498Sroberto  }
200854359Sroberto
2009132451Sroberto  if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {
201054359Sroberto    ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)");
2011182007Sroberto    return NULL;
201282498Sroberto  }
2013132451Sroberto
2014132451Sroberto  if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) {
2015132451Sroberto    if ( lib_arch.name!=NULL ) {
2016182007Sroberto      ::snprintf(diag_msg_buf, diag_msg_max_length-1,
2017132451Sroberto        " (Possible cause: can't load %s-bit .so on a %s-bit platform)",
2018132451Sroberto        lib_arch.name, arch_array[running_arch_index].name);
2019132451Sroberto    } else {
2020132451Sroberto      ::snprintf(diag_msg_buf, diag_msg_max_length-1,
2021132451Sroberto      " (Possible cause: can't load this .so (machine code=0x%x) on a %s-bit platform)",
2022132451Sroberto        lib_arch.code,
2023132451Sroberto        arch_array[running_arch_index].name);
2024132451Sroberto    }
2025132451Sroberto  }
2026132451Sroberto
2027132451Sroberto  return NULL;
2028132451Sroberto}
2029132451Sroberto
2030132451Sroberto
2031132451Sroberto
2032132451Srobertobool _print_ascii_file(const char* filename, outputStream* st) {
2033132451Sroberto  int fd = open(filename, O_RDONLY);
2034132451Sroberto  if (fd == -1) {
2035132451Sroberto     return false;
2036132451Sroberto  }
2037132451Sroberto
2038132451Sroberto  char buf[32];
2039132451Sroberto  int bytes;
2040132451Sroberto  while ((bytes = read(fd, buf, sizeof(buf))) > 0) {
2041132451Sroberto    st->print_raw(buf, bytes);
2042132451Sroberto  }
2043132451Sroberto
2044132451Sroberto  close(fd);
2045132451Sroberto
2046132451Sroberto  return true;
2047132451Sroberto}
2048132451Sroberto
2049132451Srobertovoid os::print_os_info(outputStream* st) {
2050132451Sroberto  st->print("OS:");
205182498Sroberto
2052132451Sroberto  if (!_print_ascii_file("/etc/release", st)) {
205382498Sroberto    st->print("Solaris");
2054132451Sroberto  }
2055132451Sroberto  st->cr();
2056132451Sroberto
2057132451Sroberto  // kernel
2058132451Sroberto  st->print("uname:");
2059132451Sroberto  struct utsname name;
2060132451Sroberto  uname(&name);
2061132451Sroberto  st->print(name.sysname); st->print(" ");
2062132451Sroberto  st->print(name.release); st->print(" ");
2063132451Sroberto  st->print(name.version); st->print(" ");
2064132451Sroberto  st->print(name.machine);
206582498Sroberto
2066132451Sroberto  // libthread
2067132451Sroberto  if (os::Solaris::T2_libthread()) st->print("  (T2 libthread)");
206882498Sroberto  else st->print("  (T1 libthread)");
2069132451Sroberto  st->cr();
207082498Sroberto
2071132451Sroberto  // rlimit
207282498Sroberto  st->print("rlimit:");
2073132451Sroberto  struct rlimit rlim;
2074132451Sroberto
2075132451Sroberto  st->print(" STACK ");
2076132451Sroberto  getrlimit(RLIMIT_STACK, &rlim);
2077132451Sroberto  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
2078132451Sroberto  else st->print("%uk", rlim.rlim_cur >> 10);
2079132451Sroberto
2080132451Sroberto  st->print(", CORE ");
2081182007Sroberto  getrlimit(RLIMIT_CORE, &rlim);
2082182007Sroberto  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
2083182007Sroberto  else st->print("%uk", rlim.rlim_cur >> 10);
2084182007Sroberto
2085182007Sroberto  st->print(", NOFILE ");
2086182007Sroberto  getrlimit(RLIMIT_NOFILE, &rlim);
2087132451Sroberto  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
2088182007Sroberto  else st->print("%d", rlim.rlim_cur);
2089182007Sroberto
2090182007Sroberto  st->print(", AS ");
2091182007Sroberto  getrlimit(RLIMIT_AS, &rlim);
2092182007Sroberto  if (rlim.rlim_cur == RLIM_INFINITY) st->print("infinity");
2093182007Sroberto  else st->print("%uk", rlim.rlim_cur >> 10);
2094182007Sroberto  st->cr();
2095182007Sroberto
2096132451Sroberto  // load average
2097182007Sroberto  st->print("load average:");
2098182007Sroberto  double loadavg[3];
2099182007Sroberto  os::loadavg(loadavg, 3);
2100182007Sroberto  st->print("%0.02f %0.02f %0.02f", loadavg[0], loadavg[1], loadavg[2]);
2101182007Sroberto  st->cr();
2102182007Sroberto}
2103132451Sroberto
210482498Sroberto
2105182007Srobertostatic bool check_addr0(outputStream* st) {
2106182007Sroberto  jboolean status = false;
2107182007Sroberto  int fd = open("/proc/self/map",O_RDONLY);
2108182007Sroberto  if (fd >= 0) {
2109182007Sroberto    prmap_t p;
2110182007Sroberto    while(read(fd, &p, sizeof(p)) > 0) {
2111182007Sroberto      if (p.pr_vaddr == 0x0) {
2112182007Sroberto        st->print("Warning: Address: 0x%x, Size: %dK, ",p.pr_vaddr, p.pr_size/1024, p.pr_mapname);
2113182007Sroberto        st->print("Mapped file: %s, ", p.pr_mapname[0] == '\0' ? "None" : p.pr_mapname);
2114182007Sroberto        st->print("Access:");
2115182007Sroberto        st->print("%s",(p.pr_mflags & MA_READ)  ? "r" : "-");
2116182007Sroberto        st->print("%s",(p.pr_mflags & MA_WRITE) ? "w" : "-");
2117182007Sroberto        st->print("%s",(p.pr_mflags & MA_EXEC)  ? "x" : "-");
2118182007Sroberto        st->cr();
2119182007Sroberto        status = true;
2120182007Sroberto      }
2121182007Sroberto      close(fd);
2122182007Sroberto    }
2123182007Sroberto  }
2124182007Sroberto  return status;
2125182007Sroberto}
2126182007Sroberto
2127182007Srobertovoid os::print_memory_info(outputStream* st) {
2128182007Sroberto  st->print("Memory:");
2129182007Sroberto  st->print(" %dk page", os::vm_page_size()>>10);
2130182007Sroberto  st->print(", physical " UINT64_FORMAT "k", os::physical_memory()>>10);
2131182007Sroberto  st->print("(" UINT64_FORMAT "k free)", os::available_memory() >> 10);
2132182007Sroberto  st->cr();
2133182007Sroberto  (void) check_addr0(st);
2134182007Sroberto}
2135182007Sroberto
2136182007Sroberto// Taken from /usr/include/sys/machsig.h  Supposed to be architecture specific
2137182007Sroberto// but they're the same for all the solaris architectures that we support.
2138182007Srobertoconst char *ill_names[] = { "ILL0", "ILL_ILLOPC", "ILL_ILLOPN", "ILL_ILLADR",
2139182007Sroberto                          "ILL_ILLTRP", "ILL_PRVOPC", "ILL_PRVREG",
2140182007Sroberto                          "ILL_COPROC", "ILL_BADSTK" };
2141182007Sroberto
2142182007Srobertoconst char *fpe_names[] = { "FPE0", "FPE_INTDIV", "FPE_INTOVF", "FPE_FLTDIV",
214382498Sroberto                          "FPE_FLTOVF", "FPE_FLTUND", "FPE_FLTRES",
214482498Sroberto                          "FPE_FLTINV", "FPE_FLTSUB" };
214582498Sroberto
2146132451Srobertoconst char *segv_names[] = { "SEGV0", "SEGV_MAPERR", "SEGV_ACCERR" };
214782498Sroberto
2148132451Srobertoconst char *bus_names[] = { "BUS0", "BUS_ADRALN", "BUS_ADRERR", "BUS_OBJERR" };
2149132451Sroberto
2150132451Srobertovoid os::print_siginfo(outputStream* st, void* siginfo) {
2151132451Sroberto  st->print("siginfo:");
2152132451Sroberto
2153132451Sroberto  const int buflen = 100;
2154132451Sroberto  char buf[buflen];
2155132451Sroberto  siginfo_t *si = (siginfo_t*)siginfo;
2156132451Sroberto  st->print("si_signo=%s: ", os::exception_name(si->si_signo, buf, buflen));
2157132451Sroberto  char *err = strerror(si->si_errno);
2158132451Sroberto  if (si->si_errno != 0 && err != NULL) {
2159132451Sroberto    st->print("si_errno=%s", err);
2160132451Sroberto  } else {
2161132451Sroberto    st->print("si_errno=%d", si->si_errno);
2162132451Sroberto  }
2163132451Sroberto  const int c = si->si_code;
216454359Sroberto  assert(c > 0, "unexpected si_code");
2165132451Sroberto  switch (si->si_signo) {
2166132451Sroberto  case SIGILL:
2167132451Sroberto    st->print(", si_code=%d (%s)", c, c > 8 ? "" : ill_names[c]);
2168132451Sroberto    st->print(", si_addr=" PTR_FORMAT, si->si_addr);
2169132451Sroberto    break;
2170132451Sroberto  case SIGFPE:
2171132451Sroberto    st->print(", si_code=%d (%s)", c, c > 9 ? "" : fpe_names[c]);
2172132451Sroberto    st->print(", si_addr=" PTR_FORMAT, si->si_addr);
217354359Sroberto    break;
2174132451Sroberto  case SIGSEGV:
2175132451Sroberto    st->print(", si_code=%d (%s)", c, c > 2 ? "" : segv_names[c]);
2176132451Sroberto    st->print(", si_addr=" PTR_FORMAT, si->si_addr);
2177132451Sroberto    break;
2178132451Sroberto  case SIGBUS:
2179132451Sroberto    st->print(", si_code=%d (%s)", c, c > 3 ? "" : bus_names[c]);
2180132451Sroberto    st->print(", si_addr=" PTR_FORMAT, si->si_addr);
2181132451Sroberto    break;
2182132451Sroberto  default:
2183132451Sroberto    st->print(", si_code=%d", si->si_code);
2184182007Sroberto    // no si_addr
218554359Sroberto  }
2186132451Sroberto
2187132451Sroberto  if ((si->si_signo == SIGBUS || si->si_signo == SIGSEGV) &&
2188132451Sroberto      UseSharedSpaces) {
2189132451Sroberto    FileMapInfo* mapinfo = FileMapInfo::current_info();
2190132451Sroberto    if (mapinfo->is_in_shared_space(si->si_addr)) {
2191132451Sroberto      st->print("\n\nError accessing class data sharing archive."   \
2192132451Sroberto                " Mapped file inaccessible during execution, "      \
2193132451Sroberto                " possible disk/network problem.");
2194182007Sroberto    }
2195132451Sroberto  }
2196132451Sroberto  st->cr();
2197132451Sroberto}
2198132451Sroberto
219954359Sroberto// Moved from whole group, because we need them here for diagnostic
220054359Sroberto// prints.
2201132451Sroberto#define OLDMAXSIGNUM 32
2202182007Srobertostatic int Maxsignum = 0;
2203132451Srobertostatic int *ourSigFlags = NULL;
2204132451Sroberto
220554359Srobertoextern "C" void sigINTRHandler(int, siginfo_t*, void*);
2206132451Sroberto
2207132451Srobertoint os::Solaris::get_our_sigflags(int sig) {
2208132451Sroberto  assert(ourSigFlags!=NULL, "signal data structure not initialized");
2209132451Sroberto  assert(sig > 0 && sig < Maxsignum, "vm signal out of expected range");
2210132451Sroberto  return ourSigFlags[sig];
2211132451Sroberto}
2212132451Sroberto
2213132451Srobertovoid os::Solaris::set_our_sigflags(int sig, int flags) {
2214132451Sroberto  assert(ourSigFlags!=NULL, "signal data structure not initialized");
2215132451Sroberto  assert(sig > 0 && sig < Maxsignum, "vm signal out of expected range");
2216132451Sroberto  ourSigFlags[sig] = flags;
2217132451Sroberto}
2218132451Sroberto
2219132451Sroberto
2220132451Srobertostatic const char* get_signal_handler_name(address handler,
2221132451Sroberto                                           char* buf, int buflen) {
2222132451Sroberto  int offset;
2223132451Sroberto  bool found = os::dll_address_to_library_name(handler, buf, buflen, &offset);
2224132451Sroberto  if (found) {
2225132451Sroberto    // skip directory names
2226132451Sroberto    const char *p1, *p2;
2227132451Sroberto    p1 = buf;
2228132451Sroberto    size_t len = strlen(os::file_separator());
2229132451Sroberto    while ((p2 = strstr(p1, os::file_separator())) != NULL) p1 = p2 + len;
2230132451Sroberto    jio_snprintf(buf, buflen, "%s+0x%x", p1, offset);
2231132451Sroberto  } else {
2232132451Sroberto    jio_snprintf(buf, buflen, PTR_FORMAT, handler);
2233132451Sroberto  }
2234132451Sroberto  return buf;
2235132451Sroberto}
2236132451Sroberto
2237132451Srobertostatic void print_signal_handler(outputStream* st, int sig,
2238132451Sroberto                                  char* buf, size_t buflen) {
2239132451Sroberto  struct sigaction sa;
2240132451Sroberto
2241132451Sroberto  sigaction(sig, NULL, &sa);
2242132451Sroberto
2243132451Sroberto  st->print("%s: ", os::exception_name(sig, buf, buflen));
2244132451Sroberto
2245132451Sroberto  address handler = (sa.sa_flags & SA_SIGINFO)
2246132451Sroberto                  ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
2247132451Sroberto                  : CAST_FROM_FN_PTR(address, sa.sa_handler);
2248132451Sroberto
2249132451Sroberto  if (handler == CAST_FROM_FN_PTR(address, SIG_DFL)) {
2250132451Sroberto    st->print("SIG_DFL");
2251132451Sroberto  } else if (handler == CAST_FROM_FN_PTR(address, SIG_IGN)) {
2252132451Sroberto    st->print("SIG_IGN");
225382498Sroberto  } else {
225482498Sroberto    st->print("[%s]", get_signal_handler_name(handler, buf, buflen));
225582498Sroberto  }
225682498Sroberto
225754359Sroberto  st->print(", sa_mask[0]=" PTR32_FORMAT, *(uint32_t*)&sa.sa_mask);
225854359Sroberto
2259132451Sroberto  address rh = VMError::get_resetted_sighandler(sig);
2260132451Sroberto  // May be, handler was resetted by VMError?
2261132451Sroberto  if(rh != NULL) {
226254359Sroberto    handler = rh;
2263132451Sroberto    sa.sa_flags = VMError::get_resetted_sigflags(sig);
226454359Sroberto  }
2265132451Sroberto
2266132451Sroberto  st->print(", sa_flags="   PTR32_FORMAT, sa.sa_flags);
2267132451Sroberto
2268132451Sroberto  // Check: is it our handler?
2269132451Sroberto  if(handler == CAST_FROM_FN_PTR(address, signalHandler) ||
2270132451Sroberto     handler == CAST_FROM_FN_PTR(address, sigINTRHandler)) {
2271132451Sroberto    // It is our signal handler
2272132451Sroberto    // check for flags
2273132451Sroberto    if(sa.sa_flags != os::Solaris::get_our_sigflags(sig)) {
227454359Sroberto      st->print(
227554359Sroberto        ", flags was changed from " PTR32_FORMAT ", consider using jsig library",
227654359Sroberto        os::Solaris::get_our_sigflags(sig));
227754359Sroberto    }
2278132451Sroberto  }
2279132451Sroberto  st->cr();
2280132451Sroberto}
2281132451Sroberto
2282132451Srobertovoid os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) {
2283132451Sroberto  st->print_cr("Signal Handlers:");
2284132451Sroberto  print_signal_handler(st, SIGSEGV, buf, buflen);
2285132451Sroberto  print_signal_handler(st, SIGBUS , buf, buflen);
2286132451Sroberto  print_signal_handler(st, SIGFPE , buf, buflen);
2287132451Sroberto  print_signal_handler(st, SIGPIPE, buf, buflen);
2288132451Sroberto  print_signal_handler(st, SIGXFSZ, buf, buflen);
2289132451Sroberto  print_signal_handler(st, SIGILL , buf, buflen);
2290132451Sroberto  print_signal_handler(st, INTERRUPT_SIGNAL, buf, buflen);
2291132451Sroberto  print_signal_handler(st, ASYNC_SIGNAL, buf, buflen);
2292132451Sroberto  print_signal_handler(st, BREAK_SIGNAL, buf, buflen);
2293132451Sroberto  print_signal_handler(st, SHUTDOWN1_SIGNAL , buf, buflen);
2294132451Sroberto  print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen);
2295132451Sroberto  print_signal_handler(st, SHUTDOWN3_SIGNAL, buf, buflen);
2296132451Sroberto  print_signal_handler(st, os::Solaris::SIGinterrupt(), buf, buflen);
2297132451Sroberto  print_signal_handler(st, os::Solaris::SIGasync(), buf, buflen);
229882498Sroberto}
2299132451Sroberto
2300132451Srobertostatic char saved_jvm_path[MAXPATHLEN] = { 0 };
2301132451Sroberto
2302132451Sroberto// Find the full path to the current module, libjvm.so or libjvm_g.so
2303132451Srobertovoid os::jvm_path(char *buf, jint buflen) {
2304132451Sroberto  // Error checking.
230582498Sroberto  if (buflen < MAXPATHLEN) {
230682498Sroberto    assert(false, "must use a large-enough buffer");
230754359Sroberto    buf[0] = '\0';
2308132451Sroberto    return;
230954359Sroberto  }
231054359Sroberto  // Lazy resolve the path to current module.
231182498Sroberto  if (saved_jvm_path[0] != 0) {
231254359Sroberto    strcpy(buf, saved_jvm_path);
231354359Sroberto    return;
2314132451Sroberto  }
231582498Sroberto
2316132451Sroberto  Dl_info dlinfo;
2317132451Sroberto  int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo);
2318182007Sroberto  assert(ret != 0, "cannot locate libjvm");
2319182007Sroberto  realpath((char *)dlinfo.dli_fname, buf);
2320132451Sroberto
2321132451Sroberto  if (strcmp(Arguments::sun_java_launcher(), "gamma") == 0) {
2322182007Sroberto    // Support for the gamma launcher.  Typical value for buf is
2323182007Sroberto    // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so".  If "/jre/lib/" appears at
2324132451Sroberto    // the right place in the string, then assume we are installed in a JDK and
2325132451Sroberto    // we're done.  Otherwise, check for a JAVA_HOME environment variable and fix
2326132451Sroberto    // up the path so it looks like libjvm.so is installed there (append a
2327182007Sroberto    // fake suffix hotspot/libjvm.so).
2328182007Sroberto    const char *p = buf + strlen(buf) - 1;
2329132451Sroberto    for (int count = 0; p > buf && count < 5; ++count) {
2330132451Sroberto      for (--p; p > buf && *p != '/'; --p)
2331132451Sroberto        /* empty */ ;
2332132451Sroberto    }
233382498Sroberto
2334132451Sroberto    if (strncmp(p, "/jre/lib/", 9) != 0) {
2335132451Sroberto      // Look for JAVA_HOME in the environment.
2336132451Sroberto      char* java_home_var = ::getenv("JAVA_HOME");
2337132451Sroberto      if (java_home_var != NULL && java_home_var[0] != 0) {
2338132451Sroberto        char cpu_arch[12];
2339132451Sroberto        sysinfo(SI_ARCHITECTURE, cpu_arch, sizeof(cpu_arch));
2340132451Sroberto#ifdef _LP64
2341132451Sroberto        // If we are on sparc running a 64-bit vm, look in jre/lib/sparcv9.
2342132451Sroberto        if (strcmp(cpu_arch, "sparc") == 0) {
2343132451Sroberto          strcat(cpu_arch, "v9");
2344132451Sroberto        } else if (strcmp(cpu_arch, "i386") == 0) {
2345132451Sroberto          strcpy(cpu_arch, "amd64");
2346132451Sroberto        }
2347132451Sroberto#endif
2348132451Sroberto        // Check the current module name "libjvm.so" or "libjvm_g.so".
2349132451Sroberto        p = strrchr(buf, '/');
2350132451Sroberto        assert(strstr(p, "/libjvm") == p, "invalid library name");
2351132451Sroberto        p = strstr(p, "_g") ? "_g" : "";
2352132451Sroberto
2353132451Sroberto        realpath(java_home_var, buf);
2354132451Sroberto        sprintf(buf + strlen(buf), "/jre/lib/%s", cpu_arch);
2355132451Sroberto        if (0 == access(buf, F_OK)) {
235682498Sroberto          // Use current module name "libjvm[_g].so" instead of
2357132451Sroberto          // "libjvm"debug_only("_g")".so" since for fastdebug version
2358132451Sroberto          // we should have "libjvm.so" but debug_only("_g") adds "_g"!
2359132451Sroberto          // It is used when we are choosing the HPI library's name
2360182007Sroberto          // "libhpi[_g].so" in hpi::initialize_get_interface().
2361182007Sroberto          sprintf(buf + strlen(buf), "/hotspot/libjvm%s.so", p);
2362182007Sroberto        } else {
2363132451Sroberto          // Go back to path of .so
2364132451Sroberto          realpath((char *)dlinfo.dli_fname, buf);
2365132451Sroberto        }
2366132451Sroberto      }
2367132451Sroberto    }
2368132451Sroberto  }
2369132451Sroberto
2370182007Sroberto  strcpy(saved_jvm_path, buf);
2371132451Sroberto}
2372132451Sroberto
2373132451Sroberto
2374132451Srobertovoid os::print_jni_name_prefix_on(outputStream* st, int args_size) {
2375132451Sroberto  // no prefix required, not even "_"
2376132451Sroberto}
2377182007Sroberto
2378132451Sroberto
2379132451Srobertovoid os::print_jni_name_suffix_on(outputStream* st, int args_size) {
2380132451Sroberto  // no suffix required
2381132451Sroberto}
238282498Sroberto
238382498Sroberto
238482498Sroberto// sun.misc.Signal
238582498Sroberto
238682498Srobertoextern "C" {
238782498Sroberto  static void UserHandler(int sig, void *siginfo, void *context) {
2388132451Sroberto    // Ctrl-C is pressed during error reporting, likely because the error
2389132451Sroberto    // handler fails to abort. Let VM die immediately.
2390132451Sroberto    if (sig == SIGINT && is_error_reported()) {
239182498Sroberto       os::die();
239282498Sroberto    }
2393132451Sroberto
2394132451Sroberto    os::signal_notify(sig);
239582498Sroberto    // We do not need to reinstate the signal handler each time...
239682498Sroberto  }
239782498Sroberto}
239882498Sroberto
239982498Srobertovoid* os::user_handler() {
240082498Sroberto  return CAST_FROM_FN_PTR(void*, UserHandler);
240182498Sroberto}
240282498Sroberto
240382498Srobertoextern "C" {
240482498Sroberto  typedef void (*sa_handler_t)(int);
240582498Sroberto  typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
240682498Sroberto}
240782498Sroberto
240882498Srobertovoid* os::signal(int signal_number, void* handler) {
240982498Sroberto  struct sigaction sigAct, oldSigAct;
2410132451Sroberto  sigfillset(&(sigAct.sa_mask));
241182498Sroberto  sigAct.sa_flags = SA_RESTART & ~SA_RESETHAND;
241282498Sroberto  sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler);
2413132451Sroberto
241482498Sroberto  if (sigaction(signal_number, &sigAct, &oldSigAct))
241582498Sroberto    // -1 means registration failed
241682498Sroberto    return (void *)-1;
2417182007Sroberto
241882498Sroberto  return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler);
241982498Sroberto}
242082498Sroberto
242182498Srobertovoid os::signal_raise(int signal_number) {
242282498Sroberto  raise(signal_number);
242382498Sroberto}
2424182007Sroberto
242582498Sroberto/*
2426132451Sroberto * The following code is moved from os.cpp for making this
242782498Sroberto * code platform specific, which it is by its very nature.
242882498Sroberto */
2429132451Sroberto
2430132451Sroberto// a counter for each possible signal value
2431132451Srobertostatic int Sigexit = 0;
2432132451Srobertostatic int Maxlibjsigsigs;
2433132451Srobertostatic jint *pending_signals = NULL;
2434132451Srobertostatic int *preinstalled_sigs = NULL;
2435132451Srobertostatic struct sigaction *chainedsigactions = NULL;
2436132451Srobertostatic sema_t sig_sem;
2437132451Srobertotypedef int (*version_getting_t)();
2438132451Srobertoversion_getting_t os::Solaris::get_libjsig_version = NULL;
2439132451Srobertostatic int libjsigversion = NULL;
2440132451Sroberto
2441132451Srobertoint os::sigexitnum_pd() {
2442132451Sroberto  assert(Sigexit > 0, "signal memory not yet initialized");
244382498Sroberto  return Sigexit;
244482498Sroberto}
244582498Sroberto
244682498Srobertovoid os::Solaris::init_signal_mem() {
2447132451Sroberto  // Initialize signal structures
244882498Sroberto  Maxsignum = SIGRTMAX;
2449132451Sroberto  Sigexit = Maxsignum+1;
245082498Sroberto  assert(Maxsignum >0, "Unable to obtain max signal number");
245182498Sroberto
245282498Sroberto  Maxlibjsigsigs = Maxsignum;
245382498Sroberto
2454132451Sroberto  // pending_signals has one int per signal
2455132451Sroberto  // The additional signal is for SIGEXIT - exit signal to signal_thread
2456132451Sroberto  pending_signals = (jint *)os::malloc(sizeof(jint) * (Sigexit+1));
245782498Sroberto  memset(pending_signals, 0, (sizeof(jint) * (Sigexit+1)));
245882498Sroberto
245982498Sroberto  if (UseSignalChaining) {
246082498Sroberto     chainedsigactions = (struct sigaction *)malloc(sizeof(struct sigaction)
246182498Sroberto       * (Maxsignum + 1));
2462132451Sroberto     memset(chainedsigactions, 0, (sizeof(struct sigaction) * (Maxsignum + 1)));
2463132451Sroberto     preinstalled_sigs = (int *)os::malloc(sizeof(int) * (Maxsignum + 1));
2464132451Sroberto     memset(preinstalled_sigs, 0, (sizeof(int) * (Maxsignum + 1)));
246582498Sroberto  }
246682498Sroberto  ourSigFlags = (int*)malloc(sizeof(int) * (Maxsignum + 1 ));
2467132451Sroberto  memset(ourSigFlags, 0, sizeof(int) * (Maxsignum + 1));
246882498Sroberto}
246982498Sroberto
247082498Srobertovoid os::signal_init_pd() {
247182498Sroberto  int ret;
247282498Sroberto
2473132451Sroberto  ret = ::sema_init(&sig_sem, 0, NULL, NULL);
247454359Sroberto  assert(ret == 0, "sema_init() failed");
2475132451Sroberto}
2476132451Sroberto
247782498Srobertovoid os::signal_notify(int signal_number) {
2478132451Sroberto  int ret;
2479132451Sroberto
2480132451Sroberto  Atomic::inc(&pending_signals[signal_number]);
2481132451Sroberto  ret = ::sema_post(&sig_sem);
2482132451Sroberto  assert(ret == 0, "sema_post() failed");
2483132451Sroberto}
2484132451Sroberto
2485132451Srobertostatic int check_pending_signals(bool wait_for_signal) {
2486132451Sroberto  int ret;
2487132451Sroberto  while (true) {
248882498Sroberto    for (int i = 0; i < Sigexit + 1; i++) {
2489132451Sroberto      jint n = pending_signals[i];
2490132451Sroberto      if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) {
249154359Sroberto        return i;
2492132451Sroberto      }
249354359Sroberto    }
2494132451Sroberto    if (!wait_for_signal) {
2495132451Sroberto      return -1;
2496132451Sroberto    }
249754359Sroberto    JavaThread *thread = JavaThread::current();
2498132451Sroberto    ThreadBlockInVM tbivm(thread);
2499132451Sroberto
2500132451Sroberto    bool threadIsSuspended;
2501132451Sroberto    do {
2502132451Sroberto      thread->set_suspend_equivalent();
250382498Sroberto      // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
2504132451Sroberto      while((ret = ::sema_wait(&sig_sem)) == EINTR)
2505132451Sroberto          ;
250682498Sroberto      assert(ret == 0, "sema_wait() failed");
250782498Sroberto
2508132451Sroberto      // were we externally suspended while we were waiting?
2509132451Sroberto      threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
2510132451Sroberto      if (threadIsSuspended) {
2511132451Sroberto        //
2512132451Sroberto        // The semaphore has been incremented, but while we were waiting
2513132451Sroberto        // another thread suspended us. We don't want to continue running
2514132451Sroberto        // while suspended because that would surprise the thread that
2515132451Sroberto        // suspended us.
2516132451Sroberto        //
2517132451Sroberto        ret = ::sema_post(&sig_sem);
2518132451Sroberto        assert(ret == 0, "sema_post() failed");
2519132451Sroberto
2520132451Sroberto        thread->java_suspend_self();
2521132451Sroberto      }
2522132451Sroberto    } while (threadIsSuspended);
2523132451Sroberto  }
2524132451Sroberto}
2525132451Sroberto
2526132451Srobertoint os::signal_lookup() {
2527132451Sroberto  return check_pending_signals(false);
2528132451Sroberto}
2529132451Sroberto
2530132451Srobertoint os::signal_wait() {
253182498Sroberto  return check_pending_signals(true);
2532132451Sroberto}
253382498Sroberto
253482498Sroberto////////////////////////////////////////////////////////////////////////////////
253582498Sroberto// Virtual Memory
2536132451Sroberto
2537132451Srobertostatic int page_size = -1;
2538132451Sroberto
2539132451Sroberto// The mmap MAP_ALIGN flag is supported on Solaris 9 and later.  init_2() will
2540132451Sroberto// clear this var if support is not available.
2541132451Srobertostatic bool has_map_align = true;
2542132451Sroberto
2543132451Srobertoint os::vm_page_size() {
2544132451Sroberto  assert(page_size != -1, "must call os::init");
2545132451Sroberto  return page_size;
2546132451Sroberto}
2547132451Sroberto
2548132451Sroberto// Solaris allocates memory by pages.
2549132451Srobertoint os::vm_allocation_granularity() {
255082498Sroberto  assert(page_size != -1, "must call os::init");
2551132451Sroberto  return page_size;
2552132451Sroberto}
2553132451Sroberto
2554132451Srobertobool os::commit_memory(char* addr, size_t bytes) {
2555132451Sroberto  size_t size = bytes;
2556132451Sroberto  return
2557132451Sroberto     NULL != Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED,
2558132451Sroberto                                 PROT_READ | PROT_WRITE | PROT_EXEC);
2559132451Sroberto}
256082498Sroberto
2561132451Srobertobool os::commit_memory(char* addr, size_t bytes, size_t alignment_hint) {
256282498Sroberto  if (commit_memory(addr, bytes)) {
2563132451Sroberto    if (UseMPSS && alignment_hint > (size_t)vm_page_size()) {
2564132451Sroberto      // If the large page size has been set and the VM
2565132451Sroberto      // is using large pages, use the large page size
2566132451Sroberto      // if it is smaller than the alignment hint. This is
2567132451Sroberto      // a case where the VM wants to use a larger alignment size
2568132451Sroberto      // for its own reasons but still want to use large pages
2569132451Sroberto      // (which is what matters to setting the mpss range.
2570132451Sroberto      size_t page_size = 0;
2571132451Sroberto      if (large_page_size() < alignment_hint) {
257282498Sroberto        assert(UseLargePages, "Expected to be here for large page use only");
2573132451Sroberto        page_size = large_page_size();
2574132451Sroberto      } else {
2575132451Sroberto        // If the alignment hint is less than the large page
2576132451Sroberto        // size, the VM wants a particular alignment (thus the hint)
2577132451Sroberto        // for internal reasons.  Try to set the mpss range using
257882498Sroberto        // the alignment_hint.
257982498Sroberto        page_size = alignment_hint;
258082498Sroberto      }
2581132451Sroberto      // Since this is a hint, ignore any failures.
2582132451Sroberto      (void)Solaris::set_mpss_range(addr, bytes, page_size);
2583132451Sroberto    }
2584132451Sroberto    return true;
2585132451Sroberto  }
2586132451Sroberto  return false;
2587132451Sroberto}
2588132451Sroberto
2589132451Sroberto// Uncommit the pages in a specified region.
2590132451Srobertovoid os::free_memory(char* addr, size_t bytes) {
259182498Sroberto  if (madvise(addr, bytes, MADV_FREE) < 0) {
259282498Sroberto    debug_only(warning("MADV_FREE failed."));
259382498Sroberto    return;
2594132451Sroberto  }
2595132451Sroberto}
2596132451Sroberto
2597132451Sroberto// Change the page size in a given range.
2598132451Srobertovoid os::realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
2599132451Sroberto  assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned.");
2600132451Sroberto  assert((intptr_t)(addr + bytes) % alignment_hint == 0, "End should be aligned.");
2601132451Sroberto  Solaris::set_mpss_range(addr, bytes, alignment_hint);
2602132451Sroberto}
2603132451Sroberto
2604132451Sroberto// Tell the OS to make the range local to the first-touching LWP
260582498Srobertovoid os::numa_make_local(char *addr, size_t bytes) {
2606132451Sroberto  assert((intptr_t)addr % os::vm_page_size() == 0, "Address should be page-aligned.");
2607132451Sroberto  if (madvise(addr, bytes, MADV_ACCESS_LWP) < 0) {
2608132451Sroberto    debug_only(warning("MADV_ACCESS_LWP failed."));
2609132451Sroberto  }
2610132451Sroberto}
2611132451Sroberto
2612132451Sroberto// Tell the OS that this range would be accessed from different LWPs.
2613132451Srobertovoid os::numa_make_global(char *addr, size_t bytes) {
2614132451Sroberto  assert((intptr_t)addr % os::vm_page_size() == 0, "Address should be page-aligned.");
2615132451Sroberto  if (madvise(addr, bytes, MADV_ACCESS_MANY) < 0) {
2616132451Sroberto    debug_only(warning("MADV_ACCESS_MANY failed."));
2617132451Sroberto  }
2618132451Sroberto}
2619132451Sroberto
2620132451Sroberto// Get the number of the locality groups.
2621132451Srobertosize_t os::numa_get_groups_num() {
2622132451Sroberto  size_t n = Solaris::lgrp_nlgrps(Solaris::lgrp_cookie());
2623132451Sroberto  return n != -1 ? n : 1;
2624132451Sroberto}
2625132451Sroberto
262682498Sroberto// Get a list of leaf locality groups. A leaf lgroup is group that
262782498Sroberto// doesn't have any children. Typical leaf group is a CPU or a CPU/memory
2628132451Sroberto// board. An LWP is assigned to one of these groups upon creation.
262982498Srobertosize_t os::numa_get_leaf_groups(int *ids, size_t size) {
2630182007Sroberto   if ((ids[0] = Solaris::lgrp_root(Solaris::lgrp_cookie())) == -1) {
2631182007Sroberto     ids[0] = 0;
263282498Sroberto     return 1;
2633132451Sroberto   }
2634132451Sroberto   int result_size = 0, top = 1, bottom = 0, cur = 0;
263582498Sroberto   for (int k = 0; k < size; k++) {
2636182007Sroberto     int r = Solaris::lgrp_children(Solaris::lgrp_cookie(), ids[cur],
2637132451Sroberto                                    (Solaris::lgrp_id_t*)&ids[top], size - top);
2638132451Sroberto     if (r == -1) {
2639132451Sroberto       ids[0] = 0;
2640132451Sroberto       return 1;
2641132451Sroberto     }
2642132451Sroberto     if (!r) {
2643132451Sroberto       assert (bottom <= cur, "Sanity check");
2644132451Sroberto       ids[bottom++] = ids[cur];
2645132451Sroberto     }
2646132451Sroberto     top += r;
2647132451Sroberto     cur++;
2648132451Sroberto   }
2649132451Sroberto   return bottom;
2650132451Sroberto}
2651132451Sroberto
2652132451Sroberto// Detect the topology change. Typically happens during CPU pluggin-unplugging.
2653132451Srobertobool os::numa_topology_changed() {
2654132451Sroberto  int is_stale = Solaris::lgrp_cookie_stale(Solaris::lgrp_cookie());
2655132451Sroberto  if (is_stale != -1 && is_stale) {
2656132451Sroberto    Solaris::lgrp_fini(Solaris::lgrp_cookie());
2657132451Sroberto    Solaris::lgrp_cookie_t c = Solaris::lgrp_init(Solaris::LGRP_VIEW_CALLER);
2658132451Sroberto    assert(c != 0, "Failure to initialize LGRP API");
2659132451Sroberto    Solaris::set_lgrp_cookie(c);
2660132451Sroberto    return true;
2661132451Sroberto  }
2662132451Sroberto  return false;
2663132451Sroberto}
2664132451Sroberto
2665132451Sroberto// Get the group id of the current LWP.
2666132451Srobertoint os::numa_get_group_id() {
2667132451Sroberto  int lgrp_id = os::Solaris::lgrp_home(P_LWPID, P_MYID);
2668132451Sroberto  if (lgrp_id == -1) {
2669132451Sroberto    return 0;
2670132451Sroberto  }
2671132451Sroberto  return lgrp_id;
2672132451Sroberto}
2673132451Sroberto
2674132451Sroberto// Request information about the page.
2675132451Srobertobool os::get_page_info(char *start, page_info* info) {
267654359Sroberto  const uint_t info_types[] = { MEMINFO_VLGRP, MEMINFO_VPAGESIZE };
2677132451Sroberto  uint64_t addr = (uintptr_t)start;
2678132451Sroberto  uint64_t outdata[2];
2679132451Sroberto  uint_t validity = 0;
268054359Sroberto
268154359Sroberto  if (os::Solaris::meminfo(&addr, 1, info_types, 2, outdata, &validity) < 0) {
2682132451Sroberto    return false;
268354359Sroberto  }
2684132451Sroberto
2685132451Sroberto  info->size = 0;
268682498Sroberto  info->lgrp_id = -1;
2687132451Sroberto
2688132451Sroberto  if ((validity & 1) != 0) {
2689132451Sroberto    if ((validity & 2) != 0) {
2690132451Sroberto      info->lgrp_id = outdata[0];
2691132451Sroberto    }
2692132451Sroberto    if ((validity & 4) != 0) {
2693132451Sroberto      info->size = outdata[1];
269482498Sroberto    }
2695132451Sroberto    return true;
2696132451Sroberto  }
2697132451Sroberto  return false;
2698132451Sroberto}
2699132451Sroberto
2700132451Sroberto// Scan the pages from start to end until a page different than
2701132451Sroberto// the one described in the info parameter is encountered.
270282498Srobertochar *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) {
2703132451Sroberto  const uint_t info_types[] = { MEMINFO_VLGRP, MEMINFO_VPAGESIZE };
2704132451Sroberto  const size_t types = sizeof(info_types) / sizeof(info_types[0]);
2705132451Sroberto  uint64_t addrs[MAX_MEMINFO_CNT], outdata[types * MAX_MEMINFO_CNT];
2706132451Sroberto  uint_t validity[MAX_MEMINFO_CNT];
2707132451Sroberto
2708132451Sroberto  size_t page_size = MAX2((size_t)os::vm_page_size(), page_expected->size);
2709132451Sroberto  uint64_t p = (uint64_t)start;
2710132451Sroberto  while (p < (uint64_t)end) {
2711132451Sroberto    addrs[0] = p;
2712132451Sroberto    size_t addrs_count = 1;
2713132451Sroberto    while (addrs_count < MAX_MEMINFO_CNT && addrs[addrs_count - 1] < (uint64_t)end) {
2714132451Sroberto      addrs[addrs_count] = addrs[addrs_count - 1] + page_size;
2715132451Sroberto      addrs_count++;
2716132451Sroberto    }
2717132451Sroberto
2718132451Sroberto    if (os::Solaris::meminfo(addrs, addrs_count, info_types, types, outdata, validity) < 0) {
2719132451Sroberto      return NULL;
2720132451Sroberto    }
2721132451Sroberto
2722132451Sroberto    size_t i = 0;
2723182007Sroberto    for (; i < addrs_count; i++) {
2724182007Sroberto      if ((validity[i] & 1) != 0) {
2725132451Sroberto        if ((validity[i] & 4) != 0) {
2726132451Sroberto          if (outdata[types * i + 1] != page_expected->size) {
2727132451Sroberto            break;
2728132451Sroberto          }
2729132451Sroberto        } else
2730132451Sroberto          if (page_expected->size != 0) {
2731132451Sroberto            break;
273282498Sroberto          }
273382498Sroberto
2734132451Sroberto        if ((validity[i] & 2) != 0 && page_expected->lgrp_id > 0) {
2735132451Sroberto          if (outdata[types * i] != page_expected->lgrp_id) {
2736132451Sroberto            break;
2737132451Sroberto          }
273854359Sroberto        }
273954359Sroberto      } else {
2740132451Sroberto        return NULL;
2741132451Sroberto      }
2742132451Sroberto    }
2743132451Sroberto
2744132451Sroberto    if (i != addrs_count) {
2745132451Sroberto      if ((validity[i] & 2) != 0) {
2746132451Sroberto        page_found->lgrp_id = outdata[types * i];
274782498Sroberto      } else {
2748132451Sroberto        page_found->lgrp_id = -1;
274982498Sroberto      }
2750132451Sroberto      if ((validity[i] & 4) != 0) {
2751132451Sroberto        page_found->size = outdata[types * i + 1];
2752132451Sroberto      } else {
275382498Sroberto        page_found->size = 0;
275454359Sroberto      }
2755132451Sroberto      return (char*)addrs[i];
2756132451Sroberto    }
2757132451Sroberto
2758132451Sroberto    p = addrs[addrs_count - 1] + page_size;
2759132451Sroberto  }
2760132451Sroberto  return end;
276182498Sroberto}
2762132451Sroberto
2763132451Srobertobool os::uncommit_memory(char* addr, size_t bytes) {
2764132451Sroberto  size_t size = bytes;
2765132451Sroberto  // Map uncommitted pages PROT_NONE so we fail early if we touch an
2766132451Sroberto  // uncommitted page. Otherwise, the read/write might succeed if we
276782498Sroberto  // have enough swap space to back the physical page.
2768132451Sroberto  return
2769132451Sroberto    NULL != Solaris::mmap_chunk(addr, size,
2770132451Sroberto                                MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE,
2771132451Sroberto                                PROT_NONE);
2772132451Sroberto}
277382498Sroberto
2774132451Srobertochar* os::Solaris::mmap_chunk(char *addr, size_t size, int flags, int prot) {
2775132451Sroberto  char *b = (char *)mmap(addr, size, prot, flags, os::Solaris::_dev_zero_fd, 0);
2776132451Sroberto
2777132451Sroberto  if (b == MAP_FAILED) {
2778132451Sroberto    return NULL;
2779132451Sroberto  }
2780132451Sroberto  return b;
2781132451Sroberto}
278282498Sroberto
278382498Srobertochar* os::Solaris::anon_mmap(char* requested_addr, size_t bytes, size_t alignment_hint, bool fixed) {
2784132451Sroberto  char* addr = requested_addr;
2785132451Sroberto  int flags = MAP_PRIVATE | MAP_NORESERVE;
2786132451Sroberto
2787132451Sroberto  assert(!(fixed && (alignment_hint > 0)), "alignment hint meaningless with fixed mmap");
2788132451Sroberto
278954359Sroberto  if (fixed) {
279054359Sroberto    flags |= MAP_FIXED;
2791132451Sroberto  } else if (has_map_align && (alignment_hint > (size_t) vm_page_size())) {
2792132451Sroberto    flags |= MAP_ALIGN;
2793132451Sroberto    addr = (char*) alignment_hint;
2794132451Sroberto  }
2795132451Sroberto
2796132451Sroberto  // Map uncommitted pages PROT_NONE so we fail early if we touch an
2797132451Sroberto  // uncommitted page. Otherwise, the read/write might succeed if we
2798132451Sroberto  // have enough swap space to back the physical page.
2799132451Sroberto  return mmap_chunk(addr, bytes, flags, PROT_NONE);
2800132451Sroberto}
2801132451Sroberto
2802132451Srobertochar* os::reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) {
2803132451Sroberto  char* addr = Solaris::anon_mmap(requested_addr, bytes, alignment_hint, (requested_addr != NULL));
2804132451Sroberto
2805132451Sroberto  guarantee(requested_addr == NULL || requested_addr == addr,
2806132451Sroberto            "OS failed to return requested mmap address.");
2807132451Sroberto  return addr;
2808132451Sroberto}
280954359Sroberto
281054359Sroberto// Reserve memory at an arbitrary address, only if that area is
2811132451Sroberto// available (and not reserved for something else).
2812132451Sroberto
2813132451Srobertochar* os::attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
2814132451Sroberto  const int max_tries = 10;
2815132451Sroberto  char* base[max_tries];
281682498Sroberto  size_t size[max_tries];
281754359Sroberto
281854359Sroberto  // Solaris adds a gap between mmap'ed regions.  The size of the gap
2819132451Sroberto  // is dependent on the requested size and the MMU.  Our initial gap
282054359Sroberto  // value here is just a guess and will be corrected later.
2821132451Sroberto  bool had_top_overlap = false;
2822132451Sroberto  bool have_adjusted_gap = false;
2823132451Sroberto  size_t gap = 0x400000;
2824132451Sroberto
2825132451Sroberto  // Assert only that the size is a multiple of the page size, since
2826132451Sroberto  // that's all that mmap requires, and since that's all we really know
2827132451Sroberto  // about at this low abstraction level.  If we need higher alignment,
2828132451Sroberto  // we can either pass an alignment to this method or verify alignment
2829132451Sroberto  // in one of the methods further up the call chain.  See bug 5044738.
2830132451Sroberto  assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block");
283154359Sroberto
283254359Sroberto  // Since snv_84, Solaris attempts to honor the address hint - see 5003415.
2833132451Sroberto  // Give it a try, if the kernel honors the hint we can return immediately.
2834132451Sroberto  char* addr = Solaris::anon_mmap(requested_addr, bytes, 0, false);
2835132451Sroberto  volatile int err = errno;
283654359Sroberto  if (addr == requested_addr) {
2837132451Sroberto    return addr;
2838132451Sroberto  } else if (addr != NULL) {
2839132451Sroberto    unmap_memory(addr, bytes);
284054359Sroberto  }
2841132451Sroberto
2842132451Sroberto  if (PrintMiscellaneous && Verbose) {
2843132451Sroberto    char buf[256];
2844132451Sroberto    buf[0] = '\0';
2845132451Sroberto    if (addr == NULL) {
2846132451Sroberto      jio_snprintf(buf, sizeof(buf), ": %s", strerror(err));
284756746Sroberto    }
284856746Sroberto    warning("attempt_reserve_memory_at: couldn't reserve %d bytes at "
2849132451Sroberto            PTR_FORMAT ": reserve_memory_helper returned " PTR_FORMAT
2850132451Sroberto            "%s", bytes, requested_addr, addr, buf);
2851132451Sroberto  }
285254359Sroberto
2853132451Sroberto  // Address hint method didn't work.  Fall back to the old method.
2854132451Sroberto  // In theory, once SNV becomes our oldest supported platform, this
285582498Sroberto  // code will no longer be needed.
285682498Sroberto  //
285782498Sroberto  // Repeatedly allocate blocks until the block is allocated at the
2858132451Sroberto  // right spot. Give up after max_tries.
285982498Sroberto  int i;
2860132451Sroberto  for (i = 0; i < max_tries; ++i) {
2861132451Sroberto    base[i] = reserve_memory(bytes);
2862132451Sroberto
2863132451Sroberto    if (base[i] != NULL) {
2864132451Sroberto      // Is this the block we wanted?
2865132451Sroberto      if (base[i] == requested_addr) {
2866132451Sroberto        size[i] = bytes;
2867132451Sroberto        break;
2868132451Sroberto      }
286982498Sroberto
2870132451Sroberto      // check that the gap value is right
2871132451Sroberto      if (had_top_overlap && !have_adjusted_gap) {
2872132451Sroberto        size_t actual_gap = base[i-1] - base[i] - bytes;
2873132451Sroberto        if (gap != actual_gap) {
2874132451Sroberto          // adjust the gap value and retry the last 2 allocations
2875132451Sroberto          assert(i > 0, "gap adjustment code problem");
2876132451Sroberto          have_adjusted_gap = true;  // adjust the gap only once, just in case
2877132451Sroberto          gap = actual_gap;
2878132451Sroberto          if (PrintMiscellaneous && Verbose) {
2879132451Sroberto            warning("attempt_reserve_memory_at: adjusted gap to 0x%lx", gap);
2880132451Sroberto          }
2881132451Sroberto          unmap_memory(base[i], bytes);
2882132451Sroberto          unmap_memory(base[i-1], size[i-1]);
2883182007Sroberto          i-=2;
2884132451Sroberto          continue;
288554359Sroberto        }
288654359Sroberto      }
288754359Sroberto
288854359Sroberto      // Does this overlap the block we wanted? Give back the overlapped
2889132451Sroberto      // parts and try again.
2890132451Sroberto      //
289182498Sroberto      // There is still a bug in this code: if top_overlap == bytes,
289282498Sroberto      // the overlap is offset from requested region by the value of gap.
2893132451Sroberto      // In this case giving back the overlapped part will not work,
289482498Sroberto      // because we'll give back the entire block at base[i] and
2895132451Sroberto      // therefore the subsequent allocation will not generate a new gap.
2896132451Sroberto      // This could be fixed with a new algorithm that used larger
289782498Sroberto      // or variable size chunks to find the requested region -
289882498Sroberto      // but such a change would introduce additional complications.
2899132451Sroberto      // It's rare enough that the planets align for this bug,
2900132451Sroberto      // so we'll just wait for a fix for 6204603/5003415 which
290154359Sroberto      // will provide a mmap flag to allow us to avoid this business.
2902132451Sroberto
290354359Sroberto      size_t top_overlap = requested_addr + (bytes + gap) - base[i];
2904132451Sroberto      if (top_overlap >= 0 && top_overlap < bytes) {
290554359Sroberto        had_top_overlap = true;
2906132451Sroberto        unmap_memory(base[i], top_overlap);
290754359Sroberto        base[i] += top_overlap;
2908132451Sroberto        size[i] = bytes - top_overlap;
2909132451Sroberto      } else {
2910132451Sroberto        size_t bottom_overlap = base[i] + bytes - requested_addr;
2911132451Sroberto        if (bottom_overlap >= 0 && bottom_overlap < bytes) {
2912132451Sroberto          if (PrintMiscellaneous && Verbose && bottom_overlap == 0) {
2913132451Sroberto            warning("attempt_reserve_memory_at: possible alignment bug");
2914132451Sroberto          }
2915132451Sroberto          unmap_memory(requested_addr, bottom_overlap);
2916132451Sroberto          size[i] = bytes - bottom_overlap;
2917132451Sroberto        } else {
2918132451Sroberto          size[i] = bytes;
2919182007Sroberto        }
2920132451Sroberto      }
2921132451Sroberto    }
292254359Sroberto  }
292354359Sroberto
2924132451Sroberto  // Give back the unused reserved pieces.
292554359Sroberto
2926182007Sroberto  for (int j = 0; j < i; ++j) {
2927182007Sroberto    if (base[j] != NULL) {
292854359Sroberto      unmap_memory(base[j], size[j]);
2929132451Sroberto    }
2930132451Sroberto  }
2931132451Sroberto
2932132451Sroberto  return (i < max_tries) ? requested_addr : NULL;
2933182007Sroberto}
2934182007Sroberto
2935132451Srobertobool os::release_memory(char* addr, size_t bytes) {
2936182007Sroberto  size_t size = bytes;
2937182007Sroberto  return munmap(addr, size) == 0;
2938132451Sroberto}
293954359Sroberto
2940132451Srobertostatic bool solaris_mprotect(char* addr, size_t bytes, int prot) {
2941132451Sroberto  assert(addr == (char*)align_size_down((uintptr_t)addr, os::vm_page_size()),
2942132451Sroberto         "addr must be page aligned");
294354359Sroberto  int retVal = mprotect(addr, bytes, prot);
294454359Sroberto  return retVal == 0;
294554359Sroberto}
2946132451Sroberto
294754359Sroberto// Protect memory (make it read-only. (Used to pass readonly pages through
2948132451Sroberto// JNI GetArray<type>Elements with empty arrays.)
2949132451Srobertobool os::protect_memory(char* addr, size_t bytes) {
2950132451Sroberto  return solaris_mprotect(addr, bytes, PROT_READ);
2951132451Sroberto}
2952132451Sroberto
2953132451Sroberto// guard_memory and unguard_memory only happens within stack guard pages.
2954132451Sroberto// Since ISM pertains only to the heap, guard and unguard memory should not
2955132451Sroberto/// happen with an ISM region.
2956132451Srobertobool os::guard_memory(char* addr, size_t bytes) {
2957132451Sroberto  return solaris_mprotect(addr, bytes, PROT_NONE);
2958132451Sroberto}
2959132451Sroberto
2960132451Srobertobool os::unguard_memory(char* addr, size_t bytes) {
296154359Sroberto  return solaris_mprotect(addr, bytes, PROT_READ|PROT_WRITE|PROT_EXEC);
2962132451Sroberto}
296354359Sroberto
2964132451Sroberto// Large page support
296554359Sroberto
296654359Sroberto// UseLargePages is the master flag to enable/disable large page memory.
2967132451Sroberto// UseMPSS and UseISM are supported for compatibility reasons. Their combined
2968132451Sroberto// effects can be described in the following table:
2969132451Sroberto//
2970132451Sroberto// UseLargePages UseMPSS UseISM
2971132451Sroberto//    false         *       *   => UseLargePages is the master switch, turning
2972132451Sroberto//                                 it off will turn off both UseMPSS and
2973132451Sroberto//                                 UseISM. VM will not use large page memory
2974132451Sroberto//                                 regardless the settings of UseMPSS/UseISM.
297554359Sroberto//     true      false    false => Unless future Solaris provides other
297654359Sroberto//                                 mechanism to use large page memory, this
2977132451Sroberto//                                 combination is equivalent to -UseLargePages,
2978132451Sroberto//                                 VM will not use large page memory
2979132451Sroberto//     true      true     false => JVM will use MPSS for large page memory.
2980132451Sroberto//                                 This is the default behavior.
2981132451Sroberto//     true      false    true  => JVM will use ISM for large page memory.
2982132451Sroberto//     true      true     true  => JVM will use ISM if it is available.
298356746Sroberto//                                 Otherwise, JVM will fall back to MPSS.
298454359Sroberto//                                 Becaues ISM is now available on all
2985132451Sroberto//                                 supported Solaris versions, this combination
2986132451Sroberto//                                 is equivalent to +UseISM -UseMPSS.
2987132451Sroberto
298854359Srobertotypedef int (*getpagesizes_func_type) (size_t[], int);
298954359Srobertostatic size_t _large_page_size = 0;
299054359Sroberto
2991132451Srobertobool os::Solaris::ism_sanity_check(bool warn, size_t * page_size) {
2992132451Sroberto  // x86 uses either 2M or 4M page, depending on whether PAE (Physical Address
2993132451Sroberto  // Extensions) mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. Sparc
2994132451Sroberto  // can support multiple page sizes.
2995132451Sroberto
2996132451Sroberto  // Don't bother to probe page size because getpagesizes() comes with MPSS.
299782498Sroberto  // ISM is only recommended on old Solaris where there is no MPSS support.
2998132451Sroberto  // Simply choose a conservative value as default.
2999132451Sroberto  *page_size = LargePageSizeInBytes ? LargePageSizeInBytes :
3000132451Sroberto               SPARC_ONLY(4 * M) IA32_ONLY(4 * M) AMD64_ONLY(2 * M);
3001132451Sroberto
3002132451Sroberto  // ISM is available on all supported Solaris versions
300382498Sroberto  return true;
3004132451Sroberto}
300582498Sroberto
300682498Sroberto// Insertion sort for small arrays (descending order).
3007132451Srobertostatic void insertion_sort_descending(size_t* array, int len) {
3008132451Sroberto  for (int i = 0; i < len; i++) {
3009132451Sroberto    size_t val = array[i];
301054359Sroberto    for (size_t key = i; key > 0 && array[key - 1] < val; --key) {
3011132451Sroberto      size_t tmp = array[key];
3012132451Sroberto      array[key] = array[key - 1];
3013132451Sroberto      array[key - 1] = tmp;
3014132451Sroberto    }
3015132451Sroberto  }
301682498Sroberto}
301782498Sroberto
301882498Srobertobool os::Solaris::mpss_sanity_check(bool warn, size_t * page_size) {
3019132451Sroberto  getpagesizes_func_type getpagesizes_func =
302054359Sroberto    CAST_TO_FN_PTR(getpagesizes_func_type, dlsym(RTLD_DEFAULT, "getpagesizes"));
3021132451Sroberto  if (getpagesizes_func == NULL) {
3022132451Sroberto    if (warn) {
3023132451Sroberto      warning("MPSS is not supported by the operating system.");
3024132451Sroberto    }
3025132451Sroberto    return false;
3026132451Sroberto  }
3027132451Sroberto
3028132451Sroberto  const unsigned int usable_count = VM_Version::page_size_count();
3029132451Sroberto  if (usable_count == 1) {
3030132451Sroberto    return false;
3031132451Sroberto  }
3032132451Sroberto
3033182007Sroberto  // Fill the array of page sizes.
3034132451Sroberto  int n = getpagesizes_func(_page_sizes, page_sizes_max);
3035132451Sroberto  assert(n > 0, "Solaris bug?");
3036132451Sroberto  if (n == page_sizes_max) {
3037132451Sroberto    // Add a sentinel value (necessary only if the array was completely filled
3038132451Sroberto    // since it is static (zeroed at initialization)).
3039132451Sroberto    _page_sizes[--n] = 0;
3040182007Sroberto    DEBUG_ONLY(warning("increase the size of the os::_page_sizes array.");)
3041182007Sroberto  }
3042182007Sroberto  assert(_page_sizes[n] == 0, "missing sentinel");
3043182007Sroberto
3044182007Sroberto  if (n == 1) return false;     // Only one page size available.
3045182007Sroberto
3046132451Sroberto  // Skip sizes larger than 4M (or LargePageSizeInBytes if it was set) and
3047182007Sroberto  // select up to usable_count elements.  First sort the array, find the first
3048182007Sroberto  // acceptable value, then copy the usable sizes to the top of the array and
3049182007Sroberto  // trim the rest.  Make sure to include the default page size :-).
3050182007Sroberto  //
3051132451Sroberto  // A better policy could get rid of the 4M limit by taking the sizes of the
3052182007Sroberto  // important VM memory regions (java heap and possibly the code cache) into
3053132451Sroberto  // account.
3054132451Sroberto  insertion_sort_descending(_page_sizes, n);
3055182007Sroberto  const size_t size_limit =
3056182007Sroberto    FLAG_IS_DEFAULT(LargePageSizeInBytes) ? 4 * M : LargePageSizeInBytes;
305754359Sroberto  int beg;
3058132451Sroberto  for (beg = 0; beg < n && _page_sizes[beg] > size_limit; ++beg) /* empty */ ;
3059132451Sroberto  const int end = MIN2((int)usable_count, n) - 1;
306054359Sroberto  for (int cur = 0; cur < end; ++cur, ++beg) {
306154359Sroberto    _page_sizes[cur] = _page_sizes[beg];
306254359Sroberto  }
3063132451Sroberto  _page_sizes[end] = vm_page_size();
306454359Sroberto  _page_sizes[end + 1] = 0;
3065132451Sroberto
3066132451Sroberto  if (_page_sizes[end] > _page_sizes[end - 1]) {
3067132451Sroberto    // Default page size is not the smallest; sort again.
3068132451Sroberto    insertion_sort_descending(_page_sizes, end + 1);
3069132451Sroberto  }
3070132451Sroberto  *page_size = _page_sizes[0];
307182498Sroberto
3072132451Sroberto  return true;
3073132451Sroberto}
3074132451Sroberto
3075132451Srobertobool os::large_page_init() {
3076132451Sroberto  if (!UseLargePages) {
307754359Sroberto    UseISM = false;
3078132451Sroberto    UseMPSS = false;
3079132451Sroberto    return false;
3080132451Sroberto  }
3081132451Sroberto
3082132451Sroberto  // print a warning if any large page related flag is specified on command line
3083132451Sroberto  bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages)        ||
3084132451Sroberto                         !FLAG_IS_DEFAULT(UseISM)               ||
3085132451Sroberto                         !FLAG_IS_DEFAULT(UseMPSS)              ||
3086132451Sroberto                         !FLAG_IS_DEFAULT(LargePageSizeInBytes);
3087132451Sroberto  UseISM = UseISM &&
3088132451Sroberto           Solaris::ism_sanity_check(warn_on_failure, &_large_page_size);
3089132451Sroberto  if (UseISM) {
3090132451Sroberto    // ISM disables MPSS to be compatible with old JDK behavior
3091132451Sroberto    UseMPSS = false;
3092132451Sroberto    _page_sizes[0] = _large_page_size;
3093132451Sroberto    _page_sizes[1] = vm_page_size();
3094132451Sroberto  }
3095132451Sroberto
3096132451Sroberto  UseMPSS = UseMPSS &&
3097132451Sroberto            Solaris::mpss_sanity_check(warn_on_failure, &_large_page_size);
3098132451Sroberto
3099132451Sroberto  UseLargePages = UseISM || UseMPSS;
3100132451Sroberto  return UseLargePages;
3101132451Sroberto}
3102132451Sroberto
3103132451Srobertobool os::Solaris::set_mpss_range(caddr_t start, size_t bytes, size_t align) {
3104132451Sroberto  // Signal to OS that we want large pages for addresses
3105132451Sroberto  // from addr, addr + bytes
3106132451Sroberto  struct memcntl_mha mpss_struct;
3107132451Sroberto  mpss_struct.mha_cmd = MHA_MAPSIZE_VA;
3108132451Sroberto  mpss_struct.mha_pagesize = align;
3109132451Sroberto  mpss_struct.mha_flags = 0;
3110132451Sroberto  if (memcntl(start, bytes, MC_HAT_ADVISE,
3111132451Sroberto              (caddr_t) &mpss_struct, 0, 0) < 0) {
3112132451Sroberto    debug_only(warning("Attempt to use MPSS failed."));
3113132451Sroberto    return false;
3114132451Sroberto  }
3115132451Sroberto  return true;
3116132451Sroberto}
3117132451Sroberto
3118132451Srobertochar* os::reserve_memory_special(size_t bytes) {
3119132451Sroberto  assert(UseLargePages && UseISM, "only for ISM large pages");
3120132451Sroberto
3121132451Sroberto  size_t size = bytes;
3122132451Sroberto  char* retAddr = NULL;
3123132451Sroberto  int shmid;
312454359Sroberto  key_t ismKey;
312554359Sroberto
312654359Sroberto  bool warn_on_failure = UseISM &&
3127132451Sroberto                        (!FLAG_IS_DEFAULT(UseLargePages)         ||
3128132451Sroberto                         !FLAG_IS_DEFAULT(UseISM)                ||
3129132451Sroberto                         !FLAG_IS_DEFAULT(LargePageSizeInBytes)
313054359Sroberto                        );
3131132451Sroberto  char msg[128];
3132132451Sroberto
3133132451Sroberto  ismKey = IPC_PRIVATE;
3134132451Sroberto
3135132451Sroberto  // Create a large shared memory region to attach to based on size.
3136132451Sroberto  // Currently, size is the total size of the heap
3137132451Sroberto  shmid = shmget(ismKey, size, SHM_R | SHM_W | IPC_CREAT);
3138132451Sroberto  if (shmid == -1){
3139132451Sroberto     if (warn_on_failure) {
314054359Sroberto       jio_snprintf(msg, sizeof(msg), "Failed to reserve shared memory (errno = %d).", errno);
314154359Sroberto       warning(msg);
314254359Sroberto     }
314354359Sroberto     return NULL;
314454359Sroberto  }
3145132451Sroberto
3146132451Sroberto  // Attach to the region
3147132451Sroberto  retAddr = (char *) shmat(shmid, 0, SHM_SHARE_MMU | SHM_R | SHM_W);
314854359Sroberto  int err = errno;
314982498Sroberto
3150132451Sroberto  // Remove shmid. If shmat() is successful, the actual shared memory segment
3151132451Sroberto  // will be deleted when it's detached by shmdt() or when the process
315254359Sroberto  // terminates. If shmat() is not successful this will remove the shared
3153132451Sroberto  // segment immediately.
315454359Sroberto  shmctl(shmid, IPC_RMID, NULL);
315554359Sroberto
3156132451Sroberto  if (retAddr == (char *) -1) {
315754359Sroberto    if (warn_on_failure) {
3158132451Sroberto      jio_snprintf(msg, sizeof(msg), "Failed to attach shared memory (errno = %d).", err);
3159132451Sroberto      warning(msg);
3160132451Sroberto    }
316154359Sroberto    return NULL;
3162132451Sroberto  }
3163132451Sroberto
316454359Sroberto  return retAddr;
316554359Sroberto}
316654359Sroberto
316754359Srobertobool os::release_memory_special(char* base, size_t bytes) {
3168132451Sroberto  // detaching the SHM segment will also delete it, see reserve_memory_special()
3169132451Sroberto  int rslt = shmdt(base);
317054359Sroberto  return rslt == 0;
317154359Sroberto}
3172132451Sroberto
3173132451Srobertosize_t os::large_page_size() {
317454359Sroberto  return _large_page_size;
3175132451Sroberto}
3176132451Sroberto
3177132451Sroberto// MPSS allows application to commit large page memory on demand; with ISM
3178132451Sroberto// the entire memory region must be allocated as shared memory.
3179132451Srobertobool os::can_commit_large_page_memory() {
3180132451Sroberto  return UseISM ? false : true;
3181132451Sroberto}
3182132451Sroberto
3183132451Srobertobool os::can_execute_large_page_memory() {
3184132451Sroberto  return UseISM ? false : true;
318554359Sroberto}
3186132451Sroberto
3187132451Srobertostatic int os_sleep(jlong millis, bool interruptible) {
3188132451Sroberto  const jlong limit = INT_MAX;
3189132451Sroberto  jlong prevtime;
3190132451Sroberto  int res;
3191132451Sroberto
3192132451Sroberto  while (millis > limit) {
3193132451Sroberto    if ((res = os_sleep(limit, interruptible)) != OS_OK)
3194132451Sroberto      return res;
319554359Sroberto    millis -= limit;
319654359Sroberto  }
319754359Sroberto
3198132451Sroberto  // Restart interrupted polls with new parameters until the proper delay
3199132451Sroberto  // has been completed.
3200132451Sroberto
3201132451Sroberto  prevtime = getTimeMillis();
3202132451Sroberto
320382498Sroberto  while (millis > 0) {
3204132451Sroberto    jlong newtime;
3205132451Sroberto
320682498Sroberto    if (!interruptible) {
320782498Sroberto      // Following assert fails for os::yield_all:
3208132451Sroberto      // assert(!thread->is_Java_thread(), "must not be java thread");
3209132451Sroberto      res = poll(NULL, 0, millis);
3210132451Sroberto    } else {
3211132451Sroberto      JavaThread *jt = JavaThread::current();
321254359Sroberto
3213132451Sroberto      INTERRUPTIBLE_NORESTART_VM_ALWAYS(poll(NULL, 0, millis), res, jt,
3214132451Sroberto        os::Solaris::clear_interrupted);
321582498Sroberto    }
321682498Sroberto
3217132451Sroberto    // INTERRUPTIBLE_NORESTART_VM_ALWAYS returns res == OS_INTRPT for
3218182007Sroberto    // thread.Interrupt.
3219132451Sroberto
3220132451Sroberto    if((res == OS_ERR) && (errno == EINTR)) {
3221132451Sroberto      newtime = getTimeMillis();
3222132451Sroberto      assert(newtime >= prevtime, "time moving backwards");
3223132451Sroberto    /* Doing prevtime and newtime in microseconds doesn't help precision,
322482498Sroberto       and trying to round up to avoid lost milliseconds can result in a
3225132451Sroberto       too-short delay. */
3226132451Sroberto      millis -= newtime - prevtime;
3227132451Sroberto      if(millis <= 0)
3228132451Sroberto        return OS_OK;
3229132451Sroberto      prevtime = newtime;
3230132451Sroberto    } else
3231132451Sroberto      return res;
3232132451Sroberto  }
323382498Sroberto
3234132451Sroberto  return OS_OK;
3235132451Sroberto}
3236132451Sroberto
3237132451Sroberto// Read calls from inside the vm need to perform state transitions
3238132451Srobertosize_t os::read(int fd, void *buf, unsigned int nBytes) {
3239132451Sroberto  INTERRUPTIBLE_RETURN_INT_VM(::read(fd, buf, nBytes), os::Solaris::clear_interrupted);
3240132451Sroberto}
3241132451Sroberto
3242132451Srobertoint os::sleep(Thread* thread, jlong millis, bool interruptible) {
3243132451Sroberto  assert(thread == Thread::current(),  "thread consistency check");
3244132451Sroberto
3245132451Sroberto  // TODO-FIXME: this should be removed.
324682498Sroberto  // On Solaris machines (especially 2.5.1) we found that sometimes the VM gets into a live lock
3247132451Sroberto  // situation with a JavaThread being starved out of a lwp. The kernel doesn't seem to generate
3248132451Sroberto  // a SIGWAITING signal which would enable the threads library to create a new lwp for the starving
324982498Sroberto  // thread. We suspect that because the Watcher thread keeps waking up at periodic intervals the kernel
3250132451Sroberto  // is fooled into believing that the system is making progress. In the code below we block the
325182498Sroberto  // the watcher thread while safepoint is in progress so that it would not appear as though the
3252132451Sroberto  // system is making progress.
3253132451Sroberto  if (!Solaris::T2_libthread() &&
3254132451Sroberto      thread->is_Watcher_thread() && SafepointSynchronize::is_synchronizing() && !Arguments::has_profile()) {
3255182007Sroberto    // We now try to acquire the threads lock. Since this lock is held by the VM thread during
3256182007Sroberto    // the entire safepoint, the watcher thread will  line up here during the safepoint.
3257182007Sroberto    Threads_lock->lock_without_safepoint_check();
3258132451Sroberto    Threads_lock->unlock();
325982498Sroberto  }
3260132451Sroberto
3261132451Sroberto  if (thread->is_Java_thread()) {
3262132451Sroberto    // This is a JavaThread so we honor the _thread_blocked protocol
3263132451Sroberto    // even for sleeps of 0 milliseconds. This was originally done
3264182007Sroberto    // as a workaround for bug 4338139. However, now we also do it
3265132451Sroberto    // to honor the suspend-equivalent protocol.
3266132451Sroberto
3267182007Sroberto    JavaThread *jt = (JavaThread *) thread;
3268132451Sroberto    ThreadBlockInVM tbivm(jt);
3269132451Sroberto
3270182007Sroberto    jt->set_suspend_equivalent();
3271132451Sroberto    // cleared by handle_special_suspend_equivalent_condition() or
3272132451Sroberto    // java_suspend_self() via check_and_wait_while_suspended()
3273132451Sroberto
3274132451Sroberto    int ret_code;
3275132451Sroberto    if (millis <= 0) {
327682498Sroberto      thr_yield();
327782498Sroberto      ret_code = 0;
327882498Sroberto    } else {
3279132451Sroberto      // The original sleep() implementation did not create an
3280132451Sroberto      // OSThreadWaitState helper for sleeps of 0 milliseconds.
3281132451Sroberto      // I'm preserving that decision for now.
3282132451Sroberto      OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */);
3283132451Sroberto
3284132451Sroberto      ret_code = os_sleep(millis, interruptible);
3285132451Sroberto    }
3286132451Sroberto
3287132451Sroberto    // were we externally suspended while we were waiting?
3288132451Sroberto    jt->check_and_wait_while_suspended();
3289132451Sroberto
3290132451Sroberto    return ret_code;
3291132451Sroberto  }
3292132451Sroberto
3293132451Sroberto  // non-JavaThread from this point on:
3294132451Sroberto
3295182007Sroberto  if (millis <= 0) {
3296132451Sroberto    thr_yield();
3297132451Sroberto    return 0;
3298132451Sroberto  }
3299132451Sroberto
3300132451Sroberto  OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
3301132451Sroberto
3302132451Sroberto  return os_sleep(millis, interruptible);
3303132451Sroberto}
3304132451Sroberto
3305132451Srobertoint os::naked_sleep() {
3306132451Sroberto  // %% make the sleep time an integer flag. for now use 1 millisec.
3307132451Sroberto  return os_sleep(1, false);
3308132451Sroberto}
3309132451Sroberto
3310132451Sroberto// Sleep forever; naked call to OS-specific sleep; use with CAUTION
3311132451Srobertovoid os::infinite_sleep() {
3312182007Sroberto  while (true) {    // sleep forever ...
3313132451Sroberto    ::sleep(100);   // ... 100 seconds at a time
3314132451Sroberto  }
3315132451Sroberto}
3316132451Sroberto
3317132451Sroberto// Used to convert frequent JVM_Yield() to nops
3318132451Srobertobool os::dont_yield() {
3319132451Sroberto  if (DontYieldALot) {
3320132451Sroberto    static hrtime_t last_time = 0;
3321132451Sroberto    hrtime_t diff = getTimeNanos() - last_time;
3322132451Sroberto
3323132451Sroberto    if (diff < DontYieldALotInterval * 1000000)
3324132451Sroberto      return true;
3325132451Sroberto
332682498Sroberto    last_time += diff;
332782498Sroberto
332882498Sroberto    return false;
332982498Sroberto  }
3330132451Sroberto  else {
333182498Sroberto    return false;
333254359Sroberto  }
3333132451Sroberto}
333454359Sroberto
3335132451Sroberto// Caveat: Solaris os::yield() causes a thread-state transition whereas
333654359Sroberto// the linux and win32 implementations do not.  This should be checked.
333754359Sroberto
3338132451Srobertovoid os::yield() {
3339132451Sroberto  // Yields to all threads with same or greater priority
3340132451Sroberto  os::sleep(Thread::current(), 0, false);
334154359Sroberto}
3342132451Sroberto
3343132451Sroberto// Note that yield semantics are defined by the scheduling class to which
3344132451Sroberto// the thread currently belongs.  Typically, yield will _not yield to
3345132451Sroberto// other equal or higher priority threads that reside on the dispatch queues
3346132451Sroberto// of other CPUs.
334754359Sroberto
3348132451Srobertoos::YieldResult os::NakedYield() { thr_yield(); return os::YIELD_UNKNOWN; }
3349132451Sroberto
3350132451Sroberto
3351132451Sroberto// On Solaris we found that yield_all doesn't always yield to all other threads.
335254359Sroberto// There have been cases where there is a thread ready to execute but it doesn't
3353132451Sroberto// get an lwp as the VM thread continues to spin with sleeps of 1 millisecond.
3354132451Sroberto// The 1 millisecond wait doesn't seem long enough for the kernel to issue a
3355132451Sroberto// SIGWAITING signal which will cause a new lwp to be created. So we count the
3356132451Sroberto// number of times yield_all is called in the one loop and increase the sleep
3357132451Sroberto// time after 8 attempts. If this fails too we increase the concurrency level
3358132451Sroberto// so that the starving thread would get an lwp
3359132451Sroberto
3360132451Srobertovoid os::yield_all(int attempts) {
3361132451Sroberto  // Yields to all threads, including threads with lower priorities
3362132451Sroberto  if (attempts == 0) {
3363132451Sroberto    os::sleep(Thread::current(), 1, false);
3364132451Sroberto  } else {
3365132451Sroberto    int iterations = attempts % 30;
3366132451Sroberto    if (iterations == 0 && !os::Solaris::T2_libthread()) {
3367132451Sroberto      // thr_setconcurrency and _getconcurrency make sense only under T1.
3368132451Sroberto      int noofLWPS = thr_getconcurrency();
3369132451Sroberto      if (noofLWPS < (Threads::number_of_threads() + 2)) {
3370132451Sroberto        thr_setconcurrency(thr_getconcurrency() + 1);
3371132451Sroberto      }
3372132451Sroberto    } else if (iterations < 25) {
337382498Sroberto      os::sleep(Thread::current(), 1, false);
3374132451Sroberto    } else {
337554359Sroberto      os::sleep(Thread::current(), 10, false);
337654359Sroberto    }
337782498Sroberto  }
3378132451Sroberto}
337982498Sroberto
338082498Sroberto// Called from the tight loops to possibly influence time-sharing heuristics
338182498Srobertovoid os::loop_breaker(int attempts) {
338282498Sroberto  os::yield_all(attempts);
338382498Sroberto}
338482498Sroberto
338582498Sroberto
338654359Sroberto// Interface for setting lwp priorities.  If we are using T2 libthread,
338754359Sroberto// which forces the use of BoundThreads or we manually set UseBoundThreads,
338854359Sroberto// all of our threads will be assigned to real lwp's.  Using the thr_setprio
338954359Sroberto// function is meaningless in this mode so we must adjust the real lwp's priority
339054359Sroberto// The routines below implement the getting and setting of lwp priorities.
339154359Sroberto//
339254359Sroberto// Note: There are three priority scales used on Solaris.  Java priotities
339354359Sroberto//       which range from 1 to 10, libthread "thr_setprio" scale which range
339454359Sroberto//       from 0 to 127, and the current scheduling class of the process we
339554359Sroberto//       are running in.  This is typically from -60 to +60.
339654359Sroberto//       The setting of the lwp priorities in done after a call to thr_setprio
339754359Sroberto//       so Java priorities are mapped to libthread priorities and we map from
339854359Sroberto//       the latter to lwp priorities.  We don't keep priorities stored in
339954359Sroberto//       Java priorities since some of our worker threads want to set priorities
340054359Sroberto//       higher than all Java threads.
340154359Sroberto//
340254359Sroberto// For related information:
340354359Sroberto// (1)  man -s 2 priocntl
340454359Sroberto// (2)  man -s 4 priocntl
340554359Sroberto// (3)  man dispadmin
340654359Sroberto// =    librt.so
340782498Sroberto// =    libthread/common/rtsched.c - thrp_setlwpprio().
340854359Sroberto// =    ps -cL <pid> ... to validate priority.
340954359Sroberto// =    sched_get_priority_min and _max
341054359Sroberto//              pthread_create
341154359Sroberto//              sched_setparam
341254359Sroberto//              pthread_setschedparam
341354359Sroberto//
341454359Sroberto// Assumptions:
341554359Sroberto// +    We assume that all threads in the process belong to the same
3416132451Sroberto//              scheduling class.   IE. an homogenous process.
3417132451Sroberto// +    Must be root or in IA group to change change "interactive" attribute.
341854359Sroberto//              Priocntl() will fail silently.  The only indication of failure is when
341954359Sroberto//              we read-back the value and notice that it hasn't changed.
342054359Sroberto// +    Interactive threads enter the runq at the head, non-interactive at the tail.
342154359Sroberto// +    For RT, change timeslice as well.  Invariant:
342254359Sroberto//              constant "priority integral"
342354359Sroberto//              Konst == TimeSlice * (60-Priority)
342454359Sroberto//              Given a priority, compute appropriate timeslice.
342554359Sroberto// +    Higher numerical values have higher priority.
3426132451Sroberto
3427132451Sroberto// sched class attributes
342854359Srobertotypedef struct {
342956746Sroberto        int   schedPolicy;              // classID
343054359Sroberto        int   maxPrio;
343154359Sroberto        int   minPrio;
343254359Sroberto} SchedInfo;
343356746Sroberto
3434132451Sroberto
343556746Srobertostatic SchedInfo tsLimits, iaLimits, rtLimits;
343682498Sroberto
343756746Sroberto#ifdef ASSERT
3438132451Srobertostatic int  ReadBackValidate = 1;
3439132451Sroberto#endif
3440132451Srobertostatic int  myClass     = 0;
344182498Srobertostatic int  myMin       = 0;
344256746Srobertostatic int  myMax       = 0;
344356746Srobertostatic int  myCur       = 0;
3444132451Srobertostatic bool priocntl_enable = false;
344556746Sroberto
3446182007Sroberto
3447132451Sroberto// Call the version of priocntl suitable for all supported versions
3448132451Sroberto// of Solaris. We need to call through this wrapper so that we can
3449182007Sroberto// build on Solaris 9 and run on Solaris 8, 9 and 10.
3450132451Sroberto//
3451132451Sroberto// This code should be removed if we ever stop supporting Solaris 8
3452132451Sroberto// and earlier releases.
3453132451Sroberto
3454132451Srobertostatic long priocntl_stub(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg);
3455132451Srobertotypedef long (*priocntl_type)(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg);
3456132451Srobertostatic priocntl_type priocntl_ptr = priocntl_stub;
345756746Sroberto
345856746Sroberto// Stub to set the value of the real pointer, and then call the real
345956746Sroberto// function.
3460132451Sroberto
3461132451Srobertostatic long priocntl_stub(int pcver, idtype_t idtype, id_t id, int cmd, caddr_t arg) {
3462132451Sroberto  // Try Solaris 8- name only.
3463132451Sroberto  priocntl_type tmp = (priocntl_type)dlsym(RTLD_DEFAULT, "__priocntl");
3464132451Sroberto  guarantee(tmp != NULL, "priocntl function not found.");
3465132451Sroberto  priocntl_ptr = tmp;
3466182007Sroberto  return (*priocntl_ptr)(PC_VERSION, idtype, id, cmd, arg);
3467132451Sroberto}
3468132451Sroberto
3469132451Sroberto
3470132451Sroberto// lwp_priocntl_init
3471132451Sroberto//
3472132451Sroberto// Try to determine the priority scale for our process.
3473132451Sroberto//
3474132451Sroberto// Return errno or 0 if OK.
3475132451Sroberto//
3476132451Srobertostatic
3477132451Srobertoint     lwp_priocntl_init ()
3478132451Sroberto{
3479132451Sroberto  int rslt;
3480132451Sroberto  pcinfo_t ClassInfo;
3481132451Sroberto  pcparms_t ParmInfo;
3482132451Sroberto  int i;
3483132451Sroberto
3484132451Sroberto  if (!UseThreadPriorities) return 0;
3485132451Sroberto
3486132451Sroberto  // We are using Bound threads, we need to determine our priority ranges
3487132451Sroberto  if (os::Solaris::T2_libthread() || UseBoundThreads) {
3488132451Sroberto    // If ThreadPriorityPolicy is 1, switch tables
3489132451Sroberto    if (ThreadPriorityPolicy == 1) {
3490132451Sroberto      for (i = 0 ; i < MaxPriority+1; i++)
3491132451Sroberto        os::java_to_os_priority[i] = prio_policy1[i];
3492132451Sroberto    }
3493132451Sroberto  }
3494132451Sroberto  // Not using Bound Threads, set to ThreadPolicy 1
3495132451Sroberto  else {
3496132451Sroberto    for ( i = 0 ; i < MaxPriority+1; i++ ) {
3497132451Sroberto      os::java_to_os_priority[i] = prio_policy1[i];
3498132451Sroberto    }
3499132451Sroberto    return 0;
3500132451Sroberto  }
3501132451Sroberto
3502132451Sroberto
3503132451Sroberto  // Get IDs for a set of well-known scheduling classes.
3504132451Sroberto  // TODO-FIXME: GETCLINFO returns the current # of classes in the
3505132451Sroberto  // the system.  We should have a loop that iterates over the
3506132451Sroberto  // classID values, which are known to be "small" integers.
3507132451Sroberto
3508132451Sroberto  strcpy(ClassInfo.pc_clname, "TS");
3509132451Sroberto  ClassInfo.pc_cid = -1;
3510132451Sroberto  rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3511132451Sroberto  if (rslt < 0) return errno;
3512132451Sroberto  assert(ClassInfo.pc_cid != -1, "cid for TS class is -1");
3513132451Sroberto  tsLimits.schedPolicy = ClassInfo.pc_cid;
3514132451Sroberto  tsLimits.maxPrio = ((tsinfo_t*)ClassInfo.pc_clinfo)->ts_maxupri;
3515132451Sroberto  tsLimits.minPrio = -tsLimits.maxPrio;
3516132451Sroberto
3517132451Sroberto  strcpy(ClassInfo.pc_clname, "IA");
3518132451Sroberto  ClassInfo.pc_cid = -1;
3519132451Sroberto  rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3520132451Sroberto  if (rslt < 0) return errno;
3521132451Sroberto  assert(ClassInfo.pc_cid != -1, "cid for IA class is -1");
3522132451Sroberto  iaLimits.schedPolicy = ClassInfo.pc_cid;
3523132451Sroberto  iaLimits.maxPrio = ((iainfo_t*)ClassInfo.pc_clinfo)->ia_maxupri;
3524132451Sroberto  iaLimits.minPrio = -iaLimits.maxPrio;
3525132451Sroberto
3526132451Sroberto  strcpy(ClassInfo.pc_clname, "RT");
3527132451Sroberto  ClassInfo.pc_cid = -1;
3528132451Sroberto  rslt = (*priocntl_ptr)(PC_VERSION, P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
3529132451Sroberto  if (rslt < 0) return errno;
3530132451Sroberto  assert(ClassInfo.pc_cid != -1, "cid for RT class is -1");
3531132451Sroberto  rtLimits.schedPolicy = ClassInfo.pc_cid;
3532132451Sroberto  rtLimits.maxPrio = ((rtinfo_t*)ClassInfo.pc_clinfo)->rt_maxpri;
3533132451Sroberto  rtLimits.minPrio = 0;
3534132451Sroberto
3535132451Sroberto
3536132451Sroberto  // Query our "current" scheduling class.
3537132451Sroberto  // This will normally be IA,TS or, rarely, RT.
3538132451Sroberto  memset (&ParmInfo, 0, sizeof(ParmInfo));
3539132451Sroberto  ParmInfo.pc_cid = PC_CLNULL;
3540132451Sroberto  rslt = (*priocntl_ptr) (PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo );
354154359Sroberto  if ( rslt < 0 ) return errno;
3542132451Sroberto  myClass = ParmInfo.pc_cid;
3543132451Sroberto
3544132451Sroberto  // We now know our scheduling classId, get specific information
3545132451Sroberto  // the class.
3546132451Sroberto  ClassInfo.pc_cid = myClass;
3547132451Sroberto  ClassInfo.pc_clname[0] = 0;
3548132451Sroberto  rslt = (*priocntl_ptr) (PC_VERSION, (idtype)0, 0, PC_GETCLINFO, (caddr_t)&ClassInfo );
3549132451Sroberto  if ( rslt < 0 ) return errno;
3550132451Sroberto
3551132451Sroberto  if (ThreadPriorityVerbose)
3552132451Sroberto    tty->print_cr ("lwp_priocntl_init: Class=%d(%s)...", myClass, ClassInfo.pc_clname);
3553132451Sroberto
3554132451Sroberto  memset(&ParmInfo, 0, sizeof(pcparms_t));
3555132451Sroberto  ParmInfo.pc_cid = PC_CLNULL;
3556132451Sroberto  rslt = (*priocntl_ptr)(PC_VERSION, P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo);
3557132451Sroberto  if (rslt < 0) return errno;
3558182007Sroberto
3559132451Sroberto  if (ParmInfo.pc_cid == rtLimits.schedPolicy) {
356056746Sroberto    myMin = rtLimits.minPrio;
356154359Sroberto    myMax = rtLimits.maxPrio;
356256746Sroberto  } else if (ParmInfo.pc_cid == iaLimits.schedPolicy) {
356356746Sroberto    iaparms_t *iaInfo  = (iaparms_t*)ParmInfo.pc_clparms;
356456746Sroberto    myMin = iaLimits.minPrio;
3565132451Sroberto    myMax = iaLimits.maxPrio;
356656746Sroberto    myMax = MIN2(myMax, (int)iaInfo->ia_uprilim);       // clamp - restrict
356782498Sroberto  } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) {
356856746Sroberto    tsparms_t *tsInfo  = (tsparms_t*)ParmInfo.pc_clparms;
3569132451Sroberto    myMin = tsLimits.minPrio;
3570132451Sroberto    myMax = tsLimits.maxPrio;
357156746Sroberto    myMax = MIN2(myMax, (int)tsInfo->ts_uprilim);       // clamp - restrict
357256746Sroberto  } else {
3573132451Sroberto    // No clue - punt
3574132451Sroberto    if (ThreadPriorityVerbose)
3575132451Sroberto      tty->print_cr ("Unknown scheduling class: %s ... \n", ClassInfo.pc_clname);
3576132451Sroberto    return EINVAL;      // no clue, punt
3577132451Sroberto  }
3578132451Sroberto
3579132451Sroberto  if (ThreadPriorityVerbose)
3580132451Sroberto        tty->print_cr ("Thread priority Range: [%d..%d]\n", myMin, myMax);
3581132451Sroberto
3582132451Sroberto  priocntl_enable = true;  // Enable changing priorities
3583132451Sroberto  return 0;
3584132451Sroberto}
3585132451Sroberto
3586132451Sroberto#define IAPRI(x)        ((iaparms_t *)((x).pc_clparms))
3587132451Sroberto#define RTPRI(x)        ((rtparms_t *)((x).pc_clparms))
3588132451Sroberto#define TSPRI(x)        ((tsparms_t *)((x).pc_clparms))
3589132451Sroberto
3590132451Sroberto
3591132451Sroberto// scale_to_lwp_priority
3592132451Sroberto//
3593132451Sroberto// Convert from the libthread "thr_setprio" scale to our current
3594132451Sroberto// lwp scheduling class scale.
3595132451Sroberto//
3596132451Srobertostatic
3597132451Srobertoint     scale_to_lwp_priority (int rMin, int rMax, int x)
3598132451Sroberto{
3599132451Sroberto  int v;
3600132451Sroberto
3601132451Sroberto  if (x == 127) return rMax;            // avoid round-down
360256746Sroberto    v = (((x*(rMax-rMin)))/128)+rMin;
360356746Sroberto  return v;
360456746Sroberto}
3605132451Sroberto
3606132451Sroberto
3607132451Sroberto// set_lwp_priority
3608132451Sroberto//
3609132451Sroberto// Set the priority of the lwp.  This call should only be made
3610132451Sroberto// when using bound threads (T2 threads are bound by default).
361156746Sroberto//
361282498Srobertoint     set_lwp_priority (int ThreadID, int lwpid, int newPrio )
3613132451Sroberto{
3614132451Sroberto  int rslt;
361582498Sroberto  int Actual, Expected, prv;
361682498Sroberto  pcparms_t ParmInfo;                   // for GET-SET
3617132451Sroberto#ifdef ASSERT
3618132451Sroberto  pcparms_t ReadBack;                   // for readback
361982498Sroberto#endif
3620132451Sroberto
3621132451Sroberto  // Set priority via PC_GETPARMS, update, PC_SETPARMS
3622132451Sroberto  // Query current values.
3623132451Sroberto  // TODO: accelerate this by eliminating the PC_GETPARMS call.
3624132451Sroberto  // Cache "pcparms_t" in global ParmCache.
3625132451Sroberto  // TODO: elide set-to-same-value
3626132451Sroberto
3627132451Sroberto  // If something went wrong on init, don't change priorities.
3628132451Sroberto  if ( !priocntl_enable ) {
3629132451Sroberto    if (ThreadPriorityVerbose)
3630132451Sroberto      tty->print_cr("Trying to set priority but init failed, ignoring");
3631132451Sroberto    return EINVAL;
3632132451Sroberto  }
3633132451Sroberto
3634132451Sroberto
3635132451Sroberto  // If lwp hasn't started yet, just return
3636132451Sroberto  // the _start routine will call us again.
3637132451Sroberto  if ( lwpid <= 0 ) {
3638132451Sroberto    if (ThreadPriorityVerbose) {
3639132451Sroberto      tty->print_cr ("deferring the set_lwp_priority of thread " INTPTR_FORMAT " to %d, lwpid not set",
3640132451Sroberto                     ThreadID, newPrio);
3641132451Sroberto    }
3642132451Sroberto    return 0;
3643132451Sroberto  }
3644132451Sroberto
3645132451Sroberto  if (ThreadPriorityVerbose) {
3646132451Sroberto    tty->print_cr ("set_lwp_priority(" INTPTR_FORMAT "@" INTPTR_FORMAT " %d) ",
3647132451Sroberto                   ThreadID, lwpid, newPrio);
3648132451Sroberto  }
3649132451Sroberto
3650132451Sroberto  memset(&ParmInfo, 0, sizeof(pcparms_t));
3651132451Sroberto  ParmInfo.pc_cid = PC_CLNULL;
3652132451Sroberto  rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ParmInfo);
3653132451Sroberto  if (rslt < 0) return errno;
3654132451Sroberto
3655132451Sroberto  if (ParmInfo.pc_cid == rtLimits.schedPolicy) {
3656132451Sroberto    rtparms_t *rtInfo  = (rtparms_t*)ParmInfo.pc_clparms;
3657132451Sroberto    rtInfo->rt_pri     = scale_to_lwp_priority (rtLimits.minPrio, rtLimits.maxPrio, newPrio);
3658132451Sroberto    rtInfo->rt_tqsecs  = RT_NOCHANGE;
3659132451Sroberto    rtInfo->rt_tqnsecs = RT_NOCHANGE;
3660132451Sroberto    if (ThreadPriorityVerbose) {
3661132451Sroberto      tty->print_cr("RT: %d->%d\n", newPrio, rtInfo->rt_pri);
3662132451Sroberto    }
3663132451Sroberto  } else if (ParmInfo.pc_cid == iaLimits.schedPolicy) {
3664132451Sroberto    iaparms_t *iaInfo  = (iaparms_t*)ParmInfo.pc_clparms;
3665132451Sroberto    int maxClamped     = MIN2(iaLimits.maxPrio, (int)iaInfo->ia_uprilim);
3666132451Sroberto    iaInfo->ia_upri    = scale_to_lwp_priority(iaLimits.minPrio, maxClamped, newPrio);
3667132451Sroberto    iaInfo->ia_uprilim = IA_NOCHANGE;
3668132451Sroberto    iaInfo->ia_nice    = IA_NOCHANGE;
3669132451Sroberto    iaInfo->ia_mode    = IA_NOCHANGE;
3670132451Sroberto    if (ThreadPriorityVerbose) {
3671132451Sroberto      tty->print_cr ("IA: [%d...%d] %d->%d\n",
3672132451Sroberto               iaLimits.minPrio, maxClamped, newPrio, iaInfo->ia_upri);
3673132451Sroberto    }
3674132451Sroberto  } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) {
3675132451Sroberto    tsparms_t *tsInfo  = (tsparms_t*)ParmInfo.pc_clparms;
3676132451Sroberto    int maxClamped     = MIN2(tsLimits.maxPrio, (int)tsInfo->ts_uprilim);
367782498Sroberto    prv                = tsInfo->ts_upri;
3678132451Sroberto    tsInfo->ts_upri    = scale_to_lwp_priority(tsLimits.minPrio, maxClamped, newPrio);
367982498Sroberto    tsInfo->ts_uprilim = IA_NOCHANGE;
368082498Sroberto    if (ThreadPriorityVerbose) {
368182498Sroberto      tty->print_cr ("TS: %d [%d...%d] %d->%d\n",
3682132451Sroberto               prv, tsLimits.minPrio, maxClamped, newPrio, tsInfo->ts_upri);
3683132451Sroberto    }
3684132451Sroberto    if (prv == tsInfo->ts_upri) return 0;
3685132451Sroberto  } else {
3686132451Sroberto    if ( ThreadPriorityVerbose ) {
3687132451Sroberto      tty->print_cr ("Unknown scheduling class\n");
3688132451Sroberto    }
3689132451Sroberto      return EINVAL;    // no clue, punt
3690182007Sroberto  }
3691132451Sroberto
3692132451Sroberto  rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_SETPARMS, (caddr_t)&ParmInfo);
3693182007Sroberto  if (ThreadPriorityVerbose && rslt) {
3694132451Sroberto    tty->print_cr ("PC_SETPARMS ->%d %d\n", rslt, errno);
3695132451Sroberto  }
3696132451Sroberto  if (rslt < 0) return errno;
3697132451Sroberto
3698132451Sroberto#ifdef ASSERT
3699132451Sroberto  // Sanity check: read back what we just attempted to set.
3700132451Sroberto  // In theory it could have changed in the interim ...
3701132451Sroberto  //
3702132451Sroberto  // The priocntl system call is tricky.
3703132451Sroberto  // Sometimes it'll validate the priority value argument and
3704132451Sroberto  // return EINVAL if unhappy.  At other times it fails silently.
3705132451Sroberto  // Readbacks are prudent.
3706132451Sroberto
3707132451Sroberto  if (!ReadBackValidate) return 0;
3708132451Sroberto
3709132451Sroberto  memset(&ReadBack, 0, sizeof(pcparms_t));
3710132451Sroberto  ReadBack.pc_cid = PC_CLNULL;
3711132451Sroberto  rslt = (*priocntl_ptr)(PC_VERSION, P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ReadBack);
3712132451Sroberto  assert(rslt >= 0, "priocntl failed");
3713132451Sroberto  Actual = Expected = 0xBAD;
3714132451Sroberto  assert(ParmInfo.pc_cid == ReadBack.pc_cid, "cid's don't match");
3715132451Sroberto  if (ParmInfo.pc_cid == rtLimits.schedPolicy) {
3716132451Sroberto    Actual   = RTPRI(ReadBack)->rt_pri;
3717132451Sroberto    Expected = RTPRI(ParmInfo)->rt_pri;
3718132451Sroberto  } else if (ParmInfo.pc_cid == iaLimits.schedPolicy) {
3719132451Sroberto    Actual   = IAPRI(ReadBack)->ia_upri;
3720132451Sroberto    Expected = IAPRI(ParmInfo)->ia_upri;
3721132451Sroberto  } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) {
3722132451Sroberto    Actual   = TSPRI(ReadBack)->ts_upri;
3723132451Sroberto    Expected = TSPRI(ParmInfo)->ts_upri;
3724132451Sroberto  } else {
3725132451Sroberto    if ( ThreadPriorityVerbose ) {
3726132451Sroberto      tty->print_cr("set_lwp_priority: unexpected class in readback: %d\n", ParmInfo.pc_cid);
3727132451Sroberto    }
3728132451Sroberto  }
3729132451Sroberto
373054359Sroberto  if (Actual != Expected) {
373154359Sroberto    if ( ThreadPriorityVerbose ) {
373254359Sroberto      tty->print_cr ("set_lwp_priority(%d %d) Class=%d: actual=%d vs expected=%d\n",
3733             lwpid, newPrio, ReadBack.pc_cid, Actual, Expected);
3734    }
3735  }
3736#endif
3737
3738  return 0;
3739}
3740
3741
3742
3743// Solaris only gives access to 128 real priorities at a time,
3744// so we expand Java's ten to fill this range.  This would be better
3745// if we dynamically adjusted relative priorities.
3746//
3747// The ThreadPriorityPolicy option allows us to select 2 different
3748// priority scales.
3749//
3750// ThreadPriorityPolicy=0
3751// Since the Solaris' default priority is MaximumPriority, we do not
3752// set a priority lower than Max unless a priority lower than
3753// NormPriority is requested.
3754//
3755// ThreadPriorityPolicy=1
3756// This mode causes the priority table to get filled with
3757// linear values.  NormPriority get's mapped to 50% of the
3758// Maximum priority an so on.  This will cause VM threads
3759// to get unfair treatment against other Solaris processes
3760// which do not explicitly alter their thread priorities.
3761//
3762
3763
3764int os::java_to_os_priority[MaxPriority + 1] = {
3765  -99999,         // 0 Entry should never be used
3766
3767  0,              // 1 MinPriority
3768  32,             // 2
3769  64,             // 3
3770
3771  96,             // 4
3772  127,            // 5 NormPriority
3773  127,            // 6
3774
3775  127,            // 7
3776  127,            // 8
3777  127,            // 9 NearMaxPriority
3778
3779  127             // 10 MaxPriority
3780};
3781
3782
3783OSReturn os::set_native_priority(Thread* thread, int newpri) {
3784  assert(newpri >= MinimumPriority && newpri <= MaximumPriority, "bad priority mapping");
3785  if ( !UseThreadPriorities ) return OS_OK;
3786  int status = thr_setprio(thread->osthread()->thread_id(), newpri);
3787  if ( os::Solaris::T2_libthread() || (UseBoundThreads && thread->osthread()->is_vm_created()) )
3788    status |= (set_lwp_priority (thread->osthread()->thread_id(),
3789                    thread->osthread()->lwp_id(), newpri ));
3790  return (status == 0) ? OS_OK : OS_ERR;
3791}
3792
3793
3794OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {
3795  int p;
3796  if ( !UseThreadPriorities ) {
3797    *priority_ptr = NormalPriority;
3798    return OS_OK;
3799  }
3800  int status = thr_getprio(thread->osthread()->thread_id(), &p);
3801  if (status != 0) {
3802    return OS_ERR;
3803  }
3804  *priority_ptr = p;
3805  return OS_OK;
3806}
3807
3808
3809// Hint to the underlying OS that a task switch would not be good.
3810// Void return because it's a hint and can fail.
3811void os::hint_no_preempt() {
3812  schedctl_start(schedctl_init());
3813}
3814
3815void os::interrupt(Thread* thread) {
3816  assert(Thread::current() == thread || Threads_lock->owned_by_self(), "possibility of dangling Thread pointer");
3817
3818  OSThread* osthread = thread->osthread();
3819
3820  int isInterrupted = osthread->interrupted();
3821  if (!isInterrupted) {
3822      osthread->set_interrupted(true);
3823      OrderAccess::fence();
3824      // os::sleep() is implemented with either poll (NULL,0,timeout) or
3825      // by parking on _SleepEvent.  If the former, thr_kill will unwedge
3826      // the sleeper by SIGINTR, otherwise the unpark() will wake the sleeper.
3827      ParkEvent * const slp = thread->_SleepEvent ;
3828      if (slp != NULL) slp->unpark() ;
3829  }
3830
3831  // For JSR166:  unpark after setting status but before thr_kill -dl
3832  if (thread->is_Java_thread()) {
3833    ((JavaThread*)thread)->parker()->unpark();
3834  }
3835
3836  // Handle interruptible wait() ...
3837  ParkEvent * const ev = thread->_ParkEvent ;
3838  if (ev != NULL) ev->unpark() ;
3839
3840  // When events are used everywhere for os::sleep, then this thr_kill
3841  // will only be needed if UseVMInterruptibleIO is true.
3842
3843  if (!isInterrupted) {
3844    int status = thr_kill(osthread->thread_id(), os::Solaris::SIGinterrupt());
3845    assert_status(status == 0, status, "thr_kill");
3846
3847    // Bump thread interruption counter
3848    RuntimeService::record_thread_interrupt_signaled_count();
3849  }
3850}
3851
3852
3853bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
3854  assert(Thread::current() == thread || Threads_lock->owned_by_self(), "possibility of dangling Thread pointer");
3855
3856  OSThread* osthread = thread->osthread();
3857
3858  bool res = osthread->interrupted();
3859
3860  // NOTE that since there is no "lock" around these two operations,
3861  // there is the possibility that the interrupted flag will be
3862  // "false" but that the interrupt event will be set. This is
3863  // intentional. The effect of this is that Object.wait() will appear
3864  // to have a spurious wakeup, which is not harmful, and the
3865  // possibility is so rare that it is not worth the added complexity
3866  // to add yet another lock. It has also been recommended not to put
3867  // the interrupted flag into the os::Solaris::Event structure,
3868  // because it hides the issue.
3869  if (res && clear_interrupted) {
3870    osthread->set_interrupted(false);
3871  }
3872  return res;
3873}
3874
3875
3876void os::print_statistics() {
3877}
3878
3879int os::message_box(const char* title, const char* message) {
3880  int i;
3881  fdStream err(defaultStream::error_fd());
3882  for (i = 0; i < 78; i++) err.print_raw("=");
3883  err.cr();
3884  err.print_raw_cr(title);
3885  for (i = 0; i < 78; i++) err.print_raw("-");
3886  err.cr();
3887  err.print_raw_cr(message);
3888  for (i = 0; i < 78; i++) err.print_raw("=");
3889  err.cr();
3890
3891  char buf[16];
3892  // Prevent process from exiting upon "read error" without consuming all CPU
3893  while (::read(0, buf, sizeof(buf)) <= 0) { ::sleep(100); }
3894
3895  return buf[0] == 'y' || buf[0] == 'Y';
3896}
3897
3898// A lightweight implementation that does not suspend the target thread and
3899// thus returns only a hint. Used for profiling only!
3900ExtendedPC os::get_thread_pc(Thread* thread) {
3901  // Make sure that it is called by the watcher and the Threads lock is owned.
3902  assert(Thread::current()->is_Watcher_thread(), "Must be watcher and own Threads_lock");
3903  // For now, is only used to profile the VM Thread
3904  assert(thread->is_VM_thread(), "Can only be called for VMThread");
3905  ExtendedPC epc;
3906
3907  GetThreadPC_Callback  cb(ProfileVM_lock);
3908  OSThread *osthread = thread->osthread();
3909  const int time_to_wait = 400; // 400ms wait for initial response
3910  int status = cb.interrupt(thread, time_to_wait);
3911
3912  if (cb.is_done() ) {
3913    epc = cb.addr();
3914  } else {
3915    DEBUG_ONLY(tty->print_cr("Failed to get pc for thread: %d got %d status",
3916                              osthread->thread_id(), status););
3917    // epc is already NULL
3918  }
3919  return epc;
3920}
3921
3922
3923// This does not do anything on Solaris. This is basically a hook for being
3924// able to use structured exception handling (thread-local exception filters) on, e.g., Win32.
3925void os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread) {
3926  f(value, method, args, thread);
3927}
3928
3929// This routine may be used by user applications as a "hook" to catch signals.
3930// The user-defined signal handler must pass unrecognized signals to this
3931// routine, and if it returns true (non-zero), then the signal handler must
3932// return immediately.  If the flag "abort_if_unrecognized" is true, then this
3933// routine will never retun false (zero), but instead will execute a VM panic
3934// routine kill the process.
3935//
3936// If this routine returns false, it is OK to call it again.  This allows
3937// the user-defined signal handler to perform checks either before or after
3938// the VM performs its own checks.  Naturally, the user code would be making
3939// a serious error if it tried to handle an exception (such as a null check
3940// or breakpoint) that the VM was generating for its own correct operation.
3941//
3942// This routine may recognize any of the following kinds of signals:
3943// SIGBUS, SIGSEGV, SIGILL, SIGFPE, BREAK_SIGNAL, SIGPIPE, SIGXFSZ,
3944// os::Solaris::SIGasync
3945// It should be consulted by handlers for any of those signals.
3946// It explicitly does not recognize os::Solaris::SIGinterrupt
3947//
3948// The caller of this routine must pass in the three arguments supplied
3949// to the function referred to in the "sa_sigaction" (not the "sa_handler")
3950// field of the structure passed to sigaction().  This routine assumes that
3951// the sa_flags field passed to sigaction() includes SA_SIGINFO and SA_RESTART.
3952//
3953// Note that the VM will print warnings if it detects conflicting signal
3954// handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers".
3955//
3956extern "C" int JVM_handle_solaris_signal(int signo, siginfo_t* siginfo, void* ucontext, int abort_if_unrecognized);
3957
3958
3959void signalHandler(int sig, siginfo_t* info, void* ucVoid) {
3960  JVM_handle_solaris_signal(sig, info, ucVoid, true);
3961}
3962
3963/* Do not delete - if guarantee is ever removed,  a signal handler (even empty)
3964   is needed to provoke threads blocked on IO to return an EINTR
3965   Note: this explicitly does NOT call JVM_handle_solaris_signal and
3966   does NOT participate in signal chaining due to requirement for
3967   NOT setting SA_RESTART to make EINTR work. */
3968extern "C" void sigINTRHandler(int sig, siginfo_t* info, void* ucVoid) {
3969   if (UseSignalChaining) {
3970      struct sigaction *actp = os::Solaris::get_chained_signal_action(sig);
3971      if (actp && actp->sa_handler) {
3972        vm_exit_during_initialization("Signal chaining detected for VM interrupt signal, try -XX:+UseAltSigs");
3973      }
3974   }
3975}
3976
3977// This boolean allows users to forward their own non-matching signals
3978// to JVM_handle_solaris_signal, harmlessly.
3979bool os::Solaris::signal_handlers_are_installed = false;
3980
3981// For signal-chaining
3982bool os::Solaris::libjsig_is_loaded = false;
3983typedef struct sigaction *(*get_signal_t)(int);
3984get_signal_t os::Solaris::get_signal_action = NULL;
3985
3986struct sigaction* os::Solaris::get_chained_signal_action(int sig) {
3987  struct sigaction *actp = NULL;
3988
3989  if ((libjsig_is_loaded)  && (sig <= Maxlibjsigsigs)) {
3990    // Retrieve the old signal handler from libjsig
3991    actp = (*get_signal_action)(sig);
3992  }
3993  if (actp == NULL) {
3994    // Retrieve the preinstalled signal handler from jvm
3995    actp = get_preinstalled_handler(sig);
3996  }
3997
3998  return actp;
3999}
4000
4001static bool call_chained_handler(struct sigaction *actp, int sig,
4002                                 siginfo_t *siginfo, void *context) {
4003  // Call the old signal handler
4004  if (actp->sa_handler == SIG_DFL) {
4005    // It's more reasonable to let jvm treat it as an unexpected exception
4006    // instead of taking the default action.
4007    return false;
4008  } else if (actp->sa_handler != SIG_IGN) {
4009    if ((actp->sa_flags & SA_NODEFER) == 0) {
4010      // automaticlly block the signal
4011      sigaddset(&(actp->sa_mask), sig);
4012    }
4013
4014    sa_handler_t hand;
4015    sa_sigaction_t sa;
4016    bool siginfo_flag_set = (actp->sa_flags & SA_SIGINFO) != 0;
4017    // retrieve the chained handler
4018    if (siginfo_flag_set) {
4019      sa = actp->sa_sigaction;
4020    } else {
4021      hand = actp->sa_handler;
4022    }
4023
4024    if ((actp->sa_flags & SA_RESETHAND) != 0) {
4025      actp->sa_handler = SIG_DFL;
4026    }
4027
4028    // try to honor the signal mask
4029    sigset_t oset;
4030    thr_sigsetmask(SIG_SETMASK, &(actp->sa_mask), &oset);
4031
4032    // call into the chained handler
4033    if (siginfo_flag_set) {
4034      (*sa)(sig, siginfo, context);
4035    } else {
4036      (*hand)(sig);
4037    }
4038
4039    // restore the signal mask
4040    thr_sigsetmask(SIG_SETMASK, &oset, 0);
4041  }
4042  // Tell jvm's signal handler the signal is taken care of.
4043  return true;
4044}
4045
4046bool os::Solaris::chained_handler(int sig, siginfo_t* siginfo, void* context) {
4047  bool chained = false;
4048  // signal-chaining
4049  if (UseSignalChaining) {
4050    struct sigaction *actp = get_chained_signal_action(sig);
4051    if (actp != NULL) {
4052      chained = call_chained_handler(actp, sig, siginfo, context);
4053    }
4054  }
4055  return chained;
4056}
4057
4058struct sigaction* os::Solaris::get_preinstalled_handler(int sig) {
4059  assert((chainedsigactions != (struct sigaction *)NULL) && (preinstalled_sigs != (int *)NULL) , "signals not yet initialized");
4060  if (preinstalled_sigs[sig] != 0) {
4061    return &chainedsigactions[sig];
4062  }
4063  return NULL;
4064}
4065
4066void os::Solaris::save_preinstalled_handler(int sig, struct sigaction& oldAct) {
4067
4068  assert(sig > 0 && sig <= Maxsignum, "vm signal out of expected range");
4069  assert((chainedsigactions != (struct sigaction *)NULL) && (preinstalled_sigs != (int *)NULL) , "signals not yet initialized");
4070  chainedsigactions[sig] = oldAct;
4071  preinstalled_sigs[sig] = 1;
4072}
4073
4074void os::Solaris::set_signal_handler(int sig, bool set_installed, bool oktochain) {
4075  // Check for overwrite.
4076  struct sigaction oldAct;
4077  sigaction(sig, (struct sigaction*)NULL, &oldAct);
4078  void* oldhand = oldAct.sa_sigaction ? CAST_FROM_FN_PTR(void*,  oldAct.sa_sigaction)
4079                                      : CAST_FROM_FN_PTR(void*,  oldAct.sa_handler);
4080  if (oldhand != CAST_FROM_FN_PTR(void*, SIG_DFL) &&
4081      oldhand != CAST_FROM_FN_PTR(void*, SIG_IGN) &&
4082      oldhand != CAST_FROM_FN_PTR(void*, signalHandler)) {
4083    if (AllowUserSignalHandlers || !set_installed) {
4084      // Do not overwrite; user takes responsibility to forward to us.
4085      return;
4086    } else if (UseSignalChaining) {
4087      if (oktochain) {
4088        // save the old handler in jvm
4089        save_preinstalled_handler(sig, oldAct);
4090      } else {
4091        vm_exit_during_initialization("Signal chaining not allowed for VM interrupt signal, try -XX:+UseAltSigs.");
4092      }
4093      // libjsig also interposes the sigaction() call below and saves the
4094      // old sigaction on it own.
4095    } else {
4096      fatal2("Encountered unexpected pre-existing sigaction handler %#lx for signal %d.", (long)oldhand, sig);
4097    }
4098  }
4099
4100  struct sigaction sigAct;
4101  sigfillset(&(sigAct.sa_mask));
4102  sigAct.sa_handler = SIG_DFL;
4103
4104  sigAct.sa_sigaction = signalHandler;
4105  // Handle SIGSEGV on alternate signal stack if
4106  // not using stack banging
4107  if (!UseStackBanging && sig == SIGSEGV) {
4108    sigAct.sa_flags = SA_SIGINFO | SA_RESTART | SA_ONSTACK;
4109  // Interruptible i/o requires SA_RESTART cleared so EINTR
4110  // is returned instead of restarting system calls
4111  } else if (sig == os::Solaris::SIGinterrupt()) {
4112    sigemptyset(&sigAct.sa_mask);
4113    sigAct.sa_handler = NULL;
4114    sigAct.sa_flags = SA_SIGINFO;
4115    sigAct.sa_sigaction = sigINTRHandler;
4116  } else {
4117    sigAct.sa_flags = SA_SIGINFO | SA_RESTART;
4118  }
4119  os::Solaris::set_our_sigflags(sig, sigAct.sa_flags);
4120
4121  sigaction(sig, &sigAct, &oldAct);
4122
4123  void* oldhand2 = oldAct.sa_sigaction ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction)
4124                                       : CAST_FROM_FN_PTR(void*, oldAct.sa_handler);
4125  assert(oldhand2 == oldhand, "no concurrent signal handler installation");
4126}
4127
4128
4129#define DO_SIGNAL_CHECK(sig) \
4130  if (!sigismember(&check_signal_done, sig)) \
4131    os::Solaris::check_signal_handler(sig)
4132
4133// This method is a periodic task to check for misbehaving JNI applications
4134// under CheckJNI, we can add any periodic checks here
4135
4136void os::run_periodic_checks() {
4137  // A big source of grief is hijacking virt. addr 0x0 on Solaris,
4138  // thereby preventing a NULL checks.
4139  if(!check_addr0_done) check_addr0_done = check_addr0(tty);
4140
4141  if (check_signals == false) return;
4142
4143  // SEGV and BUS if overridden could potentially prevent
4144  // generation of hs*.log in the event of a crash, debugging
4145  // such a case can be very challenging, so we absolutely
4146  // check for the following for a good measure:
4147  DO_SIGNAL_CHECK(SIGSEGV);
4148  DO_SIGNAL_CHECK(SIGILL);
4149  DO_SIGNAL_CHECK(SIGFPE);
4150  DO_SIGNAL_CHECK(SIGBUS);
4151  DO_SIGNAL_CHECK(SIGPIPE);
4152  DO_SIGNAL_CHECK(SIGXFSZ);
4153
4154  // ReduceSignalUsage allows the user to override these handlers
4155  // see comments at the very top and jvm_solaris.h
4156  if (!ReduceSignalUsage) {
4157    DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL);
4158    DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL);
4159    DO_SIGNAL_CHECK(SHUTDOWN3_SIGNAL);
4160    DO_SIGNAL_CHECK(BREAK_SIGNAL);
4161  }
4162
4163  // See comments above for using JVM1/JVM2 and UseAltSigs
4164  DO_SIGNAL_CHECK(os::Solaris::SIGinterrupt());
4165  DO_SIGNAL_CHECK(os::Solaris::SIGasync());
4166
4167}
4168
4169typedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *);
4170
4171static os_sigaction_t os_sigaction = NULL;
4172
4173void os::Solaris::check_signal_handler(int sig) {
4174  char buf[O_BUFLEN];
4175  address jvmHandler = NULL;
4176
4177  struct sigaction act;
4178  if (os_sigaction == NULL) {
4179    // only trust the default sigaction, in case it has been interposed
4180    os_sigaction = (os_sigaction_t)dlsym(RTLD_DEFAULT, "sigaction");
4181    if (os_sigaction == NULL) return;
4182  }
4183
4184  os_sigaction(sig, (struct sigaction*)NULL, &act);
4185
4186  address thisHandler = (act.sa_flags & SA_SIGINFO)
4187    ? CAST_FROM_FN_PTR(address, act.sa_sigaction)
4188    : CAST_FROM_FN_PTR(address, act.sa_handler) ;
4189
4190
4191  switch(sig) {
4192    case SIGSEGV:
4193    case SIGBUS:
4194    case SIGFPE:
4195    case SIGPIPE:
4196    case SIGXFSZ:
4197    case SIGILL:
4198      jvmHandler = CAST_FROM_FN_PTR(address, signalHandler);
4199      break;
4200
4201    case SHUTDOWN1_SIGNAL:
4202    case SHUTDOWN2_SIGNAL:
4203    case SHUTDOWN3_SIGNAL:
4204    case BREAK_SIGNAL:
4205      jvmHandler = (address)user_handler();
4206      break;
4207
4208    default:
4209      int intrsig = os::Solaris::SIGinterrupt();
4210      int asynsig = os::Solaris::SIGasync();
4211
4212      if (sig == intrsig) {
4213        jvmHandler = CAST_FROM_FN_PTR(address, sigINTRHandler);
4214      } else if (sig == asynsig) {
4215        jvmHandler = CAST_FROM_FN_PTR(address, signalHandler);
4216      } else {
4217        return;
4218      }
4219      break;
4220  }
4221
4222
4223  if (thisHandler != jvmHandler) {
4224    tty->print("Warning: %s handler ", exception_name(sig, buf, O_BUFLEN));
4225    tty->print("expected:%s", get_signal_handler_name(jvmHandler, buf, O_BUFLEN));
4226    tty->print_cr("  found:%s", get_signal_handler_name(thisHandler, buf, O_BUFLEN));
4227    // No need to check this sig any longer
4228    sigaddset(&check_signal_done, sig);
4229  } else if(os::Solaris::get_our_sigflags(sig) != 0 && act.sa_flags != os::Solaris::get_our_sigflags(sig)) {
4230    tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN));
4231    tty->print("expected:" PTR32_FORMAT, os::Solaris::get_our_sigflags(sig));
4232    tty->print_cr("  found:" PTR32_FORMAT, act.sa_flags);
4233    // No need to check this sig any longer
4234    sigaddset(&check_signal_done, sig);
4235  }
4236
4237  // Print all the signal handler state
4238  if (sigismember(&check_signal_done, sig)) {
4239    print_signal_handlers(tty, buf, O_BUFLEN);
4240  }
4241
4242}
4243
4244void os::Solaris::install_signal_handlers() {
4245  bool libjsigdone = false;
4246  signal_handlers_are_installed = true;
4247
4248  // signal-chaining
4249  typedef void (*signal_setting_t)();
4250  signal_setting_t begin_signal_setting = NULL;
4251  signal_setting_t end_signal_setting = NULL;
4252  begin_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
4253                                        dlsym(RTLD_DEFAULT, "JVM_begin_signal_setting"));
4254  if (begin_signal_setting != NULL) {
4255    end_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
4256                                        dlsym(RTLD_DEFAULT, "JVM_end_signal_setting"));
4257    get_signal_action = CAST_TO_FN_PTR(get_signal_t,
4258                                       dlsym(RTLD_DEFAULT, "JVM_get_signal_action"));
4259    get_libjsig_version = CAST_TO_FN_PTR(version_getting_t,
4260                                         dlsym(RTLD_DEFAULT, "JVM_get_libjsig_version"));
4261    libjsig_is_loaded = true;
4262    if (os::Solaris::get_libjsig_version != NULL) {
4263      libjsigversion =  (*os::Solaris::get_libjsig_version)();
4264    }
4265    assert(UseSignalChaining, "should enable signal-chaining");
4266  }
4267  if (libjsig_is_loaded) {
4268    // Tell libjsig jvm is setting signal handlers
4269    (*begin_signal_setting)();
4270  }
4271
4272  set_signal_handler(SIGSEGV, true, true);
4273  set_signal_handler(SIGPIPE, true, true);
4274  set_signal_handler(SIGXFSZ, true, true);
4275  set_signal_handler(SIGBUS, true, true);
4276  set_signal_handler(SIGILL, true, true);
4277  set_signal_handler(SIGFPE, true, true);
4278
4279
4280  if (os::Solaris::SIGinterrupt() > OLDMAXSIGNUM || os::Solaris::SIGasync() > OLDMAXSIGNUM) {
4281
4282    // Pre-1.4.1 Libjsig limited to signal chaining signals <= 32 so
4283    // can not register overridable signals which might be > 32
4284    if (libjsig_is_loaded && libjsigversion <= JSIG_VERSION_1_4_1) {
4285    // Tell libjsig jvm has finished setting signal handlers
4286      (*end_signal_setting)();
4287      libjsigdone = true;
4288    }
4289  }
4290
4291  // Never ok to chain our SIGinterrupt
4292  set_signal_handler(os::Solaris::SIGinterrupt(), true, false);
4293  set_signal_handler(os::Solaris::SIGasync(), true, true);
4294
4295  if (libjsig_is_loaded && !libjsigdone) {
4296    // Tell libjsig jvm finishes setting signal handlers
4297    (*end_signal_setting)();
4298  }
4299
4300  // We don't activate signal checker if libjsig is in place, we trust ourselves
4301  // and if UserSignalHandler is installed all bets are off
4302  if (CheckJNICalls) {
4303    if (libjsig_is_loaded) {
4304      tty->print_cr("Info: libjsig is activated, all active signal checking is disabled");
4305      check_signals = false;
4306    }
4307    if (AllowUserSignalHandlers) {
4308      tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled");
4309      check_signals = false;
4310    }
4311  }
4312}
4313
4314
4315void report_error(const char* file_name, int line_no, const char* title, const char* format, ...);
4316
4317const char * signames[] = {
4318  "SIG0",
4319  "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGTRAP",
4320  "SIGABRT", "SIGEMT", "SIGFPE", "SIGKILL", "SIGBUS",
4321  "SIGSEGV", "SIGSYS", "SIGPIPE", "SIGALRM", "SIGTERM",
4322  "SIGUSR1", "SIGUSR2", "SIGCLD", "SIGPWR", "SIGWINCH",
4323  "SIGURG", "SIGPOLL", "SIGSTOP", "SIGTSTP", "SIGCONT",
4324  "SIGTTIN", "SIGTTOU", "SIGVTALRM", "SIGPROF", "SIGXCPU",
4325  "SIGXFSZ", "SIGWAITING", "SIGLWP", "SIGFREEZE", "SIGTHAW",
4326  "SIGCANCEL", "SIGLOST"
4327};
4328
4329const char* os::exception_name(int exception_code, char* buf, size_t size) {
4330  if (0 < exception_code && exception_code <= SIGRTMAX) {
4331    // signal
4332    if (exception_code < sizeof(signames)/sizeof(const char*)) {
4333       jio_snprintf(buf, size, "%s", signames[exception_code]);
4334    } else {
4335       jio_snprintf(buf, size, "SIG%d", exception_code);
4336    }
4337    return buf;
4338  } else {
4339    return NULL;
4340  }
4341}
4342
4343// (Static) wrappers for the new libthread API
4344int_fnP_thread_t_iP_uP_stack_tP_gregset_t os::Solaris::_thr_getstate;
4345int_fnP_thread_t_i_gregset_t os::Solaris::_thr_setstate;
4346int_fnP_thread_t_i os::Solaris::_thr_setmutator;
4347int_fnP_thread_t os::Solaris::_thr_suspend_mutator;
4348int_fnP_thread_t os::Solaris::_thr_continue_mutator;
4349
4350// (Static) wrappers for the liblgrp API
4351os::Solaris::lgrp_home_func_t os::Solaris::_lgrp_home;
4352os::Solaris::lgrp_init_func_t os::Solaris::_lgrp_init;
4353os::Solaris::lgrp_fini_func_t os::Solaris::_lgrp_fini;
4354os::Solaris::lgrp_root_func_t os::Solaris::_lgrp_root;
4355os::Solaris::lgrp_children_func_t os::Solaris::_lgrp_children;
4356os::Solaris::lgrp_nlgrps_func_t os::Solaris::_lgrp_nlgrps;
4357os::Solaris::lgrp_cookie_stale_func_t os::Solaris::_lgrp_cookie_stale;
4358os::Solaris::lgrp_cookie_t os::Solaris::_lgrp_cookie = 0;
4359
4360// (Static) wrapper for meminfo() call.
4361os::Solaris::meminfo_func_t os::Solaris::_meminfo = 0;
4362
4363static address resolve_symbol(const char *name) {
4364  address addr;
4365
4366  addr = (address) dlsym(RTLD_DEFAULT, name);
4367  if(addr == NULL) {
4368    // RTLD_DEFAULT was not defined on some early versions of 2.5.1
4369    addr = (address) dlsym(RTLD_NEXT, name);
4370    if(addr == NULL) {
4371      fatal(dlerror());
4372    }
4373  }
4374  return addr;
4375}
4376
4377
4378
4379// isT2_libthread()
4380//
4381// Routine to determine if we are currently using the new T2 libthread.
4382//
4383// We determine if we are using T2 by reading /proc/self/lstatus and
4384// looking for a thread with the ASLWP bit set.  If we find this status
4385// bit set, we must assume that we are NOT using T2.  The T2 team
4386// has approved this algorithm.
4387//
4388// We need to determine if we are running with the new T2 libthread
4389// since setting native thread priorities is handled differently
4390// when using this library.  All threads created using T2 are bound
4391// threads. Calling thr_setprio is meaningless in this case.
4392//
4393bool isT2_libthread() {
4394  int i, rslt;
4395  static prheader_t * lwpArray = NULL;
4396  static int lwpSize = 0;
4397  static int lwpFile = -1;
4398  lwpstatus_t * that;
4399  int aslwpcount;
4400  char lwpName [128];
4401  bool isT2 = false;
4402
4403#define ADR(x)  ((uintptr_t)(x))
4404#define LWPINDEX(ary,ix)   ((lwpstatus_t *)(((ary)->pr_entsize * (ix)) + (ADR((ary) + 1))))
4405
4406  aslwpcount = 0;
4407  lwpSize = 16*1024;
4408  lwpArray = ( prheader_t *)NEW_C_HEAP_ARRAY (char, lwpSize);
4409  lwpFile = open ("/proc/self/lstatus", O_RDONLY, 0);
4410  if (lwpArray == NULL) {
4411      if ( ThreadPriorityVerbose ) warning ("Couldn't allocate T2 Check array\n");
4412      return(isT2);
4413  }
4414  if (lwpFile < 0) {
4415      if ( ThreadPriorityVerbose ) warning ("Couldn't open /proc/self/lstatus\n");
4416      return(isT2);
4417  }
4418  for (;;) {
4419    lseek (lwpFile, 0, SEEK_SET);
4420    rslt = read (lwpFile, lwpArray, lwpSize);
4421    if ((lwpArray->pr_nent * lwpArray->pr_entsize) <= lwpSize) {
4422      break;
4423    }
4424    FREE_C_HEAP_ARRAY(char, lwpArray);
4425    lwpSize = lwpArray->pr_nent * lwpArray->pr_entsize;
4426    lwpArray = ( prheader_t *)NEW_C_HEAP_ARRAY (char, lwpSize);
4427    if (lwpArray == NULL) {
4428        if ( ThreadPriorityVerbose ) warning ("Couldn't allocate T2 Check array\n");
4429        return(isT2);
4430    }
4431  }
4432
4433  // We got a good snapshot - now iterate over the list.
4434  for (i = 0; i < lwpArray->pr_nent; i++ ) {
4435    that = LWPINDEX(lwpArray,i);
4436    if (that->pr_flags & PR_ASLWP) {
4437      aslwpcount++;
4438    }
4439  }
4440  if ( aslwpcount == 0 ) isT2 = true;
4441
4442  FREE_C_HEAP_ARRAY(char, lwpArray);
4443  close (lwpFile);
4444  if ( ThreadPriorityVerbose ) {
4445    if ( isT2 ) tty->print_cr("We are running with a T2 libthread\n");
4446    else tty->print_cr("We are not running with a T2 libthread\n");
4447  }
4448  return (isT2);
4449}
4450
4451
4452void os::Solaris::libthread_init() {
4453  address func = (address)dlsym(RTLD_DEFAULT, "_thr_suspend_allmutators");
4454
4455  // Determine if we are running with the new T2 libthread
4456  os::Solaris::set_T2_libthread(isT2_libthread());
4457
4458  lwp_priocntl_init();
4459
4460  // RTLD_DEFAULT was not defined on some early versions of 5.5.1
4461  if(func == NULL) {
4462    func = (address) dlsym(RTLD_NEXT, "_thr_suspend_allmutators");
4463    // Guarantee that this VM is running on an new enough OS (5.6 or
4464    // later) that it will have a new enough libthread.so.
4465    guarantee(func != NULL, "libthread.so is too old.");
4466  }
4467
4468  // Initialize the new libthread getstate API wrappers
4469  func = resolve_symbol("thr_getstate");
4470  os::Solaris::set_thr_getstate(CAST_TO_FN_PTR(int_fnP_thread_t_iP_uP_stack_tP_gregset_t, func));
4471
4472  func = resolve_symbol("thr_setstate");
4473  os::Solaris::set_thr_setstate(CAST_TO_FN_PTR(int_fnP_thread_t_i_gregset_t, func));
4474
4475  func = resolve_symbol("thr_setmutator");
4476  os::Solaris::set_thr_setmutator(CAST_TO_FN_PTR(int_fnP_thread_t_i, func));
4477
4478  func = resolve_symbol("thr_suspend_mutator");
4479  os::Solaris::set_thr_suspend_mutator(CAST_TO_FN_PTR(int_fnP_thread_t, func));
4480
4481  func = resolve_symbol("thr_continue_mutator");
4482  os::Solaris::set_thr_continue_mutator(CAST_TO_FN_PTR(int_fnP_thread_t, func));
4483
4484  int size;
4485  void (*handler_info_func)(address *, int *);
4486  handler_info_func = CAST_TO_FN_PTR(void (*)(address *, int *), resolve_symbol("thr_sighndlrinfo"));
4487  handler_info_func(&handler_start, &size);
4488  handler_end = handler_start + size;
4489}
4490
4491
4492int_fnP_mutex_tP os::Solaris::_mutex_lock;
4493int_fnP_mutex_tP os::Solaris::_mutex_trylock;
4494int_fnP_mutex_tP os::Solaris::_mutex_unlock;
4495int_fnP_mutex_tP_i_vP os::Solaris::_mutex_init;
4496int_fnP_mutex_tP os::Solaris::_mutex_destroy;
4497int os::Solaris::_mutex_scope = USYNC_THREAD;
4498
4499int_fnP_cond_tP_mutex_tP_timestruc_tP os::Solaris::_cond_timedwait;
4500int_fnP_cond_tP_mutex_tP os::Solaris::_cond_wait;
4501int_fnP_cond_tP os::Solaris::_cond_signal;
4502int_fnP_cond_tP os::Solaris::_cond_broadcast;
4503int_fnP_cond_tP_i_vP os::Solaris::_cond_init;
4504int_fnP_cond_tP os::Solaris::_cond_destroy;
4505int os::Solaris::_cond_scope = USYNC_THREAD;
4506
4507void os::Solaris::synchronization_init() {
4508  if(UseLWPSynchronization) {
4509    os::Solaris::set_mutex_lock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("_lwp_mutex_lock")));
4510    os::Solaris::set_mutex_trylock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("_lwp_mutex_trylock")));
4511    os::Solaris::set_mutex_unlock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("_lwp_mutex_unlock")));
4512    os::Solaris::set_mutex_init(lwp_mutex_init);
4513    os::Solaris::set_mutex_destroy(lwp_mutex_destroy);
4514    os::Solaris::set_mutex_scope(USYNC_THREAD);
4515
4516    os::Solaris::set_cond_timedwait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP_timestruc_tP, resolve_symbol("_lwp_cond_timedwait")));
4517    os::Solaris::set_cond_wait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP, resolve_symbol("_lwp_cond_wait")));
4518    os::Solaris::set_cond_signal(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("_lwp_cond_signal")));
4519    os::Solaris::set_cond_broadcast(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("_lwp_cond_broadcast")));
4520    os::Solaris::set_cond_init(lwp_cond_init);
4521    os::Solaris::set_cond_destroy(lwp_cond_destroy);
4522    os::Solaris::set_cond_scope(USYNC_THREAD);
4523  }
4524  else {
4525    os::Solaris::set_mutex_scope(USYNC_THREAD);
4526    os::Solaris::set_cond_scope(USYNC_THREAD);
4527
4528    if(UsePthreads) {
4529      os::Solaris::set_mutex_lock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_lock")));
4530      os::Solaris::set_mutex_trylock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_trylock")));
4531      os::Solaris::set_mutex_unlock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_unlock")));
4532      os::Solaris::set_mutex_init(pthread_mutex_default_init);
4533      os::Solaris::set_mutex_destroy(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_destroy")));
4534
4535      os::Solaris::set_cond_timedwait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP_timestruc_tP, resolve_symbol("pthread_cond_timedwait")));
4536      os::Solaris::set_cond_wait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP, resolve_symbol("pthread_cond_wait")));
4537      os::Solaris::set_cond_signal(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("pthread_cond_signal")));
4538      os::Solaris::set_cond_broadcast(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("pthread_cond_broadcast")));
4539      os::Solaris::set_cond_init(pthread_cond_default_init);
4540      os::Solaris::set_cond_destroy(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("pthread_cond_destroy")));
4541    }
4542    else {
4543      os::Solaris::set_mutex_lock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("mutex_lock")));
4544      os::Solaris::set_mutex_trylock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("mutex_trylock")));
4545      os::Solaris::set_mutex_unlock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("mutex_unlock")));
4546      os::Solaris::set_mutex_init(::mutex_init);
4547      os::Solaris::set_mutex_destroy(::mutex_destroy);
4548
4549      os::Solaris::set_cond_timedwait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP_timestruc_tP, resolve_symbol("cond_timedwait")));
4550      os::Solaris::set_cond_wait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP, resolve_symbol("cond_wait")));
4551      os::Solaris::set_cond_signal(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("cond_signal")));
4552      os::Solaris::set_cond_broadcast(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("cond_broadcast")));
4553      os::Solaris::set_cond_init(::cond_init);
4554      os::Solaris::set_cond_destroy(::cond_destroy);
4555    }
4556  }
4557}
4558
4559void os::Solaris::liblgrp_init() {
4560  void *handle = dlopen("liblgrp.so", RTLD_LAZY);
4561  if (handle != NULL) {
4562    os::Solaris::set_lgrp_home(CAST_TO_FN_PTR(lgrp_home_func_t, dlsym(handle, "lgrp_home")));
4563    os::Solaris::set_lgrp_init(CAST_TO_FN_PTR(lgrp_init_func_t, dlsym(handle, "lgrp_init")));
4564    os::Solaris::set_lgrp_fini(CAST_TO_FN_PTR(lgrp_fini_func_t, dlsym(handle, "lgrp_fini")));
4565    os::Solaris::set_lgrp_root(CAST_TO_FN_PTR(lgrp_root_func_t, dlsym(handle, "lgrp_root")));
4566    os::Solaris::set_lgrp_children(CAST_TO_FN_PTR(lgrp_children_func_t, dlsym(handle, "lgrp_children")));
4567    os::Solaris::set_lgrp_nlgrps(CAST_TO_FN_PTR(lgrp_nlgrps_func_t, dlsym(handle, "lgrp_nlgrps")));
4568    os::Solaris::set_lgrp_cookie_stale(CAST_TO_FN_PTR(lgrp_cookie_stale_func_t,
4569                                       dlsym(handle, "lgrp_cookie_stale")));
4570
4571    lgrp_cookie_t c = lgrp_init(LGRP_VIEW_CALLER);
4572    set_lgrp_cookie(c);
4573  } else {
4574    warning("your OS does not support NUMA");
4575  }
4576}
4577
4578void os::Solaris::misc_sym_init() {
4579  address func = (address)dlsym(RTLD_DEFAULT, "meminfo");
4580  if(func == NULL) {
4581    func = (address) dlsym(RTLD_NEXT, "meminfo");
4582  }
4583  if (func != NULL) {
4584    os::Solaris::set_meminfo(CAST_TO_FN_PTR(meminfo_func_t, func));
4585  }
4586}
4587
4588// Symbol doesn't exist in Solaris 8 pset.h
4589#ifndef PS_MYID
4590#define PS_MYID -3
4591#endif
4592
4593// int pset_getloadavg(psetid_t pset, double loadavg[], int nelem);
4594typedef long (*pset_getloadavg_type)(psetid_t pset, double loadavg[], int nelem);
4595static pset_getloadavg_type pset_getloadavg_ptr = NULL;
4596
4597void init_pset_getloadavg_ptr(void) {
4598  pset_getloadavg_ptr =
4599    (pset_getloadavg_type)dlsym(RTLD_DEFAULT, "pset_getloadavg");
4600  if (PrintMiscellaneous && Verbose && pset_getloadavg_ptr == NULL) {
4601    warning("pset_getloadavg function not found");
4602  }
4603}
4604
4605int os::Solaris::_dev_zero_fd = -1;
4606
4607// this is called _before_ the global arguments have been parsed
4608void os::init(void) {
4609  _initial_pid = getpid();
4610
4611  max_hrtime = first_hrtime = gethrtime();
4612
4613  init_random(1234567);
4614
4615  page_size = sysconf(_SC_PAGESIZE);
4616  if (page_size == -1)
4617    fatal1("os_solaris.cpp: os::init: sysconf failed (%s)", strerror(errno));
4618  init_page_sizes((size_t) page_size);
4619
4620  Solaris::initialize_system_info();
4621
4622  int fd = open("/dev/zero", O_RDWR);
4623  if (fd < 0) {
4624    fatal1("os::init: cannot open /dev/zero (%s)", strerror(errno));
4625  } else {
4626    Solaris::set_dev_zero_fd(fd);
4627
4628    // Close on exec, child won't inherit.
4629    fcntl(fd, F_SETFD, FD_CLOEXEC);
4630  }
4631
4632  clock_tics_per_sec = CLK_TCK;
4633
4634  // check if dladdr1() exists; dladdr1 can provide more information than
4635  // dladdr for os::dll_address_to_function_name. It comes with SunOS 5.9
4636  // and is available on linker patches for 5.7 and 5.8.
4637  // libdl.so must have been loaded, this call is just an entry lookup
4638  void * hdl = dlopen("libdl.so", RTLD_NOW);
4639  if (hdl)
4640    dladdr1_func = CAST_TO_FN_PTR(dladdr1_func_type, dlsym(hdl, "dladdr1"));
4641
4642  // (Solaris only) this switches to calls that actually do locking.
4643  ThreadCritical::initialize();
4644
4645  main_thread = thr_self();
4646
4647  // Constant minimum stack size allowed. It must be at least
4648  // the minimum of what the OS supports (thr_min_stack()), and
4649  // enough to allow the thread to get to user bytecode execution.
4650  Solaris::min_stack_allowed = MAX2(thr_min_stack(), Solaris::min_stack_allowed);
4651  // If the pagesize of the VM is greater than 8K determine the appropriate
4652  // number of initial guard pages.  The user can change this with the
4653  // command line arguments, if needed.
4654  if (vm_page_size() > 8*K) {
4655    StackYellowPages = 1;
4656    StackRedPages = 1;
4657    StackShadowPages = round_to((StackShadowPages*8*K), vm_page_size()) / vm_page_size();
4658  }
4659}
4660
4661// To install functions for atexit system call
4662extern "C" {
4663  static void perfMemory_exit_helper() {
4664    perfMemory_exit();
4665  }
4666}
4667
4668// this is called _after_ the global arguments have been parsed
4669jint os::init_2(void) {
4670  // try to enable extended file IO ASAP, see 6431278
4671  os::Solaris::try_enable_extended_io();
4672
4673  // Allocate a single page and mark it as readable for safepoint polling.  Also
4674  // use this first mmap call to check support for MAP_ALIGN.
4675  address polling_page = (address)Solaris::mmap_chunk((char*)page_size,
4676                                                      page_size,
4677                                                      MAP_PRIVATE | MAP_ALIGN,
4678                                                      PROT_READ);
4679  if (polling_page == NULL) {
4680    has_map_align = false;
4681    polling_page = (address)Solaris::mmap_chunk(NULL, page_size, MAP_PRIVATE,
4682                                                PROT_READ);
4683  }
4684
4685  os::set_polling_page(polling_page);
4686
4687#ifndef PRODUCT
4688  if( Verbose && PrintMiscellaneous )
4689    tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page);
4690#endif
4691
4692  if (!UseMembar) {
4693    address mem_serialize_page = (address)Solaris::mmap_chunk( NULL, page_size, MAP_PRIVATE, PROT_READ | PROT_WRITE );
4694    guarantee( mem_serialize_page != NULL, "mmap Failed for memory serialize page");
4695    os::set_memory_serialize_page( mem_serialize_page );
4696
4697#ifndef PRODUCT
4698    if(Verbose && PrintMiscellaneous)
4699      tty->print("[Memory Serialize  Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
4700#endif
4701}
4702
4703  FLAG_SET_DEFAULT(UseLargePages, os::large_page_init());
4704
4705  // Check minimum allowable stack size for thread creation and to initialize
4706  // the java system classes, including StackOverflowError - depends on page
4707  // size.  Add a page for compiler2 recursion in main thread.
4708  // Add in BytesPerWord times page size to account for VM stack during
4709  // class initialization depending on 32 or 64 bit VM.
4710  guarantee((Solaris::min_stack_allowed >=
4711    (StackYellowPages+StackRedPages+StackShadowPages+BytesPerWord
4712     COMPILER2_PRESENT(+1)) * page_size),
4713    "need to increase Solaris::min_stack_allowed on this platform");
4714
4715  size_t threadStackSizeInBytes = ThreadStackSize * K;
4716  if (threadStackSizeInBytes != 0 &&
4717    threadStackSizeInBytes < Solaris::min_stack_allowed) {
4718    tty->print_cr("\nThe stack size specified is too small, Specify at least %dk",
4719                  Solaris::min_stack_allowed/K);
4720    return JNI_ERR;
4721  }
4722
4723  // For 64kbps there will be a 64kb page size, which makes
4724  // the usable default stack size quite a bit less.  Increase the
4725  // stack for 64kb (or any > than 8kb) pages, this increases
4726  // virtual memory fragmentation (since we're not creating the
4727  // stack on a power of 2 boundary.  The real fix for this
4728  // should be to fix the guard page mechanism.
4729
4730  if (vm_page_size() > 8*K) {
4731      threadStackSizeInBytes = (threadStackSizeInBytes != 0)
4732         ? threadStackSizeInBytes +
4733           ((StackYellowPages + StackRedPages) * vm_page_size())
4734         : 0;
4735      ThreadStackSize = threadStackSizeInBytes/K;
4736  }
4737
4738  // Make the stack size a multiple of the page size so that
4739  // the yellow/red zones can be guarded.
4740  JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes,
4741        vm_page_size()));
4742
4743  Solaris::libthread_init();
4744  if (UseNUMA) {
4745    Solaris::liblgrp_init();
4746  }
4747  Solaris::misc_sym_init();
4748  Solaris::signal_sets_init();
4749  Solaris::init_signal_mem();
4750  Solaris::install_signal_handlers();
4751
4752  if (libjsigversion < JSIG_VERSION_1_4_1) {
4753    Maxlibjsigsigs = OLDMAXSIGNUM;
4754  }
4755
4756  // initialize synchronization primitives to use either thread or
4757  // lwp synchronization (controlled by UseLWPSynchronization)
4758  Solaris::synchronization_init();
4759
4760  if (MaxFDLimit) {
4761    // set the number of file descriptors to max. print out error
4762    // if getrlimit/setrlimit fails but continue regardless.
4763    struct rlimit nbr_files;
4764    int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
4765    if (status != 0) {
4766      if (PrintMiscellaneous && (Verbose || WizardMode))
4767        perror("os::init_2 getrlimit failed");
4768    } else {
4769      nbr_files.rlim_cur = nbr_files.rlim_max;
4770      status = setrlimit(RLIMIT_NOFILE, &nbr_files);
4771      if (status != 0) {
4772        if (PrintMiscellaneous && (Verbose || WizardMode))
4773          perror("os::init_2 setrlimit failed");
4774      }
4775    }
4776  }
4777
4778  // Initialize HPI.
4779  jint hpi_result = hpi::initialize();
4780  if (hpi_result != JNI_OK) {
4781    tty->print_cr("There was an error trying to initialize the HPI library.");
4782    return hpi_result;
4783  }
4784
4785  // Calculate theoretical max. size of Threads to guard gainst
4786  // artifical out-of-memory situations, where all available address-
4787  // space has been reserved by thread stacks. Default stack size is 1Mb.
4788  size_t pre_thread_stack_size = (JavaThread::stack_size_at_create()) ?
4789    JavaThread::stack_size_at_create() : (1*K*K);
4790  assert(pre_thread_stack_size != 0, "Must have a stack");
4791  // Solaris has a maximum of 4Gb of user programs. Calculate the thread limit when
4792  // we should start doing Virtual Memory banging. Currently when the threads will
4793  // have used all but 200Mb of space.
4794  size_t max_address_space = ((unsigned int)4 * K * K * K) - (200 * K * K);
4795  Solaris::_os_thread_limit = max_address_space / pre_thread_stack_size;
4796
4797  // at-exit methods are called in the reverse order of their registration.
4798  // In Solaris 7 and earlier, atexit functions are called on return from
4799  // main or as a result of a call to exit(3C). There can be only 32 of
4800  // these functions registered and atexit() does not set errno. In Solaris
4801  // 8 and later, there is no limit to the number of functions registered
4802  // and atexit() sets errno. In addition, in Solaris 8 and later, atexit
4803  // functions are called upon dlclose(3DL) in addition to return from main
4804  // and exit(3C).
4805
4806  if (PerfAllowAtExitRegistration) {
4807    // only register atexit functions if PerfAllowAtExitRegistration is set.
4808    // atexit functions can be delayed until process exit time, which
4809    // can be problematic for embedded VM situations. Embedded VMs should
4810    // call DestroyJavaVM() to assure that VM resources are released.
4811
4812    // note: perfMemory_exit_helper atexit function may be removed in
4813    // the future if the appropriate cleanup code can be added to the
4814    // VM_Exit VMOperation's doit method.
4815    if (atexit(perfMemory_exit_helper) != 0) {
4816      warning("os::init2 atexit(perfMemory_exit_helper) failed");
4817    }
4818  }
4819
4820  // Init pset_loadavg function pointer
4821  init_pset_getloadavg_ptr();
4822
4823  return JNI_OK;
4824}
4825
4826
4827// Mark the polling page as unreadable
4828void os::make_polling_page_unreadable(void) {
4829  if( mprotect((char *)_polling_page, page_size, PROT_NONE) != 0 )
4830    fatal("Could not disable polling page");
4831};
4832
4833// Mark the polling page as readable
4834void os::make_polling_page_readable(void) {
4835  if( mprotect((char *)_polling_page, page_size, PROT_READ) != 0 )
4836    fatal("Could not enable polling page");
4837};
4838
4839// OS interface.
4840
4841int os::stat(const char *path, struct stat *sbuf) {
4842  char pathbuf[MAX_PATH];
4843  if (strlen(path) > MAX_PATH - 1) {
4844    errno = ENAMETOOLONG;
4845    return -1;
4846  }
4847  hpi::native_path(strcpy(pathbuf, path));
4848  return ::stat(pathbuf, sbuf);
4849}
4850
4851
4852bool os::check_heap(bool force) { return true; }
4853
4854typedef int (*vsnprintf_t)(char* buf, size_t count, const char* fmt, va_list argptr);
4855static vsnprintf_t sol_vsnprintf = NULL;
4856
4857int local_vsnprintf(char* buf, size_t count, const char* fmt, va_list argptr) {
4858  if (!sol_vsnprintf) {
4859    //search  for the named symbol in the objects that were loaded after libjvm
4860    void* where = RTLD_NEXT;
4861    if ((sol_vsnprintf = CAST_TO_FN_PTR(vsnprintf_t, dlsym(where, "__vsnprintf"))) == NULL)
4862        sol_vsnprintf = CAST_TO_FN_PTR(vsnprintf_t, dlsym(where, "vsnprintf"));
4863    if (!sol_vsnprintf){
4864      //search  for the named symbol in the objects that were loaded before libjvm
4865      where = RTLD_DEFAULT;
4866      if ((sol_vsnprintf = CAST_TO_FN_PTR(vsnprintf_t, dlsym(where, "__vsnprintf"))) == NULL)
4867        sol_vsnprintf = CAST_TO_FN_PTR(vsnprintf_t, dlsym(where, "vsnprintf"));
4868      assert(sol_vsnprintf != NULL, "vsnprintf not found");
4869    }
4870  }
4871  return (*sol_vsnprintf)(buf, count, fmt, argptr);
4872}
4873
4874
4875// Is a (classpath) directory empty?
4876bool os::dir_is_empty(const char* path) {
4877  DIR *dir = NULL;
4878  struct dirent *ptr;
4879
4880  dir = opendir(path);
4881  if (dir == NULL) return true;
4882
4883  /* Scan the directory */
4884  bool result = true;
4885  char buf[sizeof(struct dirent) + MAX_PATH];
4886  struct dirent *dbuf = (struct dirent *) buf;
4887  while (result && (ptr = readdir(dir, dbuf)) != NULL) {
4888    if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) {
4889      result = false;
4890    }
4891  }
4892  closedir(dir);
4893  return result;
4894}
4895
4896// create binary file, rewriting existing file if required
4897int os::create_binary_file(const char* path, bool rewrite_existing) {
4898  int oflags = O_WRONLY | O_CREAT;
4899  if (!rewrite_existing) {
4900    oflags |= O_EXCL;
4901  }
4902  return ::open64(path, oflags, S_IREAD | S_IWRITE);
4903}
4904
4905// return current position of file pointer
4906jlong os::current_file_offset(int fd) {
4907  return (jlong)::lseek64(fd, (off64_t)0, SEEK_CUR);
4908}
4909
4910// move file pointer to the specified offset
4911jlong os::seek_to_file_offset(int fd, jlong offset) {
4912  return (jlong)::lseek64(fd, (off64_t)offset, SEEK_SET);
4913}
4914
4915// Map a block of memory.
4916char* os::map_memory(int fd, const char* file_name, size_t file_offset,
4917                     char *addr, size_t bytes, bool read_only,
4918                     bool allow_exec) {
4919  int prot;
4920  int flags;
4921
4922  if (read_only) {
4923    prot = PROT_READ;
4924    flags = MAP_SHARED;
4925  } else {
4926    prot = PROT_READ | PROT_WRITE;
4927    flags = MAP_PRIVATE;
4928  }
4929
4930  if (allow_exec) {
4931    prot |= PROT_EXEC;
4932  }
4933
4934  if (addr != NULL) {
4935    flags |= MAP_FIXED;
4936  }
4937
4938  char* mapped_address = (char*)mmap(addr, (size_t)bytes, prot, flags,
4939                                     fd, file_offset);
4940  if (mapped_address == MAP_FAILED) {
4941    return NULL;
4942  }
4943  return mapped_address;
4944}
4945
4946
4947// Remap a block of memory.
4948char* os::remap_memory(int fd, const char* file_name, size_t file_offset,
4949                       char *addr, size_t bytes, bool read_only,
4950                       bool allow_exec) {
4951  // same as map_memory() on this OS
4952  return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only,
4953                        allow_exec);
4954}
4955
4956
4957// Unmap a block of memory.
4958bool os::unmap_memory(char* addr, size_t bytes) {
4959  return munmap(addr, bytes) == 0;
4960}
4961
4962void os::pause() {
4963  char filename[MAX_PATH];
4964  if (PauseAtStartupFile && PauseAtStartupFile[0]) {
4965    jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
4966  } else {
4967    jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
4968  }
4969
4970  int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
4971  if (fd != -1) {
4972    struct stat buf;
4973    close(fd);
4974    while (::stat(filename, &buf) == 0) {
4975      (void)::poll(NULL, 0, 100);
4976    }
4977  } else {
4978    jio_fprintf(stderr,
4979      "Could not open pause file '%s', continuing immediately.\n", filename);
4980  }
4981}
4982
4983#ifndef PRODUCT
4984#ifdef INTERPOSE_ON_SYSTEM_SYNCH_FUNCTIONS
4985// Turn this on if you need to trace synch operations.
4986// Set RECORD_SYNCH_LIMIT to a large-enough value,
4987// and call record_synch_enable and record_synch_disable
4988// around the computation of interest.
4989
4990void record_synch(char* name, bool returning);  // defined below
4991
4992class RecordSynch {
4993  char* _name;
4994 public:
4995  RecordSynch(char* name) :_name(name)
4996                 { record_synch(_name, false); }
4997  ~RecordSynch() { record_synch(_name,   true);  }
4998};
4999
5000#define CHECK_SYNCH_OP(ret, name, params, args, inner)          \
5001extern "C" ret name params {                                    \
5002  typedef ret name##_t params;                                  \
5003  static name##_t* implem = NULL;                               \
5004  static int callcount = 0;                                     \
5005  if (implem == NULL) {                                         \
5006    implem = (name##_t*) dlsym(RTLD_NEXT, #name);               \
5007    if (implem == NULL)  fatal(dlerror());                      \
5008  }                                                             \
5009  ++callcount;                                                  \
5010  RecordSynch _rs(#name);                                       \
5011  inner;                                                        \
5012  return implem args;                                           \
5013}
5014// in dbx, examine callcounts this way:
5015// for n in $(eval whereis callcount | awk '{print $2}'); do print $n; done
5016
5017#define CHECK_POINTER_OK(p) \
5018  (Universe::perm_gen() == NULL || !Universe::is_reserved_heap((oop)(p)))
5019#define CHECK_MU \
5020  if (!CHECK_POINTER_OK(mu)) fatal("Mutex must be in C heap only.");
5021#define CHECK_CV \
5022  if (!CHECK_POINTER_OK(cv)) fatal("Condvar must be in C heap only.");
5023#define CHECK_P(p) \
5024  if (!CHECK_POINTER_OK(p))  fatal(false,  "Pointer must be in C heap only.");
5025
5026#define CHECK_MUTEX(mutex_op) \
5027CHECK_SYNCH_OP(int, mutex_op, (mutex_t *mu), (mu), CHECK_MU);
5028
5029CHECK_MUTEX(   mutex_lock)
5030CHECK_MUTEX(  _mutex_lock)
5031CHECK_MUTEX( mutex_unlock)
5032CHECK_MUTEX(_mutex_unlock)
5033CHECK_MUTEX( mutex_trylock)
5034CHECK_MUTEX(_mutex_trylock)
5035
5036#define CHECK_COND(cond_op) \
5037CHECK_SYNCH_OP(int, cond_op, (cond_t *cv, mutex_t *mu), (cv, mu), CHECK_MU;CHECK_CV);
5038
5039CHECK_COND( cond_wait);
5040CHECK_COND(_cond_wait);
5041CHECK_COND(_cond_wait_cancel);
5042
5043#define CHECK_COND2(cond_op) \
5044CHECK_SYNCH_OP(int, cond_op, (cond_t *cv, mutex_t *mu, timestruc_t* ts), (cv, mu, ts), CHECK_MU;CHECK_CV);
5045
5046CHECK_COND2( cond_timedwait);
5047CHECK_COND2(_cond_timedwait);
5048CHECK_COND2(_cond_timedwait_cancel);
5049
5050// do the _lwp_* versions too
5051#define mutex_t lwp_mutex_t
5052#define cond_t  lwp_cond_t
5053CHECK_MUTEX(  _lwp_mutex_lock)
5054CHECK_MUTEX(  _lwp_mutex_unlock)
5055CHECK_MUTEX(  _lwp_mutex_trylock)
5056CHECK_MUTEX( __lwp_mutex_lock)
5057CHECK_MUTEX( __lwp_mutex_unlock)
5058CHECK_MUTEX( __lwp_mutex_trylock)
5059CHECK_MUTEX(___lwp_mutex_lock)
5060CHECK_MUTEX(___lwp_mutex_unlock)
5061
5062CHECK_COND(  _lwp_cond_wait);
5063CHECK_COND( __lwp_cond_wait);
5064CHECK_COND(___lwp_cond_wait);
5065
5066CHECK_COND2(  _lwp_cond_timedwait);
5067CHECK_COND2( __lwp_cond_timedwait);
5068#undef mutex_t
5069#undef cond_t
5070
5071CHECK_SYNCH_OP(int, _lwp_suspend2,       (int lwp, int *n), (lwp, n), 0);
5072CHECK_SYNCH_OP(int,__lwp_suspend2,       (int lwp, int *n), (lwp, n), 0);
5073CHECK_SYNCH_OP(int, _lwp_kill,           (int lwp, int n),  (lwp, n), 0);
5074CHECK_SYNCH_OP(int,__lwp_kill,           (int lwp, int n),  (lwp, n), 0);
5075CHECK_SYNCH_OP(int, _lwp_sema_wait,      (lwp_sema_t* p),   (p),  CHECK_P(p));
5076CHECK_SYNCH_OP(int,__lwp_sema_wait,      (lwp_sema_t* p),   (p),  CHECK_P(p));
5077CHECK_SYNCH_OP(int, _lwp_cond_broadcast, (lwp_cond_t* cv),  (cv), CHECK_CV);
5078CHECK_SYNCH_OP(int,__lwp_cond_broadcast, (lwp_cond_t* cv),  (cv), CHECK_CV);
5079
5080
5081// recording machinery:
5082
5083enum { RECORD_SYNCH_LIMIT = 200 };
5084char* record_synch_name[RECORD_SYNCH_LIMIT];
5085void* record_synch_arg0ptr[RECORD_SYNCH_LIMIT];
5086bool record_synch_returning[RECORD_SYNCH_LIMIT];
5087thread_t record_synch_thread[RECORD_SYNCH_LIMIT];
5088int record_synch_count = 0;
5089bool record_synch_enabled = false;
5090
5091// in dbx, examine recorded data this way:
5092// for n in name arg0ptr returning thread; do print record_synch_$n[0..record_synch_count-1]; done
5093
5094void record_synch(char* name, bool returning) {
5095  if (record_synch_enabled) {
5096    if (record_synch_count < RECORD_SYNCH_LIMIT) {
5097      record_synch_name[record_synch_count] = name;
5098      record_synch_returning[record_synch_count] = returning;
5099      record_synch_thread[record_synch_count] = thr_self();
5100      record_synch_arg0ptr[record_synch_count] = &name;
5101      record_synch_count++;
5102    }
5103    // put more checking code here:
5104    // ...
5105  }
5106}
5107
5108void record_synch_enable() {
5109  // start collecting trace data, if not already doing so
5110  if (!record_synch_enabled)  record_synch_count = 0;
5111  record_synch_enabled = true;
5112}
5113
5114void record_synch_disable() {
5115  // stop collecting trace data
5116  record_synch_enabled = false;
5117}
5118
5119#endif // INTERPOSE_ON_SYSTEM_SYNCH_FUNCTIONS
5120#endif // PRODUCT
5121
5122const intptr_t thr_time_off  = (intptr_t)(&((prusage_t *)(NULL))->pr_utime);
5123const intptr_t thr_time_size = (intptr_t)(&((prusage_t *)(NULL))->pr_ttime) -
5124                               (intptr_t)(&((prusage_t *)(NULL))->pr_utime);
5125
5126
5127// JVMTI & JVM monitoring and management support
5128// The thread_cpu_time() and current_thread_cpu_time() are only
5129// supported if is_thread_cpu_time_supported() returns true.
5130// They are not supported on Solaris T1.
5131
5132// current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)
5133// are used by JVM M&M and JVMTI to get user+sys or user CPU time
5134// of a thread.
5135//
5136// current_thread_cpu_time() and thread_cpu_time(Thread *)
5137// returns the fast estimate available on the platform.
5138
5139// hrtime_t gethrvtime() return value includes
5140// user time but does not include system time
5141jlong os::current_thread_cpu_time() {
5142  return (jlong) gethrvtime();
5143}
5144
5145jlong os::thread_cpu_time(Thread *thread) {
5146  // return user level CPU time only to be consistent with
5147  // what current_thread_cpu_time returns.
5148  // thread_cpu_time_info() must be changed if this changes
5149  return os::thread_cpu_time(thread, false /* user time only */);
5150}
5151
5152jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {
5153  if (user_sys_cpu_time) {
5154    return os::thread_cpu_time(Thread::current(), user_sys_cpu_time);
5155  } else {
5156    return os::current_thread_cpu_time();
5157  }
5158}
5159
5160jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
5161  char proc_name[64];
5162  int count;
5163  prusage_t prusage;
5164  jlong lwp_time;
5165  int fd;
5166
5167  sprintf(proc_name, "/proc/%d/lwp/%d/lwpusage",
5168                     getpid(),
5169                     thread->osthread()->lwp_id());
5170  fd = open(proc_name, O_RDONLY);
5171  if ( fd == -1 ) return -1;
5172
5173  do {
5174    count = pread(fd,
5175                  (void *)&prusage.pr_utime,
5176                  thr_time_size,
5177                  thr_time_off);
5178  } while (count < 0 && errno == EINTR);
5179  close(fd);
5180  if ( count < 0 ) return -1;
5181
5182  if (user_sys_cpu_time) {
5183    // user + system CPU time
5184    lwp_time = (((jlong)prusage.pr_stime.tv_sec +
5185                 (jlong)prusage.pr_utime.tv_sec) * (jlong)1000000000) +
5186                 (jlong)prusage.pr_stime.tv_nsec +
5187                 (jlong)prusage.pr_utime.tv_nsec;
5188  } else {
5189    // user level CPU time only
5190    lwp_time = ((jlong)prusage.pr_utime.tv_sec * (jlong)1000000000) +
5191                (jlong)prusage.pr_utime.tv_nsec;
5192  }
5193
5194  return(lwp_time);
5195}
5196
5197void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
5198  info_ptr->max_value = ALL_64_BITS;      // will not wrap in less than 64 bits
5199  info_ptr->may_skip_backward = false;    // elapsed time not wall time
5200  info_ptr->may_skip_forward = false;     // elapsed time not wall time
5201  info_ptr->kind = JVMTI_TIMER_USER_CPU;  // only user time is returned
5202}
5203
5204void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
5205  info_ptr->max_value = ALL_64_BITS;      // will not wrap in less than 64 bits
5206  info_ptr->may_skip_backward = false;    // elapsed time not wall time
5207  info_ptr->may_skip_forward = false;     // elapsed time not wall time
5208  info_ptr->kind = JVMTI_TIMER_USER_CPU;  // only user time is returned
5209}
5210
5211bool os::is_thread_cpu_time_supported() {
5212  if ( os::Solaris::T2_libthread() || UseBoundThreads ) {
5213    return true;
5214  } else {
5215    return false;
5216  }
5217}
5218
5219// System loadavg support.  Returns -1 if load average cannot be obtained.
5220// Return the load average for our processor set if the primitive exists
5221// (Solaris 9 and later).  Otherwise just return system wide loadavg.
5222int os::loadavg(double loadavg[], int nelem) {
5223  if (pset_getloadavg_ptr != NULL) {
5224    return (*pset_getloadavg_ptr)(PS_MYID, loadavg, nelem);
5225  } else {
5226    return ::getloadavg(loadavg, nelem);
5227  }
5228}
5229
5230//---------------------------------------------------------------------------------
5231#ifndef PRODUCT
5232
5233static address same_page(address x, address y) {
5234  intptr_t page_bits = -os::vm_page_size();
5235  if ((intptr_t(x) & page_bits) == (intptr_t(y) & page_bits))
5236    return x;
5237  else if (x > y)
5238    return (address)(intptr_t(y) | ~page_bits) + 1;
5239  else
5240    return (address)(intptr_t(y) & page_bits);
5241}
5242
5243bool os::find(address addr) {
5244  Dl_info dlinfo;
5245  memset(&dlinfo, 0, sizeof(dlinfo));
5246  if (dladdr(addr, &dlinfo)) {
5247#ifdef _LP64
5248    tty->print("0x%016lx: ", addr);
5249#else
5250    tty->print("0x%08x: ", addr);
5251#endif
5252    if (dlinfo.dli_sname != NULL)
5253      tty->print("%s+%#lx", dlinfo.dli_sname, addr-(intptr_t)dlinfo.dli_saddr);
5254    else if (dlinfo.dli_fname)
5255      tty->print("<offset %#lx>", addr-(intptr_t)dlinfo.dli_fbase);
5256    else
5257      tty->print("<absolute address>");
5258    if (dlinfo.dli_fname)  tty->print(" in %s", dlinfo.dli_fname);
5259#ifdef _LP64
5260    if (dlinfo.dli_fbase)  tty->print(" at 0x%016lx", dlinfo.dli_fbase);
5261#else
5262    if (dlinfo.dli_fbase)  tty->print(" at 0x%08x", dlinfo.dli_fbase);
5263#endif
5264    tty->cr();
5265
5266    if (Verbose) {
5267      // decode some bytes around the PC
5268      address begin = same_page(addr-40, addr);
5269      address end   = same_page(addr+40, addr);
5270      address       lowest = (address) dlinfo.dli_sname;
5271      if (!lowest)  lowest = (address) dlinfo.dli_fbase;
5272      if (begin < lowest)  begin = lowest;
5273      Dl_info dlinfo2;
5274      if (dladdr(end, &dlinfo2) && dlinfo2.dli_saddr != dlinfo.dli_saddr
5275          && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
5276        end = (address) dlinfo2.dli_saddr;
5277      Disassembler::decode(begin, end);
5278    }
5279    return true;
5280  }
5281  return false;
5282}
5283
5284#endif
5285
5286
5287// Following function has been added to support HotSparc's libjvm.so running
5288// under Solaris production JDK 1.2.2 / 1.3.0.  These came from
5289// src/solaris/hpi/native_threads in the EVM codebase.
5290//
5291// NOTE: This is no longer needed in the 1.3.1 and 1.4 production release
5292// libraries and should thus be removed. We will leave it behind for a while
5293// until we no longer want to able to run on top of 1.3.0 Solaris production
5294// JDK. See 4341971.
5295
5296#define STACK_SLACK 0x800
5297
5298extern "C" {
5299  intptr_t sysThreadAvailableStackWithSlack() {
5300    stack_t st;
5301    intptr_t retval, stack_top;
5302    retval = thr_stksegment(&st);
5303    assert(retval == 0, "incorrect return value from thr_stksegment");
5304    assert((address)&st < (address)st.ss_sp, "Invalid stack base returned");
5305    assert((address)&st > (address)st.ss_sp-st.ss_size, "Invalid stack size returned");
5306    stack_top=(intptr_t)st.ss_sp-st.ss_size;
5307    return ((intptr_t)&stack_top - stack_top - STACK_SLACK);
5308  }
5309}
5310
5311// Just to get the Kernel build to link on solaris for testing.
5312
5313extern "C" {
5314class ASGCT_CallTrace;
5315void AsyncGetCallTrace(ASGCT_CallTrace *trace, jint depth, void* ucontext)
5316  KERNEL_RETURN;
5317}
5318
5319
5320// ObjectMonitor park-unpark infrastructure ...
5321//
5322// We implement Solaris and Linux PlatformEvents with the
5323// obvious condvar-mutex-flag triple.
5324// Another alternative that works quite well is pipes:
5325// Each PlatformEvent consists of a pipe-pair.
5326// The thread associated with the PlatformEvent
5327// calls park(), which reads from the input end of the pipe.
5328// Unpark() writes into the other end of the pipe.
5329// The write-side of the pipe must be set NDELAY.
5330// Unfortunately pipes consume a large # of handles.
5331// Native solaris lwp_park() and lwp_unpark() work nicely, too.
5332// Using pipes for the 1st few threads might be workable, however.
5333//
5334// park() is permitted to return spuriously.
5335// Callers of park() should wrap the call to park() in
5336// an appropriate loop.  A litmus test for the correct
5337// usage of park is the following: if park() were modified
5338// to immediately return 0 your code should still work,
5339// albeit degenerating to a spin loop.
5340//
5341// An interesting optimization for park() is to use a trylock()
5342// to attempt to acquire the mutex.  If the trylock() fails
5343// then we know that a concurrent unpark() operation is in-progress.
5344// in that case the park() code could simply set _count to 0
5345// and return immediately.  The subsequent park() operation *might*
5346// return immediately.  That's harmless as the caller of park() is
5347// expected to loop.  By using trylock() we will have avoided a
5348// avoided a context switch caused by contention on the per-thread mutex.
5349//
5350// TODO-FIXME:
5351// 1.  Reconcile Doug's JSR166 j.u.c park-unpark with the
5352//     objectmonitor implementation.
5353// 2.  Collapse the JSR166 parker event, and the
5354//     objectmonitor ParkEvent into a single "Event" construct.
5355// 3.  In park() and unpark() add:
5356//     assert (Thread::current() == AssociatedWith).
5357// 4.  add spurious wakeup injection on a -XX:EarlyParkReturn=N switch.
5358//     1-out-of-N park() operations will return immediately.
5359//
5360// _Event transitions in park()
5361//   -1 => -1 : illegal
5362//    1 =>  0 : pass - return immediately
5363//    0 => -1 : block
5364//
5365// _Event serves as a restricted-range semaphore.
5366//
5367// Another possible encoding of _Event would be with
5368// explicit "PARKED" == 01b and "SIGNALED" == 10b bits.
5369//
5370// TODO-FIXME: add DTRACE probes for:
5371// 1.   Tx parks
5372// 2.   Ty unparks Tx
5373// 3.   Tx resumes from park
5374
5375
5376// value determined through experimentation
5377#define ROUNDINGFIX 11
5378
5379// utility to compute the abstime argument to timedwait.
5380// TODO-FIXME: switch from compute_abstime() to unpackTime().
5381
5382static timestruc_t* compute_abstime(timestruc_t* abstime, jlong millis) {
5383  // millis is the relative timeout time
5384  // abstime will be the absolute timeout time
5385  if (millis < 0)  millis = 0;
5386  struct timeval now;
5387  int status = gettimeofday(&now, NULL);
5388  assert(status == 0, "gettimeofday");
5389  jlong seconds = millis / 1000;
5390  jlong max_wait_period;
5391
5392  if (UseLWPSynchronization) {
5393    // forward port of fix for 4275818 (not sleeping long enough)
5394    // There was a bug in Solaris 6, 7 and pre-patch 5 of 8 where
5395    // _lwp_cond_timedwait() used a round_down algorithm rather
5396    // than a round_up. For millis less than our roundfactor
5397    // it rounded down to 0 which doesn't meet the spec.
5398    // For millis > roundfactor we may return a bit sooner, but
5399    // since we can not accurately identify the patch level and
5400    // this has already been fixed in Solaris 9 and 8 we will
5401    // leave it alone rather than always rounding down.
5402
5403    if (millis > 0 && millis < ROUNDINGFIX) millis = ROUNDINGFIX;
5404       // It appears that when we go directly through Solaris _lwp_cond_timedwait()
5405           // the acceptable max time threshold is smaller than for libthread on 2.5.1 and 2.6
5406           max_wait_period = 21000000;
5407  } else {
5408    max_wait_period = 50000000;
5409  }
5410  millis %= 1000;
5411  if (seconds > max_wait_period) {      // see man cond_timedwait(3T)
5412     seconds = max_wait_period;
5413  }
5414  abstime->tv_sec = now.tv_sec  + seconds;
5415  long       usec = now.tv_usec + millis * 1000;
5416  if (usec >= 1000000) {
5417    abstime->tv_sec += 1;
5418    usec -= 1000000;
5419  }
5420  abstime->tv_nsec = usec * 1000;
5421  return abstime;
5422}
5423
5424// Test-and-clear _Event, always leaves _Event set to 0, returns immediately.
5425// Conceptually TryPark() should be equivalent to park(0).
5426
5427int os::PlatformEvent::TryPark() {
5428  for (;;) {
5429    const int v = _Event ;
5430    guarantee ((v == 0) || (v == 1), "invariant") ;
5431    if (Atomic::cmpxchg (0, &_Event, v) == v) return v  ;
5432  }
5433}
5434
5435void os::PlatformEvent::park() {           // AKA: down()
5436  // Invariant: Only the thread associated with the Event/PlatformEvent
5437  // may call park().
5438  int v ;
5439  for (;;) {
5440      v = _Event ;
5441      if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
5442  }
5443  guarantee (v >= 0, "invariant") ;
5444  if (v == 0) {
5445     // Do this the hard way by blocking ...
5446     // See http://monaco.sfbay/detail.jsf?cr=5094058.
5447     // TODO-FIXME: for Solaris SPARC set fprs.FEF=0 prior to parking.
5448     // Only for SPARC >= V8PlusA
5449#if defined(__sparc) && defined(COMPILER2)
5450     if (ClearFPUAtPark) { _mark_fpu_nosave() ; }
5451#endif
5452     int status = os::Solaris::mutex_lock(_mutex);
5453     assert_status(status == 0, status,  "mutex_lock");
5454     guarantee (_nParked == 0, "invariant") ;
5455     ++ _nParked ;
5456     while (_Event < 0) {
5457        // for some reason, under 2.7 lwp_cond_wait() may return ETIME ...
5458        // Treat this the same as if the wait was interrupted
5459        // With usr/lib/lwp going to kernel, always handle ETIME
5460        status = os::Solaris::cond_wait(_cond, _mutex);
5461        if (status == ETIME) status = EINTR ;
5462        assert_status(status == 0 || status == EINTR, status, "cond_wait");
5463     }
5464     -- _nParked ;
5465     _Event = 0 ;
5466     status = os::Solaris::mutex_unlock(_mutex);
5467     assert_status(status == 0, status, "mutex_unlock");
5468  }
5469}
5470
5471int os::PlatformEvent::park(jlong millis) {
5472  guarantee (_nParked == 0, "invariant") ;
5473  int v ;
5474  for (;;) {
5475      v = _Event ;
5476      if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
5477  }
5478  guarantee (v >= 0, "invariant") ;
5479  if (v != 0) return OS_OK ;
5480
5481  int ret = OS_TIMEOUT;
5482  timestruc_t abst;
5483  compute_abstime (&abst, millis);
5484
5485  // See http://monaco.sfbay/detail.jsf?cr=5094058.
5486  // For Solaris SPARC set fprs.FEF=0 prior to parking.
5487  // Only for SPARC >= V8PlusA
5488#if defined(__sparc) && defined(COMPILER2)
5489 if (ClearFPUAtPark) { _mark_fpu_nosave() ; }
5490#endif
5491  int status = os::Solaris::mutex_lock(_mutex);
5492  assert_status(status == 0, status, "mutex_lock");
5493  guarantee (_nParked == 0, "invariant") ;
5494  ++ _nParked ;
5495  while (_Event < 0) {
5496     int status = os::Solaris::cond_timedwait(_cond, _mutex, &abst);
5497     assert_status(status == 0 || status == EINTR ||
5498                   status == ETIME || status == ETIMEDOUT,
5499                   status, "cond_timedwait");
5500     if (!FilterSpuriousWakeups) break ;                // previous semantics
5501     if (status == ETIME || status == ETIMEDOUT) break ;
5502     // We consume and ignore EINTR and spurious wakeups.
5503  }
5504  -- _nParked ;
5505  if (_Event >= 0) ret = OS_OK ;
5506  _Event = 0 ;
5507  status = os::Solaris::mutex_unlock(_mutex);
5508  assert_status(status == 0, status, "mutex_unlock");
5509  return ret;
5510}
5511
5512void os::PlatformEvent::unpark() {
5513  int v, AnyWaiters;
5514
5515  // Increment _Event.
5516  // Another acceptable implementation would be to simply swap 1
5517  // into _Event:
5518  //   if (Swap (&_Event, 1) < 0) {
5519  //      mutex_lock (_mutex) ; AnyWaiters = nParked; mutex_unlock (_mutex) ;
5520  //      if (AnyWaiters) cond_signal (_cond) ;
5521  //   }
5522
5523  for (;;) {
5524    v = _Event ;
5525    if (v > 0) {
5526       // The LD of _Event could have reordered or be satisfied
5527       // by a read-aside from this processor's write buffer.
5528       // To avoid problems execute a barrier and then
5529       // ratify the value.  A degenerate CAS() would also work.
5530       // Viz., CAS (v+0, &_Event, v) == v).
5531       OrderAccess::fence() ;
5532       if (_Event == v) return ;
5533       continue ;
5534    }
5535    if (Atomic::cmpxchg (v+1, &_Event, v) == v) break ;
5536  }
5537
5538  // If the thread associated with the event was parked, wake it.
5539  if (v < 0) {
5540     int status ;
5541     // Wait for the thread assoc with the PlatformEvent to vacate.
5542     status = os::Solaris::mutex_lock(_mutex);
5543     assert_status(status == 0, status, "mutex_lock");
5544     AnyWaiters = _nParked ;
5545     status = os::Solaris::mutex_unlock(_mutex);
5546     assert_status(status == 0, status, "mutex_unlock");
5547     guarantee (AnyWaiters == 0 || AnyWaiters == 1, "invariant") ;
5548     if (AnyWaiters != 0) {
5549       // We intentional signal *after* dropping the lock
5550       // to avoid a common class of futile wakeups.
5551       status = os::Solaris::cond_signal(_cond);
5552       assert_status(status == 0, status, "cond_signal");
5553     }
5554  }
5555}
5556
5557// JSR166
5558// -------------------------------------------------------
5559
5560/*
5561 * The solaris and linux implementations of park/unpark are fairly
5562 * conservative for now, but can be improved. They currently use a
5563 * mutex/condvar pair, plus _counter.
5564 * Park decrements _counter if > 0, else does a condvar wait.  Unpark
5565 * sets count to 1 and signals condvar.  Only one thread ever waits
5566 * on the condvar. Contention seen when trying to park implies that someone
5567 * is unparking you, so don't wait. And spurious returns are fine, so there
5568 * is no need to track notifications.
5569 */
5570
5571#define NANOSECS_PER_SEC 1000000000
5572#define NANOSECS_PER_MILLISEC 1000000
5573#define MAX_SECS 100000000
5574
5575/*
5576 * This code is common to linux and solaris and will be moved to a
5577 * common place in dolphin.
5578 *
5579 * The passed in time value is either a relative time in nanoseconds
5580 * or an absolute time in milliseconds. Either way it has to be unpacked
5581 * into suitable seconds and nanoseconds components and stored in the
5582 * given timespec structure.
5583 * Given time is a 64-bit value and the time_t used in the timespec is only
5584 * a signed-32-bit value (except on 64-bit Linux) we have to watch for
5585 * overflow if times way in the future are given. Further on Solaris versions
5586 * prior to 10 there is a restriction (see cond_timedwait) that the specified
5587 * number of seconds, in abstime, is less than current_time  + 100,000,000.
5588 * As it will be 28 years before "now + 100000000" will overflow we can
5589 * ignore overflow and just impose a hard-limit on seconds using the value
5590 * of "now + 100,000,000". This places a limit on the timeout of about 3.17
5591 * years from "now".
5592 */
5593static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) {
5594  assert (time > 0, "convertTime");
5595
5596  struct timeval now;
5597  int status = gettimeofday(&now, NULL);
5598  assert(status == 0, "gettimeofday");
5599
5600  time_t max_secs = now.tv_sec + MAX_SECS;
5601
5602  if (isAbsolute) {
5603    jlong secs = time / 1000;
5604    if (secs > max_secs) {
5605      absTime->tv_sec = max_secs;
5606    }
5607    else {
5608      absTime->tv_sec = secs;
5609    }
5610    absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC;
5611  }
5612  else {
5613    jlong secs = time / NANOSECS_PER_SEC;
5614    if (secs >= MAX_SECS) {
5615      absTime->tv_sec = max_secs;
5616      absTime->tv_nsec = 0;
5617    }
5618    else {
5619      absTime->tv_sec = now.tv_sec + secs;
5620      absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000;
5621      if (absTime->tv_nsec >= NANOSECS_PER_SEC) {
5622        absTime->tv_nsec -= NANOSECS_PER_SEC;
5623        ++absTime->tv_sec; // note: this must be <= max_secs
5624      }
5625    }
5626  }
5627  assert(absTime->tv_sec >= 0, "tv_sec < 0");
5628  assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs");
5629  assert(absTime->tv_nsec >= 0, "tv_nsec < 0");
5630  assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec");
5631}
5632
5633void Parker::park(bool isAbsolute, jlong time) {
5634
5635  // Optional fast-path check:
5636  // Return immediately if a permit is available.
5637  if (_counter > 0) {
5638      _counter = 0 ;
5639      return ;
5640  }
5641
5642  // Optional fast-exit: Check interrupt before trying to wait
5643  Thread* thread = Thread::current();
5644  assert(thread->is_Java_thread(), "Must be JavaThread");
5645  JavaThread *jt = (JavaThread *)thread;
5646  if (Thread::is_interrupted(thread, false)) {
5647    return;
5648  }
5649
5650  // First, demultiplex/decode time arguments
5651  timespec absTime;
5652  if (time < 0) { // don't wait at all
5653    return;
5654  }
5655  if (time > 0) {
5656    // Warning: this code might be exposed to the old Solaris time
5657    // round-down bugs.  Grep "roundingFix" for details.
5658    unpackTime(&absTime, isAbsolute, time);
5659  }
5660
5661  // Enter safepoint region
5662  // Beware of deadlocks such as 6317397.
5663  // The per-thread Parker:: _mutex is a classic leaf-lock.
5664  // In particular a thread must never block on the Threads_lock while
5665  // holding the Parker:: mutex.  If safepoints are pending both the
5666  // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock.
5667  ThreadBlockInVM tbivm(jt);
5668
5669  // Don't wait if cannot get lock since interference arises from
5670  // unblocking.  Also. check interrupt before trying wait
5671  if (Thread::is_interrupted(thread, false) ||
5672      os::Solaris::mutex_trylock(_mutex) != 0) {
5673    return;
5674  }
5675
5676  int status ;
5677
5678  if (_counter > 0)  { // no wait needed
5679    _counter = 0;
5680    status = os::Solaris::mutex_unlock(_mutex);
5681    assert (status == 0, "invariant") ;
5682    return;
5683  }
5684
5685#ifdef ASSERT
5686  // Don't catch signals while blocked; let the running threads have the signals.
5687  // (This allows a debugger to break into the running thread.)
5688  sigset_t oldsigs;
5689  sigset_t* allowdebug_blocked = os::Solaris::allowdebug_blocked_signals();
5690  thr_sigsetmask(SIG_BLOCK, allowdebug_blocked, &oldsigs);
5691#endif
5692
5693  OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
5694  jt->set_suspend_equivalent();
5695  // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
5696
5697  // Do this the hard way by blocking ...
5698  // See http://monaco.sfbay/detail.jsf?cr=5094058.
5699  // TODO-FIXME: for Solaris SPARC set fprs.FEF=0 prior to parking.
5700  // Only for SPARC >= V8PlusA
5701#if defined(__sparc) && defined(COMPILER2)
5702  if (ClearFPUAtPark) { _mark_fpu_nosave() ; }
5703#endif
5704
5705  if (time == 0) {
5706    status = os::Solaris::cond_wait (_cond, _mutex) ;
5707  } else {
5708    status = os::Solaris::cond_timedwait (_cond, _mutex, &absTime);
5709  }
5710  // Note that an untimed cond_wait() can sometimes return ETIME on older
5711  // versions of the Solaris.
5712  assert_status(status == 0 || status == EINTR ||
5713                status == ETIME || status == ETIMEDOUT,
5714                status, "cond_timedwait");
5715
5716#ifdef ASSERT
5717  thr_sigsetmask(SIG_SETMASK, &oldsigs, NULL);
5718#endif
5719  _counter = 0 ;
5720  status = os::Solaris::mutex_unlock(_mutex);
5721  assert_status(status == 0, status, "mutex_unlock") ;
5722
5723  // If externally suspended while waiting, re-suspend
5724  if (jt->handle_special_suspend_equivalent_condition()) {
5725    jt->java_suspend_self();
5726  }
5727
5728}
5729
5730void Parker::unpark() {
5731  int s, status ;
5732  status = os::Solaris::mutex_lock (_mutex) ;
5733  assert (status == 0, "invariant") ;
5734  s = _counter;
5735  _counter = 1;
5736  status = os::Solaris::mutex_unlock (_mutex) ;
5737  assert (status == 0, "invariant") ;
5738
5739  if (s < 1) {
5740    status = os::Solaris::cond_signal (_cond) ;
5741    assert (status == 0, "invariant") ;
5742  }
5743}
5744
5745extern char** environ;
5746
5747// Run the specified command in a separate process. Return its exit value,
5748// or -1 on failure (e.g. can't fork a new process).
5749// Unlike system(), this function can be called from signal handler. It
5750// doesn't block SIGINT et al.
5751int os::fork_and_exec(char* cmd) {
5752  char * argv[4];
5753  argv[0] = (char *)"sh";
5754  argv[1] = (char *)"-c";
5755  argv[2] = cmd;
5756  argv[3] = NULL;
5757
5758  // fork is async-safe, fork1 is not so can't use in signal handler
5759  pid_t pid;
5760  Thread* t = ThreadLocalStorage::get_thread_slow();
5761  if (t != NULL && t->is_inside_signal_handler()) {
5762    pid = fork();
5763  } else {
5764    pid = fork1();
5765  }
5766
5767  if (pid < 0) {
5768    // fork failed
5769    warning("fork failed: %s", strerror(errno));
5770    return -1;
5771
5772  } else if (pid == 0) {
5773    // child process
5774
5775    // try to be consistent with system(), which uses "/usr/bin/sh" on Solaris
5776    execve("/usr/bin/sh", argv, environ);
5777
5778    // execve failed
5779    _exit(-1);
5780
5781  } else  {
5782    // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't
5783    // care about the actual exit code, for now.
5784
5785    int status;
5786
5787    // Wait for the child process to exit.  This returns immediately if
5788    // the child has already exited. */
5789    while (waitpid(pid, &status, 0) < 0) {
5790        switch (errno) {
5791        case ECHILD: return 0;
5792        case EINTR: break;
5793        default: return -1;
5794        }
5795    }
5796
5797    if (WIFEXITED(status)) {
5798       // The child exited normally; get its exit code.
5799       return WEXITSTATUS(status);
5800    } else if (WIFSIGNALED(status)) {
5801       // The child exited because of a signal
5802       // The best value to return is 0x80 + signal number,
5803       // because that is what all Unix shells do, and because
5804       // it allows callers to distinguish between process exit and
5805       // process death by signal.
5806       return 0x80 + WTERMSIG(status);
5807    } else {
5808       // Unknown exit code; pass it through
5809       return status;
5810    }
5811  }
5812}
5813