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