annotate src/os/solaris/vm/os_solaris.cpp @ 12233:40136aa2cdb1

8010722: assert: failed: heap size is too big for compressed oops Summary: Use conservative assumptions of required alignment for the various garbage collector components into account when determining the maximum heap size that supports compressed oops. Using this conservative value avoids several circular dependencies in the calculation. Reviewed-by: stefank, dholmes
author tschatzl
date Wed, 11 Sep 2013 16:25:02 +0200
parents 4c84d351cca9
children cefad50507d8 c250880a6673 2b8e28fdf503 5656140324ed
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
7629
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1490
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1490
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1490
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
25 // no precompiled headers
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
26 #include "classfile/classLoader.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
27 #include "classfile/systemDictionary.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
28 #include "classfile/vmSymbols.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
29 #include "code/icBuffer.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
30 #include "code/vtableStubs.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
31 #include "compiler/compileBroker.hpp"
7199
cd3d6a6b95d9 8003240: x86: move MacroAssembler into separate file
twisti
parents: 6966
diff changeset
32 #include "compiler/disassembler.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
33 #include "interpreter/interpreter.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
34 #include "jvm_solaris.h"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
35 #include "memory/allocation.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
36 #include "memory/filemap.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
37 #include "mutex_solaris.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
38 #include "oops/oop.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
39 #include "os_share_solaris.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
40 #include "prims/jniFastGetField.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
41 #include "prims/jvm.h"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
42 #include "prims/jvm_misc.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
43 #include "runtime/arguments.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
44 #include "runtime/extendedPC.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
45 #include "runtime/globals.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
46 #include "runtime/interfaceSupport.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
47 #include "runtime/java.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
48 #include "runtime/javaCalls.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
49 #include "runtime/mutexLocker.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
50 #include "runtime/objectMonitor.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
51 #include "runtime/osThread.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
52 #include "runtime/perfMemory.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
53 #include "runtime/sharedRuntime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
54 #include "runtime/statSampler.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
55 #include "runtime/stubRoutines.hpp"
7180
f34d701e952e 8003935: Simplify the needed includes for using Thread::current()
stefank
parents: 6966
diff changeset
56 #include "runtime/thread.inline.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
57 #include "runtime/threadCritical.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
58 #include "runtime/timer.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
59 #include "services/attachListener.hpp"
6882
716c64bda5ba 7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents: 6854
diff changeset
60 #include "services/memTracker.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
61 #include "services/runtimeService.hpp"
2022
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
62 #include "utilities/decoder.hpp"
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
63 #include "utilities/defaultStream.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
64 #include "utilities/events.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
65 #include "utilities/growableArray.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1967
diff changeset
66 #include "utilities/vmError.hpp"
0
a61af66fc99e Initial load
duke
parents:
diff changeset
67
a61af66fc99e Initial load
duke
parents:
diff changeset
68 // put OS-includes here
a61af66fc99e Initial load
duke
parents:
diff changeset
69 # include <dlfcn.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
70 # include <errno.h>
2068
1e637defdda6 6961186: Better VM handling of unexpected exceptions from application native code
zgu
parents: 2023
diff changeset
71 # include <exception>
0
a61af66fc99e Initial load
duke
parents:
diff changeset
72 # include <link.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
73 # include <poll.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
74 # include <pthread.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
75 # include <pwd.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
76 # include <schedctl.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
77 # include <setjmp.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
78 # include <signal.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
79 # include <stdio.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
80 # include <alloca.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
81 # include <sys/filio.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
82 # include <sys/ipc.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
83 # include <sys/lwp.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
84 # include <sys/machelf.h> // for elf Sym structure used by dladdr1
a61af66fc99e Initial load
duke
parents:
diff changeset
85 # include <sys/mman.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
86 # include <sys/processor.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
87 # include <sys/procset.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
88 # include <sys/pset.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
89 # include <sys/resource.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
90 # include <sys/shm.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
91 # include <sys/socket.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
92 # include <sys/stat.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
93 # include <sys/systeminfo.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
94 # include <sys/time.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
95 # include <sys/times.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
96 # include <sys/types.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
97 # include <sys/wait.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
98 # include <sys/utsname.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
99 # include <thread.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
100 # include <unistd.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
101 # include <sys/priocntl.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
102 # include <sys/rtpriocntl.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
103 # include <sys/tspriocntl.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
104 # include <sys/iapriocntl.h>
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
105 # include <sys/fxpriocntl.h>
0
a61af66fc99e Initial load
duke
parents:
diff changeset
106 # include <sys/loadavg.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
107 # include <string.h>
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
108 # include <stdio.h>
0
a61af66fc99e Initial load
duke
parents:
diff changeset
109
a61af66fc99e Initial load
duke
parents:
diff changeset
110 # define _STRUCTURED_PROC 1 // this gets us the new structured proc interfaces of 5.6 & later
a61af66fc99e Initial load
duke
parents:
diff changeset
111 # include <sys/procfs.h> // see comment in <sys/procfs.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
112
a61af66fc99e Initial load
duke
parents:
diff changeset
113 #define MAX_PATH (2 * K)
a61af66fc99e Initial load
duke
parents:
diff changeset
114
a61af66fc99e Initial load
duke
parents:
diff changeset
115 // for timer info max values which include all bits
a61af66fc99e Initial load
duke
parents:
diff changeset
116 #define ALL_64_BITS CONST64(0xFFFFFFFFFFFFFFFF)
a61af66fc99e Initial load
duke
parents:
diff changeset
117
a61af66fc99e Initial load
duke
parents:
diff changeset
118
a61af66fc99e Initial load
duke
parents:
diff changeset
119 // Here are some liblgrp types from sys/lgrp_user.h to be able to
a61af66fc99e Initial load
duke
parents:
diff changeset
120 // compile on older systems without this header file.
a61af66fc99e Initial load
duke
parents:
diff changeset
121
a61af66fc99e Initial load
duke
parents:
diff changeset
122 #ifndef MADV_ACCESS_LWP
a61af66fc99e Initial load
duke
parents:
diff changeset
123 # define MADV_ACCESS_LWP 7 /* next LWP to access heavily */
a61af66fc99e Initial load
duke
parents:
diff changeset
124 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
125 #ifndef MADV_ACCESS_MANY
a61af66fc99e Initial load
duke
parents:
diff changeset
126 # define MADV_ACCESS_MANY 8 /* many processes to access heavily */
a61af66fc99e Initial load
duke
parents:
diff changeset
127 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
128
144
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
129 #ifndef LGRP_RSRC_CPU
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
130 # define LGRP_RSRC_CPU 0 /* CPU resources */
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
131 #endif
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
132 #ifndef LGRP_RSRC_MEM
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
133 # define LGRP_RSRC_MEM 1 /* memory resources */
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
134 #endif
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
135
0
a61af66fc99e Initial load
duke
parents:
diff changeset
136 // see thr_setprio(3T) for the basis of these numbers
a61af66fc99e Initial load
duke
parents:
diff changeset
137 #define MinimumPriority 0
a61af66fc99e Initial load
duke
parents:
diff changeset
138 #define NormalPriority 64
a61af66fc99e Initial load
duke
parents:
diff changeset
139 #define MaximumPriority 127
a61af66fc99e Initial load
duke
parents:
diff changeset
140
a61af66fc99e Initial load
duke
parents:
diff changeset
141 // Values for ThreadPriorityPolicy == 1
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
142 int prio_policy1[CriticalPriority+1] = {
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
143 -99999, 0, 16, 32, 48, 64,
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
144 80, 96, 112, 124, 127, 127 };
0
a61af66fc99e Initial load
duke
parents:
diff changeset
145
a61af66fc99e Initial load
duke
parents:
diff changeset
146 // System parameters used internally
a61af66fc99e Initial load
duke
parents:
diff changeset
147 static clock_t clock_tics_per_sec = 100;
a61af66fc99e Initial load
duke
parents:
diff changeset
148
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
149 // Track if we have called enable_extended_FILE_stdio (on Solaris 10u4+)
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
150 static bool enabled_extended_FILE_stdio = false;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
151
0
a61af66fc99e Initial load
duke
parents:
diff changeset
152 // For diagnostics to print a message once. see run_periodic_checks
a61af66fc99e Initial load
duke
parents:
diff changeset
153 static bool check_addr0_done = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
154 static sigset_t check_signal_done;
a61af66fc99e Initial load
duke
parents:
diff changeset
155 static bool check_signals = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
156
a61af66fc99e Initial load
duke
parents:
diff changeset
157 address os::Solaris::handler_start; // start pc of thr_sighndlrinfo
a61af66fc99e Initial load
duke
parents:
diff changeset
158 address os::Solaris::handler_end; // end pc of thr_sighndlrinfo
a61af66fc99e Initial load
duke
parents:
diff changeset
159
a61af66fc99e Initial load
duke
parents:
diff changeset
160 address os::Solaris::_main_stack_base = NULL; // 4352906 workaround
a61af66fc99e Initial load
duke
parents:
diff changeset
161
a61af66fc99e Initial load
duke
parents:
diff changeset
162
a61af66fc99e Initial load
duke
parents:
diff changeset
163 // "default" initializers for missing libc APIs
a61af66fc99e Initial load
duke
parents:
diff changeset
164 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
165 static int lwp_mutex_init(mutex_t *mx, int scope, void *arg) { memset(mx, 0, sizeof(mutex_t)); return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
166 static int lwp_mutex_destroy(mutex_t *mx) { return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 static int lwp_cond_init(cond_t *cv, int scope, void *arg){ memset(cv, 0, sizeof(cond_t)); return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
169 static int lwp_cond_destroy(cond_t *cv) { return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
170 }
a61af66fc99e Initial load
duke
parents:
diff changeset
171
a61af66fc99e Initial load
duke
parents:
diff changeset
172 // "default" initializers for pthread-based synchronization
a61af66fc99e Initial load
duke
parents:
diff changeset
173 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
174 static int pthread_mutex_default_init(mutex_t *mx, int scope, void *arg) { memset(mx, 0, sizeof(mutex_t)); return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
175 static int pthread_cond_default_init(cond_t *cv, int scope, void *arg){ memset(cv, 0, sizeof(cond_t)); return 0; }
a61af66fc99e Initial load
duke
parents:
diff changeset
176 }
a61af66fc99e Initial load
duke
parents:
diff changeset
177
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
178 static void unpackTime(timespec* absTime, bool isAbsolute, jlong time);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
179
0
a61af66fc99e Initial load
duke
parents:
diff changeset
180 // Thread Local Storage
a61af66fc99e Initial load
duke
parents:
diff changeset
181 // This is common to all Solaris platforms so it is defined here,
a61af66fc99e Initial load
duke
parents:
diff changeset
182 // in this common file.
a61af66fc99e Initial load
duke
parents:
diff changeset
183 // The declarations are in the os_cpu threadLS*.hpp files.
a61af66fc99e Initial load
duke
parents:
diff changeset
184 //
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // Static member initialization for TLS
a61af66fc99e Initial load
duke
parents:
diff changeset
186 Thread* ThreadLocalStorage::_get_thread_cache[ThreadLocalStorage::_pd_cache_size] = {NULL};
a61af66fc99e Initial load
duke
parents:
diff changeset
187
a61af66fc99e Initial load
duke
parents:
diff changeset
188 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
189 #define _PCT(n,d) ((100.0*(double)(n))/(double)(d))
a61af66fc99e Initial load
duke
parents:
diff changeset
190
a61af66fc99e Initial load
duke
parents:
diff changeset
191 int ThreadLocalStorage::_tcacheHit = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
192 int ThreadLocalStorage::_tcacheMiss = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
193
a61af66fc99e Initial load
duke
parents:
diff changeset
194 void ThreadLocalStorage::print_statistics() {
a61af66fc99e Initial load
duke
parents:
diff changeset
195 int total = _tcacheMiss+_tcacheHit;
a61af66fc99e Initial load
duke
parents:
diff changeset
196 tty->print_cr("Thread cache hits %d misses %d total %d percent %f\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
197 _tcacheHit, _tcacheMiss, total, _PCT(_tcacheHit, total));
a61af66fc99e Initial load
duke
parents:
diff changeset
198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
199 #undef _PCT
a61af66fc99e Initial load
duke
parents:
diff changeset
200 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
201
a61af66fc99e Initial load
duke
parents:
diff changeset
202 Thread* ThreadLocalStorage::get_thread_via_cache_slowly(uintptr_t raw_id,
a61af66fc99e Initial load
duke
parents:
diff changeset
203 int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
204 Thread *thread = get_thread_slow();
a61af66fc99e Initial load
duke
parents:
diff changeset
205 if (thread != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
206 address sp = os::current_stack_pointer();
a61af66fc99e Initial load
duke
parents:
diff changeset
207 guarantee(thread->_stack_base == NULL ||
a61af66fc99e Initial load
duke
parents:
diff changeset
208 (sp <= thread->_stack_base &&
a61af66fc99e Initial load
duke
parents:
diff changeset
209 sp >= thread->_stack_base - thread->_stack_size) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
210 is_error_reported(),
a61af66fc99e Initial load
duke
parents:
diff changeset
211 "sp must be inside of selected thread stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
212
2100
b1a2afa37ec4 7003271: Hotspot should track cumulative Java heap bytes allocated on a per-thread basis
phh
parents: 2097
diff changeset
213 thread->set_self_raw_id(raw_id); // mark for quick retrieval
0
a61af66fc99e Initial load
duke
parents:
diff changeset
214 _get_thread_cache[ index ] = thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
215 }
a61af66fc99e Initial load
duke
parents:
diff changeset
216 return thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
217 }
a61af66fc99e Initial load
duke
parents:
diff changeset
218
a61af66fc99e Initial load
duke
parents:
diff changeset
219
a61af66fc99e Initial load
duke
parents:
diff changeset
220 static const double all_zero[ sizeof(Thread) / sizeof(double) + 1 ] = {0};
a61af66fc99e Initial load
duke
parents:
diff changeset
221 #define NO_CACHED_THREAD ((Thread*)all_zero)
a61af66fc99e Initial load
duke
parents:
diff changeset
222
a61af66fc99e Initial load
duke
parents:
diff changeset
223 void ThreadLocalStorage::pd_set_thread(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
224
a61af66fc99e Initial load
duke
parents:
diff changeset
225 // Store the new value before updating the cache to prevent a race
a61af66fc99e Initial load
duke
parents:
diff changeset
226 // between get_thread_via_cache_slowly() and this store operation.
a61af66fc99e Initial load
duke
parents:
diff changeset
227 os::thread_local_storage_at_put(ThreadLocalStorage::thread_index(), thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
228
a61af66fc99e Initial load
duke
parents:
diff changeset
229 // Update thread cache with new thread if setting on thread create,
a61af66fc99e Initial load
duke
parents:
diff changeset
230 // or NO_CACHED_THREAD (zeroed) thread if resetting thread on exit.
a61af66fc99e Initial load
duke
parents:
diff changeset
231 uintptr_t raw = pd_raw_thread_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
232 int ix = pd_cache_index(raw);
a61af66fc99e Initial load
duke
parents:
diff changeset
233 _get_thread_cache[ix] = thread == NULL ? NO_CACHED_THREAD : thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
235
a61af66fc99e Initial load
duke
parents:
diff changeset
236 void ThreadLocalStorage::pd_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
237 for (int i = 0; i < _pd_cache_size; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
238 _get_thread_cache[i] = NO_CACHED_THREAD;
a61af66fc99e Initial load
duke
parents:
diff changeset
239 }
a61af66fc99e Initial load
duke
parents:
diff changeset
240 }
a61af66fc99e Initial load
duke
parents:
diff changeset
241
a61af66fc99e Initial load
duke
parents:
diff changeset
242 // Invalidate all the caches (happens to be the same as pd_init).
a61af66fc99e Initial load
duke
parents:
diff changeset
243 void ThreadLocalStorage::pd_invalidate_all() { pd_init(); }
a61af66fc99e Initial load
duke
parents:
diff changeset
244
a61af66fc99e Initial load
duke
parents:
diff changeset
245 #undef NO_CACHED_THREAD
a61af66fc99e Initial load
duke
parents:
diff changeset
246
a61af66fc99e Initial load
duke
parents:
diff changeset
247 // END Thread Local Storage
a61af66fc99e Initial load
duke
parents:
diff changeset
248
a61af66fc99e Initial load
duke
parents:
diff changeset
249 static inline size_t adjust_stack_size(address base, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
250 if ((ssize_t)size < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // 4759953: Compensate for ridiculous stack size.
a61af66fc99e Initial load
duke
parents:
diff changeset
252 size = max_intx;
a61af66fc99e Initial load
duke
parents:
diff changeset
253 }
a61af66fc99e Initial load
duke
parents:
diff changeset
254 if (size > (size_t)base) {
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // 4812466: Make sure size doesn't allow the stack to wrap the address space.
a61af66fc99e Initial load
duke
parents:
diff changeset
256 size = (size_t)base;
a61af66fc99e Initial load
duke
parents:
diff changeset
257 }
a61af66fc99e Initial load
duke
parents:
diff changeset
258 return size;
a61af66fc99e Initial load
duke
parents:
diff changeset
259 }
a61af66fc99e Initial load
duke
parents:
diff changeset
260
a61af66fc99e Initial load
duke
parents:
diff changeset
261 static inline stack_t get_stack_info() {
a61af66fc99e Initial load
duke
parents:
diff changeset
262 stack_t st;
a61af66fc99e Initial load
duke
parents:
diff changeset
263 int retval = thr_stksegment(&st);
a61af66fc99e Initial load
duke
parents:
diff changeset
264 st.ss_size = adjust_stack_size((address)st.ss_sp, st.ss_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
265 assert(retval == 0, "incorrect return value from thr_stksegment");
a61af66fc99e Initial load
duke
parents:
diff changeset
266 assert((address)&st < (address)st.ss_sp, "Invalid stack base returned");
a61af66fc99e Initial load
duke
parents:
diff changeset
267 assert((address)&st > (address)st.ss_sp-st.ss_size, "Invalid stack size returned");
a61af66fc99e Initial load
duke
parents:
diff changeset
268 return st;
a61af66fc99e Initial load
duke
parents:
diff changeset
269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
270
a61af66fc99e Initial load
duke
parents:
diff changeset
271 address os::current_stack_base() {
a61af66fc99e Initial load
duke
parents:
diff changeset
272 int r = thr_main() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
273 guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
274 bool is_primordial_thread = r;
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 // Workaround 4352906, avoid calls to thr_stksegment by
a61af66fc99e Initial load
duke
parents:
diff changeset
277 // thr_main after the first one (it looks like we trash
a61af66fc99e Initial load
duke
parents:
diff changeset
278 // some data, causing the value for ss_sp to be incorrect).
a61af66fc99e Initial load
duke
parents:
diff changeset
279 if (!is_primordial_thread || os::Solaris::_main_stack_base == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
280 stack_t st = get_stack_info();
a61af66fc99e Initial load
duke
parents:
diff changeset
281 if (is_primordial_thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
282 // cache initial value of stack base
a61af66fc99e Initial load
duke
parents:
diff changeset
283 os::Solaris::_main_stack_base = (address)st.ss_sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
284 }
a61af66fc99e Initial load
duke
parents:
diff changeset
285 return (address)st.ss_sp;
a61af66fc99e Initial load
duke
parents:
diff changeset
286 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
287 guarantee(os::Solaris::_main_stack_base != NULL, "Attempt to use null cached stack base");
a61af66fc99e Initial load
duke
parents:
diff changeset
288 return os::Solaris::_main_stack_base;
a61af66fc99e Initial load
duke
parents:
diff changeset
289 }
a61af66fc99e Initial load
duke
parents:
diff changeset
290 }
a61af66fc99e Initial load
duke
parents:
diff changeset
291
a61af66fc99e Initial load
duke
parents:
diff changeset
292 size_t os::current_stack_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
293 size_t size;
a61af66fc99e Initial load
duke
parents:
diff changeset
294
a61af66fc99e Initial load
duke
parents:
diff changeset
295 int r = thr_main() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
296 guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
297 if(!r) {
a61af66fc99e Initial load
duke
parents:
diff changeset
298 size = get_stack_info().ss_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
299 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
300 struct rlimit limits;
a61af66fc99e Initial load
duke
parents:
diff changeset
301 getrlimit(RLIMIT_STACK, &limits);
a61af66fc99e Initial load
duke
parents:
diff changeset
302 size = adjust_stack_size(os::Solaris::_main_stack_base, (size_t)limits.rlim_cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
303 }
a61af66fc99e Initial load
duke
parents:
diff changeset
304 // base may not be page aligned
a61af66fc99e Initial load
duke
parents:
diff changeset
305 address base = current_stack_base();
a61af66fc99e Initial load
duke
parents:
diff changeset
306 address bottom = (address)align_size_up((intptr_t)(base - size), os::vm_page_size());;
a61af66fc99e Initial load
duke
parents:
diff changeset
307 return (size_t)(base - bottom);
a61af66fc99e Initial load
duke
parents:
diff changeset
308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
309
548
773234c55e8c 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 499
diff changeset
310 struct tm* os::localtime_pd(const time_t* clock, struct tm* res) {
773234c55e8c 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 499
diff changeset
311 return localtime_r(clock, res);
773234c55e8c 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 499
diff changeset
312 }
773234c55e8c 6800586: -XX:+PrintGCDateStamps is using mt-unsafe localtime function
ysr
parents: 499
diff changeset
313
0
a61af66fc99e Initial load
duke
parents:
diff changeset
314 // interruptible infrastructure
a61af66fc99e Initial load
duke
parents:
diff changeset
315
a61af66fc99e Initial load
duke
parents:
diff changeset
316 // setup_interruptible saves the thread state before going into an
a61af66fc99e Initial load
duke
parents:
diff changeset
317 // interruptible system call.
a61af66fc99e Initial load
duke
parents:
diff changeset
318 // The saved state is used to restore the thread to
a61af66fc99e Initial load
duke
parents:
diff changeset
319 // its former state whether or not an interrupt is received.
a61af66fc99e Initial load
duke
parents:
diff changeset
320 // Used by classloader os::read
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
321 // os::restartable_read calls skip this layer and stay in _thread_in_native
0
a61af66fc99e Initial load
duke
parents:
diff changeset
322
a61af66fc99e Initial load
duke
parents:
diff changeset
323 void os::Solaris::setup_interruptible(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
324
a61af66fc99e Initial load
duke
parents:
diff changeset
325 JavaThreadState thread_state = thread->thread_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
326
a61af66fc99e Initial load
duke
parents:
diff changeset
327 assert(thread_state != _thread_blocked, "Coming from the wrong thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
328 assert(thread_state != _thread_in_native, "Native threads skip setup_interruptible");
a61af66fc99e Initial load
duke
parents:
diff changeset
329 OSThread* osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
330 osthread->set_saved_interrupt_thread_state(thread_state);
a61af66fc99e Initial load
duke
parents:
diff changeset
331 thread->frame_anchor()->make_walkable(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
332 ThreadStateTransition::transition(thread, thread_state, _thread_blocked);
a61af66fc99e Initial load
duke
parents:
diff changeset
333 }
a61af66fc99e Initial load
duke
parents:
diff changeset
334
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // Version of setup_interruptible() for threads that are already in
a61af66fc99e Initial load
duke
parents:
diff changeset
336 // _thread_blocked. Used by os_sleep().
a61af66fc99e Initial load
duke
parents:
diff changeset
337 void os::Solaris::setup_interruptible_already_blocked(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
338 thread->frame_anchor()->make_walkable(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
339 }
a61af66fc99e Initial load
duke
parents:
diff changeset
340
a61af66fc99e Initial load
duke
parents:
diff changeset
341 JavaThread* os::Solaris::setup_interruptible() {
a61af66fc99e Initial load
duke
parents:
diff changeset
342 JavaThread* thread = (JavaThread*)ThreadLocalStorage::thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
343 setup_interruptible(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
344 return thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
345 }
a61af66fc99e Initial load
duke
parents:
diff changeset
346
a61af66fc99e Initial load
duke
parents:
diff changeset
347 void os::Solaris::try_enable_extended_io() {
a61af66fc99e Initial load
duke
parents:
diff changeset
348 typedef int (*enable_extended_FILE_stdio_t)(int, int);
a61af66fc99e Initial load
duke
parents:
diff changeset
349
a61af66fc99e Initial load
duke
parents:
diff changeset
350 if (!UseExtendedFileIO) {
a61af66fc99e Initial load
duke
parents:
diff changeset
351 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
352 }
a61af66fc99e Initial load
duke
parents:
diff changeset
353
a61af66fc99e Initial load
duke
parents:
diff changeset
354 enable_extended_FILE_stdio_t enabler =
a61af66fc99e Initial load
duke
parents:
diff changeset
355 (enable_extended_FILE_stdio_t) dlsym(RTLD_DEFAULT,
a61af66fc99e Initial load
duke
parents:
diff changeset
356 "enable_extended_FILE_stdio");
a61af66fc99e Initial load
duke
parents:
diff changeset
357 if (enabler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
358 enabler(-1, -1);
a61af66fc99e Initial load
duke
parents:
diff changeset
359 }
a61af66fc99e Initial load
duke
parents:
diff changeset
360 }
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362
a61af66fc99e Initial load
duke
parents:
diff changeset
363 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
364
a61af66fc99e Initial load
duke
parents:
diff changeset
365 JavaThread* os::Solaris::setup_interruptible_native() {
a61af66fc99e Initial load
duke
parents:
diff changeset
366 JavaThread* thread = (JavaThread*)ThreadLocalStorage::thread();
a61af66fc99e Initial load
duke
parents:
diff changeset
367 JavaThreadState thread_state = thread->thread_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
368 assert(thread_state == _thread_in_native, "Assumed thread_in_native");
a61af66fc99e Initial load
duke
parents:
diff changeset
369 return thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
370 }
a61af66fc99e Initial load
duke
parents:
diff changeset
371
a61af66fc99e Initial load
duke
parents:
diff changeset
372 void os::Solaris::cleanup_interruptible_native(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
373 JavaThreadState thread_state = thread->thread_state();
a61af66fc99e Initial load
duke
parents:
diff changeset
374 assert(thread_state == _thread_in_native, "Assumed thread_in_native");
a61af66fc99e Initial load
duke
parents:
diff changeset
375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
376 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
377
a61af66fc99e Initial load
duke
parents:
diff changeset
378 // cleanup_interruptible reverses the effects of setup_interruptible
a61af66fc99e Initial load
duke
parents:
diff changeset
379 // setup_interruptible_already_blocked() does not need any cleanup.
a61af66fc99e Initial load
duke
parents:
diff changeset
380
a61af66fc99e Initial load
duke
parents:
diff changeset
381 void os::Solaris::cleanup_interruptible(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
382 OSThread* osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
383
a61af66fc99e Initial load
duke
parents:
diff changeset
384 ThreadStateTransition::transition(thread, _thread_blocked, osthread->saved_interrupt_thread_state());
a61af66fc99e Initial load
duke
parents:
diff changeset
385 }
a61af66fc99e Initial load
duke
parents:
diff changeset
386
a61af66fc99e Initial load
duke
parents:
diff changeset
387 // I/O interruption related counters called in _INTERRUPTIBLE
a61af66fc99e Initial load
duke
parents:
diff changeset
388
a61af66fc99e Initial load
duke
parents:
diff changeset
389 void os::Solaris::bump_interrupted_before_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
390 RuntimeService::record_interrupted_before_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
392
a61af66fc99e Initial load
duke
parents:
diff changeset
393 void os::Solaris::bump_interrupted_during_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 RuntimeService::record_interrupted_during_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
395 }
a61af66fc99e Initial load
duke
parents:
diff changeset
396
a61af66fc99e Initial load
duke
parents:
diff changeset
397 static int _processors_online = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
398
a61af66fc99e Initial load
duke
parents:
diff changeset
399 jint os::Solaris::_os_thread_limit = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
400 volatile jint os::Solaris::_os_thread_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
401
a61af66fc99e Initial load
duke
parents:
diff changeset
402 julong os::available_memory() {
a61af66fc99e Initial load
duke
parents:
diff changeset
403 return Solaris::available_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
404 }
a61af66fc99e Initial load
duke
parents:
diff changeset
405
a61af66fc99e Initial load
duke
parents:
diff changeset
406 julong os::Solaris::available_memory() {
a61af66fc99e Initial load
duke
parents:
diff changeset
407 return (julong)sysconf(_SC_AVPHYS_PAGES) * os::vm_page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
408 }
a61af66fc99e Initial load
duke
parents:
diff changeset
409
a61af66fc99e Initial load
duke
parents:
diff changeset
410 julong os::Solaris::_physical_memory = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
411
a61af66fc99e Initial load
duke
parents:
diff changeset
412 julong os::physical_memory() {
a61af66fc99e Initial load
duke
parents:
diff changeset
413 return Solaris::physical_memory();
a61af66fc99e Initial load
duke
parents:
diff changeset
414 }
a61af66fc99e Initial load
duke
parents:
diff changeset
415
a61af66fc99e Initial load
duke
parents:
diff changeset
416 static hrtime_t first_hrtime = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
417 static const hrtime_t hrtime_hz = 1000*1000*1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
418 const int LOCK_BUSY = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
419 const int LOCK_FREE = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
420 const int LOCK_INVALID = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
421 static volatile hrtime_t max_hrtime = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
422 static volatile int max_hrtime_lock = LOCK_FREE; // Update counter with LSB as lock-in-progress
a61af66fc99e Initial load
duke
parents:
diff changeset
423
a61af66fc99e Initial load
duke
parents:
diff changeset
424
a61af66fc99e Initial load
duke
parents:
diff changeset
425 void os::Solaris::initialize_system_info() {
1123
167c2986d91b 6843629: Make current hotspot build part of jdk5 control build
phh
parents: 1117
diff changeset
426 set_processor_count(sysconf(_SC_NPROCESSORS_CONF));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
427 _processors_online = sysconf (_SC_NPROCESSORS_ONLN);
a61af66fc99e Initial load
duke
parents:
diff changeset
428 _physical_memory = (julong)sysconf(_SC_PHYS_PAGES) * (julong)sysconf(_SC_PAGESIZE);
a61af66fc99e Initial load
duke
parents:
diff changeset
429 }
a61af66fc99e Initial load
duke
parents:
diff changeset
430
a61af66fc99e Initial load
duke
parents:
diff changeset
431 int os::active_processor_count() {
a61af66fc99e Initial load
duke
parents:
diff changeset
432 int online_cpus = sysconf(_SC_NPROCESSORS_ONLN);
a61af66fc99e Initial load
duke
parents:
diff changeset
433 pid_t pid = getpid();
a61af66fc99e Initial load
duke
parents:
diff changeset
434 psetid_t pset = PS_NONE;
387
fad66fdcb7fc 6673124: Runtime.availableProcessors / os::active_processor_count wrong if unused processor sets exist
xlu
parents: 356
diff changeset
435 // Are we running in a processor set or is there any processor set around?
0
a61af66fc99e Initial load
duke
parents:
diff changeset
436 if (pset_bind(PS_QUERY, P_PID, pid, &pset) == 0) {
387
fad66fdcb7fc 6673124: Runtime.availableProcessors / os::active_processor_count wrong if unused processor sets exist
xlu
parents: 356
diff changeset
437 uint_t pset_cpus;
fad66fdcb7fc 6673124: Runtime.availableProcessors / os::active_processor_count wrong if unused processor sets exist
xlu
parents: 356
diff changeset
438 // Query the number of cpus available to us.
fad66fdcb7fc 6673124: Runtime.availableProcessors / os::active_processor_count wrong if unused processor sets exist
xlu
parents: 356
diff changeset
439 if (pset_info(pset, NULL, &pset_cpus, NULL) == 0) {
fad66fdcb7fc 6673124: Runtime.availableProcessors / os::active_processor_count wrong if unused processor sets exist
xlu
parents: 356
diff changeset
440 assert(pset_cpus > 0 && pset_cpus <= online_cpus, "sanity check");
fad66fdcb7fc 6673124: Runtime.availableProcessors / os::active_processor_count wrong if unused processor sets exist
xlu
parents: 356
diff changeset
441 _processors_online = pset_cpus;
fad66fdcb7fc 6673124: Runtime.availableProcessors / os::active_processor_count wrong if unused processor sets exist
xlu
parents: 356
diff changeset
442 return pset_cpus;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
443 }
a61af66fc99e Initial load
duke
parents:
diff changeset
444 }
a61af66fc99e Initial load
duke
parents:
diff changeset
445 // Otherwise return number of online cpus
a61af66fc99e Initial load
duke
parents:
diff changeset
446 return online_cpus;
a61af66fc99e Initial load
duke
parents:
diff changeset
447 }
a61af66fc99e Initial load
duke
parents:
diff changeset
448
a61af66fc99e Initial load
duke
parents:
diff changeset
449 static bool find_processors_in_pset(psetid_t pset,
a61af66fc99e Initial load
duke
parents:
diff changeset
450 processorid_t** id_array,
a61af66fc99e Initial load
duke
parents:
diff changeset
451 uint_t* id_length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
452 bool result = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
453 // Find the number of processors in the processor set.
a61af66fc99e Initial load
duke
parents:
diff changeset
454 if (pset_info(pset, NULL, id_length, NULL) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
455 // Make up an array to hold their ids.
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
456 *id_array = NEW_C_HEAP_ARRAY(processorid_t, *id_length, mtInternal);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
457 // Fill in the array with their processor ids.
a61af66fc99e Initial load
duke
parents:
diff changeset
458 if (pset_info(pset, NULL, id_length, *id_array) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
459 result = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
462 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
464
a61af66fc99e Initial load
duke
parents:
diff changeset
465 // Callers of find_processors_online() must tolerate imprecise results --
a61af66fc99e Initial load
duke
parents:
diff changeset
466 // the system configuration can change asynchronously because of DR
a61af66fc99e Initial load
duke
parents:
diff changeset
467 // or explicit psradm operations.
a61af66fc99e Initial load
duke
parents:
diff changeset
468 //
a61af66fc99e Initial load
duke
parents:
diff changeset
469 // We also need to take care that the loop (below) terminates as the
a61af66fc99e Initial load
duke
parents:
diff changeset
470 // number of processors online can change between the _SC_NPROCESSORS_ONLN
a61af66fc99e Initial load
duke
parents:
diff changeset
471 // request and the loop that builds the list of processor ids. Unfortunately
a61af66fc99e Initial load
duke
parents:
diff changeset
472 // there's no reliable way to determine the maximum valid processor id,
a61af66fc99e Initial load
duke
parents:
diff changeset
473 // so we use a manifest constant, MAX_PROCESSOR_ID, instead. See p_online
a61af66fc99e Initial load
duke
parents:
diff changeset
474 // man pages, which claim the processor id set is "sparse, but
a61af66fc99e Initial load
duke
parents:
diff changeset
475 // not too sparse". MAX_PROCESSOR_ID is used to ensure that we eventually
a61af66fc99e Initial load
duke
parents:
diff changeset
476 // exit the loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
477 //
a61af66fc99e Initial load
duke
parents:
diff changeset
478 // In the future we'll be able to use sysconf(_SC_CPUID_MAX), but that's
a61af66fc99e Initial load
duke
parents:
diff changeset
479 // not available on S8.0.
a61af66fc99e Initial load
duke
parents:
diff changeset
480
a61af66fc99e Initial load
duke
parents:
diff changeset
481 static bool find_processors_online(processorid_t** id_array,
a61af66fc99e Initial load
duke
parents:
diff changeset
482 uint* id_length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
483 const processorid_t MAX_PROCESSOR_ID = 100000 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
484 // Find the number of processors online.
a61af66fc99e Initial load
duke
parents:
diff changeset
485 *id_length = sysconf(_SC_NPROCESSORS_ONLN);
a61af66fc99e Initial load
duke
parents:
diff changeset
486 // Make up an array to hold their ids.
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
487 *id_array = NEW_C_HEAP_ARRAY(processorid_t, *id_length, mtInternal);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
488 // Processors need not be numbered consecutively.
a61af66fc99e Initial load
duke
parents:
diff changeset
489 long found = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
490 processorid_t next = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
491 while (found < *id_length && next < MAX_PROCESSOR_ID) {
a61af66fc99e Initial load
duke
parents:
diff changeset
492 processor_info_t info;
a61af66fc99e Initial load
duke
parents:
diff changeset
493 if (processor_info(next, &info) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
494 // NB, PI_NOINTR processors are effectively online ...
a61af66fc99e Initial load
duke
parents:
diff changeset
495 if (info.pi_state == P_ONLINE || info.pi_state == P_NOINTR) {
a61af66fc99e Initial load
duke
parents:
diff changeset
496 (*id_array)[found] = next;
a61af66fc99e Initial load
duke
parents:
diff changeset
497 found += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
498 }
a61af66fc99e Initial load
duke
parents:
diff changeset
499 }
a61af66fc99e Initial load
duke
parents:
diff changeset
500 next += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
501 }
a61af66fc99e Initial load
duke
parents:
diff changeset
502 if (found < *id_length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
503 // The loop above didn't identify the expected number of processors.
a61af66fc99e Initial load
duke
parents:
diff changeset
504 // We could always retry the operation, calling sysconf(_SC_NPROCESSORS_ONLN)
a61af66fc99e Initial load
duke
parents:
diff changeset
505 // and re-running the loop, above, but there's no guarantee of progress
a61af66fc99e Initial load
duke
parents:
diff changeset
506 // if the system configuration is in flux. Instead, we just return what
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // we've got. Note that in the worst case find_processors_online() could
a61af66fc99e Initial load
duke
parents:
diff changeset
508 // return an empty set. (As a fall-back in the case of the empty set we
a61af66fc99e Initial load
duke
parents:
diff changeset
509 // could just return the ID of the current processor).
a61af66fc99e Initial load
duke
parents:
diff changeset
510 *id_length = found ;
a61af66fc99e Initial load
duke
parents:
diff changeset
511 }
a61af66fc99e Initial load
duke
parents:
diff changeset
512
a61af66fc99e Initial load
duke
parents:
diff changeset
513 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
515
a61af66fc99e Initial load
duke
parents:
diff changeset
516 static bool assign_distribution(processorid_t* id_array,
a61af66fc99e Initial load
duke
parents:
diff changeset
517 uint id_length,
a61af66fc99e Initial load
duke
parents:
diff changeset
518 uint* distribution,
a61af66fc99e Initial load
duke
parents:
diff changeset
519 uint distribution_length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
520 // We assume we can assign processorid_t's to uint's.
a61af66fc99e Initial load
duke
parents:
diff changeset
521 assert(sizeof(processorid_t) == sizeof(uint),
a61af66fc99e Initial load
duke
parents:
diff changeset
522 "can't convert processorid_t to uint");
a61af66fc99e Initial load
duke
parents:
diff changeset
523 // Quick check to see if we won't succeed.
a61af66fc99e Initial load
duke
parents:
diff changeset
524 if (id_length < distribution_length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
525 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
526 }
a61af66fc99e Initial load
duke
parents:
diff changeset
527 // Assign processor ids to the distribution.
a61af66fc99e Initial load
duke
parents:
diff changeset
528 // Try to shuffle processors to distribute work across boards,
a61af66fc99e Initial load
duke
parents:
diff changeset
529 // assuming 4 processors per board.
a61af66fc99e Initial load
duke
parents:
diff changeset
530 const uint processors_per_board = ProcessDistributionStride;
a61af66fc99e Initial load
duke
parents:
diff changeset
531 // Find the maximum processor id.
a61af66fc99e Initial load
duke
parents:
diff changeset
532 processorid_t max_id = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
533 for (uint m = 0; m < id_length; m += 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
534 max_id = MAX2(max_id, id_array[m]);
a61af66fc99e Initial load
duke
parents:
diff changeset
535 }
a61af66fc99e Initial load
duke
parents:
diff changeset
536 // The next id, to limit loops.
a61af66fc99e Initial load
duke
parents:
diff changeset
537 const processorid_t limit_id = max_id + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
538 // Make up markers for available processors.
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
539 bool* available_id = NEW_C_HEAP_ARRAY(bool, limit_id, mtInternal);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
540 for (uint c = 0; c < limit_id; c += 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
541 available_id[c] = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
542 }
a61af66fc99e Initial load
duke
parents:
diff changeset
543 for (uint a = 0; a < id_length; a += 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
544 available_id[id_array[a]] = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
545 }
a61af66fc99e Initial load
duke
parents:
diff changeset
546 // Step by "boards", then by "slot", copying to "assigned".
a61af66fc99e Initial load
duke
parents:
diff changeset
547 // NEEDS_CLEANUP: The assignment of processors should be stateful,
a61af66fc99e Initial load
duke
parents:
diff changeset
548 // remembering which processors have been assigned by
a61af66fc99e Initial load
duke
parents:
diff changeset
549 // previous calls, etc., so as to distribute several
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // independent calls of this method. What we'd like is
a61af66fc99e Initial load
duke
parents:
diff changeset
551 // It would be nice to have an API that let us ask
a61af66fc99e Initial load
duke
parents:
diff changeset
552 // how many processes are bound to a processor,
a61af66fc99e Initial load
duke
parents:
diff changeset
553 // but we don't have that, either.
a61af66fc99e Initial load
duke
parents:
diff changeset
554 // In the short term, "board" is static so that
a61af66fc99e Initial load
duke
parents:
diff changeset
555 // subsequent distributions don't all start at board 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
556 static uint board = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
557 uint assigned = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
558 // Until we've found enough processors ....
a61af66fc99e Initial load
duke
parents:
diff changeset
559 while (assigned < distribution_length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
560 // ... find the next available processor in the board.
a61af66fc99e Initial load
duke
parents:
diff changeset
561 for (uint slot = 0; slot < processors_per_board; slot += 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
562 uint try_id = board * processors_per_board + slot;
a61af66fc99e Initial load
duke
parents:
diff changeset
563 if ((try_id < limit_id) && (available_id[try_id] == true)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
564 distribution[assigned] = try_id;
a61af66fc99e Initial load
duke
parents:
diff changeset
565 available_id[try_id] = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
566 assigned += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
567 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
568 }
a61af66fc99e Initial load
duke
parents:
diff changeset
569 }
a61af66fc99e Initial load
duke
parents:
diff changeset
570 board += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
571 if (board * processors_per_board + 0 >= limit_id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
572 board = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
573 }
a61af66fc99e Initial load
duke
parents:
diff changeset
574 }
a61af66fc99e Initial load
duke
parents:
diff changeset
575 if (available_id != NULL) {
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
576 FREE_C_HEAP_ARRAY(bool, available_id, mtInternal);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
577 }
a61af66fc99e Initial load
duke
parents:
diff changeset
578 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
579 }
a61af66fc99e Initial load
duke
parents:
diff changeset
580
4006
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3956
diff changeset
581 void os::set_native_thread_name(const char *name) {
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3956
diff changeset
582 // Not yet implemented.
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3956
diff changeset
583 return;
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3956
diff changeset
584 }
436b4a3231bf 7098194: integrate macosx-port changes
dcubed
parents: 3956
diff changeset
585
0
a61af66fc99e Initial load
duke
parents:
diff changeset
586 bool os::distribute_processes(uint length, uint* distribution) {
a61af66fc99e Initial load
duke
parents:
diff changeset
587 bool result = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
588 // Find the processor id's of all the available CPUs.
a61af66fc99e Initial load
duke
parents:
diff changeset
589 processorid_t* id_array = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
590 uint id_length = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
591 // There are some races between querying information and using it,
a61af66fc99e Initial load
duke
parents:
diff changeset
592 // since processor sets can change dynamically.
a61af66fc99e Initial load
duke
parents:
diff changeset
593 psetid_t pset = PS_NONE;
a61af66fc99e Initial load
duke
parents:
diff changeset
594 // Are we running in a processor set?
a61af66fc99e Initial load
duke
parents:
diff changeset
595 if ((pset_bind(PS_QUERY, P_PID, P_MYID, &pset) == 0) && pset != PS_NONE) {
a61af66fc99e Initial load
duke
parents:
diff changeset
596 result = find_processors_in_pset(pset, &id_array, &id_length);
a61af66fc99e Initial load
duke
parents:
diff changeset
597 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
598 result = find_processors_online(&id_array, &id_length);
a61af66fc99e Initial load
duke
parents:
diff changeset
599 }
a61af66fc99e Initial load
duke
parents:
diff changeset
600 if (result == true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
601 if (id_length >= length) {
a61af66fc99e Initial load
duke
parents:
diff changeset
602 result = assign_distribution(id_array, id_length, distribution, length);
a61af66fc99e Initial load
duke
parents:
diff changeset
603 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
604 result = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
605 }
a61af66fc99e Initial load
duke
parents:
diff changeset
606 }
a61af66fc99e Initial load
duke
parents:
diff changeset
607 if (id_array != NULL) {
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
608 FREE_C_HEAP_ARRAY(processorid_t, id_array, mtInternal);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
609 }
a61af66fc99e Initial load
duke
parents:
diff changeset
610 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
611 }
a61af66fc99e Initial load
duke
parents:
diff changeset
612
a61af66fc99e Initial load
duke
parents:
diff changeset
613 bool os::bind_to_processor(uint processor_id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
614 // We assume that a processorid_t can be stored in a uint.
a61af66fc99e Initial load
duke
parents:
diff changeset
615 assert(sizeof(uint) == sizeof(processorid_t),
a61af66fc99e Initial load
duke
parents:
diff changeset
616 "can't convert uint to processorid_t");
a61af66fc99e Initial load
duke
parents:
diff changeset
617 int bind_result =
a61af66fc99e Initial load
duke
parents:
diff changeset
618 processor_bind(P_LWPID, // bind LWP.
a61af66fc99e Initial load
duke
parents:
diff changeset
619 P_MYID, // bind current LWP.
a61af66fc99e Initial load
duke
parents:
diff changeset
620 (processorid_t) processor_id, // id.
a61af66fc99e Initial load
duke
parents:
diff changeset
621 NULL); // don't return old binding.
a61af66fc99e Initial load
duke
parents:
diff changeset
622 return (bind_result == 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
623 }
a61af66fc99e Initial load
duke
parents:
diff changeset
624
a61af66fc99e Initial load
duke
parents:
diff changeset
625 bool os::getenv(const char* name, char* buffer, int len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
626 char* val = ::getenv( name );
a61af66fc99e Initial load
duke
parents:
diff changeset
627 if ( val == NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
628 || strlen(val) + 1 > len ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
629 if (len > 0) buffer[0] = 0; // return a null string
a61af66fc99e Initial load
duke
parents:
diff changeset
630 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
631 }
a61af66fc99e Initial load
duke
parents:
diff changeset
632 strcpy( buffer, val );
a61af66fc99e Initial load
duke
parents:
diff changeset
633 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
634 }
a61af66fc99e Initial load
duke
parents:
diff changeset
635
a61af66fc99e Initial load
duke
parents:
diff changeset
636
a61af66fc99e Initial load
duke
parents:
diff changeset
637 // Return true if user is running as root.
a61af66fc99e Initial load
duke
parents:
diff changeset
638
a61af66fc99e Initial load
duke
parents:
diff changeset
639 bool os::have_special_privileges() {
a61af66fc99e Initial load
duke
parents:
diff changeset
640 static bool init = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
641 static bool privileges = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
642 if (!init) {
a61af66fc99e Initial load
duke
parents:
diff changeset
643 privileges = (getuid() != geteuid()) || (getgid() != getegid());
a61af66fc99e Initial load
duke
parents:
diff changeset
644 init = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
645 }
a61af66fc99e Initial load
duke
parents:
diff changeset
646 return privileges;
a61af66fc99e Initial load
duke
parents:
diff changeset
647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
648
a61af66fc99e Initial load
duke
parents:
diff changeset
649
a61af66fc99e Initial load
duke
parents:
diff changeset
650 void os::init_system_properties_values() {
a61af66fc99e Initial load
duke
parents:
diff changeset
651 char arch[12];
a61af66fc99e Initial load
duke
parents:
diff changeset
652 sysinfo(SI_ARCHITECTURE, arch, sizeof(arch));
a61af66fc99e Initial load
duke
parents:
diff changeset
653
a61af66fc99e Initial load
duke
parents:
diff changeset
654 // The next steps are taken in the product version:
a61af66fc99e Initial load
duke
parents:
diff changeset
655 //
7456
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
656 // Obtain the JAVA_HOME value from the location of libjvm.so.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
657 // This library should be located at:
7456
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
658 // <JAVA_HOME>/jre/lib/<arch>/{client|server}/libjvm.so.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
659 //
a61af66fc99e Initial load
duke
parents:
diff changeset
660 // If "/jre/lib/" appears at the right place in the path, then we
7456
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
661 // assume libjvm.so is installed in a JDK and we use this path.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
662 //
a61af66fc99e Initial load
duke
parents:
diff changeset
663 // Otherwise exit with message: "Could not create the Java virtual machine."
a61af66fc99e Initial load
duke
parents:
diff changeset
664 //
a61af66fc99e Initial load
duke
parents:
diff changeset
665 // The following extra steps are taken in the debugging version:
a61af66fc99e Initial load
duke
parents:
diff changeset
666 //
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // If "/jre/lib/" does NOT appear at the right place in the path
a61af66fc99e Initial load
duke
parents:
diff changeset
668 // instead of exit check for $JAVA_HOME environment variable.
a61af66fc99e Initial load
duke
parents:
diff changeset
669 //
a61af66fc99e Initial load
duke
parents:
diff changeset
670 // If it is defined and we are able to locate $JAVA_HOME/jre/lib/<arch>,
7456
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
671 // then we append a fake suffix "hotspot/libjvm.so" to this path so
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
672 // it looks like libjvm.so is installed there
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
673 // <JAVA_HOME>/jre/lib/<arch>/hotspot/libjvm.so.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
674 //
a61af66fc99e Initial load
duke
parents:
diff changeset
675 // Otherwise exit.
a61af66fc99e Initial load
duke
parents:
diff changeset
676 //
a61af66fc99e Initial load
duke
parents:
diff changeset
677 // Important note: if the location of libjvm.so changes this
a61af66fc99e Initial load
duke
parents:
diff changeset
678 // code needs to be changed accordingly.
a61af66fc99e Initial load
duke
parents:
diff changeset
679
a61af66fc99e Initial load
duke
parents:
diff changeset
680 // The next few definitions allow the code to be verbatim:
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
681 #define malloc(n) (char*)NEW_C_HEAP_ARRAY(char, (n), mtInternal)
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
682 #define free(p) FREE_C_HEAP_ARRAY(char, p, mtInternal)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
683 #define getenv(n) ::getenv(n)
a61af66fc99e Initial load
duke
parents:
diff changeset
684
a61af66fc99e Initial load
duke
parents:
diff changeset
685 #define EXTENSIONS_DIR "/lib/ext"
a61af66fc99e Initial load
duke
parents:
diff changeset
686 #define ENDORSED_DIR "/lib/endorsed"
a61af66fc99e Initial load
duke
parents:
diff changeset
687 #define COMMON_DIR "/usr/jdk/packages"
a61af66fc99e Initial load
duke
parents:
diff changeset
688
a61af66fc99e Initial load
duke
parents:
diff changeset
689 {
a61af66fc99e Initial load
duke
parents:
diff changeset
690 /* sysclasspath, java_home, dll_dir */
a61af66fc99e Initial load
duke
parents:
diff changeset
691 {
a61af66fc99e Initial load
duke
parents:
diff changeset
692 char *home_path;
a61af66fc99e Initial load
duke
parents:
diff changeset
693 char *dll_path;
a61af66fc99e Initial load
duke
parents:
diff changeset
694 char *pslash;
a61af66fc99e Initial load
duke
parents:
diff changeset
695 char buf[MAXPATHLEN];
a61af66fc99e Initial load
duke
parents:
diff changeset
696 os::jvm_path(buf, sizeof(buf));
a61af66fc99e Initial load
duke
parents:
diff changeset
697
a61af66fc99e Initial load
duke
parents:
diff changeset
698 // Found the full path to libjvm.so.
a61af66fc99e Initial load
duke
parents:
diff changeset
699 // Now cut the path to <java_home>/jre if we can.
a61af66fc99e Initial load
duke
parents:
diff changeset
700 *(strrchr(buf, '/')) = '\0'; /* get rid of /libjvm.so */
a61af66fc99e Initial load
duke
parents:
diff changeset
701 pslash = strrchr(buf, '/');
a61af66fc99e Initial load
duke
parents:
diff changeset
702 if (pslash != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
703 *pslash = '\0'; /* get rid of /{client|server|hotspot} */
a61af66fc99e Initial load
duke
parents:
diff changeset
704 dll_path = malloc(strlen(buf) + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
705 if (dll_path == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
706 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
707 strcpy(dll_path, buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
708 Arguments::set_dll_dir(dll_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
709
a61af66fc99e Initial load
duke
parents:
diff changeset
710 if (pslash != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
711 pslash = strrchr(buf, '/');
a61af66fc99e Initial load
duke
parents:
diff changeset
712 if (pslash != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
713 *pslash = '\0'; /* get rid of /<arch> */
a61af66fc99e Initial load
duke
parents:
diff changeset
714 pslash = strrchr(buf, '/');
a61af66fc99e Initial load
duke
parents:
diff changeset
715 if (pslash != NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
716 *pslash = '\0'; /* get rid of /lib */
a61af66fc99e Initial load
duke
parents:
diff changeset
717 }
a61af66fc99e Initial load
duke
parents:
diff changeset
718 }
a61af66fc99e Initial load
duke
parents:
diff changeset
719
a61af66fc99e Initial load
duke
parents:
diff changeset
720 home_path = malloc(strlen(buf) + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
721 if (home_path == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
722 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
723 strcpy(home_path, buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
724 Arguments::set_java_home(home_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
725
a61af66fc99e Initial load
duke
parents:
diff changeset
726 if (!set_boot_path('/', ':'))
a61af66fc99e Initial load
duke
parents:
diff changeset
727 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
728 }
a61af66fc99e Initial load
duke
parents:
diff changeset
729
a61af66fc99e Initial load
duke
parents:
diff changeset
730 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
731 * Where to look for native libraries
a61af66fc99e Initial load
duke
parents:
diff changeset
732 */
a61af66fc99e Initial load
duke
parents:
diff changeset
733 {
a61af66fc99e Initial load
duke
parents:
diff changeset
734 // Use dlinfo() to determine the correct java.library.path.
a61af66fc99e Initial load
duke
parents:
diff changeset
735 //
a61af66fc99e Initial load
duke
parents:
diff changeset
736 // If we're launched by the Java launcher, and the user
a61af66fc99e Initial load
duke
parents:
diff changeset
737 // does not set java.library.path explicitly on the commandline,
a61af66fc99e Initial load
duke
parents:
diff changeset
738 // the Java launcher sets LD_LIBRARY_PATH for us and unsets
a61af66fc99e Initial load
duke
parents:
diff changeset
739 // LD_LIBRARY_PATH_32 and LD_LIBRARY_PATH_64. In this case
a61af66fc99e Initial load
duke
parents:
diff changeset
740 // dlinfo returns LD_LIBRARY_PATH + crle settings (including
a61af66fc99e Initial load
duke
parents:
diff changeset
741 // /usr/lib), which is exactly what we want.
a61af66fc99e Initial load
duke
parents:
diff changeset
742 //
a61af66fc99e Initial load
duke
parents:
diff changeset
743 // If the user does set java.library.path, it completely
a61af66fc99e Initial load
duke
parents:
diff changeset
744 // overwrites this setting, and always has.
a61af66fc99e Initial load
duke
parents:
diff changeset
745 //
a61af66fc99e Initial load
duke
parents:
diff changeset
746 // If we're not launched by the Java launcher, we may
a61af66fc99e Initial load
duke
parents:
diff changeset
747 // get here with any/all of the LD_LIBRARY_PATH[_32|64]
a61af66fc99e Initial load
duke
parents:
diff changeset
748 // settings. Again, dlinfo does exactly what we want.
a61af66fc99e Initial load
duke
parents:
diff changeset
749
a61af66fc99e Initial load
duke
parents:
diff changeset
750 Dl_serinfo _info, *info = &_info;
a61af66fc99e Initial load
duke
parents:
diff changeset
751 Dl_serpath *path;
a61af66fc99e Initial load
duke
parents:
diff changeset
752 char* library_path;
a61af66fc99e Initial load
duke
parents:
diff changeset
753 char *common_path;
a61af66fc99e Initial load
duke
parents:
diff changeset
754 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
755
a61af66fc99e Initial load
duke
parents:
diff changeset
756 // determine search path count and required buffer size
a61af66fc99e Initial load
duke
parents:
diff changeset
757 if (dlinfo(RTLD_SELF, RTLD_DI_SERINFOSIZE, (void *)info) == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
758 vm_exit_during_initialization("dlinfo SERINFOSIZE request", dlerror());
a61af66fc99e Initial load
duke
parents:
diff changeset
759 }
a61af66fc99e Initial load
duke
parents:
diff changeset
760
a61af66fc99e Initial load
duke
parents:
diff changeset
761 // allocate new buffer and initialize
a61af66fc99e Initial load
duke
parents:
diff changeset
762 info = (Dl_serinfo*)malloc(_info.dls_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
763 if (info == NULL) {
10161
746b070f5022 8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents: 9062
diff changeset
764 vm_exit_out_of_memory(_info.dls_size, OOM_MALLOC_ERROR,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
765 "init_system_properties_values info");
a61af66fc99e Initial load
duke
parents:
diff changeset
766 }
a61af66fc99e Initial load
duke
parents:
diff changeset
767 info->dls_size = _info.dls_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
768 info->dls_cnt = _info.dls_cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
769
a61af66fc99e Initial load
duke
parents:
diff changeset
770 // obtain search path information
a61af66fc99e Initial load
duke
parents:
diff changeset
771 if (dlinfo(RTLD_SELF, RTLD_DI_SERINFO, (void *)info) == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
772 free(info);
a61af66fc99e Initial load
duke
parents:
diff changeset
773 vm_exit_during_initialization("dlinfo SERINFO request", dlerror());
a61af66fc99e Initial load
duke
parents:
diff changeset
774 }
a61af66fc99e Initial load
duke
parents:
diff changeset
775
a61af66fc99e Initial load
duke
parents:
diff changeset
776 path = &info->dls_serpath[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
777
a61af66fc99e Initial load
duke
parents:
diff changeset
778 // Note: Due to a legacy implementation, most of the library path
a61af66fc99e Initial load
duke
parents:
diff changeset
779 // is set in the launcher. This was to accomodate linking restrictions
a61af66fc99e Initial load
duke
parents:
diff changeset
780 // on legacy Solaris implementations (which are no longer supported).
a61af66fc99e Initial load
duke
parents:
diff changeset
781 // Eventually, all the library path setting will be done here.
a61af66fc99e Initial load
duke
parents:
diff changeset
782 //
a61af66fc99e Initial load
duke
parents:
diff changeset
783 // However, to prevent the proliferation of improperly built native
a61af66fc99e Initial load
duke
parents:
diff changeset
784 // libraries, the new path component /usr/jdk/packages is added here.
a61af66fc99e Initial load
duke
parents:
diff changeset
785
a61af66fc99e Initial load
duke
parents:
diff changeset
786 // Determine the actual CPU architecture.
a61af66fc99e Initial load
duke
parents:
diff changeset
787 char cpu_arch[12];
a61af66fc99e Initial load
duke
parents:
diff changeset
788 sysinfo(SI_ARCHITECTURE, cpu_arch, sizeof(cpu_arch));
a61af66fc99e Initial load
duke
parents:
diff changeset
789 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
790 // If we are a 64-bit vm, perform the following translations:
a61af66fc99e Initial load
duke
parents:
diff changeset
791 // sparc -> sparcv9
a61af66fc99e Initial load
duke
parents:
diff changeset
792 // i386 -> amd64
a61af66fc99e Initial load
duke
parents:
diff changeset
793 if (strcmp(cpu_arch, "sparc") == 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
794 strcat(cpu_arch, "v9");
a61af66fc99e Initial load
duke
parents:
diff changeset
795 else if (strcmp(cpu_arch, "i386") == 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
796 strcpy(cpu_arch, "amd64");
a61af66fc99e Initial load
duke
parents:
diff changeset
797 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
798
a61af66fc99e Initial load
duke
parents:
diff changeset
799 // Construct the invariant part of ld_library_path. Note that the
a61af66fc99e Initial load
duke
parents:
diff changeset
800 // space for the colon and the trailing null are provided by the
a61af66fc99e Initial load
duke
parents:
diff changeset
801 // nulls included by the sizeof operator.
a61af66fc99e Initial load
duke
parents:
diff changeset
802 size_t bufsize = sizeof(COMMON_DIR) + sizeof("/lib/") + strlen(cpu_arch);
a61af66fc99e Initial load
duke
parents:
diff changeset
803 common_path = malloc(bufsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
804 if (common_path == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
805 free(info);
10161
746b070f5022 8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents: 9062
diff changeset
806 vm_exit_out_of_memory(bufsize, OOM_MALLOC_ERROR,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
807 "init_system_properties_values common_path");
a61af66fc99e Initial load
duke
parents:
diff changeset
808 }
a61af66fc99e Initial load
duke
parents:
diff changeset
809 sprintf(common_path, COMMON_DIR "/lib/%s", cpu_arch);
a61af66fc99e Initial load
duke
parents:
diff changeset
810
a61af66fc99e Initial load
duke
parents:
diff changeset
811 // struct size is more than sufficient for the path components obtained
a61af66fc99e Initial load
duke
parents:
diff changeset
812 // through the dlinfo() call, so only add additional space for the path
a61af66fc99e Initial load
duke
parents:
diff changeset
813 // components explicitly added here.
a61af66fc99e Initial load
duke
parents:
diff changeset
814 bufsize = info->dls_size + strlen(common_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
815 library_path = malloc(bufsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
816 if (library_path == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
817 free(info);
a61af66fc99e Initial load
duke
parents:
diff changeset
818 free(common_path);
10161
746b070f5022 8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents: 9062
diff changeset
819 vm_exit_out_of_memory(bufsize, OOM_MALLOC_ERROR,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
820 "init_system_properties_values library_path");
a61af66fc99e Initial load
duke
parents:
diff changeset
821 }
a61af66fc99e Initial load
duke
parents:
diff changeset
822 library_path[0] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
823
a61af66fc99e Initial load
duke
parents:
diff changeset
824 // Construct the desired Java library path from the linker's library
a61af66fc99e Initial load
duke
parents:
diff changeset
825 // search path.
a61af66fc99e Initial load
duke
parents:
diff changeset
826 //
a61af66fc99e Initial load
duke
parents:
diff changeset
827 // For compatibility, it is optimal that we insert the additional path
a61af66fc99e Initial load
duke
parents:
diff changeset
828 // components specific to the Java VM after those components specified
a61af66fc99e Initial load
duke
parents:
diff changeset
829 // in LD_LIBRARY_PATH (if any) but before those added by the ld.so
a61af66fc99e Initial load
duke
parents:
diff changeset
830 // infrastructure.
a61af66fc99e Initial load
duke
parents:
diff changeset
831 if (info->dls_cnt == 0) { // Not sure this can happen, but allow for it
a61af66fc99e Initial load
duke
parents:
diff changeset
832 strcpy(library_path, common_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
833 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
834 int inserted = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
835 for (i = 0; i < info->dls_cnt; i++, path++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
836 uint_t flags = path->dls_flags & LA_SER_MASK;
a61af66fc99e Initial load
duke
parents:
diff changeset
837 if (((flags & LA_SER_LIBPATH) == 0) && !inserted) {
a61af66fc99e Initial load
duke
parents:
diff changeset
838 strcat(library_path, common_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
839 strcat(library_path, os::path_separator());
a61af66fc99e Initial load
duke
parents:
diff changeset
840 inserted = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
841 }
a61af66fc99e Initial load
duke
parents:
diff changeset
842 strcat(library_path, path->dls_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
843 strcat(library_path, os::path_separator());
a61af66fc99e Initial load
duke
parents:
diff changeset
844 }
a61af66fc99e Initial load
duke
parents:
diff changeset
845 // eliminate trailing path separator
a61af66fc99e Initial load
duke
parents:
diff changeset
846 library_path[strlen(library_path)-1] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
847 }
a61af66fc99e Initial load
duke
parents:
diff changeset
848
a61af66fc99e Initial load
duke
parents:
diff changeset
849 // happens before argument parsing - can't use a trace flag
a61af66fc99e Initial load
duke
parents:
diff changeset
850 // tty->print_raw("init_system_properties_values: native lib path: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
851 // tty->print_raw_cr(library_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
852
a61af66fc99e Initial load
duke
parents:
diff changeset
853 // callee copies into its own buffer
a61af66fc99e Initial load
duke
parents:
diff changeset
854 Arguments::set_library_path(library_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
855
a61af66fc99e Initial load
duke
parents:
diff changeset
856 free(common_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
857 free(library_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
858 free(info);
a61af66fc99e Initial load
duke
parents:
diff changeset
859 }
a61af66fc99e Initial load
duke
parents:
diff changeset
860
a61af66fc99e Initial load
duke
parents:
diff changeset
861 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
862 * Extensions directories.
a61af66fc99e Initial load
duke
parents:
diff changeset
863 *
a61af66fc99e Initial load
duke
parents:
diff changeset
864 * Note that the space for the colon and the trailing null are provided
a61af66fc99e Initial load
duke
parents:
diff changeset
865 * by the nulls included by the sizeof operator (so actually one byte more
a61af66fc99e Initial load
duke
parents:
diff changeset
866 * than necessary is allocated).
a61af66fc99e Initial load
duke
parents:
diff changeset
867 */
a61af66fc99e Initial load
duke
parents:
diff changeset
868 {
a61af66fc99e Initial load
duke
parents:
diff changeset
869 char *buf = (char *) malloc(strlen(Arguments::get_java_home()) +
a61af66fc99e Initial load
duke
parents:
diff changeset
870 sizeof(EXTENSIONS_DIR) + sizeof(COMMON_DIR) +
a61af66fc99e Initial load
duke
parents:
diff changeset
871 sizeof(EXTENSIONS_DIR));
a61af66fc99e Initial load
duke
parents:
diff changeset
872 sprintf(buf, "%s" EXTENSIONS_DIR ":" COMMON_DIR EXTENSIONS_DIR,
a61af66fc99e Initial load
duke
parents:
diff changeset
873 Arguments::get_java_home());
a61af66fc99e Initial load
duke
parents:
diff changeset
874 Arguments::set_ext_dirs(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
875 }
a61af66fc99e Initial load
duke
parents:
diff changeset
876
a61af66fc99e Initial load
duke
parents:
diff changeset
877 /* Endorsed standards default directory. */
a61af66fc99e Initial load
duke
parents:
diff changeset
878 {
a61af66fc99e Initial load
duke
parents:
diff changeset
879 char * buf = malloc(strlen(Arguments::get_java_home()) + sizeof(ENDORSED_DIR));
a61af66fc99e Initial load
duke
parents:
diff changeset
880 sprintf(buf, "%s" ENDORSED_DIR, Arguments::get_java_home());
a61af66fc99e Initial load
duke
parents:
diff changeset
881 Arguments::set_endorsed_dirs(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
882 }
a61af66fc99e Initial load
duke
parents:
diff changeset
883 }
a61af66fc99e Initial load
duke
parents:
diff changeset
884
a61af66fc99e Initial load
duke
parents:
diff changeset
885 #undef malloc
a61af66fc99e Initial load
duke
parents:
diff changeset
886 #undef free
a61af66fc99e Initial load
duke
parents:
diff changeset
887 #undef getenv
a61af66fc99e Initial load
duke
parents:
diff changeset
888 #undef EXTENSIONS_DIR
a61af66fc99e Initial load
duke
parents:
diff changeset
889 #undef ENDORSED_DIR
a61af66fc99e Initial load
duke
parents:
diff changeset
890 #undef COMMON_DIR
a61af66fc99e Initial load
duke
parents:
diff changeset
891
a61af66fc99e Initial load
duke
parents:
diff changeset
892 }
a61af66fc99e Initial load
duke
parents:
diff changeset
893
a61af66fc99e Initial load
duke
parents:
diff changeset
894 void os::breakpoint() {
a61af66fc99e Initial load
duke
parents:
diff changeset
895 BREAKPOINT;
a61af66fc99e Initial load
duke
parents:
diff changeset
896 }
a61af66fc99e Initial load
duke
parents:
diff changeset
897
a61af66fc99e Initial load
duke
parents:
diff changeset
898 bool os::obsolete_option(const JavaVMOption *option)
a61af66fc99e Initial load
duke
parents:
diff changeset
899 {
a61af66fc99e Initial load
duke
parents:
diff changeset
900 if (!strncmp(option->optionString, "-Xt", 3)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
901 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
902 } else if (!strncmp(option->optionString, "-Xtm", 4)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
903 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
904 } else if (!strncmp(option->optionString, "-Xverifyheap", 12)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
905 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
906 } else if (!strncmp(option->optionString, "-Xmaxjitcodesize", 16)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
907 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
908 }
a61af66fc99e Initial load
duke
parents:
diff changeset
909 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
911
a61af66fc99e Initial load
duke
parents:
diff changeset
912 bool os::Solaris::valid_stack_address(Thread* thread, address sp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
913 address stackStart = (address)thread->stack_base();
a61af66fc99e Initial load
duke
parents:
diff changeset
914 address stackEnd = (address)(stackStart - (address)thread->stack_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
915 if (sp < stackStart && sp >= stackEnd ) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
916 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
917 }
a61af66fc99e Initial load
duke
parents:
diff changeset
918
a61af66fc99e Initial load
duke
parents:
diff changeset
919 extern "C" void breakpoint() {
a61af66fc99e Initial load
duke
parents:
diff changeset
920 // use debugger to set breakpoint here
a61af66fc99e Initial load
duke
parents:
diff changeset
921 }
a61af66fc99e Initial load
duke
parents:
diff changeset
922
a61af66fc99e Initial load
duke
parents:
diff changeset
923 static thread_t main_thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
924
a61af66fc99e Initial load
duke
parents:
diff changeset
925 // Thread start routine for all new Java threads
a61af66fc99e Initial load
duke
parents:
diff changeset
926 extern "C" void* java_start(void* thread_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
927 // Try to randomize the cache line index of hot stack frames.
a61af66fc99e Initial load
duke
parents:
diff changeset
928 // This helps when threads of the same stack traces evict each other's
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // cache lines. The threads can be either from the same JVM instance, or
a61af66fc99e Initial load
duke
parents:
diff changeset
930 // from different JVM instances. The benefit is especially true for
a61af66fc99e Initial load
duke
parents:
diff changeset
931 // processors with hyperthreading technology.
a61af66fc99e Initial load
duke
parents:
diff changeset
932 static int counter = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
933 int pid = os::current_process_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
934 alloca(((pid ^ counter++) & 7) * 128);
a61af66fc99e Initial load
duke
parents:
diff changeset
935
a61af66fc99e Initial load
duke
parents:
diff changeset
936 int prio;
a61af66fc99e Initial load
duke
parents:
diff changeset
937 Thread* thread = (Thread*)thread_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
938 OSThread* osthr = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
939
a61af66fc99e Initial load
duke
parents:
diff changeset
940 osthr->set_lwp_id( _lwp_self() ); // Store lwp in case we are bound
a61af66fc99e Initial load
duke
parents:
diff changeset
941 thread->_schedctl = (void *) schedctl_init () ;
a61af66fc99e Initial load
duke
parents:
diff changeset
942
a61af66fc99e Initial load
duke
parents:
diff changeset
943 if (UseNUMA) {
a61af66fc99e Initial load
duke
parents:
diff changeset
944 int lgrp_id = os::numa_get_group_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
945 if (lgrp_id != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
946 thread->set_lgrp_id(lgrp_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
947 }
a61af66fc99e Initial load
duke
parents:
diff changeset
948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
949
a61af66fc99e Initial load
duke
parents:
diff changeset
950 // If the creator called set priority before we started,
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
951 // we need to call set_native_priority now that we have an lwp.
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
952 // We used to get the priority from thr_getprio (we called
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
953 // thr_setprio way back in create_thread) and pass it to
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
954 // set_native_priority, but Solaris scales the priority
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
955 // in java_to_os_priority, so when we read it back here,
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
956 // we pass trash to set_native_priority instead of what's
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
957 // in java_to_os_priority. So we save the native priority
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
958 // in the osThread and recall it here.
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
959
0
a61af66fc99e Initial load
duke
parents:
diff changeset
960 if ( osthr->thread_id() != -1 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
961 if ( UseThreadPriorities ) {
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
962 int prio = osthr->native_priority();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
963 if (ThreadPriorityVerbose) {
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
964 tty->print_cr("Starting Thread " INTPTR_FORMAT ", LWP is "
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
965 INTPTR_FORMAT ", setting priority: %d\n",
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
966 osthr->thread_id(), osthr->lwp_id(), prio);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
967 }
a61af66fc99e Initial load
duke
parents:
diff changeset
968 os::set_native_priority(thread, prio);
a61af66fc99e Initial load
duke
parents:
diff changeset
969 }
a61af66fc99e Initial load
duke
parents:
diff changeset
970 } else if (ThreadPriorityVerbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
971 warning("Can't set priority in _start routine, thread id hasn't been set\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
972 }
a61af66fc99e Initial load
duke
parents:
diff changeset
973
a61af66fc99e Initial load
duke
parents:
diff changeset
974 assert(osthr->get_state() == RUNNABLE, "invalid os thread state");
a61af66fc99e Initial load
duke
parents:
diff changeset
975
a61af66fc99e Initial load
duke
parents:
diff changeset
976 // initialize signal mask for this thread
a61af66fc99e Initial load
duke
parents:
diff changeset
977 os::Solaris::hotspot_sigmask(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
978
a61af66fc99e Initial load
duke
parents:
diff changeset
979 thread->run();
a61af66fc99e Initial load
duke
parents:
diff changeset
980
a61af66fc99e Initial load
duke
parents:
diff changeset
981 // One less thread is executing
a61af66fc99e Initial load
duke
parents:
diff changeset
982 // When the VMThread gets here, the main thread may have already exited
a61af66fc99e Initial load
duke
parents:
diff changeset
983 // which frees the CodeHeap containing the Atomic::dec code
a61af66fc99e Initial load
duke
parents:
diff changeset
984 if (thread != VMThread::vm_thread() && VMThread::vm_thread() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
985 Atomic::dec(&os::Solaris::_os_thread_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
986 }
a61af66fc99e Initial load
duke
parents:
diff changeset
987
a61af66fc99e Initial load
duke
parents:
diff changeset
988 if (UseDetachedThreads) {
a61af66fc99e Initial load
duke
parents:
diff changeset
989 thr_exit(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
990 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
991 }
a61af66fc99e Initial load
duke
parents:
diff changeset
992 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
993 }
a61af66fc99e Initial load
duke
parents:
diff changeset
994
a61af66fc99e Initial load
duke
parents:
diff changeset
995 static OSThread* create_os_thread(Thread* thread, thread_t thread_id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
996 // Allocate the OSThread object
a61af66fc99e Initial load
duke
parents:
diff changeset
997 OSThread* osthread = new OSThread(NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
998 if (osthread == NULL) return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
999
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 // Store info on the Solaris thread into the OSThread
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 osthread->set_thread_id(thread_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 osthread->set_lwp_id(_lwp_self());
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 thread->_schedctl = (void *) schedctl_init () ;
a61af66fc99e Initial load
duke
parents:
diff changeset
1004
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 if (UseNUMA) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 int lgrp_id = os::numa_get_group_id();
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 if (lgrp_id != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 thread->set_lgrp_id(lgrp_id);
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1011
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 if ( ThreadPriorityVerbose ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 tty->print_cr("In create_os_thread, Thread " INTPTR_FORMAT ", LWP is " INTPTR_FORMAT "\n",
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 osthread->thread_id(), osthread->lwp_id() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1016
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 // Initial thread state is INITIALIZED, not SUSPENDED
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 osthread->set_state(INITIALIZED);
a61af66fc99e Initial load
duke
parents:
diff changeset
1019
a61af66fc99e Initial load
duke
parents:
diff changeset
1020 return osthread;
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1022
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 void os::Solaris::hotspot_sigmask(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1024
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 //Save caller's signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 sigset_t sigmask;
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 thr_sigsetmask(SIG_SETMASK, NULL, &sigmask);
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 OSThread *osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 osthread->set_caller_sigmask(sigmask);
a61af66fc99e Initial load
duke
parents:
diff changeset
1030
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 thr_sigsetmask(SIG_UNBLOCK, os::Solaris::unblocked_signals(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 if (!ReduceSignalUsage) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 if (thread->is_VM_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 // Only the VM thread handles BREAK_SIGNAL ...
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 thr_sigsetmask(SIG_UNBLOCK, vm_signals(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 // ... all other threads block BREAK_SIGNAL
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 assert(!sigismember(vm_signals(), SIGINT), "SIGINT should not be blocked");
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 thr_sigsetmask(SIG_BLOCK, vm_signals(), NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1043
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 bool os::create_attached_thread(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 thread->verify_not_published();
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 OSThread* osthread = create_os_thread(thread, thr_self());
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 if (osthread == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1052
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 // Initial thread state is RUNNABLE
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 osthread->set_state(RUNNABLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 thread->set_osthread(osthread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1056
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 // initialize signal mask for this thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 // and save the caller's signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 os::Solaris::hotspot_sigmask(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1060
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1063
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 bool os::create_main_thread(JavaThread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 thread->verify_not_published();
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 if (_starting_thread == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 _starting_thread = create_os_thread(thread, main_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 if (_starting_thread == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1074
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 // The primodial thread is runnable from the start
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 _starting_thread->set_state(RUNNABLE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1077
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 thread->set_osthread(_starting_thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1079
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 // initialize signal mask for this thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 // and save the caller's signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 os::Solaris::hotspot_sigmask(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1083
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1086
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 // _T2_libthread is true if we believe we are running with the newer
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 // SunSoft lwp/libthread.so (2.8 patch, 2.9 default)
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 bool os::Solaris::_T2_libthread = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1090
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 bool os::create_thread(Thread* thread, ThreadType thr_type, size_t stack_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 // Allocate the OSThread object
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 OSThread* osthread = new OSThread(NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 if (osthread == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1097
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 if ( ThreadPriorityVerbose ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 char *thrtyp;
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 switch ( thr_type ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 case vm_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 thrtyp = (char *)"vm";
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 case cgc_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 thrtyp = (char *)"cgc";
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 case pgc_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 thrtyp = (char *)"pgc";
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 case java_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 thrtyp = (char *)"java";
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 case compiler_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 thrtyp = (char *)"compiler";
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 case watcher_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1117 thrtyp = (char *)"watcher";
a61af66fc99e Initial load
duke
parents:
diff changeset
1118 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1119 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
1120 thrtyp = (char *)"unknown";
a61af66fc99e Initial load
duke
parents:
diff changeset
1121 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 tty->print_cr("In create_thread, creating a %s thread\n", thrtyp);
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1125
a61af66fc99e Initial load
duke
parents:
diff changeset
1126 // Calculate stack size if it's not specified by caller.
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 if (stack_size == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 // The default stack size 1M (2M for LP64).
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 stack_size = (BytesPerWord >> 2) * K * K;
a61af66fc99e Initial load
duke
parents:
diff changeset
1130
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 switch (thr_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 case os::java_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 // Java threads use ThreadStackSize which default value can be changed with the flag -Xss
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 if (JavaThread::stack_size_at_create() > 0) stack_size = JavaThread::stack_size_at_create();
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 case os::compiler_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 if (CompilerThreadStackSize > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 stack_size = (size_t)(CompilerThreadStackSize * K);
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 } // else fall through:
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 // use VMThreadStackSize if CompilerThreadStackSize is not defined
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 case os::vm_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 case os::pgc_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 case os::cgc_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 case os::watcher_thread:
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 if (VMThreadStackSize > 0) stack_size = (size_t)(VMThreadStackSize * K);
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 stack_size = MAX2(stack_size, os::Solaris::min_stack_allowed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1151
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 // Initial state is ALLOCATED but not INITIALIZED
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 osthread->set_state(ALLOCATED);
a61af66fc99e Initial load
duke
parents:
diff changeset
1154
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 if (os::Solaris::_os_thread_count > os::Solaris::_os_thread_limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1156 // We got lots of threads. Check if we still have some address space left.
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 // Need to be at least 5Mb of unreserved address space. We do check by
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 // trying to reserve some.
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 const size_t VirtualMemoryBangSize = 20*K*K;
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 char* mem = os::reserve_memory(VirtualMemoryBangSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 if (mem == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 delete osthread;
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 // Release the memory again
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 os::release_memory(mem, VirtualMemoryBangSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1169
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 // Setup osthread because the child thread may need it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 thread->set_osthread(osthread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1172
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 // Create the Solaris thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 // explicit THR_BOUND for T2_libthread case in case
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 // that assumption is not accurate, but our alternate signal stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 // handling is based on it which must have bound threads
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 thread_t tid = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1178 long flags = (UseDetachedThreads ? THR_DETACHED : 0) | THR_SUSPENDED
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 | ((UseBoundThreads || os::Solaris::T2_libthread() ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 (thr_type == vm_thread) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 (thr_type == cgc_thread) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 (thr_type == pgc_thread) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 (thr_type == compiler_thread && BackgroundCompilation)) ?
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 THR_BOUND : 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
1185 int status;
a61af66fc99e Initial load
duke
parents:
diff changeset
1186
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 // 4376845 -- libthread/kernel don't provide enough LWPs to utilize all CPUs.
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 // On multiprocessors systems, libthread sometimes under-provisions our
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 // process with LWPs. On a 30-way systems, for instance, we could have
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 // 50 user-level threads in ready state and only 2 or 3 LWPs assigned
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 // to our process. This can result in under utilization of PEs.
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 // I suspect the problem is related to libthread's LWP
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 // pool management and to the kernel's SIGBLOCKING "last LWP parked"
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 // upcall policy.
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 // The following code is palliative -- it attempts to ensure that our
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 // process has sufficient LWPs to take advantage of multiple PEs.
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 // Proper long-term cures include using user-level threads bound to LWPs
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 // (THR_BOUND) or using LWP-based synchronization. Note that there is a
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 // slight timing window with respect to sampling _os_thread_count, but
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 // the race is benign. Also, we should periodically recompute
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 // _processors_online as the min of SC_NPROCESSORS_ONLN and the
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 // the number of PEs in our partition. You might be tempted to use
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 // THR_NEW_LWP here, but I'd recommend against it as that could
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 // result in undesirable growth of the libthread's LWP pool.
a61af66fc99e Initial load
duke
parents:
diff changeset
1207 // The fix below isn't sufficient; for instance, it doesn't take into count
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 // LWPs parked on IO. It does, however, help certain CPU-bound benchmarks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 // Some pathologies this scheme doesn't handle:
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 // * Threads can block, releasing the LWPs. The LWPs can age out.
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 // When a large number of threads become ready again there aren't
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 // enough LWPs available to service them. This can occur when the
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 // number of ready threads oscillates.
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 // * LWPs/Threads park on IO, thus taking the LWP out of circulation.
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 // Finally, we should call thr_setconcurrency() periodically to refresh
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 // the LWP pool and thwart the LWP age-out mechanism.
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 // The "+3" term provides a little slop -- we want to slightly overprovision.
a61af66fc99e Initial load
duke
parents:
diff changeset
1220
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 if (AdjustConcurrency && os::Solaris::_os_thread_count < (_processors_online+3)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 if (!(flags & THR_BOUND)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 thr_setconcurrency (os::Solaris::_os_thread_count); // avoid starvation
a61af66fc99e Initial load
duke
parents:
diff changeset
1224 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1226 // Although this doesn't hurt, we should warn of undefined behavior
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 // when using unbound T1 threads with schedctl(). This should never
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 // happen, as the compiler and VM threads are always created bound
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 DEBUG_ONLY(
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 if ((VMThreadHintNoPreempt || CompilerThreadHintNoPreempt) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 (!os::Solaris::T2_libthread() && (!(flags & THR_BOUND))) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 ((thr_type == vm_thread) || (thr_type == cgc_thread) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 (thr_type == pgc_thread) || (thr_type == compiler_thread && BackgroundCompilation))) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 warning("schedctl behavior undefined when Compiler/VM/GC Threads are Unbound");
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 );
a61af66fc99e Initial load
duke
parents:
diff changeset
1237
a61af66fc99e Initial load
duke
parents:
diff changeset
1238
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 // Mark that we don't have an lwp or thread id yet.
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 // In case we attempt to set the priority before the thread starts.
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 osthread->set_lwp_id(-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 osthread->set_thread_id(-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1243
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 status = thr_create(NULL, stack_size, java_start, thread, flags, &tid);
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 if (status != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1246 if (PrintMiscellaneous && (Verbose || WizardMode)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 perror("os::create_thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1249 thread->set_osthread(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 // Need to clean up stuff we've allocated so far
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 delete osthread;
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1254
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 Atomic::inc(&os::Solaris::_os_thread_count);
a61af66fc99e Initial load
duke
parents:
diff changeset
1256
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 // Store info on the Solaris thread into the OSThread
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 osthread->set_thread_id(tid);
a61af66fc99e Initial load
duke
parents:
diff changeset
1259
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 // Remember that we created this thread so we can set priority on it
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 osthread->set_vm_created();
a61af66fc99e Initial load
duke
parents:
diff changeset
1262
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
1263 // Set the default thread priority. If using bound threads, setting
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
1264 // lwp priority will be delayed until thread start.
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
1265 set_native_priority(thread,
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
1266 DefaultThreadPriority == -1 ?
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 java_to_os_priority[NormPriority] :
a61af66fc99e Initial load
duke
parents:
diff changeset
1268 DefaultThreadPriority);
a61af66fc99e Initial load
duke
parents:
diff changeset
1269
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 // Initial thread state is INITIALIZED, not SUSPENDED
a61af66fc99e Initial load
duke
parents:
diff changeset
1271 osthread->set_state(INITIALIZED);
a61af66fc99e Initial load
duke
parents:
diff changeset
1272
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 // The thread is returned suspended (in state INITIALIZED), and is started higher up in the call chain
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1276
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 /* defined for >= Solaris 10. This allows builds on earlier versions
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 * of Solaris to take advantage of the newly reserved Solaris JVM signals
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 * With SIGJVM1, SIGJVM2, INTERRUPT_SIGNAL is SIGJVM1, ASYNC_SIGNAL is SIGJVM2
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 * and -XX:+UseAltSigs does nothing since these should have no conflict
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 */
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 #if !defined(SIGJVM1)
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 #define SIGJVM1 39
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 #define SIGJVM2 40
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1286
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 debug_only(static bool signal_sets_initialized = false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 static sigset_t unblocked_sigs, vm_sigs, allowdebug_blocked_sigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 int os::Solaris::_SIGinterrupt = INTERRUPT_SIGNAL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 int os::Solaris::_SIGasync = ASYNC_SIGNAL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1291
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 bool os::Solaris::is_sig_ignored(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 struct sigaction oact;
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 sigaction(sig, (struct sigaction*)NULL, &oact);
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 void* ohlr = oact.sa_sigaction ? CAST_FROM_FN_PTR(void*, oact.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 : CAST_FROM_FN_PTR(void*, oact.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 if (ohlr == CAST_FROM_FN_PTR(void*, SIG_IGN))
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 else
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1302
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 // Note: SIGRTMIN is a macro that calls sysconf() so it will
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 // dynamically detect SIGRTMIN value for the system at runtime, not buildtime
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 static bool isJVM1available() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 return SIGJVM1 < SIGRTMIN;
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1308
a61af66fc99e Initial load
duke
parents:
diff changeset
1309 void os::Solaris::signal_sets_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 // Should also have an assertion stating we are still single-threaded.
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 assert(!signal_sets_initialized, "Already initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 // Fill in signals that are necessarily unblocked for all threads in
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 // the VM. Currently, we unblock the following signals:
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 // SHUTDOWN{1,2,3}_SIGNAL: for shutdown hooks support (unless over-ridden
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 // by -Xrs (=ReduceSignalUsage));
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 // BREAK_SIGNAL which is unblocked only by the VM thread and blocked by all
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 // other threads. The "ReduceSignalUsage" boolean tells us not to alter
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 // the dispositions or masks wrt these signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 // Programs embedding the VM that want to use the above signals for their
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 // own purposes must, at this time, use the "-Xrs" option to prevent
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 // interference with shutdown hooks and BREAK_SIGNAL thread dumping.
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 // (See bug 4345157, and other related bugs).
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 // In reality, though, unblocking these signals is really a nop, since
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 // these signals are not blocked by default.
a61af66fc99e Initial load
duke
parents:
diff changeset
1325 sigemptyset(&unblocked_sigs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 sigemptyset(&allowdebug_blocked_sigs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 sigaddset(&unblocked_sigs, SIGILL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 sigaddset(&unblocked_sigs, SIGSEGV);
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 sigaddset(&unblocked_sigs, SIGBUS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 sigaddset(&unblocked_sigs, SIGFPE);
a61af66fc99e Initial load
duke
parents:
diff changeset
1331
a61af66fc99e Initial load
duke
parents:
diff changeset
1332 if (isJVM1available) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 os::Solaris::set_SIGinterrupt(SIGJVM1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 os::Solaris::set_SIGasync(SIGJVM2);
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 } else if (UseAltSigs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 os::Solaris::set_SIGinterrupt(ALT_INTERRUPT_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 os::Solaris::set_SIGasync(ALT_ASYNC_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 os::Solaris::set_SIGinterrupt(INTERRUPT_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 os::Solaris::set_SIGasync(ASYNC_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1342
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 sigaddset(&unblocked_sigs, os::Solaris::SIGinterrupt());
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 sigaddset(&unblocked_sigs, os::Solaris::SIGasync());
a61af66fc99e Initial load
duke
parents:
diff changeset
1345
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 if (!ReduceSignalUsage) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 if (!os::Solaris::is_sig_ignored(SHUTDOWN1_SIGNAL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 sigaddset(&unblocked_sigs, SHUTDOWN1_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1349 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN1_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1351 if (!os::Solaris::is_sig_ignored(SHUTDOWN2_SIGNAL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 sigaddset(&unblocked_sigs, SHUTDOWN2_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1353 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN2_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1354 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 if (!os::Solaris::is_sig_ignored(SHUTDOWN3_SIGNAL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 sigaddset(&unblocked_sigs, SHUTDOWN3_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1357 sigaddset(&allowdebug_blocked_sigs, SHUTDOWN3_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 // Fill in signals that are blocked by all but the VM thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 sigemptyset(&vm_sigs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 if (!ReduceSignalUsage)
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 sigaddset(&vm_sigs, BREAK_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 debug_only(signal_sets_initialized = true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1365
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 // For diagnostics only used in run_periodic_checks
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 sigemptyset(&check_signal_done);
a61af66fc99e Initial load
duke
parents:
diff changeset
1368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1369
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 // These are signals that are unblocked while a thread is running Java.
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 // (For some reason, they get blocked by default.)
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 sigset_t* os::Solaris::unblocked_signals() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 assert(signal_sets_initialized, "Not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 return &unblocked_sigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1376
a61af66fc99e Initial load
duke
parents:
diff changeset
1377 // These are the signals that are blocked while a (non-VM) thread is
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 // running Java. Only the VM thread handles these signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
1379 sigset_t* os::Solaris::vm_signals() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 assert(signal_sets_initialized, "Not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 return &vm_sigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1383
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 // These are signals that are blocked during cond_wait to allow debugger in
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 sigset_t* os::Solaris::allowdebug_blocked_signals() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 assert(signal_sets_initialized, "Not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 return &allowdebug_blocked_sigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1389
2068
1e637defdda6 6961186: Better VM handling of unexpected exceptions from application native code
zgu
parents: 2023
diff changeset
1390
1e637defdda6 6961186: Better VM handling of unexpected exceptions from application native code
zgu
parents: 2023
diff changeset
1391 void _handle_uncaught_cxx_exception() {
1e637defdda6 6961186: Better VM handling of unexpected exceptions from application native code
zgu
parents: 2023
diff changeset
1392 VMError err("An uncaught C++ exception");
1e637defdda6 6961186: Better VM handling of unexpected exceptions from application native code
zgu
parents: 2023
diff changeset
1393 err.report_and_die();
1e637defdda6 6961186: Better VM handling of unexpected exceptions from application native code
zgu
parents: 2023
diff changeset
1394 }
1e637defdda6 6961186: Better VM handling of unexpected exceptions from application native code
zgu
parents: 2023
diff changeset
1395
1e637defdda6 6961186: Better VM handling of unexpected exceptions from application native code
zgu
parents: 2023
diff changeset
1396
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 // First crack at OS-specific initialization, from inside the new thread.
6768
716e6ef4482a 7190089: NMT ON: NMT failed assertion on thread's stack base address
zgu
parents: 6725
diff changeset
1398 void os::initialize_thread(Thread* thr) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 int r = thr_main() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 guarantee (r == 0 || r == 1, "CR6501650 or CR6493689") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 if (r) {
6768
716e6ef4482a 7190089: NMT ON: NMT failed assertion on thread's stack base address
zgu
parents: 6725
diff changeset
1402 JavaThread* jt = (JavaThread *)thr;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 assert(jt != NULL,"Sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1404 size_t stack_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 address base = jt->stack_base();
a61af66fc99e Initial load
duke
parents:
diff changeset
1406 if (Arguments::created_by_java_launcher()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 // Use 2MB to allow for Solaris 7 64 bit mode.
a61af66fc99e Initial load
duke
parents:
diff changeset
1408 stack_size = JavaThread::stack_size_at_create() == 0
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 ? 2048*K : JavaThread::stack_size_at_create();
a61af66fc99e Initial load
duke
parents:
diff changeset
1410
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 // There are rare cases when we may have already used more than
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 // the basic stack size allotment before this method is invoked.
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 // Attempt to allow for a normally sized java_stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 size_t current_stack_offset = (size_t)(base - (address)&stack_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 stack_size += ReservedSpace::page_align_size_down(current_stack_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 // 6269555: If we were not created by a Java launcher, i.e. if we are
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 // running embedded in a native application, treat the primordial thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 // as much like a native attached thread as possible. This means using
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 // the current stack size from thr_stksegment(), unless it is too large
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 // to reliably setup guard pages. A reasonable max size is 8MB.
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 size_t current_size = current_stack_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 // This should never happen, but just in case....
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 if (current_size == 0) current_size = 2 * K * K;
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 stack_size = current_size > (8 * K * K) ? (8 * K * K) : current_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 address bottom = (address)align_size_up((intptr_t)(base - stack_size), os::vm_page_size());;
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 stack_size = (size_t)(base - bottom);
a61af66fc99e Initial load
duke
parents:
diff changeset
1429
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 assert(stack_size > 0, "Stack size calculation problem");
a61af66fc99e Initial load
duke
parents:
diff changeset
1431
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 if (stack_size > jt->stack_size()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 NOT_PRODUCT(
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 struct rlimit limits;
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 getrlimit(RLIMIT_STACK, &limits);
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 size_t size = adjust_stack_size(base, (size_t)limits.rlim_cur);
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 assert(size >= jt->stack_size(), "Stack size problem in main thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 )
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 tty->print_cr(
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 "Stack size of %d Kb exceeds current limit of %d Kb.\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 "(Stack sizes are rounded up to a multiple of the system page size.)\n"
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 "See limit(1) to increase the stack size limit.",
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 stack_size / K, jt->stack_size() / K);
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 vm_exit(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 assert(jt->stack_size() >= stack_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 "Attempt to map more stack than was allocated");
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 jt->set_stack_size(stack_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1450
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 // 5/22/01: Right now alternate signal stacks do not handle
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 // throwing stack overflow exceptions, see bug 4463178
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 // Until a fix is found for this, T2 will NOT imply alternate signal
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 // stacks.
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 // If using T2 libthread threads, install an alternate signal stack.
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 // Because alternate stacks associate with LWPs on Solaris,
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 // see sigaltstack(2), if using UNBOUND threads, or if UseBoundThreads
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 // we prefer to explicitly stack bang.
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 // If not using T2 libthread, but using UseBoundThreads any threads
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 // (primordial thread, jni_attachCurrentThread) we do not create,
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 // probably are not bound, therefore they can not have an alternate
a61af66fc99e Initial load
duke
parents:
diff changeset
1462 // signal stack. Since our stack banging code is generated and
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 // is shared across threads, all threads must be bound to allow
a61af66fc99e Initial load
duke
parents:
diff changeset
1464 // using alternate signal stacks. The alternative is to interpose
a61af66fc99e Initial load
duke
parents:
diff changeset
1465 // on _lwp_create to associate an alt sig stack with each LWP,
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 // and this could be a problem when the JVM is embedded.
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 // We would prefer to use alternate signal stacks with T2
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 // Since there is currently no accurate way to detect T2
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 // we do not. Assuming T2 when running T1 causes sig 11s or assertions
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 // on installing alternate signal stacks
a61af66fc99e Initial load
duke
parents:
diff changeset
1471
a61af66fc99e Initial load
duke
parents:
diff changeset
1472
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 // 05/09/03: removed alternate signal stack support for Solaris
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 // The alternate signal stack mechanism is no longer needed to
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 // handle stack overflow. This is now handled by allocating
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 // guard pages (red zone) and stackbanging.
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 // Initially the alternate signal stack mechanism was removed because
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 // it did not work with T1 llibthread. Alternate
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 // signal stacks MUST have all threads bound to lwps. Applications
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 // can create their own threads and attach them without their being
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 // bound under T1. This is frequently the case for the primordial thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 // If we were ever to reenable this mechanism we would need to
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 // use the dynamic check for T2 libthread.
a61af66fc99e Initial load
duke
parents:
diff changeset
1484
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 os::Solaris::init_thread_fpu_state();
2068
1e637defdda6 6961186: Better VM handling of unexpected exceptions from application native code
zgu
parents: 2023
diff changeset
1486 std::set_terminate(_handle_uncaught_cxx_exception);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1488
a61af66fc99e Initial load
duke
parents:
diff changeset
1489
a61af66fc99e Initial load
duke
parents:
diff changeset
1490
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 // Free Solaris resources related to the OSThread
a61af66fc99e Initial load
duke
parents:
diff changeset
1492 void os::free_thread(OSThread* osthread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 assert(osthread != NULL, "os::free_thread but osthread not set");
a61af66fc99e Initial load
duke
parents:
diff changeset
1494
a61af66fc99e Initial load
duke
parents:
diff changeset
1495
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 // We are told to free resources of the argument thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 // but we can only really operate on the current thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 // The main thread must take the VMThread down synchronously
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 // before the main thread exits and frees up CodeHeap
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 guarantee((Thread::current()->osthread() == osthread
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 || (osthread == VMThread::vm_thread()->osthread())), "os::free_thread but not current thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
1502 if (Thread::current()->osthread() == osthread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 // Restore caller's signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 sigset_t sigmask = osthread->caller_sigmask();
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 thr_sigsetmask(SIG_SETMASK, &sigmask, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1507 delete osthread;
a61af66fc99e Initial load
duke
parents:
diff changeset
1508 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1509
a61af66fc99e Initial load
duke
parents:
diff changeset
1510 void os::pd_start_thread(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 int status = thr_continue(thread->osthread()->thread_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 assert_status(status == 0, status, "thr_continue failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1514
a61af66fc99e Initial load
duke
parents:
diff changeset
1515
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 intx os::current_thread_id() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1517 return (intx)thr_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1519
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 static pid_t _initial_pid = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1521
a61af66fc99e Initial load
duke
parents:
diff changeset
1522 int os::current_process_id() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 return (int)(_initial_pid ? _initial_pid : getpid());
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1525
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 int os::allocate_thread_local_storage() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 // %%% in Win32 this allocates a memory segment pointed to by a
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 // register. Dan Stein can implement a similar feature in
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 // Solaris. Alternatively, the VM can do the same thing
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 // explicitly: malloc some storage and keep the pointer in a
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 // register (which is part of the thread's context) (or keep it
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 // in TLS).
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 // %%% In current versions of Solaris, thr_self and TSD can
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 // be accessed via short sequences of displaced indirections.
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 // The value of thr_self is available as %g7(36).
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 // The value of thr_getspecific(k) is stored in %g7(12)(4)(k*4-4),
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 // assuming that the current thread already has a value bound to k.
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 // It may be worth experimenting with such access patterns,
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 // and later having the parameters formally exported from a Solaris
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 // interface. I think, however, that it will be faster to
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 // maintain the invariant that %g2 always contains the
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 // JavaThread in Java code, and have stubs simply
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 // treat %g2 as a caller-save register, preserving it in a %lN.
a61af66fc99e Initial load
duke
parents:
diff changeset
1544 thread_key_t tk;
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 if (thr_keycreate( &tk, NULL ) )
1490
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
1546 fatal(err_msg("os::allocate_thread_local_storage: thr_keycreate failed "
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
1547 "(%s)", strerror(errno)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 return int(tk);
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1550
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 void os::free_thread_local_storage(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 // %%% don't think we need anything here
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 // if ( pthread_key_delete((pthread_key_t) tk) )
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 // fatal("os::free_thread_local_storage: pthread_key_delete failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1556
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 #define SMALLINT 32 // libthread allocate for tsd_common is a version specific
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 // small number - point is NO swap space available
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 void os::thread_local_storage_at_put(int index, void* value) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 // %%% this is used only in threadLocalStorage.cpp
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 if (thr_setspecific((thread_key_t)index, value)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 if (errno == ENOMEM) {
10161
746b070f5022 8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents: 9062
diff changeset
1563 vm_exit_out_of_memory(SMALLINT, OOM_MALLOC_ERROR,
746b070f5022 8011661: Insufficient memory message says "malloc" when sometimes it should say "mmap"
ccheung
parents: 9062
diff changeset
1564 "thr_setspecific: out of swap space");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 } else {
1490
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
1566 fatal(err_msg("os::thread_local_storage_at_put: thr_setspecific failed "
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
1567 "(%s)", strerror(errno)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 ThreadLocalStorage::set_thread_in_slot ((Thread *) value) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1573
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 // This function could be called before TLS is initialized, for example, when
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 // VM receives an async signal or when VM causes a fatal error during
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 // initialization. Return NULL if thr_getspecific() fails.
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 void* os::thread_local_storage_at(int index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 // %%% this is used only in threadLocalStorage.cpp
a61af66fc99e Initial load
duke
parents:
diff changeset
1579 void* r = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 return thr_getspecific((thread_key_t)index, &r) != 0 ? NULL : r;
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1582
a61af66fc99e Initial load
duke
parents:
diff changeset
1583
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 // gethrtime can move backwards if read from one cpu and then a different cpu
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 // getTimeNanos is guaranteed to not move backward on Solaris
a61af66fc99e Initial load
duke
parents:
diff changeset
1586 // local spinloop created as faster for a CAS on an int than
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 // a CAS on a 64bit jlong. Also Atomic::cmpxchg for jlong is not
a61af66fc99e Initial load
duke
parents:
diff changeset
1588 // supported on sparc v8 or pre supports_cx8 intel boxes.
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 // oldgetTimeNanos for systems which do not support CAS on 64bit jlong
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 // i.e. sparc v8 and pre supports_cx8 (i486) intel boxes
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 inline hrtime_t oldgetTimeNanos() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1592 int gotlock = LOCK_INVALID;
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 hrtime_t newtime = gethrtime();
a61af66fc99e Initial load
duke
parents:
diff changeset
1594
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1596 // grab lock for max_hrtime
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 int curlock = max_hrtime_lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
1598 if (curlock & LOCK_BUSY) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 if (gotlock = Atomic::cmpxchg(LOCK_BUSY, &max_hrtime_lock, LOCK_FREE) != LOCK_FREE) continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 if (newtime > max_hrtime) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 max_hrtime = newtime;
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 newtime = max_hrtime;
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1605 // release lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 max_hrtime_lock = LOCK_FREE;
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 return newtime;
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 // gethrtime can move backwards if read from one cpu and then a different cpu
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 // getTimeNanos is guaranteed to not move backward on Solaris
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 inline hrtime_t getTimeNanos() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 if (VM_Version::supports_cx8()) {
499
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1614 const hrtime_t now = gethrtime();
894
665be97e8704 6863420: os::javaTimeNanos() go backward on Solaris x86
kvn
parents: 691
diff changeset
1615 // Use atomic long load since 32-bit x86 uses 2 registers to keep long.
665be97e8704 6863420: os::javaTimeNanos() go backward on Solaris x86
kvn
parents: 691
diff changeset
1616 const hrtime_t prev = Atomic::load((volatile jlong*)&max_hrtime);
499
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1617 if (now <= prev) return prev; // same or retrograde time;
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1618 const hrtime_t obsv = Atomic::cmpxchg(now, (volatile jlong*)&max_hrtime, prev);
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1619 assert(obsv >= prev, "invariant"); // Monotonicity
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1620 // If the CAS succeeded then we're done and return "now".
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1621 // If the CAS failed and the observed value "obs" is >= now then
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1622 // we should return "obs". If the CAS failed and now > obs > prv then
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1623 // some other thread raced this thread and installed a new value, in which case
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1624 // we could either (a) retry the entire operation, (b) retry trying to install now
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1625 // or (c) just return obs. We use (c). No loop is required although in some cases
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1626 // we might discard a higher "now" value in deference to a slightly lower but freshly
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1627 // installed obs value. That's entirely benign -- it admits no new orderings compared
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1628 // to (a) or (b) -- and greatly reduces coherence traffic.
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1629 // We might also condition (c) on the magnitude of the delta between obs and now.
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1630 // Avoiding excessive CAS operations to hot RW locations is critical.
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1631 // See http://blogs.sun.com/dave/entry/cas_and_cache_trivia_invalidate
8a25d96bcf08 6784100: getTimeNanos - CAS reduction
xlu
parents: 477
diff changeset
1632 return (prev == obsv) ? now : obsv ;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 return oldgetTimeNanos();
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1637
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 // Time since start-up in seconds to a fine granularity.
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 // Used by VMSelfDestructTimer and the MemProfiler.
a61af66fc99e Initial load
duke
parents:
diff changeset
1640 double os::elapsedTime() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 return (double)(getTimeNanos() - first_hrtime) / (double)hrtime_hz;
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1643
a61af66fc99e Initial load
duke
parents:
diff changeset
1644 jlong os::elapsed_counter() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 return (jlong)(getTimeNanos() - first_hrtime);
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1647
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 jlong os::elapsed_frequency() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 return hrtime_hz;
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1651
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 // Return the real, user, and system times in seconds from an
a61af66fc99e Initial load
duke
parents:
diff changeset
1653 // arbitrary fixed point in the past.
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 bool os::getTimesSecs(double* process_real_time,
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 double* process_user_time,
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 double* process_system_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 struct tms ticks;
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 clock_t real_ticks = times(&ticks);
a61af66fc99e Initial load
duke
parents:
diff changeset
1659
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 if (real_ticks == (clock_t) (-1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 double ticks_per_second = (double) clock_tics_per_sec;
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 *process_user_time = ((double) ticks.tms_utime) / ticks_per_second;
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 *process_system_time = ((double) ticks.tms_stime) / ticks_per_second;
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 // For consistency return the real time from getTimeNanos()
a61af66fc99e Initial load
duke
parents:
diff changeset
1667 // converted to seconds.
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 *process_real_time = ((double) getTimeNanos()) / ((double) NANOUNITS);
a61af66fc99e Initial load
duke
parents:
diff changeset
1669
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1673
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1674 bool os::supports_vtime() { return true; }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1675
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1676 bool os::enable_vtime() {
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1677 int fd = ::open("/proc/self/ctl", O_WRONLY);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1678 if (fd == -1)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1679 return false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1680
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1681 long cmd[] = { PCSET, PR_MSACCT };
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1682 int res = ::write(fd, cmd, sizeof(long) * 2);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1683 ::close(fd);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1684 if (res != sizeof(long) * 2)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1685 return false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1686
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1687 return true;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1688 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1689
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1690 bool os::vtime_enabled() {
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1691 int fd = ::open("/proc/self/status", O_RDONLY);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1692 if (fd == -1)
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1693 return false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1694
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1695 pstatus_t status;
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1696 int res = os::read(fd, (void*) &status, sizeof(pstatus_t));
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
1697 ::close(fd);
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1698 if (res != sizeof(pstatus_t))
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1699 return false;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1700
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1701 return status.pr_flags & PR_MSACCT;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1702 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1703
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1704 double os::elapsedVTime() {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1705 return (double)gethrvtime() / (double)hrtime_hz;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1706 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
1707
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 // Used internally for comparisons only
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 // getTimeMillis guaranteed to not move backwards on Solaris
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 jlong getTimeMillis() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 jlong nanotime = getTimeNanos();
4712
e7dead7e90af 7117303: VM uses non-monotonic time source and complains that it is non-monotonic
johnc
parents: 4082
diff changeset
1712 return (jlong)(nanotime / NANOSECS_PER_MILLISEC);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1714
61
5a76ab815e34 6667833: Remove CacheTimeMillis
sbohne
parents: 60
diff changeset
1715 // Must return millis since Jan 1 1970 for JVM_CurrentTimeMillis
5a76ab815e34 6667833: Remove CacheTimeMillis
sbohne
parents: 60
diff changeset
1716 jlong os::javaTimeMillis() {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 timeval t;
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 if (gettimeofday( &t, NULL) == -1)
1490
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
1719 fatal(err_msg("os::javaTimeMillis: gettimeofday (%s)", strerror(errno)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 return jlong(t.tv_sec) * 1000 + jlong(t.tv_usec) / 1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1722
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 jlong os::javaTimeNanos() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 return (jlong)getTimeNanos();
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1726
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 void os::javaTimeNanos_info(jvmtiTimerInfo *info_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 info_ptr->max_value = ALL_64_BITS; // gethrtime() uses all 64 bits
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 info_ptr->may_skip_backward = false; // not subject to resetting or drifting
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 info_ptr->may_skip_forward = false; // not subject to resetting or drifting
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 info_ptr->kind = JVMTI_TIMER_ELAPSED; // elapsed not CPU time
a61af66fc99e Initial load
duke
parents:
diff changeset
1732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1733
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 char * os::local_time_string(char *buf, size_t buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 struct tm t;
a61af66fc99e Initial load
duke
parents:
diff changeset
1736 time_t long_time;
a61af66fc99e Initial load
duke
parents:
diff changeset
1737 time(&long_time);
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 localtime_r(&long_time, &t);
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 jio_snprintf(buf, buflen, "%d-%02d-%02d %02d:%02d:%02d",
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 t.tm_year + 1900, t.tm_mon + 1, t.tm_mday,
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 t.tm_hour, t.tm_min, t.tm_sec);
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 return buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1744
a61af66fc99e Initial load
duke
parents:
diff changeset
1745 // Note: os::shutdown() might be called very early during initialization, or
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 // called from signal handler. Before adding something to os::shutdown(), make
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 // sure it is async-safe and can handle partially initialized VM.
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 void os::shutdown() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1749
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 // allow PerfMemory to attempt cleanup of any persistent resources
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 perfMemory_exit();
a61af66fc99e Initial load
duke
parents:
diff changeset
1752
a61af66fc99e Initial load
duke
parents:
diff changeset
1753 // needs to remove object in file system
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 AttachListener::abort();
a61af66fc99e Initial load
duke
parents:
diff changeset
1755
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 // flush buffered output, finish log files
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 ostream_abort();
a61af66fc99e Initial load
duke
parents:
diff changeset
1758
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 // Check for abort hook
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 abort_hook_t abort_hook = Arguments::abort_hook();
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 if (abort_hook != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 abort_hook();
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1764 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1765
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 // Note: os::abort() might be called very early during initialization, or
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 // called from signal handler. Before adding something to os::abort(), make
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 // sure it is async-safe and can handle partially initialized VM.
a61af66fc99e Initial load
duke
parents:
diff changeset
1769 void os::abort(bool dump_core) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 os::shutdown();
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 if (dump_core) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 fdStream out(defaultStream::output_fd());
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 out.print_raw("Current thread is ");
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 char buf[16];
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 jio_snprintf(buf, sizeof(buf), UINTX_FORMAT, os::current_thread_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 out.print_raw_cr(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
1778 out.print_raw_cr("Dumping core ...");
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 ::abort(); // dump core (for debugging)
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1782
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 ::exit(1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1785
a61af66fc99e Initial load
duke
parents:
diff changeset
1786 // Die immediately, no exit hook, no abort hook, no cleanup.
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 void os::die() {
8066
b5e3ec9c69fa 8007779: os::die() on solaris should generate core file
sla
parents: 7629
diff changeset
1788 ::abort(); // dump core (for debugging)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1790
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 // unused
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 void os::set_error_file(const char *logfile) {}
a61af66fc99e Initial load
duke
parents:
diff changeset
1793
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 // DLL functions
a61af66fc99e Initial load
duke
parents:
diff changeset
1795
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 const char* os::dll_file_extension() { return ".so"; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1797
2130
34d64ad817f4 7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents: 2102
diff changeset
1798 // This must be hard coded because it's the system's temporary
34d64ad817f4 7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents: 2102
diff changeset
1799 // directory not the java application's temp directory, ala java.io.tmpdir.
34d64ad817f4 7009828: Fix for 6938627 breaks visualvm monitoring when -Djava.io.tmpdir is defined
coleenp
parents: 2102
diff changeset
1800 const char* os::get_temp_directory() { return "/tmp"; }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1801
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1802 static bool file_exists(const char* filename) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1803 struct stat statbuf;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1804 if (filename == NULL || strlen(filename) == 0) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1805 return false;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1806 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1807 return os::stat(filename, &statbuf) == 0;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1808 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1809
6966
6cb0d32b828b 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 6882
diff changeset
1810 bool os::dll_build_name(char* buffer, size_t buflen,
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1811 const char* pname, const char* fname) {
6966
6cb0d32b828b 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 6882
diff changeset
1812 bool retval = false;
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1813 const size_t pnamelen = pname ? strlen(pname) : 0;
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1814
6966
6cb0d32b828b 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 6882
diff changeset
1815 // Return error on buffer overflow.
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1816 if (pnamelen + strlen(fname) + 10 > (size_t) buflen) {
6966
6cb0d32b828b 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 6882
diff changeset
1817 return retval;
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1818 }
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1819
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1820 if (pnamelen == 0) {
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1821 snprintf(buffer, buflen, "lib%s.so", fname);
6966
6cb0d32b828b 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 6882
diff changeset
1822 retval = true;
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1823 } else if (strchr(pname, *os::path_separator()) != NULL) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1824 int n;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1825 char** pelements = split_path(pname, &n);
9059
17bf4d428955 8006103: [parfait] Possible null pointer dereference at hotspot/src/os/linux/vm/os_linux.cpp; os_windows.cpp; os_solaris.cpp; os_bsd.cpp
ccheung
parents: 8744
diff changeset
1826 if (pelements == NULL) {
9062
dcubed
parents: 8854 9060
diff changeset
1827 return false;
9059
17bf4d428955 8006103: [parfait] Possible null pointer dereference at hotspot/src/os/linux/vm/os_linux.cpp; os_windows.cpp; os_solaris.cpp; os_bsd.cpp
ccheung
parents: 8744
diff changeset
1828 }
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1829 for (int i = 0 ; i < n ; i++) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1830 // really shouldn't be NULL but what the heck, check can't hurt
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1831 if (pelements[i] == NULL || strlen(pelements[i]) == 0) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1832 continue; // skip the empty path values
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1833 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1834 snprintf(buffer, buflen, "%s/lib%s.so", pelements[i], fname);
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1835 if (file_exists(buffer)) {
6966
6cb0d32b828b 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 6882
diff changeset
1836 retval = true;
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1837 break;
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1838 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1839 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1840 // release the storage
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1841 for (int i = 0 ; i < n ; i++) {
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1842 if (pelements[i] != NULL) {
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
1843 FREE_C_HEAP_ARRAY(char, pelements[i], mtInternal);
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1844 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1845 }
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1846 if (pelements != NULL) {
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
1847 FREE_C_HEAP_ARRAY(char*, pelements, mtInternal);
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1848 }
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1849 } else {
691
956304450e80 6819213: revive sun.boot.library.path
phh
parents: 656
diff changeset
1850 snprintf(buffer, buflen, "%s/lib%s.so", pname, fname);
6966
6cb0d32b828b 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 6882
diff changeset
1851 retval = true;
6cb0d32b828b 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 6882
diff changeset
1852 }
6cb0d32b828b 8001185: parsing of sun.boot.library.path in os::dll_build_name somewhat broken
bpittore
parents: 6882
diff changeset
1853 return retval;
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1854 }
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
1855
7456
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
1856 // check if addr is inside libjvm.so
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1857 bool os::address_is_in_vm(address addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1858 static address libjvm_base_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
1859 Dl_info dlinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1860
a61af66fc99e Initial load
duke
parents:
diff changeset
1861 if (libjvm_base_addr == NULL) {
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1862 if (dladdr(CAST_FROM_FN_PTR(void *, os::address_is_in_vm), &dlinfo) != 0) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1863 libjvm_base_addr = (address)dlinfo.dli_fbase;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1864 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1865 assert(libjvm_base_addr !=NULL, "Cannot obtain base address for libjvm");
a61af66fc99e Initial load
duke
parents:
diff changeset
1866 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1867
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1868 if (dladdr((void *)addr, &dlinfo) != 0) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1869 if (libjvm_base_addr == (address)dlinfo.dli_fbase) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1870 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1871
a61af66fc99e Initial load
duke
parents:
diff changeset
1872 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1874
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 typedef int (*dladdr1_func_type) (void *, Dl_info *, void **, int);
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 static dladdr1_func_type dladdr1_func = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1877
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 bool os::dll_address_to_function_name(address addr, char *buf,
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 int buflen, int * offset) {
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1880 // buf is not optional, but offset is optional
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1881 assert(buf != NULL, "sanity check");
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1882
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 Dl_info dlinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1884
a61af66fc99e Initial load
duke
parents:
diff changeset
1885 // dladdr1_func was initialized in os::init()
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1886 if (dladdr1_func != NULL) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1887 // yes, we have dladdr1
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1888
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1889 // Support for dladdr1 is checked at runtime; it may be
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1890 // available even if the vm is built on a machine that does
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1891 // not have dladdr1 support. Make sure there is a value for
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1892 // RTLD_DL_SYMENT.
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1893 #ifndef RTLD_DL_SYMENT
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1894 #define RTLD_DL_SYMENT 1
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1895 #endif
2259
2a57c59eb548 7018101: os::dll_address_to_function_name returning wrong answers in 64 bit
never
parents: 2130
diff changeset
1896 #ifdef _LP64
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1897 Elf64_Sym * info;
2259
2a57c59eb548 7018101: os::dll_address_to_function_name returning wrong answers in 64 bit
never
parents: 2130
diff changeset
1898 #else
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1899 Elf32_Sym * info;
2259
2a57c59eb548 7018101: os::dll_address_to_function_name returning wrong answers in 64 bit
never
parents: 2130
diff changeset
1900 #endif
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1901 if (dladdr1_func((void *)addr, &dlinfo, (void **)&info,
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1902 RTLD_DL_SYMENT) != 0) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1903 // see if we have a matching symbol that covers our address
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1904 if (dlinfo.dli_saddr != NULL &&
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1905 (char *)dlinfo.dli_saddr + info->st_size > (char *)addr) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1906 if (dlinfo.dli_sname != NULL) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1907 if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1908 jio_snprintf(buf, buflen, "%s", dlinfo.dli_sname);
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1909 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1910 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
2022
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1911 return true;
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1912 }
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1913 }
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1914 // no matching symbol so try for just file info
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1915 if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {
2022
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1916 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1917 buf, buflen, offset, dlinfo.dli_fname)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 return true;
2022
2d4762ec74af 7003748: Decode C stack frames when symbols are presented (PhoneHome project)
zgu
parents: 1972
diff changeset
1919 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1920 }
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1921 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1922 buf[0] = '\0';
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1923 if (offset != NULL) *offset = -1;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1924 return false;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1925 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1926
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1927 // no, only dladdr is available
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1928 if (dladdr((void *)addr, &dlinfo) != 0) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1929 // see if we have a matching symbol
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1930 if (dlinfo.dli_saddr != NULL && dlinfo.dli_sname != NULL) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1931 if (!Decoder::demangle(dlinfo.dli_sname, buf, buflen)) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1932 jio_snprintf(buf, buflen, dlinfo.dli_sname);
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1933 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1934 if (offset != NULL) *offset = addr - (address)dlinfo.dli_saddr;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1935 return true;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1936 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1937 // no matching symbol so try for just file info
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1938 if (dlinfo.dli_fname != NULL && dlinfo.dli_fbase != NULL) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1939 if (Decoder::decode((address)(addr - (address)dlinfo.dli_fbase),
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1940 buf, buflen, offset, dlinfo.dli_fname)) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1941 return true;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1942 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1943 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1944 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1945 buf[0] = '\0';
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1946 if (offset != NULL) *offset = -1;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1947 return false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1949
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 bool os::dll_address_to_library_name(address addr, char* buf,
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 int buflen, int* offset) {
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1952 // buf is not optional, but offset is optional
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1953 assert(buf != NULL, "sanity check");
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1954
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 Dl_info dlinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
1956
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1957 if (dladdr((void*)addr, &dlinfo) != 0) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1958 if (dlinfo.dli_fname != NULL) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1959 jio_snprintf(buf, buflen, "%s", dlinfo.dli_fname);
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1960 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1961 if (dlinfo.dli_fbase != NULL && offset != NULL) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1962 *offset = addr - (address)dlinfo.dli_fbase;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1963 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1964 return true;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1965 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1966
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1967 buf[0] = '\0';
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1968 if (offset) *offset = -1;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1969 return false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1971
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 // Prints the names and full paths of all opened dynamic libraries
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 // for current process
a61af66fc99e Initial load
duke
parents:
diff changeset
1974 void os::print_dll_info(outputStream * st) {
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1975 Dl_info dli;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1976 void *handle;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1977 Link_map *map;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1978 Link_map *p;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1979
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1980 st->print_cr("Dynamic libraries:"); st->flush();
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1981
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1982 if (dladdr(CAST_FROM_FN_PTR(void *, os::print_dll_info), &dli) == 0 ||
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1983 dli.dli_fname == NULL) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1984 st->print_cr("Error: Cannot print dynamic libraries.");
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1985 return;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1986 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1987 handle = dlopen(dli.dli_fname, RTLD_LAZY);
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1988 if (handle == NULL) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1989 st->print_cr("Error: Cannot print dynamic libraries.");
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1990 return;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1991 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1992 dlinfo(handle, RTLD_DI_LINKMAP, &map);
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1993 if (map == NULL) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1994 st->print_cr("Error: Cannot print dynamic libraries.");
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1995 return;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1996 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1997
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1998 while (map->l_prev != NULL)
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
1999 map = map->l_prev;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
2000
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
2001 while (map != NULL) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
2002 st->print_cr(PTR_FORMAT " \t%s", map->l_addr, map->l_name);
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
2003 map = map->l_next;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
2004 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
2005
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
2006 dlclose(handle);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2008
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 // Loads .dll/.so and
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 // in case of error it checks if .dll/.so was built for the
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 // same architecture as Hotspot is running on
a61af66fc99e Initial load
duke
parents:
diff changeset
2012
a61af66fc99e Initial load
duke
parents:
diff changeset
2013 void * os::dll_load(const char *filename, char *ebuf, int ebuflen)
a61af66fc99e Initial load
duke
parents:
diff changeset
2014 {
a61af66fc99e Initial load
duke
parents:
diff changeset
2015 void * result= ::dlopen(filename, RTLD_LAZY);
a61af66fc99e Initial load
duke
parents:
diff changeset
2016 if (result != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2017 // Successful loading
a61af66fc99e Initial load
duke
parents:
diff changeset
2018 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
2019 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2020
a61af66fc99e Initial load
duke
parents:
diff changeset
2021 Elf32_Ehdr elf_head;
a61af66fc99e Initial load
duke
parents:
diff changeset
2022
a61af66fc99e Initial load
duke
parents:
diff changeset
2023 // Read system error message into ebuf
a61af66fc99e Initial load
duke
parents:
diff changeset
2024 // It may or may not be overwritten below
a61af66fc99e Initial load
duke
parents:
diff changeset
2025 ::strncpy(ebuf, ::dlerror(), ebuflen-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2026 ebuf[ebuflen-1]='\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
2027 int diag_msg_max_length=ebuflen-strlen(ebuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2028 char* diag_msg_buf=ebuf+strlen(ebuf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2029
a61af66fc99e Initial load
duke
parents:
diff changeset
2030 if (diag_msg_max_length==0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2031 // No more space in ebuf for additional diagnostics message
a61af66fc99e Initial load
duke
parents:
diff changeset
2032 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2033 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2034
a61af66fc99e Initial load
duke
parents:
diff changeset
2035
a61af66fc99e Initial load
duke
parents:
diff changeset
2036 int file_descriptor= ::open(filename, O_RDONLY | O_NONBLOCK);
a61af66fc99e Initial load
duke
parents:
diff changeset
2037
a61af66fc99e Initial load
duke
parents:
diff changeset
2038 if (file_descriptor < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2039 // Can't open library, report dlerror() message
a61af66fc99e Initial load
duke
parents:
diff changeset
2040 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2041 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2042
a61af66fc99e Initial load
duke
parents:
diff changeset
2043 bool failed_to_read_elf_head=
a61af66fc99e Initial load
duke
parents:
diff changeset
2044 (sizeof(elf_head)!=
a61af66fc99e Initial load
duke
parents:
diff changeset
2045 (::read(file_descriptor, &elf_head,sizeof(elf_head)))) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
2046
a61af66fc99e Initial load
duke
parents:
diff changeset
2047 ::close(file_descriptor);
a61af66fc99e Initial load
duke
parents:
diff changeset
2048 if (failed_to_read_elf_head) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2049 // file i/o error - report dlerror() msg
a61af66fc99e Initial load
duke
parents:
diff changeset
2050 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2051 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2052
a61af66fc99e Initial load
duke
parents:
diff changeset
2053 typedef struct {
a61af66fc99e Initial load
duke
parents:
diff changeset
2054 Elf32_Half code; // Actual value as defined in elf.h
a61af66fc99e Initial load
duke
parents:
diff changeset
2055 Elf32_Half compat_class; // Compatibility of archs at VM's sense
a61af66fc99e Initial load
duke
parents:
diff changeset
2056 char elf_class; // 32 or 64 bit
a61af66fc99e Initial load
duke
parents:
diff changeset
2057 char endianess; // MSB or LSB
a61af66fc99e Initial load
duke
parents:
diff changeset
2058 char* name; // String representation
a61af66fc99e Initial load
duke
parents:
diff changeset
2059 } arch_t;
a61af66fc99e Initial load
duke
parents:
diff changeset
2060
a61af66fc99e Initial load
duke
parents:
diff changeset
2061 static const arch_t arch_array[]={
a61af66fc99e Initial load
duke
parents:
diff changeset
2062 {EM_386, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
a61af66fc99e Initial load
duke
parents:
diff changeset
2063 {EM_486, EM_386, ELFCLASS32, ELFDATA2LSB, (char*)"IA 32"},
a61af66fc99e Initial load
duke
parents:
diff changeset
2064 {EM_IA_64, EM_IA_64, ELFCLASS64, ELFDATA2LSB, (char*)"IA 64"},
a61af66fc99e Initial load
duke
parents:
diff changeset
2065 {EM_X86_64, EM_X86_64, ELFCLASS64, ELFDATA2LSB, (char*)"AMD 64"},
a61af66fc99e Initial load
duke
parents:
diff changeset
2066 {EM_SPARC, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
a61af66fc99e Initial load
duke
parents:
diff changeset
2067 {EM_SPARC32PLUS, EM_SPARC, ELFCLASS32, ELFDATA2MSB, (char*)"Sparc 32"},
a61af66fc99e Initial load
duke
parents:
diff changeset
2068 {EM_SPARCV9, EM_SPARCV9, ELFCLASS64, ELFDATA2MSB, (char*)"Sparc v9 64"},
a61af66fc99e Initial load
duke
parents:
diff changeset
2069 {EM_PPC, EM_PPC, ELFCLASS32, ELFDATA2MSB, (char*)"Power PC 32"},
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2070 {EM_PPC64, EM_PPC64, ELFCLASS64, ELFDATA2MSB, (char*)"Power PC 64"},
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2071 {EM_ARM, EM_ARM, ELFCLASS32, ELFDATA2LSB, (char*)"ARM 32"}
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2073
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 #if (defined IA32)
a61af66fc99e Initial load
duke
parents:
diff changeset
2075 static Elf32_Half running_arch_code=EM_386;
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 #elif (defined AMD64)
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 static Elf32_Half running_arch_code=EM_X86_64;
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 #elif (defined IA64)
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 static Elf32_Half running_arch_code=EM_IA_64;
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 #elif (defined __sparc) && (defined _LP64)
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 static Elf32_Half running_arch_code=EM_SPARCV9;
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 #elif (defined __sparc) && (!defined _LP64)
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 static Elf32_Half running_arch_code=EM_SPARC;
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 #elif (defined __powerpc64__)
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 static Elf32_Half running_arch_code=EM_PPC64;
a61af66fc99e Initial load
duke
parents:
diff changeset
2086 #elif (defined __powerpc__)
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 static Elf32_Half running_arch_code=EM_PPC;
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2088 #elif (defined ARM)
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2089 static Elf32_Half running_arch_code=EM_ARM;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 #error Method os::dll_load requires that one of following is defined:\
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
2092 IA32, AMD64, IA64, __sparc, __powerpc__, ARM, ARM
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2094
a61af66fc99e Initial load
duke
parents:
diff changeset
2095 // Identify compatability class for VM's architecture and library's architecture
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 // Obtain string descriptions for architectures
a61af66fc99e Initial load
duke
parents:
diff changeset
2097
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 arch_t lib_arch={elf_head.e_machine,0,elf_head.e_ident[EI_CLASS], elf_head.e_ident[EI_DATA], NULL};
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 int running_arch_index=-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2100
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 for (unsigned int i=0 ; i < ARRAY_SIZE(arch_array) ; i++ ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2102 if (running_arch_code == arch_array[i].code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 running_arch_index = i;
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 if (lib_arch.code == arch_array[i].code) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 lib_arch.compat_class = arch_array[i].compat_class;
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 lib_arch.name = arch_array[i].name;
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2110
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 assert(running_arch_index != -1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 "Didn't find running architecture code (running_arch_code) in arch_array");
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 if (running_arch_index == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 // Even though running architecture detection failed
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 // we may still continue with reporting dlerror() message
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2118
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 if (lib_arch.endianess != arch_array[running_arch_index].endianess) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: endianness mismatch)");
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2123
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 if (lib_arch.elf_class != arch_array[running_arch_index].elf_class) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 ::snprintf(diag_msg_buf, diag_msg_max_length-1," (Possible cause: architecture word width mismatch)");
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2128
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 if (lib_arch.compat_class != arch_array[running_arch_index].compat_class) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 if ( lib_arch.name!=NULL ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 ::snprintf(diag_msg_buf, diag_msg_max_length-1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2132 " (Possible cause: can't load %s-bit .so on a %s-bit platform)",
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 lib_arch.name, arch_array[running_arch_index].name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2135 ::snprintf(diag_msg_buf, diag_msg_max_length-1,
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 " (Possible cause: can't load this .so (machine code=0x%x) on a %s-bit platform)",
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 lib_arch.code,
a61af66fc99e Initial load
duke
parents:
diff changeset
2138 arch_array[running_arch_index].name);
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2141
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2144
242
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
2145 void* os::dll_lookup(void* handle, const char* name) {
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
2146 return dlsym(handle, name);
d95b224e9f17 6721093: -XX:AppendRatio=N not supported
kamg
parents: 237
diff changeset
2147 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2148
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2149 int os::stat(const char *path, struct stat *sbuf) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2150 char pathbuf[MAX_PATH];
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2151 if (strlen(path) > MAX_PATH - 1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2152 errno = ENAMETOOLONG;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2153 return -1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2154 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2155 os::native_path(strcpy(pathbuf, path));
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2156 return ::stat(pathbuf, sbuf);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2157 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2158
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2159 static bool _print_ascii_file(const char* filename, outputStream* st) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2160 int fd = ::open(filename, O_RDONLY);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 if (fd == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2164
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 char buf[32];
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 int bytes;
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2167 while ((bytes = ::read(fd, buf, sizeof(buf))) > 0) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 st->print_raw(buf, bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2170
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2171 ::close(fd);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2172
a61af66fc99e Initial load
duke
parents:
diff changeset
2173 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2175
6080
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2176 void os::print_os_info_brief(outputStream* st) {
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2177 os::Solaris::print_distro_info(st);
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2178
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2179 os::Posix::print_uname_info(st);
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2180
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2181 os::Solaris::print_libversion_info(st);
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2182 }
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2183
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 void os::print_os_info(outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 st->print("OS:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2186
6080
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2187 os::Solaris::print_distro_info(st);
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2188
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2189 os::Posix::print_uname_info(st);
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2190
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2191 os::Solaris::print_libversion_info(st);
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2192
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2193 os::Posix::print_rlimit_info(st);
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2194
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2195 os::Posix::print_load_average(st);
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2196 }
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2197
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2198 void os::Solaris::print_distro_info(outputStream* st) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2199 if (!_print_ascii_file("/etc/release", st)) {
6080
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2200 st->print("Solaris");
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2201 }
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2202 st->cr();
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2203 }
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2204
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2205 void os::Solaris::print_libversion_info(outputStream* st) {
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2206 if (os::Solaris::T2_libthread()) {
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2207 st->print(" (T2 libthread)");
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2208 }
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2209 else {
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2210 st->print(" (T1 libthread)");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 st->cr();
6080
7432b9db36ff 7165755: OS Information much longer on linux than other platforms
nloodin
parents: 5903
diff changeset
2213 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2214
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 static bool check_addr0(outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 jboolean status = false;
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2217 int fd = ::open("/proc/self/map",O_RDONLY);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 if (fd >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 prmap_t p;
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2220 while(::read(fd, &p, sizeof(p)) > 0) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 if (p.pr_vaddr == 0x0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 st->print("Warning: Address: 0x%x, Size: %dK, ",p.pr_vaddr, p.pr_size/1024, p.pr_mapname);
a61af66fc99e Initial load
duke
parents:
diff changeset
2223 st->print("Mapped file: %s, ", p.pr_mapname[0] == '\0' ? "None" : p.pr_mapname);
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 st->print("Access:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 st->print("%s",(p.pr_mflags & MA_READ) ? "r" : "-");
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 st->print("%s",(p.pr_mflags & MA_WRITE) ? "w" : "-");
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 st->print("%s",(p.pr_mflags & MA_EXEC) ? "x" : "-");
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 status = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 }
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2231 ::close(fd);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 return status;
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2236
3800
bf6481e5f96d 7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents: 3318
diff changeset
2237 void os::pd_print_cpu_info(outputStream* st) {
bf6481e5f96d 7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents: 3318
diff changeset
2238 // Nothing to do for now.
bf6481e5f96d 7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents: 3318
diff changeset
2239 }
bf6481e5f96d 7061225: os::print_cpu_info() should support os-specific data
jcoomes
parents: 3318
diff changeset
2240
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 void os::print_memory_info(outputStream* st) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 st->print("Memory:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2243 st->print(" %dk page", os::vm_page_size()>>10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 st->print(", physical " UINT64_FORMAT "k", os::physical_memory()>>10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 st->print("(" UINT64_FORMAT "k free)", os::available_memory() >> 10);
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2247 (void) check_addr0(st);
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2249
a61af66fc99e Initial load
duke
parents:
diff changeset
2250 // Taken from /usr/include/sys/machsig.h Supposed to be architecture specific
a61af66fc99e Initial load
duke
parents:
diff changeset
2251 // but they're the same for all the solaris architectures that we support.
a61af66fc99e Initial load
duke
parents:
diff changeset
2252 const char *ill_names[] = { "ILL0", "ILL_ILLOPC", "ILL_ILLOPN", "ILL_ILLADR",
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 "ILL_ILLTRP", "ILL_PRVOPC", "ILL_PRVREG",
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 "ILL_COPROC", "ILL_BADSTK" };
a61af66fc99e Initial load
duke
parents:
diff changeset
2255
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 const char *fpe_names[] = { "FPE0", "FPE_INTDIV", "FPE_INTOVF", "FPE_FLTDIV",
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 "FPE_FLTOVF", "FPE_FLTUND", "FPE_FLTRES",
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 "FPE_FLTINV", "FPE_FLTSUB" };
a61af66fc99e Initial load
duke
parents:
diff changeset
2259
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 const char *segv_names[] = { "SEGV0", "SEGV_MAPERR", "SEGV_ACCERR" };
a61af66fc99e Initial load
duke
parents:
diff changeset
2261
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 const char *bus_names[] = { "BUS0", "BUS_ADRALN", "BUS_ADRERR", "BUS_OBJERR" };
a61af66fc99e Initial load
duke
parents:
diff changeset
2263
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 void os::print_siginfo(outputStream* st, void* siginfo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 st->print("siginfo:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2266
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 const int buflen = 100;
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 char buf[buflen];
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 siginfo_t *si = (siginfo_t*)siginfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
2270 st->print("si_signo=%s: ", os::exception_name(si->si_signo, buf, buflen));
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 char *err = strerror(si->si_errno);
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 if (si->si_errno != 0 && err != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 st->print("si_errno=%s", err);
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 st->print("si_errno=%d", si->si_errno);
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2277 const int c = si->si_code;
a61af66fc99e Initial load
duke
parents:
diff changeset
2278 assert(c > 0, "unexpected si_code");
a61af66fc99e Initial load
duke
parents:
diff changeset
2279 switch (si->si_signo) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2280 case SIGILL:
a61af66fc99e Initial load
duke
parents:
diff changeset
2281 st->print(", si_code=%d (%s)", c, c > 8 ? "" : ill_names[c]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2282 st->print(", si_addr=" PTR_FORMAT, si->si_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2283 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2284 case SIGFPE:
a61af66fc99e Initial load
duke
parents:
diff changeset
2285 st->print(", si_code=%d (%s)", c, c > 9 ? "" : fpe_names[c]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2286 st->print(", si_addr=" PTR_FORMAT, si->si_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2287 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2288 case SIGSEGV:
a61af66fc99e Initial load
duke
parents:
diff changeset
2289 st->print(", si_code=%d (%s)", c, c > 2 ? "" : segv_names[c]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2290 st->print(", si_addr=" PTR_FORMAT, si->si_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2291 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2292 case SIGBUS:
a61af66fc99e Initial load
duke
parents:
diff changeset
2293 st->print(", si_code=%d (%s)", c, c > 3 ? "" : bus_names[c]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2294 st->print(", si_addr=" PTR_FORMAT, si->si_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
2295 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2296 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
2297 st->print(", si_code=%d", si->si_code);
a61af66fc99e Initial load
duke
parents:
diff changeset
2298 // no si_addr
a61af66fc99e Initial load
duke
parents:
diff changeset
2299 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2300
a61af66fc99e Initial load
duke
parents:
diff changeset
2301 if ((si->si_signo == SIGBUS || si->si_signo == SIGSEGV) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
2302 UseSharedSpaces) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2303 FileMapInfo* mapinfo = FileMapInfo::current_info();
a61af66fc99e Initial load
duke
parents:
diff changeset
2304 if (mapinfo->is_in_shared_space(si->si_addr)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2305 st->print("\n\nError accessing class data sharing archive." \
a61af66fc99e Initial load
duke
parents:
diff changeset
2306 " Mapped file inaccessible during execution, " \
a61af66fc99e Initial load
duke
parents:
diff changeset
2307 " possible disk/network problem.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2308 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2309 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2310 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2312
a61af66fc99e Initial load
duke
parents:
diff changeset
2313 // Moved from whole group, because we need them here for diagnostic
a61af66fc99e Initial load
duke
parents:
diff changeset
2314 // prints.
a61af66fc99e Initial load
duke
parents:
diff changeset
2315 #define OLDMAXSIGNUM 32
a61af66fc99e Initial load
duke
parents:
diff changeset
2316 static int Maxsignum = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2317 static int *ourSigFlags = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2318
a61af66fc99e Initial load
duke
parents:
diff changeset
2319 extern "C" void sigINTRHandler(int, siginfo_t*, void*);
a61af66fc99e Initial load
duke
parents:
diff changeset
2320
a61af66fc99e Initial load
duke
parents:
diff changeset
2321 int os::Solaris::get_our_sigflags(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2322 assert(ourSigFlags!=NULL, "signal data structure not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
2323 assert(sig > 0 && sig < Maxsignum, "vm signal out of expected range");
a61af66fc99e Initial load
duke
parents:
diff changeset
2324 return ourSigFlags[sig];
a61af66fc99e Initial load
duke
parents:
diff changeset
2325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2326
a61af66fc99e Initial load
duke
parents:
diff changeset
2327 void os::Solaris::set_our_sigflags(int sig, int flags) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2328 assert(ourSigFlags!=NULL, "signal data structure not initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
2329 assert(sig > 0 && sig < Maxsignum, "vm signal out of expected range");
a61af66fc99e Initial load
duke
parents:
diff changeset
2330 ourSigFlags[sig] = flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
2331 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2332
a61af66fc99e Initial load
duke
parents:
diff changeset
2333
a61af66fc99e Initial load
duke
parents:
diff changeset
2334 static const char* get_signal_handler_name(address handler,
a61af66fc99e Initial load
duke
parents:
diff changeset
2335 char* buf, int buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2336 int offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
2337 bool found = os::dll_address_to_library_name(handler, buf, buflen, &offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2338 if (found) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2339 // skip directory names
a61af66fc99e Initial load
duke
parents:
diff changeset
2340 const char *p1, *p2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2341 p1 = buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
2342 size_t len = strlen(os::file_separator());
a61af66fc99e Initial load
duke
parents:
diff changeset
2343 while ((p2 = strstr(p1, os::file_separator())) != NULL) p1 = p2 + len;
a61af66fc99e Initial load
duke
parents:
diff changeset
2344 jio_snprintf(buf, buflen, "%s+0x%x", p1, offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
2345 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2346 jio_snprintf(buf, buflen, PTR_FORMAT, handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2348 return buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
2349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2350
a61af66fc99e Initial load
duke
parents:
diff changeset
2351 static void print_signal_handler(outputStream* st, int sig,
a61af66fc99e Initial load
duke
parents:
diff changeset
2352 char* buf, size_t buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2353 struct sigaction sa;
a61af66fc99e Initial load
duke
parents:
diff changeset
2354
a61af66fc99e Initial load
duke
parents:
diff changeset
2355 sigaction(sig, NULL, &sa);
a61af66fc99e Initial load
duke
parents:
diff changeset
2356
a61af66fc99e Initial load
duke
parents:
diff changeset
2357 st->print("%s: ", os::exception_name(sig, buf, buflen));
a61af66fc99e Initial load
duke
parents:
diff changeset
2358
a61af66fc99e Initial load
duke
parents:
diff changeset
2359 address handler = (sa.sa_flags & SA_SIGINFO)
a61af66fc99e Initial load
duke
parents:
diff changeset
2360 ? CAST_FROM_FN_PTR(address, sa.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
2361 : CAST_FROM_FN_PTR(address, sa.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2362
a61af66fc99e Initial load
duke
parents:
diff changeset
2363 if (handler == CAST_FROM_FN_PTR(address, SIG_DFL)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2364 st->print("SIG_DFL");
a61af66fc99e Initial load
duke
parents:
diff changeset
2365 } else if (handler == CAST_FROM_FN_PTR(address, SIG_IGN)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2366 st->print("SIG_IGN");
a61af66fc99e Initial load
duke
parents:
diff changeset
2367 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2368 st->print("[%s]", get_signal_handler_name(handler, buf, buflen));
a61af66fc99e Initial load
duke
parents:
diff changeset
2369 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2370
a61af66fc99e Initial load
duke
parents:
diff changeset
2371 st->print(", sa_mask[0]=" PTR32_FORMAT, *(uint32_t*)&sa.sa_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
2372
a61af66fc99e Initial load
duke
parents:
diff changeset
2373 address rh = VMError::get_resetted_sighandler(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
2374 // May be, handler was resetted by VMError?
a61af66fc99e Initial load
duke
parents:
diff changeset
2375 if(rh != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2376 handler = rh;
a61af66fc99e Initial load
duke
parents:
diff changeset
2377 sa.sa_flags = VMError::get_resetted_sigflags(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
2378 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2379
a61af66fc99e Initial load
duke
parents:
diff changeset
2380 st->print(", sa_flags=" PTR32_FORMAT, sa.sa_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
2381
a61af66fc99e Initial load
duke
parents:
diff changeset
2382 // Check: is it our handler?
a61af66fc99e Initial load
duke
parents:
diff changeset
2383 if(handler == CAST_FROM_FN_PTR(address, signalHandler) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
2384 handler == CAST_FROM_FN_PTR(address, sigINTRHandler)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2385 // It is our signal handler
a61af66fc99e Initial load
duke
parents:
diff changeset
2386 // check for flags
a61af66fc99e Initial load
duke
parents:
diff changeset
2387 if(sa.sa_flags != os::Solaris::get_our_sigflags(sig)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2388 st->print(
a61af66fc99e Initial load
duke
parents:
diff changeset
2389 ", flags was changed from " PTR32_FORMAT ", consider using jsig library",
a61af66fc99e Initial load
duke
parents:
diff changeset
2390 os::Solaris::get_our_sigflags(sig));
a61af66fc99e Initial load
duke
parents:
diff changeset
2391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2392 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2393 st->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
2394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2395
a61af66fc99e Initial load
duke
parents:
diff changeset
2396 void os::print_signal_handlers(outputStream* st, char* buf, size_t buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2397 st->print_cr("Signal Handlers:");
a61af66fc99e Initial load
duke
parents:
diff changeset
2398 print_signal_handler(st, SIGSEGV, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2399 print_signal_handler(st, SIGBUS , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2400 print_signal_handler(st, SIGFPE , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2401 print_signal_handler(st, SIGPIPE, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2402 print_signal_handler(st, SIGXFSZ, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2403 print_signal_handler(st, SIGILL , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2404 print_signal_handler(st, INTERRUPT_SIGNAL, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2405 print_signal_handler(st, ASYNC_SIGNAL, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2406 print_signal_handler(st, BREAK_SIGNAL, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2407 print_signal_handler(st, SHUTDOWN1_SIGNAL , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2408 print_signal_handler(st, SHUTDOWN2_SIGNAL , buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2409 print_signal_handler(st, SHUTDOWN3_SIGNAL, buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2410 print_signal_handler(st, os::Solaris::SIGinterrupt(), buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2411 print_signal_handler(st, os::Solaris::SIGasync(), buf, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
2412 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2413
a61af66fc99e Initial load
duke
parents:
diff changeset
2414 static char saved_jvm_path[MAXPATHLEN] = { 0 };
a61af66fc99e Initial load
duke
parents:
diff changeset
2415
7456
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
2416 // Find the full path to the current module, libjvm.so
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2417 void os::jvm_path(char *buf, jint buflen) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2418 // Error checking.
a61af66fc99e Initial load
duke
parents:
diff changeset
2419 if (buflen < MAXPATHLEN) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2420 assert(false, "must use a large-enough buffer");
a61af66fc99e Initial load
duke
parents:
diff changeset
2421 buf[0] = '\0';
a61af66fc99e Initial load
duke
parents:
diff changeset
2422 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2423 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2424 // Lazy resolve the path to current module.
a61af66fc99e Initial load
duke
parents:
diff changeset
2425 if (saved_jvm_path[0] != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2426 strcpy(buf, saved_jvm_path);
a61af66fc99e Initial load
duke
parents:
diff changeset
2427 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2428 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2429
a61af66fc99e Initial load
duke
parents:
diff changeset
2430 Dl_info dlinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
2431 int ret = dladdr(CAST_FROM_FN_PTR(void *, os::jvm_path), &dlinfo);
a61af66fc99e Initial load
duke
parents:
diff changeset
2432 assert(ret != 0, "cannot locate libjvm");
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
2433 if (ret != 0 && dlinfo.dli_fname != NULL) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
2434 realpath((char *)dlinfo.dli_fname, buf);
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
2435 } else {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
2436 buf[0] = '\0';
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
2437 return;
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
2438 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2439
2302
da091bb67459 7022037: Pause when exiting if debugger is attached on windows
sla
parents: 2191
diff changeset
2440 if (Arguments::created_by_gamma_launcher()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2441 // Support for the gamma launcher. Typical value for buf is
a61af66fc99e Initial load
duke
parents:
diff changeset
2442 // "<JAVA_HOME>/jre/lib/<arch>/<vmtype>/libjvm.so". If "/jre/lib/" appears at
a61af66fc99e Initial load
duke
parents:
diff changeset
2443 // the right place in the string, then assume we are installed in a JDK and
a61af66fc99e Initial load
duke
parents:
diff changeset
2444 // we're done. Otherwise, check for a JAVA_HOME environment variable and fix
a61af66fc99e Initial load
duke
parents:
diff changeset
2445 // up the path so it looks like libjvm.so is installed there (append a
a61af66fc99e Initial load
duke
parents:
diff changeset
2446 // fake suffix hotspot/libjvm.so).
a61af66fc99e Initial load
duke
parents:
diff changeset
2447 const char *p = buf + strlen(buf) - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2448 for (int count = 0; p > buf && count < 5; ++count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2449 for (--p; p > buf && *p != '/'; --p)
a61af66fc99e Initial load
duke
parents:
diff changeset
2450 /* empty */ ;
a61af66fc99e Initial load
duke
parents:
diff changeset
2451 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2452
a61af66fc99e Initial load
duke
parents:
diff changeset
2453 if (strncmp(p, "/jre/lib/", 9) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2454 // Look for JAVA_HOME in the environment.
a61af66fc99e Initial load
duke
parents:
diff changeset
2455 char* java_home_var = ::getenv("JAVA_HOME");
a61af66fc99e Initial load
duke
parents:
diff changeset
2456 if (java_home_var != NULL && java_home_var[0] != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2457 char cpu_arch[12];
1642
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2458 char* jrelib_p;
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2459 int len;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2460 sysinfo(SI_ARCHITECTURE, cpu_arch, sizeof(cpu_arch));
a61af66fc99e Initial load
duke
parents:
diff changeset
2461 #ifdef _LP64
a61af66fc99e Initial load
duke
parents:
diff changeset
2462 // If we are on sparc running a 64-bit vm, look in jre/lib/sparcv9.
a61af66fc99e Initial load
duke
parents:
diff changeset
2463 if (strcmp(cpu_arch, "sparc") == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2464 strcat(cpu_arch, "v9");
a61af66fc99e Initial load
duke
parents:
diff changeset
2465 } else if (strcmp(cpu_arch, "i386") == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2466 strcpy(cpu_arch, "amd64");
a61af66fc99e Initial load
duke
parents:
diff changeset
2467 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2468 #endif
7456
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
2469 // Check the current module name "libjvm.so".
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2470 p = strrchr(buf, '/');
a61af66fc99e Initial load
duke
parents:
diff changeset
2471 assert(strstr(p, "/libjvm") == p, "invalid library name");
a61af66fc99e Initial load
duke
parents:
diff changeset
2472
a61af66fc99e Initial load
duke
parents:
diff changeset
2473 realpath(java_home_var, buf);
1642
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2474 // determine if this is a legacy image or modules image
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2475 // modules image doesn't have "jre" subdirectory
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2476 len = strlen(buf);
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2477 jrelib_p = buf + len;
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2478 snprintf(jrelib_p, buflen-len, "/jre/lib/%s", cpu_arch);
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2479 if (0 != access(buf, F_OK)) {
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2480 snprintf(jrelib_p, buflen-len, "/lib/%s", cpu_arch);
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2481 }
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2482
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2483 if (0 == access(buf, F_OK)) {
7456
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
2484 // Use current module name "libjvm.so"
1642
0e7d2a08b605 6967423: Hotspot support for modules image
mchung
parents: 1552
diff changeset
2485 len = strlen(buf);
7456
7d42f3b08300 8005044: remove crufty '_g' support from HS runtime code
dcubed
parents: 7206
diff changeset
2486 snprintf(buf + len, buflen-len, "/hotspot/libjvm.so");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2487 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2488 // Go back to path of .so
a61af66fc99e Initial load
duke
parents:
diff changeset
2489 realpath((char *)dlinfo.dli_fname, buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2490 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2491 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2492 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2494
a61af66fc99e Initial load
duke
parents:
diff changeset
2495 strcpy(saved_jvm_path, buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2496 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2497
a61af66fc99e Initial load
duke
parents:
diff changeset
2498
a61af66fc99e Initial load
duke
parents:
diff changeset
2499 void os::print_jni_name_prefix_on(outputStream* st, int args_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2500 // no prefix required, not even "_"
a61af66fc99e Initial load
duke
parents:
diff changeset
2501 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2502
a61af66fc99e Initial load
duke
parents:
diff changeset
2503
a61af66fc99e Initial load
duke
parents:
diff changeset
2504 void os::print_jni_name_suffix_on(outputStream* st, int args_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2505 // no suffix required
a61af66fc99e Initial load
duke
parents:
diff changeset
2506 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2507
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2508 // This method is a copy of JDK's sysGetLastErrorString
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2509 // from src/solaris/hpi/src/system_md.c
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2510
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2511 size_t os::lasterror(char *buf, size_t len) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2512
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2513 if (errno == 0) return 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2514
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2515 const char *s = ::strerror(errno);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2516 size_t n = ::strlen(s);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2517 if (n >= len) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2518 n = len - 1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2519 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2520 ::strncpy(buf, s, n);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2521 buf[n] = '\0';
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2522 return n;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2523 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
2524
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2525
a61af66fc99e Initial load
duke
parents:
diff changeset
2526 // sun.misc.Signal
a61af66fc99e Initial load
duke
parents:
diff changeset
2527
a61af66fc99e Initial load
duke
parents:
diff changeset
2528 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
2529 static void UserHandler(int sig, void *siginfo, void *context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2530 // Ctrl-C is pressed during error reporting, likely because the error
a61af66fc99e Initial load
duke
parents:
diff changeset
2531 // handler fails to abort. Let VM die immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
2532 if (sig == SIGINT && is_error_reported()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2533 os::die();
a61af66fc99e Initial load
duke
parents:
diff changeset
2534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2535
a61af66fc99e Initial load
duke
parents:
diff changeset
2536 os::signal_notify(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
2537 // We do not need to reinstate the signal handler each time...
a61af66fc99e Initial load
duke
parents:
diff changeset
2538 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2539 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2540
a61af66fc99e Initial load
duke
parents:
diff changeset
2541 void* os::user_handler() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2542 return CAST_FROM_FN_PTR(void*, UserHandler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2543 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2544
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2545 class Semaphore : public StackObj {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2546 public:
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2547 Semaphore();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2548 ~Semaphore();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2549 void signal();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2550 void wait();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2551 bool trywait();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2552 bool timedwait(unsigned int sec, int nsec);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2553 private:
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2554 sema_t _semaphore;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2555 };
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2556
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2557
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2558 Semaphore::Semaphore() {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2559 sema_init(&_semaphore, 0, NULL, NULL);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2560 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2561
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2562 Semaphore::~Semaphore() {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2563 sema_destroy(&_semaphore);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2564 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2565
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2566 void Semaphore::signal() {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2567 sema_post(&_semaphore);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2568 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2569
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2570 void Semaphore::wait() {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2571 sema_wait(&_semaphore);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2572 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2573
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2574 bool Semaphore::trywait() {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2575 return sema_trywait(&_semaphore) == 0;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2576 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2577
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2578 bool Semaphore::timedwait(unsigned int sec, int nsec) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2579 struct timespec ts;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2580 unpackTime(&ts, false, (sec * NANOSECS_PER_SEC) + nsec);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2581
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2582 while (1) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2583 int result = sema_timedwait(&_semaphore, &ts);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2584 if (result == 0) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2585 return true;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2586 } else if (errno == EINTR) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2587 continue;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2588 } else if (errno == ETIME) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2589 return false;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2590 } else {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2591 return false;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2592 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2593 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2594 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
2595
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2596 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
2597 typedef void (*sa_handler_t)(int);
a61af66fc99e Initial load
duke
parents:
diff changeset
2598 typedef void (*sa_sigaction_t)(int, siginfo_t *, void *);
a61af66fc99e Initial load
duke
parents:
diff changeset
2599 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2600
a61af66fc99e Initial load
duke
parents:
diff changeset
2601 void* os::signal(int signal_number, void* handler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2602 struct sigaction sigAct, oldSigAct;
a61af66fc99e Initial load
duke
parents:
diff changeset
2603 sigfillset(&(sigAct.sa_mask));
a61af66fc99e Initial load
duke
parents:
diff changeset
2604 sigAct.sa_flags = SA_RESTART & ~SA_RESETHAND;
a61af66fc99e Initial load
duke
parents:
diff changeset
2605 sigAct.sa_handler = CAST_TO_FN_PTR(sa_handler_t, handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2606
a61af66fc99e Initial load
duke
parents:
diff changeset
2607 if (sigaction(signal_number, &sigAct, &oldSigAct))
a61af66fc99e Initial load
duke
parents:
diff changeset
2608 // -1 means registration failed
a61af66fc99e Initial load
duke
parents:
diff changeset
2609 return (void *)-1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2610
a61af66fc99e Initial load
duke
parents:
diff changeset
2611 return CAST_FROM_FN_PTR(void*, oldSigAct.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
2612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2613
a61af66fc99e Initial load
duke
parents:
diff changeset
2614 void os::signal_raise(int signal_number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2615 raise(signal_number);
a61af66fc99e Initial load
duke
parents:
diff changeset
2616 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2617
a61af66fc99e Initial load
duke
parents:
diff changeset
2618 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
2619 * The following code is moved from os.cpp for making this
a61af66fc99e Initial load
duke
parents:
diff changeset
2620 * code platform specific, which it is by its very nature.
a61af66fc99e Initial load
duke
parents:
diff changeset
2621 */
a61af66fc99e Initial load
duke
parents:
diff changeset
2622
a61af66fc99e Initial load
duke
parents:
diff changeset
2623 // a counter for each possible signal value
a61af66fc99e Initial load
duke
parents:
diff changeset
2624 static int Sigexit = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2625 static int Maxlibjsigsigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
2626 static jint *pending_signals = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2627 static int *preinstalled_sigs = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2628 static struct sigaction *chainedsigactions = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2629 static sema_t sig_sem;
a61af66fc99e Initial load
duke
parents:
diff changeset
2630 typedef int (*version_getting_t)();
a61af66fc99e Initial load
duke
parents:
diff changeset
2631 version_getting_t os::Solaris::get_libjsig_version = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2632 static int libjsigversion = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
2633
a61af66fc99e Initial load
duke
parents:
diff changeset
2634 int os::sigexitnum_pd() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2635 assert(Sigexit > 0, "signal memory not yet initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
2636 return Sigexit;
a61af66fc99e Initial load
duke
parents:
diff changeset
2637 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2638
a61af66fc99e Initial load
duke
parents:
diff changeset
2639 void os::Solaris::init_signal_mem() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2640 // Initialize signal structures
a61af66fc99e Initial load
duke
parents:
diff changeset
2641 Maxsignum = SIGRTMAX;
a61af66fc99e Initial load
duke
parents:
diff changeset
2642 Sigexit = Maxsignum+1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2643 assert(Maxsignum >0, "Unable to obtain max signal number");
a61af66fc99e Initial load
duke
parents:
diff changeset
2644
a61af66fc99e Initial load
duke
parents:
diff changeset
2645 Maxlibjsigsigs = Maxsignum;
a61af66fc99e Initial load
duke
parents:
diff changeset
2646
a61af66fc99e Initial load
duke
parents:
diff changeset
2647 // pending_signals has one int per signal
a61af66fc99e Initial load
duke
parents:
diff changeset
2648 // The additional signal is for SIGEXIT - exit signal to signal_thread
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
2649 pending_signals = (jint *)os::malloc(sizeof(jint) * (Sigexit+1), mtInternal);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2650 memset(pending_signals, 0, (sizeof(jint) * (Sigexit+1)));
a61af66fc99e Initial load
duke
parents:
diff changeset
2651
a61af66fc99e Initial load
duke
parents:
diff changeset
2652 if (UseSignalChaining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2653 chainedsigactions = (struct sigaction *)malloc(sizeof(struct sigaction)
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
2654 * (Maxsignum + 1), mtInternal);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2655 memset(chainedsigactions, 0, (sizeof(struct sigaction) * (Maxsignum + 1)));
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
2656 preinstalled_sigs = (int *)os::malloc(sizeof(int) * (Maxsignum + 1), mtInternal);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2657 memset(preinstalled_sigs, 0, (sizeof(int) * (Maxsignum + 1)));
a61af66fc99e Initial load
duke
parents:
diff changeset
2658 }
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
2659 ourSigFlags = (int*)malloc(sizeof(int) * (Maxsignum + 1 ), mtInternal);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2660 memset(ourSigFlags, 0, sizeof(int) * (Maxsignum + 1));
a61af66fc99e Initial load
duke
parents:
diff changeset
2661 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2662
a61af66fc99e Initial load
duke
parents:
diff changeset
2663 void os::signal_init_pd() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2664 int ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
2665
a61af66fc99e Initial load
duke
parents:
diff changeset
2666 ret = ::sema_init(&sig_sem, 0, NULL, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
2667 assert(ret == 0, "sema_init() failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2668 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2669
a61af66fc99e Initial load
duke
parents:
diff changeset
2670 void os::signal_notify(int signal_number) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2671 int ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
2672
a61af66fc99e Initial load
duke
parents:
diff changeset
2673 Atomic::inc(&pending_signals[signal_number]);
a61af66fc99e Initial load
duke
parents:
diff changeset
2674 ret = ::sema_post(&sig_sem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2675 assert(ret == 0, "sema_post() failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2676 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2677
a61af66fc99e Initial load
duke
parents:
diff changeset
2678 static int check_pending_signals(bool wait_for_signal) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2679 int ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
2680 while (true) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2681 for (int i = 0; i < Sigexit + 1; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2682 jint n = pending_signals[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
2683 if (n > 0 && n == Atomic::cmpxchg(n - 1, &pending_signals[i], n)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2684 return i;
a61af66fc99e Initial load
duke
parents:
diff changeset
2685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2686 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2687 if (!wait_for_signal) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2688 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2689 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2690 JavaThread *thread = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
2691 ThreadBlockInVM tbivm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
2692
a61af66fc99e Initial load
duke
parents:
diff changeset
2693 bool threadIsSuspended;
a61af66fc99e Initial load
duke
parents:
diff changeset
2694 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
2695 thread->set_suspend_equivalent();
a61af66fc99e Initial load
duke
parents:
diff changeset
2696 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
a61af66fc99e Initial load
duke
parents:
diff changeset
2697 while((ret = ::sema_wait(&sig_sem)) == EINTR)
a61af66fc99e Initial load
duke
parents:
diff changeset
2698 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
2699 assert(ret == 0, "sema_wait() failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2700
a61af66fc99e Initial load
duke
parents:
diff changeset
2701 // were we externally suspended while we were waiting?
a61af66fc99e Initial load
duke
parents:
diff changeset
2702 threadIsSuspended = thread->handle_special_suspend_equivalent_condition();
a61af66fc99e Initial load
duke
parents:
diff changeset
2703 if (threadIsSuspended) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2704 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2705 // The semaphore has been incremented, but while we were waiting
a61af66fc99e Initial load
duke
parents:
diff changeset
2706 // another thread suspended us. We don't want to continue running
a61af66fc99e Initial load
duke
parents:
diff changeset
2707 // while suspended because that would surprise the thread that
a61af66fc99e Initial load
duke
parents:
diff changeset
2708 // suspended us.
a61af66fc99e Initial load
duke
parents:
diff changeset
2709 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2710 ret = ::sema_post(&sig_sem);
a61af66fc99e Initial load
duke
parents:
diff changeset
2711 assert(ret == 0, "sema_post() failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
2712
a61af66fc99e Initial load
duke
parents:
diff changeset
2713 thread->java_suspend_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
2714 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2715 } while (threadIsSuspended);
a61af66fc99e Initial load
duke
parents:
diff changeset
2716 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2717 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2718
a61af66fc99e Initial load
duke
parents:
diff changeset
2719 int os::signal_lookup() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2720 return check_pending_signals(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
2721 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2722
a61af66fc99e Initial load
duke
parents:
diff changeset
2723 int os::signal_wait() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2724 return check_pending_signals(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2725 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2726
a61af66fc99e Initial load
duke
parents:
diff changeset
2727 ////////////////////////////////////////////////////////////////////////////////
a61af66fc99e Initial load
duke
parents:
diff changeset
2728 // Virtual Memory
a61af66fc99e Initial load
duke
parents:
diff changeset
2729
a61af66fc99e Initial load
duke
parents:
diff changeset
2730 static int page_size = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2731
a61af66fc99e Initial load
duke
parents:
diff changeset
2732 // The mmap MAP_ALIGN flag is supported on Solaris 9 and later. init_2() will
a61af66fc99e Initial load
duke
parents:
diff changeset
2733 // clear this var if support is not available.
a61af66fc99e Initial load
duke
parents:
diff changeset
2734 static bool has_map_align = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2735
a61af66fc99e Initial load
duke
parents:
diff changeset
2736 int os::vm_page_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2737 assert(page_size != -1, "must call os::init");
a61af66fc99e Initial load
duke
parents:
diff changeset
2738 return page_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
2739 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2740
a61af66fc99e Initial load
duke
parents:
diff changeset
2741 // Solaris allocates memory by pages.
a61af66fc99e Initial load
duke
parents:
diff changeset
2742 int os::vm_allocation_granularity() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2743 assert(page_size != -1, "must call os::init");
a61af66fc99e Initial load
duke
parents:
diff changeset
2744 return page_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
2745 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2746
10969
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2747 static bool recoverable_mmap_error(int err) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2748 // See if the error is one we can let the caller handle. This
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2749 // list of errno values comes from the Solaris mmap(2) man page.
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2750 switch (err) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2751 case EBADF:
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2752 case EINVAL:
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2753 case ENOTSUP:
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2754 // let the caller deal with these errors
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2755 return true;
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2756
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2757 default:
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2758 // Any remaining errors on this OS can cause our reserved mapping
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2759 // to be lost. That can cause confusion where different data
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2760 // structures think they have the same memory mapped. The worst
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2761 // scenario is if both the VM and a library think they have the
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2762 // same memory mapped.
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2763 return false;
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2764 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2765 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2766
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2767 static void warn_fail_commit_memory(char* addr, size_t bytes, bool exec,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2768 int err) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2769 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2770 ", %d) failed; error='%s' (errno=%d)", addr, bytes, exec,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2771 strerror(err), err);
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2772 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2773
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2774 static void warn_fail_commit_memory(char* addr, size_t bytes,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2775 size_t alignment_hint, bool exec,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2776 int err) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2777 warning("INFO: os::commit_memory(" PTR_FORMAT ", " SIZE_FORMAT
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2778 ", " SIZE_FORMAT ", %d) failed; error='%s' (errno=%d)", addr, bytes,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2779 alignment_hint, exec, strerror(err), err);
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2780 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2781
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2782 int os::Solaris::commit_memory_impl(char* addr, size_t bytes, bool exec) {
656
6bdd6923ba16 6541756: Reduce executable C-heap
coleenp
parents: 647
diff changeset
2783 int prot = exec ? PROT_READ|PROT_WRITE|PROT_EXEC : PROT_READ|PROT_WRITE;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2784 size_t size = bytes;
3885
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3859
diff changeset
2785 char *res = Solaris::mmap_chunk(addr, size, MAP_PRIVATE|MAP_FIXED, prot);
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3859
diff changeset
2786 if (res != NULL) {
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3859
diff changeset
2787 if (UseNUMAInterleaving) {
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3859
diff changeset
2788 numa_make_global(addr, bytes);
3cd0157e1d4d 7082969: NUMA interleaving
iveresov
parents: 3859
diff changeset
2789 }
10969
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2790 return 0;
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2791 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2792
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2793 int err = errno; // save errno from mmap() call in mmap_chunk()
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2794
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2795 if (!recoverable_mmap_error(err)) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2796 warn_fail_commit_memory(addr, bytes, exec, err);
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2797 vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, "committing reserved memory.");
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2798 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2799
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2800 return err;
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2801 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2802
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2803 bool os::pd_commit_memory(char* addr, size_t bytes, bool exec) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2804 return Solaris::commit_memory_impl(addr, bytes, exec) == 0;
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2805 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2806
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2807 void os::pd_commit_memory_or_exit(char* addr, size_t bytes, bool exec,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2808 const char* mesg) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2809 assert(mesg != NULL, "mesg must be specified");
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2810 int err = os::Solaris::commit_memory_impl(addr, bytes, exec);
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2811 if (err != 0) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2812 // the caller wants all commit errors to exit with the specified mesg:
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2813 warn_fail_commit_memory(addr, bytes, exec, err);
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2814 vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, mesg);
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2815 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2816 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2817
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2818 int os::Solaris::commit_memory_impl(char* addr, size_t bytes,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2819 size_t alignment_hint, bool exec) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2820 int err = Solaris::commit_memory_impl(addr, bytes, exec);
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2821 if (err == 0) {
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
2822 if (UseLargePages && (alignment_hint > (size_t)vm_page_size())) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2823 // If the large page size has been set and the VM
a61af66fc99e Initial load
duke
parents:
diff changeset
2824 // is using large pages, use the large page size
a61af66fc99e Initial load
duke
parents:
diff changeset
2825 // if it is smaller than the alignment hint. This is
a61af66fc99e Initial load
duke
parents:
diff changeset
2826 // a case where the VM wants to use a larger alignment size
a61af66fc99e Initial load
duke
parents:
diff changeset
2827 // for its own reasons but still want to use large pages
a61af66fc99e Initial load
duke
parents:
diff changeset
2828 // (which is what matters to setting the mpss range.
a61af66fc99e Initial load
duke
parents:
diff changeset
2829 size_t page_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2830 if (large_page_size() < alignment_hint) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2831 assert(UseLargePages, "Expected to be here for large page use only");
a61af66fc99e Initial load
duke
parents:
diff changeset
2832 page_size = large_page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
2833 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2834 // If the alignment hint is less than the large page
a61af66fc99e Initial load
duke
parents:
diff changeset
2835 // size, the VM wants a particular alignment (thus the hint)
a61af66fc99e Initial load
duke
parents:
diff changeset
2836 // for internal reasons. Try to set the mpss range using
a61af66fc99e Initial load
duke
parents:
diff changeset
2837 // the alignment_hint.
a61af66fc99e Initial load
duke
parents:
diff changeset
2838 page_size = alignment_hint;
a61af66fc99e Initial load
duke
parents:
diff changeset
2839 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2840 // Since this is a hint, ignore any failures.
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
2841 (void)Solaris::setup_large_pages(addr, bytes, page_size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2842 }
10969
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2843 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2844 return err;
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2845 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2846
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2847 bool os::pd_commit_memory(char* addr, size_t bytes, size_t alignment_hint,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2848 bool exec) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2849 return Solaris::commit_memory_impl(addr, bytes, alignment_hint, exec) == 0;
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2850 }
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2851
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2852 void os::pd_commit_memory_or_exit(char* addr, size_t bytes,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2853 size_t alignment_hint, bool exec,
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2854 const char* mesg) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2855 assert(mesg != NULL, "mesg must be specified");
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2856 int err = os::Solaris::commit_memory_impl(addr, bytes, alignment_hint, exec);
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2857 if (err != 0) {
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2858 // the caller wants all commit errors to exit with the specified mesg:
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2859 warn_fail_commit_memory(addr, bytes, alignment_hint, exec, err);
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2860 vm_exit_out_of_memory(bytes, OOM_MMAP_ERROR, mesg);
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2861 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2863
a61af66fc99e Initial load
duke
parents:
diff changeset
2864 // Uncommit the pages in a specified region.
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
2865 void os::pd_free_memory(char* addr, size_t bytes, size_t alignment_hint) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2866 if (madvise(addr, bytes, MADV_FREE) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2867 debug_only(warning("MADV_FREE failed."));
a61af66fc99e Initial load
duke
parents:
diff changeset
2868 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2869 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2870 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2871
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
2872 bool os::pd_create_stack_guard_pages(char* addr, size_t size) {
10969
a837fa3d3f86 8013057: assert(_needs_gc || SafepointSynchronize::is_at_safepoint()) failed: only read at safepoint
dcubed
parents: 10405
diff changeset
2873 return os::commit_memory(addr, size, !ExecMem);
1320
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2874 }
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2875
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2876 bool os::remove_stack_guard_pages(char* addr, size_t size) {
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2877 return os::uncommit_memory(addr, size);
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2878 }
3b3d12e645e7 6929067: Stack guard pages should be removed when thread is detached
coleenp
parents: 1123
diff changeset
2879
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2880 // Change the page size in a given range.
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
2881 void os::pd_realign_memory(char *addr, size_t bytes, size_t alignment_hint) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2882 assert((intptr_t)addr % alignment_hint == 0, "Address should be aligned.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2883 assert((intptr_t)(addr + bytes) % alignment_hint == 0, "End should be aligned.");
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
2884 if (UseLargePages) {
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
2885 Solaris::setup_large_pages(addr, bytes, alignment_hint);
3292
c303b3532d4a 7037939: NUMA: Disable adaptive resizing if SHM large pages are used
iveresov
parents: 2304
diff changeset
2886 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2887 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2888
a61af66fc99e Initial load
duke
parents:
diff changeset
2889 // Tell the OS to make the range local to the first-touching LWP
141
fcbfc50865ab 6684395: Port NUMA-aware allocator to linux
iveresov
parents: 89
diff changeset
2890 void os::numa_make_local(char *addr, size_t bytes, int lgrp_hint) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2891 assert((intptr_t)addr % os::vm_page_size() == 0, "Address should be page-aligned.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2892 if (madvise(addr, bytes, MADV_ACCESS_LWP) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2893 debug_only(warning("MADV_ACCESS_LWP failed."));
a61af66fc99e Initial load
duke
parents:
diff changeset
2894 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2895 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2896
a61af66fc99e Initial load
duke
parents:
diff changeset
2897 // Tell the OS that this range would be accessed from different LWPs.
a61af66fc99e Initial load
duke
parents:
diff changeset
2898 void os::numa_make_global(char *addr, size_t bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2899 assert((intptr_t)addr % os::vm_page_size() == 0, "Address should be page-aligned.");
a61af66fc99e Initial load
duke
parents:
diff changeset
2900 if (madvise(addr, bytes, MADV_ACCESS_MANY) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2901 debug_only(warning("MADV_ACCESS_MANY failed."));
a61af66fc99e Initial load
duke
parents:
diff changeset
2902 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2903 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2904
a61af66fc99e Initial load
duke
parents:
diff changeset
2905 // Get the number of the locality groups.
a61af66fc99e Initial load
duke
parents:
diff changeset
2906 size_t os::numa_get_groups_num() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2907 size_t n = Solaris::lgrp_nlgrps(Solaris::lgrp_cookie());
a61af66fc99e Initial load
duke
parents:
diff changeset
2908 return n != -1 ? n : 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2909 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2910
a61af66fc99e Initial load
duke
parents:
diff changeset
2911 // Get a list of leaf locality groups. A leaf lgroup is group that
a61af66fc99e Initial load
duke
parents:
diff changeset
2912 // doesn't have any children. Typical leaf group is a CPU or a CPU/memory
a61af66fc99e Initial load
duke
parents:
diff changeset
2913 // board. An LWP is assigned to one of these groups upon creation.
a61af66fc99e Initial load
duke
parents:
diff changeset
2914 size_t os::numa_get_leaf_groups(int *ids, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2915 if ((ids[0] = Solaris::lgrp_root(Solaris::lgrp_cookie())) == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2916 ids[0] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2917 return 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2918 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2919 int result_size = 0, top = 1, bottom = 0, cur = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2920 for (int k = 0; k < size; k++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2921 int r = Solaris::lgrp_children(Solaris::lgrp_cookie(), ids[cur],
a61af66fc99e Initial load
duke
parents:
diff changeset
2922 (Solaris::lgrp_id_t*)&ids[top], size - top);
a61af66fc99e Initial load
duke
parents:
diff changeset
2923 if (r == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2924 ids[0] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2925 return 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2926 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2927 if (!r) {
144
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2928 // That's a leaf node.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2929 assert (bottom <= cur, "Sanity check");
144
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2930 // Check if the node has memory
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2931 if (Solaris::lgrp_resources(Solaris::lgrp_cookie(), ids[cur],
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2932 NULL, 0, LGRP_RSRC_MEM) > 0) {
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2933 ids[bottom++] = ids[cur];
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2934 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2935 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2936 top += r;
a61af66fc99e Initial load
duke
parents:
diff changeset
2937 cur++;
a61af66fc99e Initial load
duke
parents:
diff changeset
2938 }
268
d6340ab4105b 6723228: NUMA allocator: assert(lgrp_id != -1, "No lgrp_id set")
iveresov
parents: 267
diff changeset
2939 if (bottom == 0) {
d6340ab4105b 6723228: NUMA allocator: assert(lgrp_id != -1, "No lgrp_id set")
iveresov
parents: 267
diff changeset
2940 // Handle a situation, when the OS reports no memory available.
d6340ab4105b 6723228: NUMA allocator: assert(lgrp_id != -1, "No lgrp_id set")
iveresov
parents: 267
diff changeset
2941 // Assume UMA architecture.
d6340ab4105b 6723228: NUMA allocator: assert(lgrp_id != -1, "No lgrp_id set")
iveresov
parents: 267
diff changeset
2942 ids[0] = 0;
d6340ab4105b 6723228: NUMA allocator: assert(lgrp_id != -1, "No lgrp_id set")
iveresov
parents: 267
diff changeset
2943 return 1;
d6340ab4105b 6723228: NUMA allocator: assert(lgrp_id != -1, "No lgrp_id set")
iveresov
parents: 267
diff changeset
2944 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2945 return bottom;
a61af66fc99e Initial load
duke
parents:
diff changeset
2946 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2947
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 144
diff changeset
2948 // Detect the topology change. Typically happens during CPU plugging-unplugging.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2949 bool os::numa_topology_changed() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2950 int is_stale = Solaris::lgrp_cookie_stale(Solaris::lgrp_cookie());
a61af66fc99e Initial load
duke
parents:
diff changeset
2951 if (is_stale != -1 && is_stale) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2952 Solaris::lgrp_fini(Solaris::lgrp_cookie());
a61af66fc99e Initial load
duke
parents:
diff changeset
2953 Solaris::lgrp_cookie_t c = Solaris::lgrp_init(Solaris::LGRP_VIEW_CALLER);
a61af66fc99e Initial load
duke
parents:
diff changeset
2954 assert(c != 0, "Failure to initialize LGRP API");
a61af66fc99e Initial load
duke
parents:
diff changeset
2955 Solaris::set_lgrp_cookie(c);
a61af66fc99e Initial load
duke
parents:
diff changeset
2956 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2957 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2958 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2959 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2960
a61af66fc99e Initial load
duke
parents:
diff changeset
2961 // Get the group id of the current LWP.
a61af66fc99e Initial load
duke
parents:
diff changeset
2962 int os::numa_get_group_id() {
144
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2963 int lgrp_id = Solaris::lgrp_home(P_LWPID, P_MYID);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2964 if (lgrp_id == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2965 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2966 }
144
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2967 const int size = os::numa_get_groups_num();
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2968 int *ids = (int*)alloca(size * sizeof(int));
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2969
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2970 // Get the ids of all lgroups with memory; r is the count.
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2971 int r = Solaris::lgrp_resources(Solaris::lgrp_cookie(), lgrp_id,
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2972 (Solaris::lgrp_id_t*)ids, size, LGRP_RSRC_MEM);
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2973 if (r <= 0) {
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2974 return 0;
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2975 }
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
2976 return ids[os::random() % r];
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2977 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2978
a61af66fc99e Initial load
duke
parents:
diff changeset
2979 // Request information about the page.
a61af66fc99e Initial load
duke
parents:
diff changeset
2980 bool os::get_page_info(char *start, page_info* info) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2981 const uint_t info_types[] = { MEMINFO_VLGRP, MEMINFO_VPAGESIZE };
a61af66fc99e Initial load
duke
parents:
diff changeset
2982 uint64_t addr = (uintptr_t)start;
a61af66fc99e Initial load
duke
parents:
diff changeset
2983 uint64_t outdata[2];
a61af66fc99e Initial load
duke
parents:
diff changeset
2984 uint_t validity = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2985
a61af66fc99e Initial load
duke
parents:
diff changeset
2986 if (os::Solaris::meminfo(&addr, 1, info_types, 2, outdata, &validity) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2987 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2988 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2989
a61af66fc99e Initial load
duke
parents:
diff changeset
2990 info->size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2991 info->lgrp_id = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
2992
a61af66fc99e Initial load
duke
parents:
diff changeset
2993 if ((validity & 1) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2994 if ((validity & 2) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2995 info->lgrp_id = outdata[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
2996 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2997 if ((validity & 4) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2998 info->size = outdata[1];
a61af66fc99e Initial load
duke
parents:
diff changeset
2999 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3000 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3002 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3003 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3004
a61af66fc99e Initial load
duke
parents:
diff changeset
3005 // Scan the pages from start to end until a page different than
a61af66fc99e Initial load
duke
parents:
diff changeset
3006 // the one described in the info parameter is encountered.
a61af66fc99e Initial load
duke
parents:
diff changeset
3007 char *os::scan_pages(char *start, char* end, page_info* page_expected, page_info* page_found) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3008 const uint_t info_types[] = { MEMINFO_VLGRP, MEMINFO_VPAGESIZE };
a61af66fc99e Initial load
duke
parents:
diff changeset
3009 const size_t types = sizeof(info_types) / sizeof(info_types[0]);
a61af66fc99e Initial load
duke
parents:
diff changeset
3010 uint64_t addrs[MAX_MEMINFO_CNT], outdata[types * MAX_MEMINFO_CNT];
a61af66fc99e Initial load
duke
parents:
diff changeset
3011 uint_t validity[MAX_MEMINFO_CNT];
a61af66fc99e Initial load
duke
parents:
diff changeset
3012
a61af66fc99e Initial load
duke
parents:
diff changeset
3013 size_t page_size = MAX2((size_t)os::vm_page_size(), page_expected->size);
a61af66fc99e Initial load
duke
parents:
diff changeset
3014 uint64_t p = (uint64_t)start;
a61af66fc99e Initial load
duke
parents:
diff changeset
3015 while (p < (uint64_t)end) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3016 addrs[0] = p;
a61af66fc99e Initial load
duke
parents:
diff changeset
3017 size_t addrs_count = 1;
8739
ca9580859cf4 8004697: SIGSEGV on Solaris sparc with -XX:+UseNUMA
stefank
parents: 8067
diff changeset
3018 while (addrs_count < MAX_MEMINFO_CNT && addrs[addrs_count - 1] + page_size < (uint64_t)end) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3019 addrs[addrs_count] = addrs[addrs_count - 1] + page_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
3020 addrs_count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
3021 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3022
a61af66fc99e Initial load
duke
parents:
diff changeset
3023 if (os::Solaris::meminfo(addrs, addrs_count, info_types, types, outdata, validity) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3024 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3025 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3026
a61af66fc99e Initial load
duke
parents:
diff changeset
3027 size_t i = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3028 for (; i < addrs_count; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3029 if ((validity[i] & 1) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3030 if ((validity[i] & 4) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3031 if (outdata[types * i + 1] != page_expected->size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3032 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3033 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3034 } else
a61af66fc99e Initial load
duke
parents:
diff changeset
3035 if (page_expected->size != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3036 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3037 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3038
a61af66fc99e Initial load
duke
parents:
diff changeset
3039 if ((validity[i] & 2) != 0 && page_expected->lgrp_id > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3040 if (outdata[types * i] != page_expected->lgrp_id) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3041 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3042 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3043 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3044 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3045 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3046 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3047 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3048
a61af66fc99e Initial load
duke
parents:
diff changeset
3049 if (i != addrs_count) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3050 if ((validity[i] & 2) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3051 page_found->lgrp_id = outdata[types * i];
a61af66fc99e Initial load
duke
parents:
diff changeset
3052 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3053 page_found->lgrp_id = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3054 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3055 if ((validity[i] & 4) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3056 page_found->size = outdata[types * i + 1];
a61af66fc99e Initial load
duke
parents:
diff changeset
3057 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3058 page_found->size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3059 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3060 return (char*)addrs[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
3061 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3062
a61af66fc99e Initial load
duke
parents:
diff changeset
3063 p = addrs[addrs_count - 1] + page_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
3064 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3065 return end;
a61af66fc99e Initial load
duke
parents:
diff changeset
3066 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3067
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
3068 bool os::pd_uncommit_memory(char* addr, size_t bytes) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3069 size_t size = bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
3070 // Map uncommitted pages PROT_NONE so we fail early if we touch an
a61af66fc99e Initial load
duke
parents:
diff changeset
3071 // uncommitted page. Otherwise, the read/write might succeed if we
a61af66fc99e Initial load
duke
parents:
diff changeset
3072 // have enough swap space to back the physical page.
a61af66fc99e Initial load
duke
parents:
diff changeset
3073 return
a61af66fc99e Initial load
duke
parents:
diff changeset
3074 NULL != Solaris::mmap_chunk(addr, size,
a61af66fc99e Initial load
duke
parents:
diff changeset
3075 MAP_PRIVATE|MAP_FIXED|MAP_NORESERVE,
a61af66fc99e Initial load
duke
parents:
diff changeset
3076 PROT_NONE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3077 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3078
a61af66fc99e Initial load
duke
parents:
diff changeset
3079 char* os::Solaris::mmap_chunk(char *addr, size_t size, int flags, int prot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3080 char *b = (char *)mmap(addr, size, prot, flags, os::Solaris::_dev_zero_fd, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
3081
a61af66fc99e Initial load
duke
parents:
diff changeset
3082 if (b == MAP_FAILED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3083 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3084 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3085 return b;
a61af66fc99e Initial load
duke
parents:
diff changeset
3086 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3087
60
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3088 char* os::Solaris::anon_mmap(char* requested_addr, size_t bytes, size_t alignment_hint, bool fixed) {
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3089 char* addr = requested_addr;
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3090 int flags = MAP_PRIVATE | MAP_NORESERVE;
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3091
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3092 assert(!(fixed && (alignment_hint > 0)), "alignment hint meaningless with fixed mmap");
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3093
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3094 if (fixed) {
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3095 flags |= MAP_FIXED;
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3096 } else if (has_map_align && (alignment_hint > (size_t) vm_page_size())) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3097 flags |= MAP_ALIGN;
a61af66fc99e Initial load
duke
parents:
diff changeset
3098 addr = (char*) alignment_hint;
a61af66fc99e Initial load
duke
parents:
diff changeset
3099 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3100
a61af66fc99e Initial load
duke
parents:
diff changeset
3101 // Map uncommitted pages PROT_NONE so we fail early if we touch an
a61af66fc99e Initial load
duke
parents:
diff changeset
3102 // uncommitted page. Otherwise, the read/write might succeed if we
a61af66fc99e Initial load
duke
parents:
diff changeset
3103 // have enough swap space to back the physical page.
60
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3104 return mmap_chunk(addr, bytes, flags, PROT_NONE);
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3105 }
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3106
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
3107 char* os::pd_reserve_memory(size_t bytes, char* requested_addr, size_t alignment_hint) {
60
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3108 char* addr = Solaris::anon_mmap(requested_addr, bytes, alignment_hint, (requested_addr != NULL));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3109
a61af66fc99e Initial load
duke
parents:
diff changeset
3110 guarantee(requested_addr == NULL || requested_addr == addr,
a61af66fc99e Initial load
duke
parents:
diff changeset
3111 "OS failed to return requested mmap address.");
a61af66fc99e Initial load
duke
parents:
diff changeset
3112 return addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3114
a61af66fc99e Initial load
duke
parents:
diff changeset
3115 // Reserve memory at an arbitrary address, only if that area is
a61af66fc99e Initial load
duke
parents:
diff changeset
3116 // available (and not reserved for something else).
a61af66fc99e Initial load
duke
parents:
diff changeset
3117
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
3118 char* os::pd_attempt_reserve_memory_at(size_t bytes, char* requested_addr) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3119 const int max_tries = 10;
a61af66fc99e Initial load
duke
parents:
diff changeset
3120 char* base[max_tries];
a61af66fc99e Initial load
duke
parents:
diff changeset
3121 size_t size[max_tries];
a61af66fc99e Initial load
duke
parents:
diff changeset
3122
a61af66fc99e Initial load
duke
parents:
diff changeset
3123 // Solaris adds a gap between mmap'ed regions. The size of the gap
a61af66fc99e Initial load
duke
parents:
diff changeset
3124 // is dependent on the requested size and the MMU. Our initial gap
a61af66fc99e Initial load
duke
parents:
diff changeset
3125 // value here is just a guess and will be corrected later.
a61af66fc99e Initial load
duke
parents:
diff changeset
3126 bool had_top_overlap = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3127 bool have_adjusted_gap = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3128 size_t gap = 0x400000;
a61af66fc99e Initial load
duke
parents:
diff changeset
3129
a61af66fc99e Initial load
duke
parents:
diff changeset
3130 // Assert only that the size is a multiple of the page size, since
a61af66fc99e Initial load
duke
parents:
diff changeset
3131 // that's all that mmap requires, and since that's all we really know
a61af66fc99e Initial load
duke
parents:
diff changeset
3132 // about at this low abstraction level. If we need higher alignment,
a61af66fc99e Initial load
duke
parents:
diff changeset
3133 // we can either pass an alignment to this method or verify alignment
a61af66fc99e Initial load
duke
parents:
diff changeset
3134 // in one of the methods further up the call chain. See bug 5044738.
a61af66fc99e Initial load
duke
parents:
diff changeset
3135 assert(bytes % os::vm_page_size() == 0, "reserving unexpected size block");
a61af66fc99e Initial load
duke
parents:
diff changeset
3136
60
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3137 // Since snv_84, Solaris attempts to honor the address hint - see 5003415.
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3138 // Give it a try, if the kernel honors the hint we can return immediately.
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3139 char* addr = Solaris::anon_mmap(requested_addr, bytes, 0, false);
6882
716c64bda5ba 7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents: 6854
diff changeset
3140
60
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3141 volatile int err = errno;
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3142 if (addr == requested_addr) {
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3143 return addr;
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3144 } else if (addr != NULL) {
6882
716c64bda5ba 7199092: NMT: NMT needs to deal overlapped virtual memory ranges
zgu
parents: 6854
diff changeset
3145 pd_unmap_memory(addr, bytes);
60
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3146 }
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3147
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3148 if (PrintMiscellaneous && Verbose) {
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3149 char buf[256];
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3150 buf[0] = '\0';
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3151 if (addr == NULL) {
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3152 jio_snprintf(buf, sizeof(buf), ": %s", strerror(err));
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3153 }
2080
c04052fd6ae1 7006505: Use kstat info to identify SPARC processor
kvn
parents: 1980
diff changeset
3154 warning("attempt_reserve_memory_at: couldn't reserve " SIZE_FORMAT " bytes at "
60
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3155 PTR_FORMAT ": reserve_memory_helper returned " PTR_FORMAT
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3156 "%s", bytes, requested_addr, addr, buf);
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3157 }
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3158
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3159 // Address hint method didn't work. Fall back to the old method.
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3160 // In theory, once SNV becomes our oldest supported platform, this
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3161 // code will no longer be needed.
8d84e28e68ba 6204603: Modify hotspot to use new Solaris mmap semantics for class data archive file
sbohne
parents: 0
diff changeset
3162 //
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3163 // Repeatedly allocate blocks until the block is allocated at the
a61af66fc99e Initial load
duke
parents:
diff changeset
3164 // right spot. Give up after max_tries.
a61af66fc99e Initial load
duke
parents:
diff changeset
3165 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
3166 for (i = 0; i < max_tries; ++i) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3167 base[i] = reserve_memory(bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
3168
a61af66fc99e Initial load
duke
parents:
diff changeset
3169 if (base[i] != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3170 // Is this the block we wanted?
a61af66fc99e Initial load
duke
parents:
diff changeset
3171 if (base[i] == requested_addr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3172 size[i] = bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
3173 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
3174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3175
a61af66fc99e Initial load
duke
parents:
diff changeset
3176 // check that the gap value is right
a61af66fc99e Initial load
duke
parents:
diff changeset
3177 if (had_top_overlap && !have_adjusted_gap) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3178 size_t actual_gap = base[i-1] - base[i] - bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
3179 if (gap != actual_gap) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3180 // adjust the gap value and retry the last 2 allocations
a61af66fc99e Initial load
duke
parents:
diff changeset
3181 assert(i > 0, "gap adjustment code problem");
a61af66fc99e Initial load
duke
parents:
diff changeset
3182 have_adjusted_gap = true; // adjust the gap only once, just in case
a61af66fc99e Initial load
duke
parents:
diff changeset
3183 gap = actual_gap;
a61af66fc99e Initial load
duke
parents:
diff changeset
3184 if (PrintMiscellaneous && Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3185 warning("attempt_reserve_memory_at: adjusted gap to 0x%lx", gap);
a61af66fc99e Initial load
duke
parents:
diff changeset
3186 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3187 unmap_memory(base[i], bytes);
a61af66fc99e Initial load
duke
parents:
diff changeset
3188 unmap_memory(base[i-1], size[i-1]);
a61af66fc99e Initial load
duke
parents:
diff changeset
3189 i-=2;
a61af66fc99e Initial load
duke
parents:
diff changeset
3190 continue;
a61af66fc99e Initial load
duke
parents:
diff changeset
3191 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3193
a61af66fc99e Initial load
duke
parents:
diff changeset
3194 // Does this overlap the block we wanted? Give back the overlapped
a61af66fc99e Initial load
duke
parents:
diff changeset
3195 // parts and try again.
a61af66fc99e Initial load
duke
parents:
diff changeset
3196 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3197 // There is still a bug in this code: if top_overlap == bytes,
a61af66fc99e Initial load
duke
parents:
diff changeset
3198 // the overlap is offset from requested region by the value of gap.
a61af66fc99e Initial load
duke
parents:
diff changeset
3199 // In this case giving back the overlapped part will not work,
a61af66fc99e Initial load
duke
parents:
diff changeset
3200 // because we'll give back the entire block at base[i] and
a61af66fc99e Initial load
duke
parents:
diff changeset
3201 // therefore the subsequent allocation will not generate a new gap.
a61af66fc99e Initial load
duke
parents:
diff changeset
3202 // This could be fixed with a new algorithm that used larger
a61af66fc99e Initial load
duke
parents:
diff changeset
3203 // or variable size chunks to find the requested region -
a61af66fc99e Initial load
duke
parents:
diff changeset
3204 // but such a change would introduce additional complications.
a61af66fc99e Initial load
duke
parents:
diff changeset
3205 // It's rare enough that the planets align for this bug,
a61af66fc99e Initial load
duke
parents:
diff changeset
3206 // so we'll just wait for a fix for 6204603/5003415 which
a61af66fc99e Initial load
duke
parents:
diff changeset
3207 // will provide a mmap flag to allow us to avoid this business.
a61af66fc99e Initial load
duke
parents:
diff changeset
3208
a61af66fc99e Initial load
duke
parents:
diff changeset
3209 size_t top_overlap = requested_addr + (bytes + gap) - base[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
3210 if (top_overlap >= 0 && top_overlap < bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3211 had_top_overlap = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3212 unmap_memory(base[i], top_overlap);
a61af66fc99e Initial load
duke
parents:
diff changeset
3213 base[i] += top_overlap;
a61af66fc99e Initial load
duke
parents:
diff changeset
3214 size[i] = bytes - top_overlap;
a61af66fc99e Initial load
duke
parents:
diff changeset
3215 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3216 size_t bottom_overlap = base[i] + bytes - requested_addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
3217 if (bottom_overlap >= 0 && bottom_overlap < bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3218 if (PrintMiscellaneous && Verbose && bottom_overlap == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3219 warning("attempt_reserve_memory_at: possible alignment bug");
a61af66fc99e Initial load
duke
parents:
diff changeset
3220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3221 unmap_memory(requested_addr, bottom_overlap);
a61af66fc99e Initial load
duke
parents:
diff changeset
3222 size[i] = bytes - bottom_overlap;
a61af66fc99e Initial load
duke
parents:
diff changeset
3223 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3224 size[i] = bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
3225 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3228 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3229
a61af66fc99e Initial load
duke
parents:
diff changeset
3230 // Give back the unused reserved pieces.
a61af66fc99e Initial load
duke
parents:
diff changeset
3231
a61af66fc99e Initial load
duke
parents:
diff changeset
3232 for (int j = 0; j < i; ++j) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3233 if (base[j] != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3234 unmap_memory(base[j], size[j]);
a61af66fc99e Initial load
duke
parents:
diff changeset
3235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3237
a61af66fc99e Initial load
duke
parents:
diff changeset
3238 return (i < max_tries) ? requested_addr : NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3239 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3240
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
3241 bool os::pd_release_memory(char* addr, size_t bytes) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3242 size_t size = bytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
3243 return munmap(addr, size) == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3245
a61af66fc99e Initial load
duke
parents:
diff changeset
3246 static bool solaris_mprotect(char* addr, size_t bytes, int prot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3247 assert(addr == (char*)align_size_down((uintptr_t)addr, os::vm_page_size()),
a61af66fc99e Initial load
duke
parents:
diff changeset
3248 "addr must be page aligned");
a61af66fc99e Initial load
duke
parents:
diff changeset
3249 int retVal = mprotect(addr, bytes, prot);
a61af66fc99e Initial load
duke
parents:
diff changeset
3250 return retVal == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3252
237
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3253 // Protect memory (Used to pass readonly pages through
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3254 // JNI GetArray<type>Elements with empty arrays.)
477
24fda36852ce 6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents: 462
diff changeset
3255 // Also, used for serialization page and for compressed oops null pointer
24fda36852ce 6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents: 462
diff changeset
3256 // checking.
237
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3257 bool os::protect_memory(char* addr, size_t bytes, ProtType prot,
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3258 bool is_committed) {
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3259 unsigned int p = 0;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3260 switch (prot) {
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3261 case MEM_PROT_NONE: p = PROT_NONE; break;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3262 case MEM_PROT_READ: p = PROT_READ; break;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3263 case MEM_PROT_RW: p = PROT_READ|PROT_WRITE; break;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3264 case MEM_PROT_RWX: p = PROT_READ|PROT_WRITE|PROT_EXEC; break;
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3265 default:
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3266 ShouldNotReachHere();
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3267 }
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3268 // is_committed is unused.
1fdb98a17101 6716785: implicit null checks not triggering with CompressedOops
coleenp
parents: 196
diff changeset
3269 return solaris_mprotect(addr, bytes, p);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3270 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3271
a61af66fc99e Initial load
duke
parents:
diff changeset
3272 // guard_memory and unguard_memory only happens within stack guard pages.
a61af66fc99e Initial load
duke
parents:
diff changeset
3273 // Since ISM pertains only to the heap, guard and unguard memory should not
a61af66fc99e Initial load
duke
parents:
diff changeset
3274 /// happen with an ISM region.
a61af66fc99e Initial load
duke
parents:
diff changeset
3275 bool os::guard_memory(char* addr, size_t bytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3276 return solaris_mprotect(addr, bytes, PROT_NONE);
a61af66fc99e Initial load
duke
parents:
diff changeset
3277 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3278
a61af66fc99e Initial load
duke
parents:
diff changeset
3279 bool os::unguard_memory(char* addr, size_t bytes) {
477
24fda36852ce 6727377: VM stack guard pages on Windows should PAGE_READWRITE not PAGE_EXECUTE_READWRITE
coleenp
parents: 462
diff changeset
3280 return solaris_mprotect(addr, bytes, PROT_READ|PROT_WRITE);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3281 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3282
a61af66fc99e Initial load
duke
parents:
diff changeset
3283 // Large page support
a61af66fc99e Initial load
duke
parents:
diff changeset
3284 static size_t _large_page_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3285
a61af66fc99e Initial load
duke
parents:
diff changeset
3286 // Insertion sort for small arrays (descending order).
a61af66fc99e Initial load
duke
parents:
diff changeset
3287 static void insertion_sort_descending(size_t* array, int len) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3288 for (int i = 0; i < len; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3289 size_t val = array[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
3290 for (size_t key = i; key > 0 && array[key - 1] < val; --key) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3291 size_t tmp = array[key];
a61af66fc99e Initial load
duke
parents:
diff changeset
3292 array[key] = array[key - 1];
a61af66fc99e Initial load
duke
parents:
diff changeset
3293 array[key - 1] = tmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
3294 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3295 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3296 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3297
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3298 bool os::Solaris::mpss_sanity_check(bool warn, size_t* page_size) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3299 const unsigned int usable_count = VM_Version::page_size_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
3300 if (usable_count == 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3301 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3303
3859
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3304 // Find the right getpagesizes interface. When solaris 11 is the minimum
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3305 // build platform, getpagesizes() (without the '2') can be called directly.
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3306 typedef int (*gps_t)(size_t[], int);
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3307 gps_t gps_func = CAST_TO_FN_PTR(gps_t, dlsym(RTLD_DEFAULT, "getpagesizes2"));
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3308 if (gps_func == NULL) {
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3309 gps_func = CAST_TO_FN_PTR(gps_t, dlsym(RTLD_DEFAULT, "getpagesizes"));
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3310 if (gps_func == NULL) {
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3311 if (warn) {
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3312 warning("MPSS is not supported by the operating system.");
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3313 }
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3314 return false;
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3315 }
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3316 }
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3317
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3318 // Fill the array of page sizes.
3859
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3319 int n = (*gps_func)(_page_sizes, page_sizes_max);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3320 assert(n > 0, "Solaris bug?");
3859
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3321
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3322 if (n == page_sizes_max) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3323 // Add a sentinel value (necessary only if the array was completely filled
a61af66fc99e Initial load
duke
parents:
diff changeset
3324 // since it is static (zeroed at initialization)).
a61af66fc99e Initial load
duke
parents:
diff changeset
3325 _page_sizes[--n] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3326 DEBUG_ONLY(warning("increase the size of the os::_page_sizes array.");)
a61af66fc99e Initial load
duke
parents:
diff changeset
3327 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3328 assert(_page_sizes[n] == 0, "missing sentinel");
3859
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3329 trace_page_sizes("available page sizes", _page_sizes, n);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3330
a61af66fc99e Initial load
duke
parents:
diff changeset
3331 if (n == 1) return false; // Only one page size available.
a61af66fc99e Initial load
duke
parents:
diff changeset
3332
a61af66fc99e Initial load
duke
parents:
diff changeset
3333 // Skip sizes larger than 4M (or LargePageSizeInBytes if it was set) and
a61af66fc99e Initial load
duke
parents:
diff changeset
3334 // select up to usable_count elements. First sort the array, find the first
a61af66fc99e Initial load
duke
parents:
diff changeset
3335 // acceptable value, then copy the usable sizes to the top of the array and
a61af66fc99e Initial load
duke
parents:
diff changeset
3336 // trim the rest. Make sure to include the default page size :-).
a61af66fc99e Initial load
duke
parents:
diff changeset
3337 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3338 // A better policy could get rid of the 4M limit by taking the sizes of the
a61af66fc99e Initial load
duke
parents:
diff changeset
3339 // important VM memory regions (java heap and possibly the code cache) into
a61af66fc99e Initial load
duke
parents:
diff changeset
3340 // account.
a61af66fc99e Initial load
duke
parents:
diff changeset
3341 insertion_sort_descending(_page_sizes, n);
a61af66fc99e Initial load
duke
parents:
diff changeset
3342 const size_t size_limit =
a61af66fc99e Initial load
duke
parents:
diff changeset
3343 FLAG_IS_DEFAULT(LargePageSizeInBytes) ? 4 * M : LargePageSizeInBytes;
a61af66fc99e Initial load
duke
parents:
diff changeset
3344 int beg;
a61af66fc99e Initial load
duke
parents:
diff changeset
3345 for (beg = 0; beg < n && _page_sizes[beg] > size_limit; ++beg) /* empty */ ;
a61af66fc99e Initial load
duke
parents:
diff changeset
3346 const int end = MIN2((int)usable_count, n) - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3347 for (int cur = 0; cur < end; ++cur, ++beg) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3348 _page_sizes[cur] = _page_sizes[beg];
a61af66fc99e Initial load
duke
parents:
diff changeset
3349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3350 _page_sizes[end] = vm_page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
3351 _page_sizes[end + 1] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3352
a61af66fc99e Initial load
duke
parents:
diff changeset
3353 if (_page_sizes[end] > _page_sizes[end - 1]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3354 // Default page size is not the smallest; sort again.
a61af66fc99e Initial load
duke
parents:
diff changeset
3355 insertion_sort_descending(_page_sizes, end + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3356 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3357 *page_size = _page_sizes[0];
a61af66fc99e Initial load
duke
parents:
diff changeset
3358
3859
24cee90e9453 6791672: enable 1G and larger pages on solaris
jcoomes
parents: 3800
diff changeset
3359 trace_page_sizes("usable page sizes", _page_sizes, end + 1);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3360 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3361 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3362
3318
188c9a5d6a6d 7040485: Use transparent huge page on linux by default
iveresov
parents: 3292
diff changeset
3363 void os::large_page_init() {
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3364 if (UseLargePages) {
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3365 // print a warning if any large page related flag is specified on command line
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3366 bool warn_on_failure = !FLAG_IS_DEFAULT(UseLargePages) ||
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3367 !FLAG_IS_DEFAULT(LargePageSizeInBytes);
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3368
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3369 UseLargePages = Solaris::mpss_sanity_check(warn_on_failure, &_large_page_size);
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3370 }
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3371 }
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3372
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3373 bool os::Solaris::setup_large_pages(caddr_t start, size_t bytes, size_t align) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3374 // Signal to OS that we want large pages for addresses
a61af66fc99e Initial load
duke
parents:
diff changeset
3375 // from addr, addr + bytes
a61af66fc99e Initial load
duke
parents:
diff changeset
3376 struct memcntl_mha mpss_struct;
a61af66fc99e Initial load
duke
parents:
diff changeset
3377 mpss_struct.mha_cmd = MHA_MAPSIZE_VA;
a61af66fc99e Initial load
duke
parents:
diff changeset
3378 mpss_struct.mha_pagesize = align;
a61af66fc99e Initial load
duke
parents:
diff changeset
3379 mpss_struct.mha_flags = 0;
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3380 // Upon successful completion, memcntl() returns 0
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3381 if (memcntl(start, bytes, MC_HAT_ADVISE, (caddr_t) &mpss_struct, 0, 0)) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3382 debug_only(warning("Attempt to use MPSS failed."));
a61af66fc99e Initial load
duke
parents:
diff changeset
3383 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3384 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3385 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3386 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3387
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11112
diff changeset
3388 char* os::reserve_memory_special(size_t size, size_t alignment, char* addr, bool exec) {
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3389 fatal("os::reserve_memory_special should not be called on Solaris.");
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3390 return NULL;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3392
a61af66fc99e Initial load
duke
parents:
diff changeset
3393 bool os::release_memory_special(char* base, size_t bytes) {
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3394 fatal("os::release_memory_special should not be called on Solaris.");
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3395 return false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3397
a61af66fc99e Initial load
duke
parents:
diff changeset
3398 size_t os::large_page_size() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3399 return _large_page_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
3400 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3401
a61af66fc99e Initial load
duke
parents:
diff changeset
3402 // MPSS allows application to commit large page memory on demand; with ISM
a61af66fc99e Initial load
duke
parents:
diff changeset
3403 // the entire memory region must be allocated as shared memory.
a61af66fc99e Initial load
duke
parents:
diff changeset
3404 bool os::can_commit_large_page_memory() {
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3405 return true;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3406 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3407
79
82db0859acbe 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 61
diff changeset
3408 bool os::can_execute_large_page_memory() {
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3409 return true;
79
82db0859acbe 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 61
diff changeset
3410 }
82db0859acbe 6642862: Code cache allocation fails with large pages after 6588638
jcoomes
parents: 61
diff changeset
3411
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3412 static int os_sleep(jlong millis, bool interruptible) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3413 const jlong limit = INT_MAX;
a61af66fc99e Initial load
duke
parents:
diff changeset
3414 jlong prevtime;
a61af66fc99e Initial load
duke
parents:
diff changeset
3415 int res;
a61af66fc99e Initial load
duke
parents:
diff changeset
3416
a61af66fc99e Initial load
duke
parents:
diff changeset
3417 while (millis > limit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3418 if ((res = os_sleep(limit, interruptible)) != OS_OK)
a61af66fc99e Initial load
duke
parents:
diff changeset
3419 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
3420 millis -= limit;
a61af66fc99e Initial load
duke
parents:
diff changeset
3421 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3422
a61af66fc99e Initial load
duke
parents:
diff changeset
3423 // Restart interrupted polls with new parameters until the proper delay
a61af66fc99e Initial load
duke
parents:
diff changeset
3424 // has been completed.
a61af66fc99e Initial load
duke
parents:
diff changeset
3425
a61af66fc99e Initial load
duke
parents:
diff changeset
3426 prevtime = getTimeMillis();
a61af66fc99e Initial load
duke
parents:
diff changeset
3427
a61af66fc99e Initial load
duke
parents:
diff changeset
3428 while (millis > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3429 jlong newtime;
a61af66fc99e Initial load
duke
parents:
diff changeset
3430
a61af66fc99e Initial load
duke
parents:
diff changeset
3431 if (!interruptible) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3432 // Following assert fails for os::yield_all:
a61af66fc99e Initial load
duke
parents:
diff changeset
3433 // assert(!thread->is_Java_thread(), "must not be java thread");
a61af66fc99e Initial load
duke
parents:
diff changeset
3434 res = poll(NULL, 0, millis);
a61af66fc99e Initial load
duke
parents:
diff changeset
3435 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3436 JavaThread *jt = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
3437
a61af66fc99e Initial load
duke
parents:
diff changeset
3438 INTERRUPTIBLE_NORESTART_VM_ALWAYS(poll(NULL, 0, millis), res, jt,
a61af66fc99e Initial load
duke
parents:
diff changeset
3439 os::Solaris::clear_interrupted);
a61af66fc99e Initial load
duke
parents:
diff changeset
3440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3441
a61af66fc99e Initial load
duke
parents:
diff changeset
3442 // INTERRUPTIBLE_NORESTART_VM_ALWAYS returns res == OS_INTRPT for
a61af66fc99e Initial load
duke
parents:
diff changeset
3443 // thread.Interrupt.
a61af66fc99e Initial load
duke
parents:
diff changeset
3444
1967
22260322f0be 6751923: JNDI wake up when clock_settime() is called
zgu
parents: 1867
diff changeset
3445 // See c/r 6751923. Poll can return 0 before time
22260322f0be 6751923: JNDI wake up when clock_settime() is called
zgu
parents: 1867
diff changeset
3446 // has elapsed if time is set via clock_settime (as NTP does).
22260322f0be 6751923: JNDI wake up when clock_settime() is called
zgu
parents: 1867
diff changeset
3447 // res == 0 if poll timed out (see man poll RETURN VALUES)
22260322f0be 6751923: JNDI wake up when clock_settime() is called
zgu
parents: 1867
diff changeset
3448 // using the logic below checks that we really did
22260322f0be 6751923: JNDI wake up when clock_settime() is called
zgu
parents: 1867
diff changeset
3449 // sleep at least "millis" if not we'll sleep again.
22260322f0be 6751923: JNDI wake up when clock_settime() is called
zgu
parents: 1867
diff changeset
3450 if( ( res == 0 ) || ((res == OS_ERR) && (errno == EINTR))) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3451 newtime = getTimeMillis();
a61af66fc99e Initial load
duke
parents:
diff changeset
3452 assert(newtime >= prevtime, "time moving backwards");
a61af66fc99e Initial load
duke
parents:
diff changeset
3453 /* Doing prevtime and newtime in microseconds doesn't help precision,
a61af66fc99e Initial load
duke
parents:
diff changeset
3454 and trying to round up to avoid lost milliseconds can result in a
a61af66fc99e Initial load
duke
parents:
diff changeset
3455 too-short delay. */
a61af66fc99e Initial load
duke
parents:
diff changeset
3456 millis -= newtime - prevtime;
a61af66fc99e Initial load
duke
parents:
diff changeset
3457 if(millis <= 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
3458 return OS_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
3459 prevtime = newtime;
a61af66fc99e Initial load
duke
parents:
diff changeset
3460 } else
a61af66fc99e Initial load
duke
parents:
diff changeset
3461 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
3462 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3463
a61af66fc99e Initial load
duke
parents:
diff changeset
3464 return OS_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
3465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3466
a61af66fc99e Initial load
duke
parents:
diff changeset
3467 // Read calls from inside the vm need to perform state transitions
a61af66fc99e Initial load
duke
parents:
diff changeset
3468 size_t os::read(int fd, void *buf, unsigned int nBytes) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3469 INTERRUPTIBLE_RETURN_INT_VM(::read(fd, buf, nBytes), os::Solaris::clear_interrupted);
a61af66fc99e Initial load
duke
parents:
diff changeset
3470 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3471
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
3472 size_t os::restartable_read(int fd, void *buf, unsigned int nBytes) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
3473 INTERRUPTIBLE_RETURN_INT(::read(fd, buf, nBytes), os::Solaris::clear_interrupted);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
3474 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
3475
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3476 int os::sleep(Thread* thread, jlong millis, bool interruptible) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3477 assert(thread == Thread::current(), "thread consistency check");
a61af66fc99e Initial load
duke
parents:
diff changeset
3478
a61af66fc99e Initial load
duke
parents:
diff changeset
3479 // TODO-FIXME: this should be removed.
a61af66fc99e Initial load
duke
parents:
diff changeset
3480 // On Solaris machines (especially 2.5.1) we found that sometimes the VM gets into a live lock
a61af66fc99e Initial load
duke
parents:
diff changeset
3481 // situation with a JavaThread being starved out of a lwp. The kernel doesn't seem to generate
a61af66fc99e Initial load
duke
parents:
diff changeset
3482 // a SIGWAITING signal which would enable the threads library to create a new lwp for the starving
a61af66fc99e Initial load
duke
parents:
diff changeset
3483 // thread. We suspect that because the Watcher thread keeps waking up at periodic intervals the kernel
a61af66fc99e Initial load
duke
parents:
diff changeset
3484 // is fooled into believing that the system is making progress. In the code below we block the
a61af66fc99e Initial load
duke
parents:
diff changeset
3485 // the watcher thread while safepoint is in progress so that it would not appear as though the
a61af66fc99e Initial load
duke
parents:
diff changeset
3486 // system is making progress.
a61af66fc99e Initial load
duke
parents:
diff changeset
3487 if (!Solaris::T2_libthread() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
3488 thread->is_Watcher_thread() && SafepointSynchronize::is_synchronizing() && !Arguments::has_profile()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3489 // We now try to acquire the threads lock. Since this lock is held by the VM thread during
a61af66fc99e Initial load
duke
parents:
diff changeset
3490 // the entire safepoint, the watcher thread will line up here during the safepoint.
a61af66fc99e Initial load
duke
parents:
diff changeset
3491 Threads_lock->lock_without_safepoint_check();
a61af66fc99e Initial load
duke
parents:
diff changeset
3492 Threads_lock->unlock();
a61af66fc99e Initial load
duke
parents:
diff changeset
3493 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3494
a61af66fc99e Initial load
duke
parents:
diff changeset
3495 if (thread->is_Java_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3496 // This is a JavaThread so we honor the _thread_blocked protocol
a61af66fc99e Initial load
duke
parents:
diff changeset
3497 // even for sleeps of 0 milliseconds. This was originally done
a61af66fc99e Initial load
duke
parents:
diff changeset
3498 // as a workaround for bug 4338139. However, now we also do it
a61af66fc99e Initial load
duke
parents:
diff changeset
3499 // to honor the suspend-equivalent protocol.
a61af66fc99e Initial load
duke
parents:
diff changeset
3500
a61af66fc99e Initial load
duke
parents:
diff changeset
3501 JavaThread *jt = (JavaThread *) thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
3502 ThreadBlockInVM tbivm(jt);
a61af66fc99e Initial load
duke
parents:
diff changeset
3503
a61af66fc99e Initial load
duke
parents:
diff changeset
3504 jt->set_suspend_equivalent();
a61af66fc99e Initial load
duke
parents:
diff changeset
3505 // cleared by handle_special_suspend_equivalent_condition() or
a61af66fc99e Initial load
duke
parents:
diff changeset
3506 // java_suspend_self() via check_and_wait_while_suspended()
a61af66fc99e Initial load
duke
parents:
diff changeset
3507
a61af66fc99e Initial load
duke
parents:
diff changeset
3508 int ret_code;
a61af66fc99e Initial load
duke
parents:
diff changeset
3509 if (millis <= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3510 thr_yield();
a61af66fc99e Initial load
duke
parents:
diff changeset
3511 ret_code = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3512 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3513 // The original sleep() implementation did not create an
a61af66fc99e Initial load
duke
parents:
diff changeset
3514 // OSThreadWaitState helper for sleeps of 0 milliseconds.
a61af66fc99e Initial load
duke
parents:
diff changeset
3515 // I'm preserving that decision for now.
a61af66fc99e Initial load
duke
parents:
diff changeset
3516 OSThreadWaitState osts(jt->osthread(), false /* not Object.wait() */);
a61af66fc99e Initial load
duke
parents:
diff changeset
3517
a61af66fc99e Initial load
duke
parents:
diff changeset
3518 ret_code = os_sleep(millis, interruptible);
a61af66fc99e Initial load
duke
parents:
diff changeset
3519 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3520
a61af66fc99e Initial load
duke
parents:
diff changeset
3521 // were we externally suspended while we were waiting?
a61af66fc99e Initial load
duke
parents:
diff changeset
3522 jt->check_and_wait_while_suspended();
a61af66fc99e Initial load
duke
parents:
diff changeset
3523
a61af66fc99e Initial load
duke
parents:
diff changeset
3524 return ret_code;
a61af66fc99e Initial load
duke
parents:
diff changeset
3525 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3526
a61af66fc99e Initial load
duke
parents:
diff changeset
3527 // non-JavaThread from this point on:
a61af66fc99e Initial load
duke
parents:
diff changeset
3528
a61af66fc99e Initial load
duke
parents:
diff changeset
3529 if (millis <= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3530 thr_yield();
a61af66fc99e Initial load
duke
parents:
diff changeset
3531 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3532 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3533
a61af66fc99e Initial load
duke
parents:
diff changeset
3534 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
a61af66fc99e Initial load
duke
parents:
diff changeset
3535
a61af66fc99e Initial load
duke
parents:
diff changeset
3536 return os_sleep(millis, interruptible);
a61af66fc99e Initial load
duke
parents:
diff changeset
3537 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3538
a61af66fc99e Initial load
duke
parents:
diff changeset
3539 int os::naked_sleep() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3540 // %% make the sleep time an integer flag. for now use 1 millisec.
a61af66fc99e Initial load
duke
parents:
diff changeset
3541 return os_sleep(1, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3542 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3543
a61af66fc99e Initial load
duke
parents:
diff changeset
3544 // Sleep forever; naked call to OS-specific sleep; use with CAUTION
a61af66fc99e Initial load
duke
parents:
diff changeset
3545 void os::infinite_sleep() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3546 while (true) { // sleep forever ...
a61af66fc99e Initial load
duke
parents:
diff changeset
3547 ::sleep(100); // ... 100 seconds at a time
a61af66fc99e Initial load
duke
parents:
diff changeset
3548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3549 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3550
a61af66fc99e Initial load
duke
parents:
diff changeset
3551 // Used to convert frequent JVM_Yield() to nops
a61af66fc99e Initial load
duke
parents:
diff changeset
3552 bool os::dont_yield() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3553 if (DontYieldALot) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3554 static hrtime_t last_time = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3555 hrtime_t diff = getTimeNanos() - last_time;
a61af66fc99e Initial load
duke
parents:
diff changeset
3556
a61af66fc99e Initial load
duke
parents:
diff changeset
3557 if (diff < DontYieldALotInterval * 1000000)
a61af66fc99e Initial load
duke
parents:
diff changeset
3558 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
3559
a61af66fc99e Initial load
duke
parents:
diff changeset
3560 last_time += diff;
a61af66fc99e Initial load
duke
parents:
diff changeset
3561
a61af66fc99e Initial load
duke
parents:
diff changeset
3562 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3563 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3564 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3565 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3566 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3567 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3568
a61af66fc99e Initial load
duke
parents:
diff changeset
3569 // Caveat: Solaris os::yield() causes a thread-state transition whereas
a61af66fc99e Initial load
duke
parents:
diff changeset
3570 // the linux and win32 implementations do not. This should be checked.
a61af66fc99e Initial load
duke
parents:
diff changeset
3571
a61af66fc99e Initial load
duke
parents:
diff changeset
3572 void os::yield() {
a61af66fc99e Initial load
duke
parents:
diff changeset
3573 // Yields to all threads with same or greater priority
a61af66fc99e Initial load
duke
parents:
diff changeset
3574 os::sleep(Thread::current(), 0, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3575 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3576
a61af66fc99e Initial load
duke
parents:
diff changeset
3577 // Note that yield semantics are defined by the scheduling class to which
a61af66fc99e Initial load
duke
parents:
diff changeset
3578 // the thread currently belongs. Typically, yield will _not yield to
a61af66fc99e Initial load
duke
parents:
diff changeset
3579 // other equal or higher priority threads that reside on the dispatch queues
a61af66fc99e Initial load
duke
parents:
diff changeset
3580 // of other CPUs.
a61af66fc99e Initial load
duke
parents:
diff changeset
3581
a61af66fc99e Initial load
duke
parents:
diff changeset
3582 os::YieldResult os::NakedYield() { thr_yield(); return os::YIELD_UNKNOWN; }
a61af66fc99e Initial load
duke
parents:
diff changeset
3583
a61af66fc99e Initial load
duke
parents:
diff changeset
3584
a61af66fc99e Initial load
duke
parents:
diff changeset
3585 // On Solaris we found that yield_all doesn't always yield to all other threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
3586 // There have been cases where there is a thread ready to execute but it doesn't
a61af66fc99e Initial load
duke
parents:
diff changeset
3587 // get an lwp as the VM thread continues to spin with sleeps of 1 millisecond.
a61af66fc99e Initial load
duke
parents:
diff changeset
3588 // The 1 millisecond wait doesn't seem long enough for the kernel to issue a
a61af66fc99e Initial load
duke
parents:
diff changeset
3589 // SIGWAITING signal which will cause a new lwp to be created. So we count the
a61af66fc99e Initial load
duke
parents:
diff changeset
3590 // number of times yield_all is called in the one loop and increase the sleep
a61af66fc99e Initial load
duke
parents:
diff changeset
3591 // time after 8 attempts. If this fails too we increase the concurrency level
a61af66fc99e Initial load
duke
parents:
diff changeset
3592 // so that the starving thread would get an lwp
a61af66fc99e Initial load
duke
parents:
diff changeset
3593
a61af66fc99e Initial load
duke
parents:
diff changeset
3594 void os::yield_all(int attempts) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3595 // Yields to all threads, including threads with lower priorities
a61af66fc99e Initial load
duke
parents:
diff changeset
3596 if (attempts == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3597 os::sleep(Thread::current(), 1, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3598 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3599 int iterations = attempts % 30;
a61af66fc99e Initial load
duke
parents:
diff changeset
3600 if (iterations == 0 && !os::Solaris::T2_libthread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3601 // thr_setconcurrency and _getconcurrency make sense only under T1.
a61af66fc99e Initial load
duke
parents:
diff changeset
3602 int noofLWPS = thr_getconcurrency();
a61af66fc99e Initial load
duke
parents:
diff changeset
3603 if (noofLWPS < (Threads::number_of_threads() + 2)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3604 thr_setconcurrency(thr_getconcurrency() + 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
3605 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3606 } else if (iterations < 25) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3607 os::sleep(Thread::current(), 1, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3608 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3609 os::sleep(Thread::current(), 10, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
3610 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3611 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3613
a61af66fc99e Initial load
duke
parents:
diff changeset
3614 // Called from the tight loops to possibly influence time-sharing heuristics
a61af66fc99e Initial load
duke
parents:
diff changeset
3615 void os::loop_breaker(int attempts) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3616 os::yield_all(attempts);
a61af66fc99e Initial load
duke
parents:
diff changeset
3617 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3618
a61af66fc99e Initial load
duke
parents:
diff changeset
3619
a61af66fc99e Initial load
duke
parents:
diff changeset
3620 // Interface for setting lwp priorities. If we are using T2 libthread,
a61af66fc99e Initial load
duke
parents:
diff changeset
3621 // which forces the use of BoundThreads or we manually set UseBoundThreads,
a61af66fc99e Initial load
duke
parents:
diff changeset
3622 // all of our threads will be assigned to real lwp's. Using the thr_setprio
a61af66fc99e Initial load
duke
parents:
diff changeset
3623 // function is meaningless in this mode so we must adjust the real lwp's priority
a61af66fc99e Initial load
duke
parents:
diff changeset
3624 // The routines below implement the getting and setting of lwp priorities.
a61af66fc99e Initial load
duke
parents:
diff changeset
3625 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3626 // Note: There are three priority scales used on Solaris. Java priotities
a61af66fc99e Initial load
duke
parents:
diff changeset
3627 // which range from 1 to 10, libthread "thr_setprio" scale which range
a61af66fc99e Initial load
duke
parents:
diff changeset
3628 // from 0 to 127, and the current scheduling class of the process we
a61af66fc99e Initial load
duke
parents:
diff changeset
3629 // are running in. This is typically from -60 to +60.
a61af66fc99e Initial load
duke
parents:
diff changeset
3630 // The setting of the lwp priorities in done after a call to thr_setprio
a61af66fc99e Initial load
duke
parents:
diff changeset
3631 // so Java priorities are mapped to libthread priorities and we map from
a61af66fc99e Initial load
duke
parents:
diff changeset
3632 // the latter to lwp priorities. We don't keep priorities stored in
a61af66fc99e Initial load
duke
parents:
diff changeset
3633 // Java priorities since some of our worker threads want to set priorities
a61af66fc99e Initial load
duke
parents:
diff changeset
3634 // higher than all Java threads.
a61af66fc99e Initial load
duke
parents:
diff changeset
3635 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3636 // For related information:
a61af66fc99e Initial load
duke
parents:
diff changeset
3637 // (1) man -s 2 priocntl
a61af66fc99e Initial load
duke
parents:
diff changeset
3638 // (2) man -s 4 priocntl
a61af66fc99e Initial load
duke
parents:
diff changeset
3639 // (3) man dispadmin
a61af66fc99e Initial load
duke
parents:
diff changeset
3640 // = librt.so
a61af66fc99e Initial load
duke
parents:
diff changeset
3641 // = libthread/common/rtsched.c - thrp_setlwpprio().
a61af66fc99e Initial load
duke
parents:
diff changeset
3642 // = ps -cL <pid> ... to validate priority.
a61af66fc99e Initial load
duke
parents:
diff changeset
3643 // = sched_get_priority_min and _max
a61af66fc99e Initial load
duke
parents:
diff changeset
3644 // pthread_create
a61af66fc99e Initial load
duke
parents:
diff changeset
3645 // sched_setparam
a61af66fc99e Initial load
duke
parents:
diff changeset
3646 // pthread_setschedparam
a61af66fc99e Initial load
duke
parents:
diff changeset
3647 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3648 // Assumptions:
a61af66fc99e Initial load
duke
parents:
diff changeset
3649 // + We assume that all threads in the process belong to the same
a61af66fc99e Initial load
duke
parents:
diff changeset
3650 // scheduling class. IE. an homogenous process.
a61af66fc99e Initial load
duke
parents:
diff changeset
3651 // + Must be root or in IA group to change change "interactive" attribute.
a61af66fc99e Initial load
duke
parents:
diff changeset
3652 // Priocntl() will fail silently. The only indication of failure is when
a61af66fc99e Initial load
duke
parents:
diff changeset
3653 // we read-back the value and notice that it hasn't changed.
a61af66fc99e Initial load
duke
parents:
diff changeset
3654 // + Interactive threads enter the runq at the head, non-interactive at the tail.
a61af66fc99e Initial load
duke
parents:
diff changeset
3655 // + For RT, change timeslice as well. Invariant:
a61af66fc99e Initial load
duke
parents:
diff changeset
3656 // constant "priority integral"
a61af66fc99e Initial load
duke
parents:
diff changeset
3657 // Konst == TimeSlice * (60-Priority)
a61af66fc99e Initial load
duke
parents:
diff changeset
3658 // Given a priority, compute appropriate timeslice.
a61af66fc99e Initial load
duke
parents:
diff changeset
3659 // + Higher numerical values have higher priority.
a61af66fc99e Initial load
duke
parents:
diff changeset
3660
a61af66fc99e Initial load
duke
parents:
diff changeset
3661 // sched class attributes
a61af66fc99e Initial load
duke
parents:
diff changeset
3662 typedef struct {
a61af66fc99e Initial load
duke
parents:
diff changeset
3663 int schedPolicy; // classID
a61af66fc99e Initial load
duke
parents:
diff changeset
3664 int maxPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3665 int minPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3666 } SchedInfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
3667
a61af66fc99e Initial load
duke
parents:
diff changeset
3668
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3669 static SchedInfo tsLimits, iaLimits, rtLimits, fxLimits;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3670
a61af66fc99e Initial load
duke
parents:
diff changeset
3671 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3672 static int ReadBackValidate = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
3673 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3674 static int myClass = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3675 static int myMin = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3676 static int myMax = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3677 static int myCur = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3678 static bool priocntl_enable = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
3679
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3680 static const int criticalPrio = 60; // FX/60 is critical thread class/priority on T4
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3681 static int java_MaxPriority_to_os_priority = 0; // Saved mapping
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3682
a61af66fc99e Initial load
duke
parents:
diff changeset
3683
a61af66fc99e Initial load
duke
parents:
diff changeset
3684 // lwp_priocntl_init
a61af66fc99e Initial load
duke
parents:
diff changeset
3685 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3686 // Try to determine the priority scale for our process.
a61af66fc99e Initial load
duke
parents:
diff changeset
3687 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3688 // Return errno or 0 if OK.
a61af66fc99e Initial load
duke
parents:
diff changeset
3689 //
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3690 static int lwp_priocntl_init () {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3691 int rslt;
a61af66fc99e Initial load
duke
parents:
diff changeset
3692 pcinfo_t ClassInfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
3693 pcparms_t ParmInfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
3694 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
3695
a61af66fc99e Initial load
duke
parents:
diff changeset
3696 if (!UseThreadPriorities) return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3697
a61af66fc99e Initial load
duke
parents:
diff changeset
3698 // We are using Bound threads, we need to determine our priority ranges
a61af66fc99e Initial load
duke
parents:
diff changeset
3699 if (os::Solaris::T2_libthread() || UseBoundThreads) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3700 // If ThreadPriorityPolicy is 1, switch tables
a61af66fc99e Initial load
duke
parents:
diff changeset
3701 if (ThreadPriorityPolicy == 1) {
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3702 for (i = 0 ; i < CriticalPriority+1; i++)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3703 os::java_to_os_priority[i] = prio_policy1[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
3704 }
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3705 if (UseCriticalJavaThreadPriority) {
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3706 // MaxPriority always maps to the FX scheduling class and criticalPrio.
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3707 // See set_native_priority() and set_lwp_class_and_priority().
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3708 // Save original MaxPriority mapping in case attempt to
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3709 // use critical priority fails.
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3710 java_MaxPriority_to_os_priority = os::java_to_os_priority[MaxPriority];
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3711 // Set negative to distinguish from other priorities
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3712 os::java_to_os_priority[MaxPriority] = -criticalPrio;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3713 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3714 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3715 // Not using Bound Threads, set to ThreadPolicy 1
a61af66fc99e Initial load
duke
parents:
diff changeset
3716 else {
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3717 for ( i = 0 ; i < CriticalPriority+1; i++ ) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3718 os::java_to_os_priority[i] = prio_policy1[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
3719 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3720 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3721 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3722
a61af66fc99e Initial load
duke
parents:
diff changeset
3723 // Get IDs for a set of well-known scheduling classes.
a61af66fc99e Initial load
duke
parents:
diff changeset
3724 // TODO-FIXME: GETCLINFO returns the current # of classes in the
a61af66fc99e Initial load
duke
parents:
diff changeset
3725 // the system. We should have a loop that iterates over the
a61af66fc99e Initial load
duke
parents:
diff changeset
3726 // classID values, which are known to be "small" integers.
a61af66fc99e Initial load
duke
parents:
diff changeset
3727
a61af66fc99e Initial load
duke
parents:
diff changeset
3728 strcpy(ClassInfo.pc_clname, "TS");
a61af66fc99e Initial load
duke
parents:
diff changeset
3729 ClassInfo.pc_cid = -1;
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3730 rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3731 if (rslt < 0) return errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
3732 assert(ClassInfo.pc_cid != -1, "cid for TS class is -1");
a61af66fc99e Initial load
duke
parents:
diff changeset
3733 tsLimits.schedPolicy = ClassInfo.pc_cid;
a61af66fc99e Initial load
duke
parents:
diff changeset
3734 tsLimits.maxPrio = ((tsinfo_t*)ClassInfo.pc_clinfo)->ts_maxupri;
a61af66fc99e Initial load
duke
parents:
diff changeset
3735 tsLimits.minPrio = -tsLimits.maxPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3736
a61af66fc99e Initial load
duke
parents:
diff changeset
3737 strcpy(ClassInfo.pc_clname, "IA");
a61af66fc99e Initial load
duke
parents:
diff changeset
3738 ClassInfo.pc_cid = -1;
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3739 rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3740 if (rslt < 0) return errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
3741 assert(ClassInfo.pc_cid != -1, "cid for IA class is -1");
a61af66fc99e Initial load
duke
parents:
diff changeset
3742 iaLimits.schedPolicy = ClassInfo.pc_cid;
a61af66fc99e Initial load
duke
parents:
diff changeset
3743 iaLimits.maxPrio = ((iainfo_t*)ClassInfo.pc_clinfo)->ia_maxupri;
a61af66fc99e Initial load
duke
parents:
diff changeset
3744 iaLimits.minPrio = -iaLimits.maxPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3745
a61af66fc99e Initial load
duke
parents:
diff changeset
3746 strcpy(ClassInfo.pc_clname, "RT");
a61af66fc99e Initial load
duke
parents:
diff changeset
3747 ClassInfo.pc_cid = -1;
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3748 rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3749 if (rslt < 0) return errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
3750 assert(ClassInfo.pc_cid != -1, "cid for RT class is -1");
a61af66fc99e Initial load
duke
parents:
diff changeset
3751 rtLimits.schedPolicy = ClassInfo.pc_cid;
a61af66fc99e Initial load
duke
parents:
diff changeset
3752 rtLimits.maxPrio = ((rtinfo_t*)ClassInfo.pc_clinfo)->rt_maxpri;
a61af66fc99e Initial load
duke
parents:
diff changeset
3753 rtLimits.minPrio = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3754
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3755 strcpy(ClassInfo.pc_clname, "FX");
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3756 ClassInfo.pc_cid = -1;
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3757 rslt = priocntl(P_ALL, 0, PC_GETCID, (caddr_t)&ClassInfo);
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3758 if (rslt < 0) return errno;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3759 assert(ClassInfo.pc_cid != -1, "cid for FX class is -1");
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3760 fxLimits.schedPolicy = ClassInfo.pc_cid;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3761 fxLimits.maxPrio = ((fxinfo_t*)ClassInfo.pc_clinfo)->fx_maxupri;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3762 fxLimits.minPrio = 0;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3763
a61af66fc99e Initial load
duke
parents:
diff changeset
3764 // Query our "current" scheduling class.
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3765 // This will normally be IA, TS or, rarely, FX or RT.
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3766 memset(&ParmInfo, 0, sizeof(ParmInfo));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3767 ParmInfo.pc_cid = PC_CLNULL;
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3768 rslt = priocntl(P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo);
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3769 if (rslt < 0) return errno;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3770 myClass = ParmInfo.pc_cid;
a61af66fc99e Initial load
duke
parents:
diff changeset
3771
a61af66fc99e Initial load
duke
parents:
diff changeset
3772 // We now know our scheduling classId, get specific information
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3773 // about the class.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3774 ClassInfo.pc_cid = myClass;
a61af66fc99e Initial load
duke
parents:
diff changeset
3775 ClassInfo.pc_clname[0] = 0;
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3776 rslt = priocntl((idtype)0, 0, PC_GETCLINFO, (caddr_t)&ClassInfo);
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3777 if (rslt < 0) return errno;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3778
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3779 if (ThreadPriorityVerbose) {
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3780 tty->print_cr("lwp_priocntl_init: Class=%d(%s)...", myClass, ClassInfo.pc_clname);
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3781 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3782
a61af66fc99e Initial load
duke
parents:
diff changeset
3783 memset(&ParmInfo, 0, sizeof(pcparms_t));
a61af66fc99e Initial load
duke
parents:
diff changeset
3784 ParmInfo.pc_cid = PC_CLNULL;
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3785 rslt = priocntl(P_PID, P_MYID, PC_GETPARMS, (caddr_t)&ParmInfo);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3786 if (rslt < 0) return errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
3787
a61af66fc99e Initial load
duke
parents:
diff changeset
3788 if (ParmInfo.pc_cid == rtLimits.schedPolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3789 myMin = rtLimits.minPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3790 myMax = rtLimits.maxPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3791 } else if (ParmInfo.pc_cid == iaLimits.schedPolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3792 iaparms_t *iaInfo = (iaparms_t*)ParmInfo.pc_clparms;
a61af66fc99e Initial load
duke
parents:
diff changeset
3793 myMin = iaLimits.minPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3794 myMax = iaLimits.maxPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3795 myMax = MIN2(myMax, (int)iaInfo->ia_uprilim); // clamp - restrict
a61af66fc99e Initial load
duke
parents:
diff changeset
3796 } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3797 tsparms_t *tsInfo = (tsparms_t*)ParmInfo.pc_clparms;
a61af66fc99e Initial load
duke
parents:
diff changeset
3798 myMin = tsLimits.minPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3799 myMax = tsLimits.maxPrio;
a61af66fc99e Initial load
duke
parents:
diff changeset
3800 myMax = MIN2(myMax, (int)tsInfo->ts_uprilim); // clamp - restrict
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3801 } else if (ParmInfo.pc_cid == fxLimits.schedPolicy) {
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3802 fxparms_t *fxInfo = (fxparms_t*)ParmInfo.pc_clparms;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3803 myMin = fxLimits.minPrio;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3804 myMax = fxLimits.maxPrio;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3805 myMax = MIN2(myMax, (int)fxInfo->fx_uprilim); // clamp - restrict
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3806 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
3807 // No clue - punt
a61af66fc99e Initial load
duke
parents:
diff changeset
3808 if (ThreadPriorityVerbose)
a61af66fc99e Initial load
duke
parents:
diff changeset
3809 tty->print_cr ("Unknown scheduling class: %s ... \n", ClassInfo.pc_clname);
a61af66fc99e Initial load
duke
parents:
diff changeset
3810 return EINVAL; // no clue, punt
a61af66fc99e Initial load
duke
parents:
diff changeset
3811 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3812
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3813 if (ThreadPriorityVerbose) {
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3814 tty->print_cr ("Thread priority Range: [%d..%d]\n", myMin, myMax);
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3815 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3816
a61af66fc99e Initial load
duke
parents:
diff changeset
3817 priocntl_enable = true; // Enable changing priorities
a61af66fc99e Initial load
duke
parents:
diff changeset
3818 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3819 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3820
a61af66fc99e Initial load
duke
parents:
diff changeset
3821 #define IAPRI(x) ((iaparms_t *)((x).pc_clparms))
a61af66fc99e Initial load
duke
parents:
diff changeset
3822 #define RTPRI(x) ((rtparms_t *)((x).pc_clparms))
a61af66fc99e Initial load
duke
parents:
diff changeset
3823 #define TSPRI(x) ((tsparms_t *)((x).pc_clparms))
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3824 #define FXPRI(x) ((fxparms_t *)((x).pc_clparms))
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3825
a61af66fc99e Initial load
duke
parents:
diff changeset
3826
a61af66fc99e Initial load
duke
parents:
diff changeset
3827 // scale_to_lwp_priority
a61af66fc99e Initial load
duke
parents:
diff changeset
3828 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3829 // Convert from the libthread "thr_setprio" scale to our current
a61af66fc99e Initial load
duke
parents:
diff changeset
3830 // lwp scheduling class scale.
a61af66fc99e Initial load
duke
parents:
diff changeset
3831 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3832 static
a61af66fc99e Initial load
duke
parents:
diff changeset
3833 int scale_to_lwp_priority (int rMin, int rMax, int x)
a61af66fc99e Initial load
duke
parents:
diff changeset
3834 {
a61af66fc99e Initial load
duke
parents:
diff changeset
3835 int v;
a61af66fc99e Initial load
duke
parents:
diff changeset
3836
a61af66fc99e Initial load
duke
parents:
diff changeset
3837 if (x == 127) return rMax; // avoid round-down
a61af66fc99e Initial load
duke
parents:
diff changeset
3838 v = (((x*(rMax-rMin)))/128)+rMin;
a61af66fc99e Initial load
duke
parents:
diff changeset
3839 return v;
a61af66fc99e Initial load
duke
parents:
diff changeset
3840 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3841
a61af66fc99e Initial load
duke
parents:
diff changeset
3842
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3843 // set_lwp_class_and_priority
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3844 //
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3845 // Set the class and priority of the lwp. This call should only
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3846 // be made when using bound threads (T2 threads are bound by default).
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3847 //
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3848 int set_lwp_class_and_priority(int ThreadID, int lwpid,
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3849 int newPrio, int new_class, bool scale) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3850 int rslt;
a61af66fc99e Initial load
duke
parents:
diff changeset
3851 int Actual, Expected, prv;
a61af66fc99e Initial load
duke
parents:
diff changeset
3852 pcparms_t ParmInfo; // for GET-SET
a61af66fc99e Initial load
duke
parents:
diff changeset
3853 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3854 pcparms_t ReadBack; // for readback
a61af66fc99e Initial load
duke
parents:
diff changeset
3855 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
3856
a61af66fc99e Initial load
duke
parents:
diff changeset
3857 // Set priority via PC_GETPARMS, update, PC_SETPARMS
a61af66fc99e Initial load
duke
parents:
diff changeset
3858 // Query current values.
a61af66fc99e Initial load
duke
parents:
diff changeset
3859 // TODO: accelerate this by eliminating the PC_GETPARMS call.
a61af66fc99e Initial load
duke
parents:
diff changeset
3860 // Cache "pcparms_t" in global ParmCache.
a61af66fc99e Initial load
duke
parents:
diff changeset
3861 // TODO: elide set-to-same-value
a61af66fc99e Initial load
duke
parents:
diff changeset
3862
a61af66fc99e Initial load
duke
parents:
diff changeset
3863 // If something went wrong on init, don't change priorities.
a61af66fc99e Initial load
duke
parents:
diff changeset
3864 if ( !priocntl_enable ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3865 if (ThreadPriorityVerbose)
a61af66fc99e Initial load
duke
parents:
diff changeset
3866 tty->print_cr("Trying to set priority but init failed, ignoring");
a61af66fc99e Initial load
duke
parents:
diff changeset
3867 return EINVAL;
a61af66fc99e Initial load
duke
parents:
diff changeset
3868 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3869
a61af66fc99e Initial load
duke
parents:
diff changeset
3870 // If lwp hasn't started yet, just return
a61af66fc99e Initial load
duke
parents:
diff changeset
3871 // the _start routine will call us again.
a61af66fc99e Initial load
duke
parents:
diff changeset
3872 if ( lwpid <= 0 ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3873 if (ThreadPriorityVerbose) {
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3874 tty->print_cr ("deferring the set_lwp_class_and_priority of thread "
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3875 INTPTR_FORMAT " to %d, lwpid not set",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3876 ThreadID, newPrio);
a61af66fc99e Initial load
duke
parents:
diff changeset
3877 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3878 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3879 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3880
a61af66fc99e Initial load
duke
parents:
diff changeset
3881 if (ThreadPriorityVerbose) {
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3882 tty->print_cr ("set_lwp_class_and_priority("
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3883 INTPTR_FORMAT "@" INTPTR_FORMAT " %d) ",
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3884 ThreadID, lwpid, newPrio);
a61af66fc99e Initial load
duke
parents:
diff changeset
3885 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3886
a61af66fc99e Initial load
duke
parents:
diff changeset
3887 memset(&ParmInfo, 0, sizeof(pcparms_t));
a61af66fc99e Initial load
duke
parents:
diff changeset
3888 ParmInfo.pc_cid = PC_CLNULL;
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3889 rslt = priocntl(P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ParmInfo);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3890 if (rslt < 0) return errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
3891
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3892 int cur_class = ParmInfo.pc_cid;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3893 ParmInfo.pc_cid = (id_t)new_class;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3894
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3895 if (new_class == rtLimits.schedPolicy) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3896 rtparms_t *rtInfo = (rtparms_t*)ParmInfo.pc_clparms;
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3897 rtInfo->rt_pri = scale ? scale_to_lwp_priority(rtLimits.minPrio,
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3898 rtLimits.maxPrio, newPrio)
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3899 : newPrio;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3900 rtInfo->rt_tqsecs = RT_NOCHANGE;
a61af66fc99e Initial load
duke
parents:
diff changeset
3901 rtInfo->rt_tqnsecs = RT_NOCHANGE;
a61af66fc99e Initial load
duke
parents:
diff changeset
3902 if (ThreadPriorityVerbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3903 tty->print_cr("RT: %d->%d\n", newPrio, rtInfo->rt_pri);
a61af66fc99e Initial load
duke
parents:
diff changeset
3904 }
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3905 } else if (new_class == iaLimits.schedPolicy) {
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3906 iaparms_t* iaInfo = (iaparms_t*)ParmInfo.pc_clparms;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3907 int maxClamped = MIN2(iaLimits.maxPrio,
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3908 cur_class == new_class
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3909 ? (int)iaInfo->ia_uprilim : iaLimits.maxPrio);
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3910 iaInfo->ia_upri = scale ? scale_to_lwp_priority(iaLimits.minPrio,
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3911 maxClamped, newPrio)
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3912 : newPrio;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3913 iaInfo->ia_uprilim = cur_class == new_class
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3914 ? IA_NOCHANGE : (pri_t)iaLimits.maxPrio;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3915 iaInfo->ia_mode = IA_NOCHANGE;
a61af66fc99e Initial load
duke
parents:
diff changeset
3916 if (ThreadPriorityVerbose) {
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3917 tty->print_cr("IA: [%d...%d] %d->%d\n",
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3918 iaLimits.minPrio, maxClamped, newPrio, iaInfo->ia_upri);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3919 }
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3920 } else if (new_class == tsLimits.schedPolicy) {
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3921 tsparms_t* tsInfo = (tsparms_t*)ParmInfo.pc_clparms;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3922 int maxClamped = MIN2(tsLimits.maxPrio,
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3923 cur_class == new_class
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3924 ? (int)tsInfo->ts_uprilim : tsLimits.maxPrio);
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3925 tsInfo->ts_upri = scale ? scale_to_lwp_priority(tsLimits.minPrio,
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3926 maxClamped, newPrio)
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3927 : newPrio;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3928 tsInfo->ts_uprilim = cur_class == new_class
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3929 ? TS_NOCHANGE : (pri_t)tsLimits.maxPrio;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3930 if (ThreadPriorityVerbose) {
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3931 tty->print_cr("TS: [%d...%d] %d->%d\n",
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3932 tsLimits.minPrio, maxClamped, newPrio, tsInfo->ts_upri);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3933 }
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3934 } else if (new_class == fxLimits.schedPolicy) {
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3935 fxparms_t* fxInfo = (fxparms_t*)ParmInfo.pc_clparms;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3936 int maxClamped = MIN2(fxLimits.maxPrio,
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3937 cur_class == new_class
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3938 ? (int)fxInfo->fx_uprilim : fxLimits.maxPrio);
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3939 fxInfo->fx_upri = scale ? scale_to_lwp_priority(fxLimits.minPrio,
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3940 maxClamped, newPrio)
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3941 : newPrio;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3942 fxInfo->fx_uprilim = cur_class == new_class
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3943 ? FX_NOCHANGE : (pri_t)fxLimits.maxPrio;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3944 fxInfo->fx_tqsecs = FX_NOCHANGE;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3945 fxInfo->fx_tqnsecs = FX_NOCHANGE;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3946 if (ThreadPriorityVerbose) {
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3947 tty->print_cr("FX: [%d...%d] %d->%d\n",
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3948 fxLimits.minPrio, maxClamped, newPrio, fxInfo->fx_upri);
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3949 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3950 } else {
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3951 if (ThreadPriorityVerbose) {
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3952 tty->print_cr("Unknown new scheduling class %d\n", new_class);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3953 }
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3954 return EINVAL; // no clue, punt
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3955 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3956
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3957 rslt = priocntl(P_LWPID, lwpid, PC_SETPARMS, (caddr_t)&ParmInfo);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3958 if (ThreadPriorityVerbose && rslt) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3959 tty->print_cr ("PC_SETPARMS ->%d %d\n", rslt, errno);
a61af66fc99e Initial load
duke
parents:
diff changeset
3960 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3961 if (rslt < 0) return errno;
a61af66fc99e Initial load
duke
parents:
diff changeset
3962
a61af66fc99e Initial load
duke
parents:
diff changeset
3963 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
3964 // Sanity check: read back what we just attempted to set.
a61af66fc99e Initial load
duke
parents:
diff changeset
3965 // In theory it could have changed in the interim ...
a61af66fc99e Initial load
duke
parents:
diff changeset
3966 //
a61af66fc99e Initial load
duke
parents:
diff changeset
3967 // The priocntl system call is tricky.
a61af66fc99e Initial load
duke
parents:
diff changeset
3968 // Sometimes it'll validate the priority value argument and
a61af66fc99e Initial load
duke
parents:
diff changeset
3969 // return EINVAL if unhappy. At other times it fails silently.
a61af66fc99e Initial load
duke
parents:
diff changeset
3970 // Readbacks are prudent.
a61af66fc99e Initial load
duke
parents:
diff changeset
3971
a61af66fc99e Initial load
duke
parents:
diff changeset
3972 if (!ReadBackValidate) return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
3973
a61af66fc99e Initial load
duke
parents:
diff changeset
3974 memset(&ReadBack, 0, sizeof(pcparms_t));
a61af66fc99e Initial load
duke
parents:
diff changeset
3975 ReadBack.pc_cid = PC_CLNULL;
11111
dec841e0c9aa 8016749: -XX:+UseISM fails an assert(obj->is_oop()) when running SPECjbb2005
anoll
parents: 10986
diff changeset
3976 rslt = priocntl(P_LWPID, lwpid, PC_GETPARMS, (caddr_t)&ReadBack);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3977 assert(rslt >= 0, "priocntl failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
3978 Actual = Expected = 0xBAD;
a61af66fc99e Initial load
duke
parents:
diff changeset
3979 assert(ParmInfo.pc_cid == ReadBack.pc_cid, "cid's don't match");
a61af66fc99e Initial load
duke
parents:
diff changeset
3980 if (ParmInfo.pc_cid == rtLimits.schedPolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3981 Actual = RTPRI(ReadBack)->rt_pri;
a61af66fc99e Initial load
duke
parents:
diff changeset
3982 Expected = RTPRI(ParmInfo)->rt_pri;
a61af66fc99e Initial load
duke
parents:
diff changeset
3983 } else if (ParmInfo.pc_cid == iaLimits.schedPolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3984 Actual = IAPRI(ReadBack)->ia_upri;
a61af66fc99e Initial load
duke
parents:
diff changeset
3985 Expected = IAPRI(ParmInfo)->ia_upri;
a61af66fc99e Initial load
duke
parents:
diff changeset
3986 } else if (ParmInfo.pc_cid == tsLimits.schedPolicy) {
a61af66fc99e Initial load
duke
parents:
diff changeset
3987 Actual = TSPRI(ReadBack)->ts_upri;
a61af66fc99e Initial load
duke
parents:
diff changeset
3988 Expected = TSPRI(ParmInfo)->ts_upri;
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3989 } else if (ParmInfo.pc_cid == fxLimits.schedPolicy) {
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3990 Actual = FXPRI(ReadBack)->fx_upri;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3991 Expected = FXPRI(ParmInfo)->fx_upri;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3992 } else {
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3993 if (ThreadPriorityVerbose) {
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3994 tty->print_cr("set_lwp_class_and_priority: unexpected class in readback: %d\n",
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
3995 ParmInfo.pc_cid);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3996 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3997 }
a61af66fc99e Initial load
duke
parents:
diff changeset
3998
a61af66fc99e Initial load
duke
parents:
diff changeset
3999 if (Actual != Expected) {
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4000 if (ThreadPriorityVerbose) {
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4001 tty->print_cr ("set_lwp_class_and_priority(%d %d) Class=%d: actual=%d vs expected=%d\n",
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4002 lwpid, newPrio, ReadBack.pc_cid, Actual, Expected);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4003 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4004 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4005 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
4006
a61af66fc99e Initial load
duke
parents:
diff changeset
4007 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4008 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4009
a61af66fc99e Initial load
duke
parents:
diff changeset
4010 // Solaris only gives access to 128 real priorities at a time,
a61af66fc99e Initial load
duke
parents:
diff changeset
4011 // so we expand Java's ten to fill this range. This would be better
a61af66fc99e Initial load
duke
parents:
diff changeset
4012 // if we dynamically adjusted relative priorities.
a61af66fc99e Initial load
duke
parents:
diff changeset
4013 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4014 // The ThreadPriorityPolicy option allows us to select 2 different
a61af66fc99e Initial load
duke
parents:
diff changeset
4015 // priority scales.
a61af66fc99e Initial load
duke
parents:
diff changeset
4016 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4017 // ThreadPriorityPolicy=0
a61af66fc99e Initial load
duke
parents:
diff changeset
4018 // Since the Solaris' default priority is MaximumPriority, we do not
a61af66fc99e Initial load
duke
parents:
diff changeset
4019 // set a priority lower than Max unless a priority lower than
a61af66fc99e Initial load
duke
parents:
diff changeset
4020 // NormPriority is requested.
a61af66fc99e Initial load
duke
parents:
diff changeset
4021 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4022 // ThreadPriorityPolicy=1
a61af66fc99e Initial load
duke
parents:
diff changeset
4023 // This mode causes the priority table to get filled with
a61af66fc99e Initial load
duke
parents:
diff changeset
4024 // linear values. NormPriority get's mapped to 50% of the
a61af66fc99e Initial load
duke
parents:
diff changeset
4025 // Maximum priority an so on. This will cause VM threads
a61af66fc99e Initial load
duke
parents:
diff changeset
4026 // to get unfair treatment against other Solaris processes
a61af66fc99e Initial load
duke
parents:
diff changeset
4027 // which do not explicitly alter their thread priorities.
a61af66fc99e Initial load
duke
parents:
diff changeset
4028 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4029
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4030 int os::java_to_os_priority[CriticalPriority + 1] = {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4031 -99999, // 0 Entry should never be used
a61af66fc99e Initial load
duke
parents:
diff changeset
4032
a61af66fc99e Initial load
duke
parents:
diff changeset
4033 0, // 1 MinPriority
a61af66fc99e Initial load
duke
parents:
diff changeset
4034 32, // 2
a61af66fc99e Initial load
duke
parents:
diff changeset
4035 64, // 3
a61af66fc99e Initial load
duke
parents:
diff changeset
4036
a61af66fc99e Initial load
duke
parents:
diff changeset
4037 96, // 4
a61af66fc99e Initial load
duke
parents:
diff changeset
4038 127, // 5 NormPriority
a61af66fc99e Initial load
duke
parents:
diff changeset
4039 127, // 6
a61af66fc99e Initial load
duke
parents:
diff changeset
4040
a61af66fc99e Initial load
duke
parents:
diff changeset
4041 127, // 7
a61af66fc99e Initial load
duke
parents:
diff changeset
4042 127, // 8
a61af66fc99e Initial load
duke
parents:
diff changeset
4043 127, // 9 NearMaxPriority
a61af66fc99e Initial load
duke
parents:
diff changeset
4044
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4045 127, // 10 MaxPriority
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4046
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4047 -criticalPrio // 11 CriticalPriority
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4048 };
a61af66fc99e Initial load
duke
parents:
diff changeset
4049
a61af66fc99e Initial load
duke
parents:
diff changeset
4050 OSReturn os::set_native_priority(Thread* thread, int newpri) {
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4051 OSThread* osthread = thread->osthread();
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4052
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4053 // Save requested priority in case the thread hasn't been started
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4054 osthread->set_native_priority(newpri);
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4055
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4056 // Check for critical priority request
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4057 bool fxcritical = false;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4058 if (newpri == -criticalPrio) {
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4059 fxcritical = true;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4060 newpri = criticalPrio;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4061 }
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4062
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4063 assert(newpri >= MinimumPriority && newpri <= MaximumPriority, "bad priority mapping");
4854
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4064 if (!UseThreadPriorities) return OS_OK;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4065
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4066 int status = 0;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4067
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4068 if (!fxcritical) {
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4069 // Use thr_setprio only if we have a priority that thr_setprio understands
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4070 status = thr_setprio(thread->osthread()->thread_id(), newpri);
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4071 }
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4072
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4073 if (os::Solaris::T2_libthread() ||
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4074 (UseBoundThreads && osthread->is_vm_created())) {
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4075 int lwp_status =
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4076 set_lwp_class_and_priority(osthread->thread_id(),
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4077 osthread->lwp_id(),
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4078 newpri,
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4079 fxcritical ? fxLimits.schedPolicy : myClass,
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4080 !fxcritical);
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4081 if (lwp_status != 0 && fxcritical) {
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4082 // Try again, this time without changing the scheduling class
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4083 newpri = java_MaxPriority_to_os_priority;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4084 lwp_status = set_lwp_class_and_priority(osthread->thread_id(),
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4085 osthread->lwp_id(),
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4086 newpri, myClass, false);
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4087 }
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4088 status |= lwp_status;
de268c8a8075 7082553: Interpret Thread.setPriority(Thread.MAX_PRIORITY) to mean FX60 on Solaris 10 and 11
phh
parents: 4803
diff changeset
4089 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4090 return (status == 0) ? OS_OK : OS_ERR;
a61af66fc99e Initial load
duke
parents:
diff changeset
4091 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4092
a61af66fc99e Initial load
duke
parents:
diff changeset
4093
a61af66fc99e Initial load
duke
parents:
diff changeset
4094 OSReturn os::get_native_priority(const Thread* const thread, int *priority_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4095 int p;
a61af66fc99e Initial load
duke
parents:
diff changeset
4096 if ( !UseThreadPriorities ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4097 *priority_ptr = NormalPriority;
a61af66fc99e Initial load
duke
parents:
diff changeset
4098 return OS_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
4099 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4100 int status = thr_getprio(thread->osthread()->thread_id(), &p);
a61af66fc99e Initial load
duke
parents:
diff changeset
4101 if (status != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4102 return OS_ERR;
a61af66fc99e Initial load
duke
parents:
diff changeset
4103 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4104 *priority_ptr = p;
a61af66fc99e Initial load
duke
parents:
diff changeset
4105 return OS_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
4106 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4107
a61af66fc99e Initial load
duke
parents:
diff changeset
4108
a61af66fc99e Initial load
duke
parents:
diff changeset
4109 // Hint to the underlying OS that a task switch would not be good.
a61af66fc99e Initial load
duke
parents:
diff changeset
4110 // Void return because it's a hint and can fail.
a61af66fc99e Initial load
duke
parents:
diff changeset
4111 void os::hint_no_preempt() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4112 schedctl_start(schedctl_init());
a61af66fc99e Initial load
duke
parents:
diff changeset
4113 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4114
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4115 static void resume_clear_context(OSThread *osthread) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4116 osthread->set_ucontext(NULL);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4117 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4118
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4119 static void suspend_save_context(OSThread *osthread, ucontext_t* context) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4120 osthread->set_ucontext(context);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4121 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4122
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4123 static Semaphore sr_semaphore;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4124
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4125 void os::Solaris::SR_handler(Thread* thread, ucontext_t* uc) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4126 // Save and restore errno to avoid confusing native code with EINTR
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4127 // after sigsuspend.
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4128 int old_errno = errno;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4129
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4130 OSThread* osthread = thread->osthread();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4131 assert(thread->is_VM_thread() || thread->is_Java_thread(), "Must be VMThread or JavaThread");
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4132
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4133 os::SuspendResume::State current = osthread->sr.state();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4134 if (current == os::SuspendResume::SR_SUSPEND_REQUEST) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4135 suspend_save_context(osthread, uc);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4136
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4137 // attempt to switch the state, we assume we had a SUSPEND_REQUEST
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4138 os::SuspendResume::State state = osthread->sr.suspended();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4139 if (state == os::SuspendResume::SR_SUSPENDED) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4140 sigset_t suspend_set; // signals for sigsuspend()
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4141
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4142 // get current set of blocked signals and unblock resume signal
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4143 thr_sigsetmask(SIG_BLOCK, NULL, &suspend_set);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4144 sigdelset(&suspend_set, os::Solaris::SIGasync());
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4145
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4146 sr_semaphore.signal();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4147 // wait here until we are resumed
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4148 while (1) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4149 sigsuspend(&suspend_set);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4150
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4151 os::SuspendResume::State result = osthread->sr.running();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4152 if (result == os::SuspendResume::SR_RUNNING) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4153 sr_semaphore.signal();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4154 break;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4155 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4156 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4157
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4158 } else if (state == os::SuspendResume::SR_RUNNING) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4159 // request was cancelled, continue
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4160 } else {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4161 ShouldNotReachHere();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4162 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4163
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4164 resume_clear_context(osthread);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4165 } else if (current == os::SuspendResume::SR_RUNNING) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4166 // request was cancelled, continue
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4167 } else if (current == os::SuspendResume::SR_WAKEUP_REQUEST) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4168 // ignore
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4169 } else {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4170 // ignore
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4171 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4172
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4173 errno = old_errno;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4174 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4175
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4176
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4177 void os::interrupt(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4178 assert(Thread::current() == thread || Threads_lock->owned_by_self(), "possibility of dangling Thread pointer");
a61af66fc99e Initial load
duke
parents:
diff changeset
4179
a61af66fc99e Initial load
duke
parents:
diff changeset
4180 OSThread* osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
4181
a61af66fc99e Initial load
duke
parents:
diff changeset
4182 int isInterrupted = osthread->interrupted();
a61af66fc99e Initial load
duke
parents:
diff changeset
4183 if (!isInterrupted) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4184 osthread->set_interrupted(true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4185 OrderAccess::fence();
a61af66fc99e Initial load
duke
parents:
diff changeset
4186 // os::sleep() is implemented with either poll (NULL,0,timeout) or
a61af66fc99e Initial load
duke
parents:
diff changeset
4187 // by parking on _SleepEvent. If the former, thr_kill will unwedge
a61af66fc99e Initial load
duke
parents:
diff changeset
4188 // the sleeper by SIGINTR, otherwise the unpark() will wake the sleeper.
a61af66fc99e Initial load
duke
parents:
diff changeset
4189 ParkEvent * const slp = thread->_SleepEvent ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4190 if (slp != NULL) slp->unpark() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4191 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4192
a61af66fc99e Initial load
duke
parents:
diff changeset
4193 // For JSR166: unpark after setting status but before thr_kill -dl
a61af66fc99e Initial load
duke
parents:
diff changeset
4194 if (thread->is_Java_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4195 ((JavaThread*)thread)->parker()->unpark();
a61af66fc99e Initial load
duke
parents:
diff changeset
4196 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4197
a61af66fc99e Initial load
duke
parents:
diff changeset
4198 // Handle interruptible wait() ...
a61af66fc99e Initial load
duke
parents:
diff changeset
4199 ParkEvent * const ev = thread->_ParkEvent ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4200 if (ev != NULL) ev->unpark() ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4201
a61af66fc99e Initial load
duke
parents:
diff changeset
4202 // When events are used everywhere for os::sleep, then this thr_kill
a61af66fc99e Initial load
duke
parents:
diff changeset
4203 // will only be needed if UseVMInterruptibleIO is true.
a61af66fc99e Initial load
duke
parents:
diff changeset
4204
a61af66fc99e Initial load
duke
parents:
diff changeset
4205 if (!isInterrupted) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4206 int status = thr_kill(osthread->thread_id(), os::Solaris::SIGinterrupt());
a61af66fc99e Initial load
duke
parents:
diff changeset
4207 assert_status(status == 0, status, "thr_kill");
a61af66fc99e Initial load
duke
parents:
diff changeset
4208
a61af66fc99e Initial load
duke
parents:
diff changeset
4209 // Bump thread interruption counter
a61af66fc99e Initial load
duke
parents:
diff changeset
4210 RuntimeService::record_thread_interrupt_signaled_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
4211 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4212 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4213
a61af66fc99e Initial load
duke
parents:
diff changeset
4214
a61af66fc99e Initial load
duke
parents:
diff changeset
4215 bool os::is_interrupted(Thread* thread, bool clear_interrupted) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4216 assert(Thread::current() == thread || Threads_lock->owned_by_self(), "possibility of dangling Thread pointer");
a61af66fc99e Initial load
duke
parents:
diff changeset
4217
a61af66fc99e Initial load
duke
parents:
diff changeset
4218 OSThread* osthread = thread->osthread();
a61af66fc99e Initial load
duke
parents:
diff changeset
4219
a61af66fc99e Initial load
duke
parents:
diff changeset
4220 bool res = osthread->interrupted();
a61af66fc99e Initial load
duke
parents:
diff changeset
4221
a61af66fc99e Initial load
duke
parents:
diff changeset
4222 // NOTE that since there is no "lock" around these two operations,
a61af66fc99e Initial load
duke
parents:
diff changeset
4223 // there is the possibility that the interrupted flag will be
a61af66fc99e Initial load
duke
parents:
diff changeset
4224 // "false" but that the interrupt event will be set. This is
a61af66fc99e Initial load
duke
parents:
diff changeset
4225 // intentional. The effect of this is that Object.wait() will appear
a61af66fc99e Initial load
duke
parents:
diff changeset
4226 // to have a spurious wakeup, which is not harmful, and the
a61af66fc99e Initial load
duke
parents:
diff changeset
4227 // possibility is so rare that it is not worth the added complexity
a61af66fc99e Initial load
duke
parents:
diff changeset
4228 // to add yet another lock. It has also been recommended not to put
a61af66fc99e Initial load
duke
parents:
diff changeset
4229 // the interrupted flag into the os::Solaris::Event structure,
a61af66fc99e Initial load
duke
parents:
diff changeset
4230 // because it hides the issue.
a61af66fc99e Initial load
duke
parents:
diff changeset
4231 if (res && clear_interrupted) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4232 osthread->set_interrupted(false);
a61af66fc99e Initial load
duke
parents:
diff changeset
4233 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4234 return res;
a61af66fc99e Initial load
duke
parents:
diff changeset
4235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4236
a61af66fc99e Initial load
duke
parents:
diff changeset
4237
a61af66fc99e Initial load
duke
parents:
diff changeset
4238 void os::print_statistics() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4239 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4240
a61af66fc99e Initial load
duke
parents:
diff changeset
4241 int os::message_box(const char* title, const char* message) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4242 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
4243 fdStream err(defaultStream::error_fd());
a61af66fc99e Initial load
duke
parents:
diff changeset
4244 for (i = 0; i < 78; i++) err.print_raw("=");
a61af66fc99e Initial load
duke
parents:
diff changeset
4245 err.cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4246 err.print_raw_cr(title);
a61af66fc99e Initial load
duke
parents:
diff changeset
4247 for (i = 0; i < 78; i++) err.print_raw("-");
a61af66fc99e Initial load
duke
parents:
diff changeset
4248 err.cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4249 err.print_raw_cr(message);
a61af66fc99e Initial load
duke
parents:
diff changeset
4250 for (i = 0; i < 78; i++) err.print_raw("=");
a61af66fc99e Initial load
duke
parents:
diff changeset
4251 err.cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
4252
a61af66fc99e Initial load
duke
parents:
diff changeset
4253 char buf[16];
a61af66fc99e Initial load
duke
parents:
diff changeset
4254 // Prevent process from exiting upon "read error" without consuming all CPU
a61af66fc99e Initial load
duke
parents:
diff changeset
4255 while (::read(0, buf, sizeof(buf)) <= 0) { ::sleep(100); }
a61af66fc99e Initial load
duke
parents:
diff changeset
4256
a61af66fc99e Initial load
duke
parents:
diff changeset
4257 return buf[0] == 'y' || buf[0] == 'Y';
a61af66fc99e Initial load
duke
parents:
diff changeset
4258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4259
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4260 static int sr_notify(OSThread* osthread) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4261 int status = thr_kill(osthread->thread_id(), os::Solaris::SIGasync());
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4262 assert_status(status == 0, status, "thr_kill");
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4263 return status;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4264 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4265
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4266 // "Randomly" selected value for how long we want to spin
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4267 // before bailing out on suspending a thread, also how often
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4268 // we send a signal to a thread we want to resume
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4269 static const int RANDOMLY_LARGE_INTEGER = 1000000;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4270 static const int RANDOMLY_LARGE_INTEGER2 = 100;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4271
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4272 static bool do_suspend(OSThread* osthread) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4273 assert(osthread->sr.is_running(), "thread should be running");
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4274 assert(!sr_semaphore.trywait(), "semaphore has invalid state");
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4275
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4276 // mark as suspended and send signal
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4277 if (osthread->sr.request_suspend() != os::SuspendResume::SR_SUSPEND_REQUEST) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4278 // failed to switch, state wasn't running?
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4279 ShouldNotReachHere();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4280 return false;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4281 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4282
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4283 if (sr_notify(osthread) != 0) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4284 ShouldNotReachHere();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4285 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4286
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4287 // managed to send the signal and switch to SUSPEND_REQUEST, now wait for SUSPENDED
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4288 while (true) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4289 if (sr_semaphore.timedwait(0, 2000 * NANOSECS_PER_MILLISEC)) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4290 break;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4291 } else {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4292 // timeout
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4293 os::SuspendResume::State cancelled = osthread->sr.cancel_suspend();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4294 if (cancelled == os::SuspendResume::SR_RUNNING) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4295 return false;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4296 } else if (cancelled == os::SuspendResume::SR_SUSPENDED) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4297 // make sure that we consume the signal on the semaphore as well
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4298 sr_semaphore.wait();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4299 break;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4300 } else {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4301 ShouldNotReachHere();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4302 return false;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4303 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4304 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4305 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4306
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4307 guarantee(osthread->sr.is_suspended(), "Must be suspended");
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4308 return true;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4309 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4310
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4311 static void do_resume(OSThread* osthread) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4312 assert(osthread->sr.is_suspended(), "thread should be suspended");
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4313 assert(!sr_semaphore.trywait(), "invalid semaphore state");
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4314
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4315 if (osthread->sr.request_wakeup() != os::SuspendResume::SR_WAKEUP_REQUEST) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4316 // failed to switch to WAKEUP_REQUEST
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4317 ShouldNotReachHere();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4318 return;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4319 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4320
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4321 while (true) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4322 if (sr_notify(osthread) == 0) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4323 if (sr_semaphore.timedwait(0, 2 * NANOSECS_PER_MILLISEC)) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4324 if (osthread->sr.is_running()) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4325 return;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4326 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4327 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4328 } else {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4329 ShouldNotReachHere();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4330 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4331 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4332
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4333 guarantee(osthread->sr.is_running(), "Must be running!");
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4334 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4335
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4336 void os::SuspendedThreadTask::internal_do_task() {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4337 if (do_suspend(_thread->osthread())) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4338 SuspendedThreadTaskContext context(_thread, _thread->osthread()->ucontext());
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4339 do_task(context);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4340 do_resume(_thread->osthread());
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4341 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4342 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4343
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4344 class PcFetcher : public os::SuspendedThreadTask {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4345 public:
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4346 PcFetcher(Thread* thread) : os::SuspendedThreadTask(thread) {}
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4347 ExtendedPC result();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4348 protected:
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4349 void do_task(const os::SuspendedThreadTaskContext& context);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4350 private:
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4351 ExtendedPC _epc;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4352 };
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4353
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4354 ExtendedPC PcFetcher::result() {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4355 guarantee(is_done(), "task is not done yet.");
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4356 return _epc;
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4357 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4358
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4359 void PcFetcher::do_task(const os::SuspendedThreadTaskContext& context) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4360 Thread* thread = context.thread();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4361 OSThread* osthread = thread->osthread();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4362 if (osthread->ucontext() != NULL) {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4363 _epc = os::Solaris::ucontext_get_pc((ucontext_t *) context.ucontext());
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4364 } else {
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4365 // NULL context is unexpected, double-check this is the VMThread
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4366 guarantee(thread->is_VM_thread(), "can only be called for VMThread");
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4367 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4368 }
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4369
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4370 // A lightweight implementation that does not suspend the target thread and
a61af66fc99e Initial load
duke
parents:
diff changeset
4371 // thus returns only a hint. Used for profiling only!
a61af66fc99e Initial load
duke
parents:
diff changeset
4372 ExtendedPC os::get_thread_pc(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4373 // Make sure that it is called by the watcher and the Threads lock is owned.
a61af66fc99e Initial load
duke
parents:
diff changeset
4374 assert(Thread::current()->is_Watcher_thread(), "Must be watcher and own Threads_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
4375 // For now, is only used to profile the VM Thread
a61af66fc99e Initial load
duke
parents:
diff changeset
4376 assert(thread->is_VM_thread(), "Can only be called for VMThread");
10405
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4377 PcFetcher fetcher(thread);
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4378 fetcher.run();
f2110083203d 8005849: JEP 167: Event-Based JVM Tracing
sla
parents: 10208
diff changeset
4379 return fetcher.result();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4380 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4381
a61af66fc99e Initial load
duke
parents:
diff changeset
4382
a61af66fc99e Initial load
duke
parents:
diff changeset
4383 // This does not do anything on Solaris. This is basically a hook for being
a61af66fc99e Initial load
duke
parents:
diff changeset
4384 // able to use structured exception handling (thread-local exception filters) on, e.g., Win32.
a61af66fc99e Initial load
duke
parents:
diff changeset
4385 void os::os_exception_wrapper(java_call_t f, JavaValue* value, methodHandle* method, JavaCallArguments* args, Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4386 f(value, method, args, thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
4387 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4388
a61af66fc99e Initial load
duke
parents:
diff changeset
4389 // This routine may be used by user applications as a "hook" to catch signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
4390 // The user-defined signal handler must pass unrecognized signals to this
a61af66fc99e Initial load
duke
parents:
diff changeset
4391 // routine, and if it returns true (non-zero), then the signal handler must
a61af66fc99e Initial load
duke
parents:
diff changeset
4392 // return immediately. If the flag "abort_if_unrecognized" is true, then this
a61af66fc99e Initial load
duke
parents:
diff changeset
4393 // routine will never retun false (zero), but instead will execute a VM panic
a61af66fc99e Initial load
duke
parents:
diff changeset
4394 // routine kill the process.
a61af66fc99e Initial load
duke
parents:
diff changeset
4395 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4396 // If this routine returns false, it is OK to call it again. This allows
a61af66fc99e Initial load
duke
parents:
diff changeset
4397 // the user-defined signal handler to perform checks either before or after
a61af66fc99e Initial load
duke
parents:
diff changeset
4398 // the VM performs its own checks. Naturally, the user code would be making
a61af66fc99e Initial load
duke
parents:
diff changeset
4399 // a serious error if it tried to handle an exception (such as a null check
a61af66fc99e Initial load
duke
parents:
diff changeset
4400 // or breakpoint) that the VM was generating for its own correct operation.
a61af66fc99e Initial load
duke
parents:
diff changeset
4401 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4402 // This routine may recognize any of the following kinds of signals:
a61af66fc99e Initial load
duke
parents:
diff changeset
4403 // SIGBUS, SIGSEGV, SIGILL, SIGFPE, BREAK_SIGNAL, SIGPIPE, SIGXFSZ,
a61af66fc99e Initial load
duke
parents:
diff changeset
4404 // os::Solaris::SIGasync
a61af66fc99e Initial load
duke
parents:
diff changeset
4405 // It should be consulted by handlers for any of those signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
4406 // It explicitly does not recognize os::Solaris::SIGinterrupt
a61af66fc99e Initial load
duke
parents:
diff changeset
4407 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4408 // The caller of this routine must pass in the three arguments supplied
a61af66fc99e Initial load
duke
parents:
diff changeset
4409 // to the function referred to in the "sa_sigaction" (not the "sa_handler")
a61af66fc99e Initial load
duke
parents:
diff changeset
4410 // field of the structure passed to sigaction(). This routine assumes that
a61af66fc99e Initial load
duke
parents:
diff changeset
4411 // the sa_flags field passed to sigaction() includes SA_SIGINFO and SA_RESTART.
a61af66fc99e Initial load
duke
parents:
diff changeset
4412 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4413 // Note that the VM will print warnings if it detects conflicting signal
a61af66fc99e Initial load
duke
parents:
diff changeset
4414 // handlers, unless invoked with the option "-XX:+AllowUserSignalHandlers".
a61af66fc99e Initial load
duke
parents:
diff changeset
4415 //
2191
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 2130
diff changeset
4416 extern "C" JNIEXPORT int
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 2130
diff changeset
4417 JVM_handle_solaris_signal(int signo, siginfo_t* siginfo, void* ucontext,
d70fe6ab4436 6588413: Use -fvisibility=hidden for gcc compiles
coleenp
parents: 2130
diff changeset
4418 int abort_if_unrecognized);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4419
a61af66fc99e Initial load
duke
parents:
diff changeset
4420
a61af66fc99e Initial load
duke
parents:
diff changeset
4421 void signalHandler(int sig, siginfo_t* info, void* ucVoid) {
8067
5cd2fac2ae70 6749267: Signal handler should save/restore errno
hseigel
parents: 8066
diff changeset
4422 int orig_errno = errno; // Preserve errno value over signal handler.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4423 JVM_handle_solaris_signal(sig, info, ucVoid, true);
8067
5cd2fac2ae70 6749267: Signal handler should save/restore errno
hseigel
parents: 8066
diff changeset
4424 errno = orig_errno;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4425 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4426
a61af66fc99e Initial load
duke
parents:
diff changeset
4427 /* Do not delete - if guarantee is ever removed, a signal handler (even empty)
a61af66fc99e Initial load
duke
parents:
diff changeset
4428 is needed to provoke threads blocked on IO to return an EINTR
a61af66fc99e Initial load
duke
parents:
diff changeset
4429 Note: this explicitly does NOT call JVM_handle_solaris_signal and
a61af66fc99e Initial load
duke
parents:
diff changeset
4430 does NOT participate in signal chaining due to requirement for
a61af66fc99e Initial load
duke
parents:
diff changeset
4431 NOT setting SA_RESTART to make EINTR work. */
a61af66fc99e Initial load
duke
parents:
diff changeset
4432 extern "C" void sigINTRHandler(int sig, siginfo_t* info, void* ucVoid) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4433 if (UseSignalChaining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4434 struct sigaction *actp = os::Solaris::get_chained_signal_action(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4435 if (actp && actp->sa_handler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4436 vm_exit_during_initialization("Signal chaining detected for VM interrupt signal, try -XX:+UseAltSigs");
a61af66fc99e Initial load
duke
parents:
diff changeset
4437 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4438 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4439 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4440
a61af66fc99e Initial load
duke
parents:
diff changeset
4441 // This boolean allows users to forward their own non-matching signals
a61af66fc99e Initial load
duke
parents:
diff changeset
4442 // to JVM_handle_solaris_signal, harmlessly.
a61af66fc99e Initial load
duke
parents:
diff changeset
4443 bool os::Solaris::signal_handlers_are_installed = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4444
a61af66fc99e Initial load
duke
parents:
diff changeset
4445 // For signal-chaining
a61af66fc99e Initial load
duke
parents:
diff changeset
4446 bool os::Solaris::libjsig_is_loaded = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4447 typedef struct sigaction *(*get_signal_t)(int);
a61af66fc99e Initial load
duke
parents:
diff changeset
4448 get_signal_t os::Solaris::get_signal_action = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4449
a61af66fc99e Initial load
duke
parents:
diff changeset
4450 struct sigaction* os::Solaris::get_chained_signal_action(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4451 struct sigaction *actp = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4452
a61af66fc99e Initial load
duke
parents:
diff changeset
4453 if ((libjsig_is_loaded) && (sig <= Maxlibjsigsigs)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4454 // Retrieve the old signal handler from libjsig
a61af66fc99e Initial load
duke
parents:
diff changeset
4455 actp = (*get_signal_action)(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4456 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4457 if (actp == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4458 // Retrieve the preinstalled signal handler from jvm
a61af66fc99e Initial load
duke
parents:
diff changeset
4459 actp = get_preinstalled_handler(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4461
a61af66fc99e Initial load
duke
parents:
diff changeset
4462 return actp;
a61af66fc99e Initial load
duke
parents:
diff changeset
4463 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4464
a61af66fc99e Initial load
duke
parents:
diff changeset
4465 static bool call_chained_handler(struct sigaction *actp, int sig,
a61af66fc99e Initial load
duke
parents:
diff changeset
4466 siginfo_t *siginfo, void *context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4467 // Call the old signal handler
a61af66fc99e Initial load
duke
parents:
diff changeset
4468 if (actp->sa_handler == SIG_DFL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4469 // It's more reasonable to let jvm treat it as an unexpected exception
a61af66fc99e Initial load
duke
parents:
diff changeset
4470 // instead of taking the default action.
a61af66fc99e Initial load
duke
parents:
diff changeset
4471 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4472 } else if (actp->sa_handler != SIG_IGN) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4473 if ((actp->sa_flags & SA_NODEFER) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4474 // automaticlly block the signal
a61af66fc99e Initial load
duke
parents:
diff changeset
4475 sigaddset(&(actp->sa_mask), sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4476 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4477
a61af66fc99e Initial load
duke
parents:
diff changeset
4478 sa_handler_t hand;
a61af66fc99e Initial load
duke
parents:
diff changeset
4479 sa_sigaction_t sa;
a61af66fc99e Initial load
duke
parents:
diff changeset
4480 bool siginfo_flag_set = (actp->sa_flags & SA_SIGINFO) != 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4481 // retrieve the chained handler
a61af66fc99e Initial load
duke
parents:
diff changeset
4482 if (siginfo_flag_set) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4483 sa = actp->sa_sigaction;
a61af66fc99e Initial load
duke
parents:
diff changeset
4484 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4485 hand = actp->sa_handler;
a61af66fc99e Initial load
duke
parents:
diff changeset
4486 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4487
a61af66fc99e Initial load
duke
parents:
diff changeset
4488 if ((actp->sa_flags & SA_RESETHAND) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4489 actp->sa_handler = SIG_DFL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4490 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4491
a61af66fc99e Initial load
duke
parents:
diff changeset
4492 // try to honor the signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
4493 sigset_t oset;
a61af66fc99e Initial load
duke
parents:
diff changeset
4494 thr_sigsetmask(SIG_SETMASK, &(actp->sa_mask), &oset);
a61af66fc99e Initial load
duke
parents:
diff changeset
4495
a61af66fc99e Initial load
duke
parents:
diff changeset
4496 // call into the chained handler
a61af66fc99e Initial load
duke
parents:
diff changeset
4497 if (siginfo_flag_set) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4498 (*sa)(sig, siginfo, context);
a61af66fc99e Initial load
duke
parents:
diff changeset
4499 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4500 (*hand)(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4501 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4502
a61af66fc99e Initial load
duke
parents:
diff changeset
4503 // restore the signal mask
a61af66fc99e Initial load
duke
parents:
diff changeset
4504 thr_sigsetmask(SIG_SETMASK, &oset, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
4505 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4506 // Tell jvm's signal handler the signal is taken care of.
a61af66fc99e Initial load
duke
parents:
diff changeset
4507 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4508 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4509
a61af66fc99e Initial load
duke
parents:
diff changeset
4510 bool os::Solaris::chained_handler(int sig, siginfo_t* siginfo, void* context) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4511 bool chained = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4512 // signal-chaining
a61af66fc99e Initial load
duke
parents:
diff changeset
4513 if (UseSignalChaining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4514 struct sigaction *actp = get_chained_signal_action(sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4515 if (actp != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4516 chained = call_chained_handler(actp, sig, siginfo, context);
a61af66fc99e Initial load
duke
parents:
diff changeset
4517 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4518 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4519 return chained;
a61af66fc99e Initial load
duke
parents:
diff changeset
4520 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4521
a61af66fc99e Initial load
duke
parents:
diff changeset
4522 struct sigaction* os::Solaris::get_preinstalled_handler(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4523 assert((chainedsigactions != (struct sigaction *)NULL) && (preinstalled_sigs != (int *)NULL) , "signals not yet initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
4524 if (preinstalled_sigs[sig] != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4525 return &chainedsigactions[sig];
a61af66fc99e Initial load
duke
parents:
diff changeset
4526 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4527 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4528 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4529
a61af66fc99e Initial load
duke
parents:
diff changeset
4530 void os::Solaris::save_preinstalled_handler(int sig, struct sigaction& oldAct) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4531
a61af66fc99e Initial load
duke
parents:
diff changeset
4532 assert(sig > 0 && sig <= Maxsignum, "vm signal out of expected range");
a61af66fc99e Initial load
duke
parents:
diff changeset
4533 assert((chainedsigactions != (struct sigaction *)NULL) && (preinstalled_sigs != (int *)NULL) , "signals not yet initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
4534 chainedsigactions[sig] = oldAct;
a61af66fc99e Initial load
duke
parents:
diff changeset
4535 preinstalled_sigs[sig] = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
4536 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4537
a61af66fc99e Initial load
duke
parents:
diff changeset
4538 void os::Solaris::set_signal_handler(int sig, bool set_installed, bool oktochain) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4539 // Check for overwrite.
a61af66fc99e Initial load
duke
parents:
diff changeset
4540 struct sigaction oldAct;
a61af66fc99e Initial load
duke
parents:
diff changeset
4541 sigaction(sig, (struct sigaction*)NULL, &oldAct);
a61af66fc99e Initial load
duke
parents:
diff changeset
4542 void* oldhand = oldAct.sa_sigaction ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
4543 : CAST_FROM_FN_PTR(void*, oldAct.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
4544 if (oldhand != CAST_FROM_FN_PTR(void*, SIG_DFL) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
4545 oldhand != CAST_FROM_FN_PTR(void*, SIG_IGN) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
4546 oldhand != CAST_FROM_FN_PTR(void*, signalHandler)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4547 if (AllowUserSignalHandlers || !set_installed) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4548 // Do not overwrite; user takes responsibility to forward to us.
a61af66fc99e Initial load
duke
parents:
diff changeset
4549 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
4550 } else if (UseSignalChaining) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4551 if (oktochain) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4552 // save the old handler in jvm
a61af66fc99e Initial load
duke
parents:
diff changeset
4553 save_preinstalled_handler(sig, oldAct);
a61af66fc99e Initial load
duke
parents:
diff changeset
4554 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4555 vm_exit_during_initialization("Signal chaining not allowed for VM interrupt signal, try -XX:+UseAltSigs.");
a61af66fc99e Initial load
duke
parents:
diff changeset
4556 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4557 // libjsig also interposes the sigaction() call below and saves the
a61af66fc99e Initial load
duke
parents:
diff changeset
4558 // old sigaction on it own.
a61af66fc99e Initial load
duke
parents:
diff changeset
4559 } else {
1490
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
4560 fatal(err_msg("Encountered unexpected pre-existing sigaction handler "
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
4561 "%#lx for signal %d.", (long)oldhand, sig));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4562 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4563 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4564
a61af66fc99e Initial load
duke
parents:
diff changeset
4565 struct sigaction sigAct;
a61af66fc99e Initial load
duke
parents:
diff changeset
4566 sigfillset(&(sigAct.sa_mask));
a61af66fc99e Initial load
duke
parents:
diff changeset
4567 sigAct.sa_handler = SIG_DFL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4568
a61af66fc99e Initial load
duke
parents:
diff changeset
4569 sigAct.sa_sigaction = signalHandler;
a61af66fc99e Initial load
duke
parents:
diff changeset
4570 // Handle SIGSEGV on alternate signal stack if
a61af66fc99e Initial load
duke
parents:
diff changeset
4571 // not using stack banging
a61af66fc99e Initial load
duke
parents:
diff changeset
4572 if (!UseStackBanging && sig == SIGSEGV) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4573 sigAct.sa_flags = SA_SIGINFO | SA_RESTART | SA_ONSTACK;
a61af66fc99e Initial load
duke
parents:
diff changeset
4574 // Interruptible i/o requires SA_RESTART cleared so EINTR
a61af66fc99e Initial load
duke
parents:
diff changeset
4575 // is returned instead of restarting system calls
a61af66fc99e Initial load
duke
parents:
diff changeset
4576 } else if (sig == os::Solaris::SIGinterrupt()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4577 sigemptyset(&sigAct.sa_mask);
a61af66fc99e Initial load
duke
parents:
diff changeset
4578 sigAct.sa_handler = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4579 sigAct.sa_flags = SA_SIGINFO;
a61af66fc99e Initial load
duke
parents:
diff changeset
4580 sigAct.sa_sigaction = sigINTRHandler;
a61af66fc99e Initial load
duke
parents:
diff changeset
4581 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4582 sigAct.sa_flags = SA_SIGINFO | SA_RESTART;
a61af66fc99e Initial load
duke
parents:
diff changeset
4583 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4584 os::Solaris::set_our_sigflags(sig, sigAct.sa_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
4585
a61af66fc99e Initial load
duke
parents:
diff changeset
4586 sigaction(sig, &sigAct, &oldAct);
a61af66fc99e Initial load
duke
parents:
diff changeset
4587
a61af66fc99e Initial load
duke
parents:
diff changeset
4588 void* oldhand2 = oldAct.sa_sigaction ? CAST_FROM_FN_PTR(void*, oldAct.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
4589 : CAST_FROM_FN_PTR(void*, oldAct.sa_handler);
a61af66fc99e Initial load
duke
parents:
diff changeset
4590 assert(oldhand2 == oldhand, "no concurrent signal handler installation");
a61af66fc99e Initial load
duke
parents:
diff changeset
4591 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4592
a61af66fc99e Initial load
duke
parents:
diff changeset
4593
a61af66fc99e Initial load
duke
parents:
diff changeset
4594 #define DO_SIGNAL_CHECK(sig) \
a61af66fc99e Initial load
duke
parents:
diff changeset
4595 if (!sigismember(&check_signal_done, sig)) \
a61af66fc99e Initial load
duke
parents:
diff changeset
4596 os::Solaris::check_signal_handler(sig)
a61af66fc99e Initial load
duke
parents:
diff changeset
4597
a61af66fc99e Initial load
duke
parents:
diff changeset
4598 // This method is a periodic task to check for misbehaving JNI applications
a61af66fc99e Initial load
duke
parents:
diff changeset
4599 // under CheckJNI, we can add any periodic checks here
a61af66fc99e Initial load
duke
parents:
diff changeset
4600
a61af66fc99e Initial load
duke
parents:
diff changeset
4601 void os::run_periodic_checks() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4602 // A big source of grief is hijacking virt. addr 0x0 on Solaris,
a61af66fc99e Initial load
duke
parents:
diff changeset
4603 // thereby preventing a NULL checks.
a61af66fc99e Initial load
duke
parents:
diff changeset
4604 if(!check_addr0_done) check_addr0_done = check_addr0(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
4605
a61af66fc99e Initial load
duke
parents:
diff changeset
4606 if (check_signals == false) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
4607
a61af66fc99e Initial load
duke
parents:
diff changeset
4608 // SEGV and BUS if overridden could potentially prevent
a61af66fc99e Initial load
duke
parents:
diff changeset
4609 // generation of hs*.log in the event of a crash, debugging
a61af66fc99e Initial load
duke
parents:
diff changeset
4610 // such a case can be very challenging, so we absolutely
a61af66fc99e Initial load
duke
parents:
diff changeset
4611 // check for the following for a good measure:
a61af66fc99e Initial load
duke
parents:
diff changeset
4612 DO_SIGNAL_CHECK(SIGSEGV);
a61af66fc99e Initial load
duke
parents:
diff changeset
4613 DO_SIGNAL_CHECK(SIGILL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4614 DO_SIGNAL_CHECK(SIGFPE);
a61af66fc99e Initial load
duke
parents:
diff changeset
4615 DO_SIGNAL_CHECK(SIGBUS);
a61af66fc99e Initial load
duke
parents:
diff changeset
4616 DO_SIGNAL_CHECK(SIGPIPE);
a61af66fc99e Initial load
duke
parents:
diff changeset
4617 DO_SIGNAL_CHECK(SIGXFSZ);
a61af66fc99e Initial load
duke
parents:
diff changeset
4618
a61af66fc99e Initial load
duke
parents:
diff changeset
4619 // ReduceSignalUsage allows the user to override these handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
4620 // see comments at the very top and jvm_solaris.h
a61af66fc99e Initial load
duke
parents:
diff changeset
4621 if (!ReduceSignalUsage) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4622 DO_SIGNAL_CHECK(SHUTDOWN1_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4623 DO_SIGNAL_CHECK(SHUTDOWN2_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4624 DO_SIGNAL_CHECK(SHUTDOWN3_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4625 DO_SIGNAL_CHECK(BREAK_SIGNAL);
a61af66fc99e Initial load
duke
parents:
diff changeset
4626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4627
a61af66fc99e Initial load
duke
parents:
diff changeset
4628 // See comments above for using JVM1/JVM2 and UseAltSigs
a61af66fc99e Initial load
duke
parents:
diff changeset
4629 DO_SIGNAL_CHECK(os::Solaris::SIGinterrupt());
a61af66fc99e Initial load
duke
parents:
diff changeset
4630 DO_SIGNAL_CHECK(os::Solaris::SIGasync());
a61af66fc99e Initial load
duke
parents:
diff changeset
4631
a61af66fc99e Initial load
duke
parents:
diff changeset
4632 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4633
a61af66fc99e Initial load
duke
parents:
diff changeset
4634 typedef int (*os_sigaction_t)(int, const struct sigaction *, struct sigaction *);
a61af66fc99e Initial load
duke
parents:
diff changeset
4635
a61af66fc99e Initial load
duke
parents:
diff changeset
4636 static os_sigaction_t os_sigaction = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4637
a61af66fc99e Initial load
duke
parents:
diff changeset
4638 void os::Solaris::check_signal_handler(int sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4639 char buf[O_BUFLEN];
a61af66fc99e Initial load
duke
parents:
diff changeset
4640 address jvmHandler = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4641
a61af66fc99e Initial load
duke
parents:
diff changeset
4642 struct sigaction act;
a61af66fc99e Initial load
duke
parents:
diff changeset
4643 if (os_sigaction == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4644 // only trust the default sigaction, in case it has been interposed
a61af66fc99e Initial load
duke
parents:
diff changeset
4645 os_sigaction = (os_sigaction_t)dlsym(RTLD_DEFAULT, "sigaction");
a61af66fc99e Initial load
duke
parents:
diff changeset
4646 if (os_sigaction == NULL) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
4647 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4648
a61af66fc99e Initial load
duke
parents:
diff changeset
4649 os_sigaction(sig, (struct sigaction*)NULL, &act);
a61af66fc99e Initial load
duke
parents:
diff changeset
4650
a61af66fc99e Initial load
duke
parents:
diff changeset
4651 address thisHandler = (act.sa_flags & SA_SIGINFO)
a61af66fc99e Initial load
duke
parents:
diff changeset
4652 ? CAST_FROM_FN_PTR(address, act.sa_sigaction)
a61af66fc99e Initial load
duke
parents:
diff changeset
4653 : CAST_FROM_FN_PTR(address, act.sa_handler) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
4654
a61af66fc99e Initial load
duke
parents:
diff changeset
4655
a61af66fc99e Initial load
duke
parents:
diff changeset
4656 switch(sig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4657 case SIGSEGV:
a61af66fc99e Initial load
duke
parents:
diff changeset
4658 case SIGBUS:
a61af66fc99e Initial load
duke
parents:
diff changeset
4659 case SIGFPE:
a61af66fc99e Initial load
duke
parents:
diff changeset
4660 case SIGPIPE:
a61af66fc99e Initial load
duke
parents:
diff changeset
4661 case SIGXFSZ:
a61af66fc99e Initial load
duke
parents:
diff changeset
4662 case SIGILL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4663 jvmHandler = CAST_FROM_FN_PTR(address, signalHandler);
a61af66fc99e Initial load
duke
parents:
diff changeset
4664 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4665
a61af66fc99e Initial load
duke
parents:
diff changeset
4666 case SHUTDOWN1_SIGNAL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4667 case SHUTDOWN2_SIGNAL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4668 case SHUTDOWN3_SIGNAL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4669 case BREAK_SIGNAL:
a61af66fc99e Initial load
duke
parents:
diff changeset
4670 jvmHandler = (address)user_handler();
a61af66fc99e Initial load
duke
parents:
diff changeset
4671 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4672
a61af66fc99e Initial load
duke
parents:
diff changeset
4673 default:
a61af66fc99e Initial load
duke
parents:
diff changeset
4674 int intrsig = os::Solaris::SIGinterrupt();
a61af66fc99e Initial load
duke
parents:
diff changeset
4675 int asynsig = os::Solaris::SIGasync();
a61af66fc99e Initial load
duke
parents:
diff changeset
4676
a61af66fc99e Initial load
duke
parents:
diff changeset
4677 if (sig == intrsig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4678 jvmHandler = CAST_FROM_FN_PTR(address, sigINTRHandler);
a61af66fc99e Initial load
duke
parents:
diff changeset
4679 } else if (sig == asynsig) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4680 jvmHandler = CAST_FROM_FN_PTR(address, signalHandler);
a61af66fc99e Initial load
duke
parents:
diff changeset
4681 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4682 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
4683 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4684 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4685 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4686
a61af66fc99e Initial load
duke
parents:
diff changeset
4687
a61af66fc99e Initial load
duke
parents:
diff changeset
4688 if (thisHandler != jvmHandler) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4689 tty->print("Warning: %s handler ", exception_name(sig, buf, O_BUFLEN));
a61af66fc99e Initial load
duke
parents:
diff changeset
4690 tty->print("expected:%s", get_signal_handler_name(jvmHandler, buf, O_BUFLEN));
a61af66fc99e Initial load
duke
parents:
diff changeset
4691 tty->print_cr(" found:%s", get_signal_handler_name(thisHandler, buf, O_BUFLEN));
a61af66fc99e Initial load
duke
parents:
diff changeset
4692 // No need to check this sig any longer
a61af66fc99e Initial load
duke
parents:
diff changeset
4693 sigaddset(&check_signal_done, sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4694 } else if(os::Solaris::get_our_sigflags(sig) != 0 && act.sa_flags != os::Solaris::get_our_sigflags(sig)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4695 tty->print("Warning: %s handler flags ", exception_name(sig, buf, O_BUFLEN));
a61af66fc99e Initial load
duke
parents:
diff changeset
4696 tty->print("expected:" PTR32_FORMAT, os::Solaris::get_our_sigflags(sig));
a61af66fc99e Initial load
duke
parents:
diff changeset
4697 tty->print_cr(" found:" PTR32_FORMAT, act.sa_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
4698 // No need to check this sig any longer
a61af66fc99e Initial load
duke
parents:
diff changeset
4699 sigaddset(&check_signal_done, sig);
a61af66fc99e Initial load
duke
parents:
diff changeset
4700 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4701
a61af66fc99e Initial load
duke
parents:
diff changeset
4702 // Print all the signal handler state
a61af66fc99e Initial load
duke
parents:
diff changeset
4703 if (sigismember(&check_signal_done, sig)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4704 print_signal_handlers(tty, buf, O_BUFLEN);
a61af66fc99e Initial load
duke
parents:
diff changeset
4705 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4706
a61af66fc99e Initial load
duke
parents:
diff changeset
4707 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4708
a61af66fc99e Initial load
duke
parents:
diff changeset
4709 void os::Solaris::install_signal_handlers() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4710 bool libjsigdone = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4711 signal_handlers_are_installed = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4712
a61af66fc99e Initial load
duke
parents:
diff changeset
4713 // signal-chaining
a61af66fc99e Initial load
duke
parents:
diff changeset
4714 typedef void (*signal_setting_t)();
a61af66fc99e Initial load
duke
parents:
diff changeset
4715 signal_setting_t begin_signal_setting = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4716 signal_setting_t end_signal_setting = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4717 begin_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
a61af66fc99e Initial load
duke
parents:
diff changeset
4718 dlsym(RTLD_DEFAULT, "JVM_begin_signal_setting"));
a61af66fc99e Initial load
duke
parents:
diff changeset
4719 if (begin_signal_setting != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4720 end_signal_setting = CAST_TO_FN_PTR(signal_setting_t,
a61af66fc99e Initial load
duke
parents:
diff changeset
4721 dlsym(RTLD_DEFAULT, "JVM_end_signal_setting"));
a61af66fc99e Initial load
duke
parents:
diff changeset
4722 get_signal_action = CAST_TO_FN_PTR(get_signal_t,
a61af66fc99e Initial load
duke
parents:
diff changeset
4723 dlsym(RTLD_DEFAULT, "JVM_get_signal_action"));
a61af66fc99e Initial load
duke
parents:
diff changeset
4724 get_libjsig_version = CAST_TO_FN_PTR(version_getting_t,
a61af66fc99e Initial load
duke
parents:
diff changeset
4725 dlsym(RTLD_DEFAULT, "JVM_get_libjsig_version"));
a61af66fc99e Initial load
duke
parents:
diff changeset
4726 libjsig_is_loaded = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4727 if (os::Solaris::get_libjsig_version != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4728 libjsigversion = (*os::Solaris::get_libjsig_version)();
a61af66fc99e Initial load
duke
parents:
diff changeset
4729 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4730 assert(UseSignalChaining, "should enable signal-chaining");
a61af66fc99e Initial load
duke
parents:
diff changeset
4731 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4732 if (libjsig_is_loaded) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4733 // Tell libjsig jvm is setting signal handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
4734 (*begin_signal_setting)();
a61af66fc99e Initial load
duke
parents:
diff changeset
4735 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4736
a61af66fc99e Initial load
duke
parents:
diff changeset
4737 set_signal_handler(SIGSEGV, true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4738 set_signal_handler(SIGPIPE, true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4739 set_signal_handler(SIGXFSZ, true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4740 set_signal_handler(SIGBUS, true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4741 set_signal_handler(SIGILL, true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4742 set_signal_handler(SIGFPE, true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4743
a61af66fc99e Initial load
duke
parents:
diff changeset
4744
a61af66fc99e Initial load
duke
parents:
diff changeset
4745 if (os::Solaris::SIGinterrupt() > OLDMAXSIGNUM || os::Solaris::SIGasync() > OLDMAXSIGNUM) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4746
a61af66fc99e Initial load
duke
parents:
diff changeset
4747 // Pre-1.4.1 Libjsig limited to signal chaining signals <= 32 so
a61af66fc99e Initial load
duke
parents:
diff changeset
4748 // can not register overridable signals which might be > 32
a61af66fc99e Initial load
duke
parents:
diff changeset
4749 if (libjsig_is_loaded && libjsigversion <= JSIG_VERSION_1_4_1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4750 // Tell libjsig jvm has finished setting signal handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
4751 (*end_signal_setting)();
a61af66fc99e Initial load
duke
parents:
diff changeset
4752 libjsigdone = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
4753 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4754 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4755
a61af66fc99e Initial load
duke
parents:
diff changeset
4756 // Never ok to chain our SIGinterrupt
a61af66fc99e Initial load
duke
parents:
diff changeset
4757 set_signal_handler(os::Solaris::SIGinterrupt(), true, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
4758 set_signal_handler(os::Solaris::SIGasync(), true, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
4759
a61af66fc99e Initial load
duke
parents:
diff changeset
4760 if (libjsig_is_loaded && !libjsigdone) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4761 // Tell libjsig jvm finishes setting signal handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
4762 (*end_signal_setting)();
a61af66fc99e Initial load
duke
parents:
diff changeset
4763 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4764
a61af66fc99e Initial load
duke
parents:
diff changeset
4765 // We don't activate signal checker if libjsig is in place, we trust ourselves
3956
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3885
diff changeset
4766 // and if UserSignalHandler is installed all bets are off.
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3885
diff changeset
4767 // Log that signal checking is off only if -verbose:jni is specified.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4768 if (CheckJNICalls) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4769 if (libjsig_is_loaded) {
3956
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3885
diff changeset
4770 if (PrintJNIResolving) {
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3885
diff changeset
4771 tty->print_cr("Info: libjsig is activated, all active signal checking is disabled");
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3885
diff changeset
4772 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4773 check_signals = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4774 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4775 if (AllowUserSignalHandlers) {
3956
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3885
diff changeset
4776 if (PrintJNIResolving) {
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3885
diff changeset
4777 tty->print_cr("Info: AllowUserSignalHandlers is activated, all active signal checking is disabled");
3607aac85aa9 7051189: Need to suppress info message if -xcheck:jni used with libjsig.so
kevinw
parents: 3885
diff changeset
4778 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4779 check_signals = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4780 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4781 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4782 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4783
a61af66fc99e Initial load
duke
parents:
diff changeset
4784
a61af66fc99e Initial load
duke
parents:
diff changeset
4785 void report_error(const char* file_name, int line_no, const char* title, const char* format, ...);
a61af66fc99e Initial load
duke
parents:
diff changeset
4786
a61af66fc99e Initial load
duke
parents:
diff changeset
4787 const char * signames[] = {
a61af66fc99e Initial load
duke
parents:
diff changeset
4788 "SIG0",
a61af66fc99e Initial load
duke
parents:
diff changeset
4789 "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGTRAP",
a61af66fc99e Initial load
duke
parents:
diff changeset
4790 "SIGABRT", "SIGEMT", "SIGFPE", "SIGKILL", "SIGBUS",
a61af66fc99e Initial load
duke
parents:
diff changeset
4791 "SIGSEGV", "SIGSYS", "SIGPIPE", "SIGALRM", "SIGTERM",
a61af66fc99e Initial load
duke
parents:
diff changeset
4792 "SIGUSR1", "SIGUSR2", "SIGCLD", "SIGPWR", "SIGWINCH",
a61af66fc99e Initial load
duke
parents:
diff changeset
4793 "SIGURG", "SIGPOLL", "SIGSTOP", "SIGTSTP", "SIGCONT",
a61af66fc99e Initial load
duke
parents:
diff changeset
4794 "SIGTTIN", "SIGTTOU", "SIGVTALRM", "SIGPROF", "SIGXCPU",
a61af66fc99e Initial load
duke
parents:
diff changeset
4795 "SIGXFSZ", "SIGWAITING", "SIGLWP", "SIGFREEZE", "SIGTHAW",
a61af66fc99e Initial load
duke
parents:
diff changeset
4796 "SIGCANCEL", "SIGLOST"
a61af66fc99e Initial load
duke
parents:
diff changeset
4797 };
a61af66fc99e Initial load
duke
parents:
diff changeset
4798
a61af66fc99e Initial load
duke
parents:
diff changeset
4799 const char* os::exception_name(int exception_code, char* buf, size_t size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4800 if (0 < exception_code && exception_code <= SIGRTMAX) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4801 // signal
a61af66fc99e Initial load
duke
parents:
diff changeset
4802 if (exception_code < sizeof(signames)/sizeof(const char*)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4803 jio_snprintf(buf, size, "%s", signames[exception_code]);
a61af66fc99e Initial load
duke
parents:
diff changeset
4804 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4805 jio_snprintf(buf, size, "SIG%d", exception_code);
a61af66fc99e Initial load
duke
parents:
diff changeset
4806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4807 return buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
4808 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4809 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4810 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4811 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4812
a61af66fc99e Initial load
duke
parents:
diff changeset
4813 // (Static) wrappers for the new libthread API
a61af66fc99e Initial load
duke
parents:
diff changeset
4814 int_fnP_thread_t_iP_uP_stack_tP_gregset_t os::Solaris::_thr_getstate;
a61af66fc99e Initial load
duke
parents:
diff changeset
4815 int_fnP_thread_t_i_gregset_t os::Solaris::_thr_setstate;
a61af66fc99e Initial load
duke
parents:
diff changeset
4816 int_fnP_thread_t_i os::Solaris::_thr_setmutator;
a61af66fc99e Initial load
duke
parents:
diff changeset
4817 int_fnP_thread_t os::Solaris::_thr_suspend_mutator;
a61af66fc99e Initial load
duke
parents:
diff changeset
4818 int_fnP_thread_t os::Solaris::_thr_continue_mutator;
a61af66fc99e Initial load
duke
parents:
diff changeset
4819
641
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4820 // (Static) wrapper for getisax(2) call.
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4821 os::Solaris::getisax_func_t os::Solaris::_getisax = 0;
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4822
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4823 // (Static) wrappers for the liblgrp API
a61af66fc99e Initial load
duke
parents:
diff changeset
4824 os::Solaris::lgrp_home_func_t os::Solaris::_lgrp_home;
a61af66fc99e Initial load
duke
parents:
diff changeset
4825 os::Solaris::lgrp_init_func_t os::Solaris::_lgrp_init;
a61af66fc99e Initial load
duke
parents:
diff changeset
4826 os::Solaris::lgrp_fini_func_t os::Solaris::_lgrp_fini;
a61af66fc99e Initial load
duke
parents:
diff changeset
4827 os::Solaris::lgrp_root_func_t os::Solaris::_lgrp_root;
a61af66fc99e Initial load
duke
parents:
diff changeset
4828 os::Solaris::lgrp_children_func_t os::Solaris::_lgrp_children;
144
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
4829 os::Solaris::lgrp_resources_func_t os::Solaris::_lgrp_resources;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4830 os::Solaris::lgrp_nlgrps_func_t os::Solaris::_lgrp_nlgrps;
a61af66fc99e Initial load
duke
parents:
diff changeset
4831 os::Solaris::lgrp_cookie_stale_func_t os::Solaris::_lgrp_cookie_stale;
a61af66fc99e Initial load
duke
parents:
diff changeset
4832 os::Solaris::lgrp_cookie_t os::Solaris::_lgrp_cookie = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4833
a61af66fc99e Initial load
duke
parents:
diff changeset
4834 // (Static) wrapper for meminfo() call.
a61af66fc99e Initial load
duke
parents:
diff changeset
4835 os::Solaris::meminfo_func_t os::Solaris::_meminfo = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4836
641
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4837 static address resolve_symbol_lazy(const char* name) {
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4838 address addr = (address) dlsym(RTLD_DEFAULT, name);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4839 if(addr == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4840 // RTLD_DEFAULT was not defined on some early versions of 2.5.1
a61af66fc99e Initial load
duke
parents:
diff changeset
4841 addr = (address) dlsym(RTLD_NEXT, name);
641
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4842 }
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4843 return addr;
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4844 }
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4845
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4846 static address resolve_symbol(const char* name) {
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4847 address addr = resolve_symbol_lazy(name);
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4848 if(addr == NULL) {
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
4849 fatal(dlerror());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4850 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4851 return addr;
a61af66fc99e Initial load
duke
parents:
diff changeset
4852 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4853
a61af66fc99e Initial load
duke
parents:
diff changeset
4854
a61af66fc99e Initial load
duke
parents:
diff changeset
4855
a61af66fc99e Initial load
duke
parents:
diff changeset
4856 // isT2_libthread()
a61af66fc99e Initial load
duke
parents:
diff changeset
4857 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4858 // Routine to determine if we are currently using the new T2 libthread.
a61af66fc99e Initial load
duke
parents:
diff changeset
4859 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4860 // We determine if we are using T2 by reading /proc/self/lstatus and
a61af66fc99e Initial load
duke
parents:
diff changeset
4861 // looking for a thread with the ASLWP bit set. If we find this status
a61af66fc99e Initial load
duke
parents:
diff changeset
4862 // bit set, we must assume that we are NOT using T2. The T2 team
a61af66fc99e Initial load
duke
parents:
diff changeset
4863 // has approved this algorithm.
a61af66fc99e Initial load
duke
parents:
diff changeset
4864 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4865 // We need to determine if we are running with the new T2 libthread
a61af66fc99e Initial load
duke
parents:
diff changeset
4866 // since setting native thread priorities is handled differently
a61af66fc99e Initial load
duke
parents:
diff changeset
4867 // when using this library. All threads created using T2 are bound
a61af66fc99e Initial load
duke
parents:
diff changeset
4868 // threads. Calling thr_setprio is meaningless in this case.
a61af66fc99e Initial load
duke
parents:
diff changeset
4869 //
a61af66fc99e Initial load
duke
parents:
diff changeset
4870 bool isT2_libthread() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4871 static prheader_t * lwpArray = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
4872 static int lwpSize = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
4873 static int lwpFile = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
4874 lwpstatus_t * that;
a61af66fc99e Initial load
duke
parents:
diff changeset
4875 char lwpName [128];
a61af66fc99e Initial load
duke
parents:
diff changeset
4876 bool isT2 = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
4877
a61af66fc99e Initial load
duke
parents:
diff changeset
4878 #define ADR(x) ((uintptr_t)(x))
a61af66fc99e Initial load
duke
parents:
diff changeset
4879 #define LWPINDEX(ary,ix) ((lwpstatus_t *)(((ary)->pr_entsize * (ix)) + (ADR((ary) + 1))))
a61af66fc99e Initial load
duke
parents:
diff changeset
4880
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4881 lwpFile = ::open("/proc/self/lstatus", O_RDONLY, 0);
89
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4882 if (lwpFile < 0) {
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4883 if (ThreadPriorityVerbose) warning ("Couldn't open /proc/self/lstatus\n");
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4884 return false;
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4885 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4886 lwpSize = 16*1024;
a61af66fc99e Initial load
duke
parents:
diff changeset
4887 for (;;) {
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4888 ::lseek64 (lwpFile, 0, SEEK_SET);
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
4889 lwpArray = (prheader_t *)NEW_C_HEAP_ARRAY(char, lwpSize, mtInternal);
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4890 if (::read(lwpFile, lwpArray, lwpSize) < 0) {
89
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4891 if (ThreadPriorityVerbose) warning("Error reading /proc/self/lstatus\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4892 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
4893 }
89
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4894 if ((lwpArray->pr_nent * lwpArray->pr_entsize) <= lwpSize) {
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4895 // We got a good snapshot - now iterate over the list.
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4896 int aslwpcount = 0;
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4897 for (int i = 0; i < lwpArray->pr_nent; i++ ) {
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4898 that = LWPINDEX(lwpArray,i);
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4899 if (that->pr_flags & PR_ASLWP) {
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4900 aslwpcount++;
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4901 }
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4902 }
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4903 if (aslwpcount == 0) isT2 = true;
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4904 break;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4905 }
89
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4906 lwpSize = lwpArray->pr_nent * lwpArray->pr_entsize;
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
4907 FREE_C_HEAP_ARRAY(char, lwpArray, mtInternal); // retry.
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
4908 }
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
4909
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
4910 FREE_C_HEAP_ARRAY(char, lwpArray, mtInternal);
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
4911 ::close (lwpFile);
89
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4912 if (ThreadPriorityVerbose) {
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4913 if (isT2) tty->print_cr("We are running with a T2 libthread\n");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4914 else tty->print_cr("We are not running with a T2 libthread\n");
a61af66fc99e Initial load
duke
parents:
diff changeset
4915 }
89
b97de546208e 6671882: memory access after free in solaris/vm/os_solaris.cpp
xlu
parents: 79
diff changeset
4916 return isT2;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
4917 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4918
a61af66fc99e Initial load
duke
parents:
diff changeset
4919
a61af66fc99e Initial load
duke
parents:
diff changeset
4920 void os::Solaris::libthread_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4921 address func = (address)dlsym(RTLD_DEFAULT, "_thr_suspend_allmutators");
a61af66fc99e Initial load
duke
parents:
diff changeset
4922
a61af66fc99e Initial load
duke
parents:
diff changeset
4923 // Determine if we are running with the new T2 libthread
a61af66fc99e Initial load
duke
parents:
diff changeset
4924 os::Solaris::set_T2_libthread(isT2_libthread());
a61af66fc99e Initial load
duke
parents:
diff changeset
4925
a61af66fc99e Initial load
duke
parents:
diff changeset
4926 lwp_priocntl_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
4927
a61af66fc99e Initial load
duke
parents:
diff changeset
4928 // RTLD_DEFAULT was not defined on some early versions of 5.5.1
a61af66fc99e Initial load
duke
parents:
diff changeset
4929 if(func == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4930 func = (address) dlsym(RTLD_NEXT, "_thr_suspend_allmutators");
a61af66fc99e Initial load
duke
parents:
diff changeset
4931 // Guarantee that this VM is running on an new enough OS (5.6 or
a61af66fc99e Initial load
duke
parents:
diff changeset
4932 // later) that it will have a new enough libthread.so.
a61af66fc99e Initial load
duke
parents:
diff changeset
4933 guarantee(func != NULL, "libthread.so is too old.");
a61af66fc99e Initial load
duke
parents:
diff changeset
4934 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4935
a61af66fc99e Initial load
duke
parents:
diff changeset
4936 // Initialize the new libthread getstate API wrappers
a61af66fc99e Initial load
duke
parents:
diff changeset
4937 func = resolve_symbol("thr_getstate");
a61af66fc99e Initial load
duke
parents:
diff changeset
4938 os::Solaris::set_thr_getstate(CAST_TO_FN_PTR(int_fnP_thread_t_iP_uP_stack_tP_gregset_t, func));
a61af66fc99e Initial load
duke
parents:
diff changeset
4939
a61af66fc99e Initial load
duke
parents:
diff changeset
4940 func = resolve_symbol("thr_setstate");
a61af66fc99e Initial load
duke
parents:
diff changeset
4941 os::Solaris::set_thr_setstate(CAST_TO_FN_PTR(int_fnP_thread_t_i_gregset_t, func));
a61af66fc99e Initial load
duke
parents:
diff changeset
4942
a61af66fc99e Initial load
duke
parents:
diff changeset
4943 func = resolve_symbol("thr_setmutator");
a61af66fc99e Initial load
duke
parents:
diff changeset
4944 os::Solaris::set_thr_setmutator(CAST_TO_FN_PTR(int_fnP_thread_t_i, func));
a61af66fc99e Initial load
duke
parents:
diff changeset
4945
a61af66fc99e Initial load
duke
parents:
diff changeset
4946 func = resolve_symbol("thr_suspend_mutator");
a61af66fc99e Initial load
duke
parents:
diff changeset
4947 os::Solaris::set_thr_suspend_mutator(CAST_TO_FN_PTR(int_fnP_thread_t, func));
a61af66fc99e Initial load
duke
parents:
diff changeset
4948
a61af66fc99e Initial load
duke
parents:
diff changeset
4949 func = resolve_symbol("thr_continue_mutator");
a61af66fc99e Initial load
duke
parents:
diff changeset
4950 os::Solaris::set_thr_continue_mutator(CAST_TO_FN_PTR(int_fnP_thread_t, func));
a61af66fc99e Initial load
duke
parents:
diff changeset
4951
a61af66fc99e Initial load
duke
parents:
diff changeset
4952 int size;
a61af66fc99e Initial load
duke
parents:
diff changeset
4953 void (*handler_info_func)(address *, int *);
a61af66fc99e Initial load
duke
parents:
diff changeset
4954 handler_info_func = CAST_TO_FN_PTR(void (*)(address *, int *), resolve_symbol("thr_sighndlrinfo"));
a61af66fc99e Initial load
duke
parents:
diff changeset
4955 handler_info_func(&handler_start, &size);
a61af66fc99e Initial load
duke
parents:
diff changeset
4956 handler_end = handler_start + size;
a61af66fc99e Initial load
duke
parents:
diff changeset
4957 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4958
a61af66fc99e Initial load
duke
parents:
diff changeset
4959
a61af66fc99e Initial load
duke
parents:
diff changeset
4960 int_fnP_mutex_tP os::Solaris::_mutex_lock;
a61af66fc99e Initial load
duke
parents:
diff changeset
4961 int_fnP_mutex_tP os::Solaris::_mutex_trylock;
a61af66fc99e Initial load
duke
parents:
diff changeset
4962 int_fnP_mutex_tP os::Solaris::_mutex_unlock;
a61af66fc99e Initial load
duke
parents:
diff changeset
4963 int_fnP_mutex_tP_i_vP os::Solaris::_mutex_init;
a61af66fc99e Initial load
duke
parents:
diff changeset
4964 int_fnP_mutex_tP os::Solaris::_mutex_destroy;
a61af66fc99e Initial load
duke
parents:
diff changeset
4965 int os::Solaris::_mutex_scope = USYNC_THREAD;
a61af66fc99e Initial load
duke
parents:
diff changeset
4966
a61af66fc99e Initial load
duke
parents:
diff changeset
4967 int_fnP_cond_tP_mutex_tP_timestruc_tP os::Solaris::_cond_timedwait;
a61af66fc99e Initial load
duke
parents:
diff changeset
4968 int_fnP_cond_tP_mutex_tP os::Solaris::_cond_wait;
a61af66fc99e Initial load
duke
parents:
diff changeset
4969 int_fnP_cond_tP os::Solaris::_cond_signal;
a61af66fc99e Initial load
duke
parents:
diff changeset
4970 int_fnP_cond_tP os::Solaris::_cond_broadcast;
a61af66fc99e Initial load
duke
parents:
diff changeset
4971 int_fnP_cond_tP_i_vP os::Solaris::_cond_init;
a61af66fc99e Initial load
duke
parents:
diff changeset
4972 int_fnP_cond_tP os::Solaris::_cond_destroy;
a61af66fc99e Initial load
duke
parents:
diff changeset
4973 int os::Solaris::_cond_scope = USYNC_THREAD;
a61af66fc99e Initial load
duke
parents:
diff changeset
4974
a61af66fc99e Initial load
duke
parents:
diff changeset
4975 void os::Solaris::synchronization_init() {
a61af66fc99e Initial load
duke
parents:
diff changeset
4976 if(UseLWPSynchronization) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4977 os::Solaris::set_mutex_lock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("_lwp_mutex_lock")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4978 os::Solaris::set_mutex_trylock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("_lwp_mutex_trylock")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4979 os::Solaris::set_mutex_unlock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("_lwp_mutex_unlock")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4980 os::Solaris::set_mutex_init(lwp_mutex_init);
a61af66fc99e Initial load
duke
parents:
diff changeset
4981 os::Solaris::set_mutex_destroy(lwp_mutex_destroy);
a61af66fc99e Initial load
duke
parents:
diff changeset
4982 os::Solaris::set_mutex_scope(USYNC_THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
4983
a61af66fc99e Initial load
duke
parents:
diff changeset
4984 os::Solaris::set_cond_timedwait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP_timestruc_tP, resolve_symbol("_lwp_cond_timedwait")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4985 os::Solaris::set_cond_wait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP, resolve_symbol("_lwp_cond_wait")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4986 os::Solaris::set_cond_signal(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("_lwp_cond_signal")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4987 os::Solaris::set_cond_broadcast(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("_lwp_cond_broadcast")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4988 os::Solaris::set_cond_init(lwp_cond_init);
a61af66fc99e Initial load
duke
parents:
diff changeset
4989 os::Solaris::set_cond_destroy(lwp_cond_destroy);
a61af66fc99e Initial load
duke
parents:
diff changeset
4990 os::Solaris::set_cond_scope(USYNC_THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
4991 }
a61af66fc99e Initial load
duke
parents:
diff changeset
4992 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
4993 os::Solaris::set_mutex_scope(USYNC_THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
4994 os::Solaris::set_cond_scope(USYNC_THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
4995
a61af66fc99e Initial load
duke
parents:
diff changeset
4996 if(UsePthreads) {
a61af66fc99e Initial load
duke
parents:
diff changeset
4997 os::Solaris::set_mutex_lock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_lock")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4998 os::Solaris::set_mutex_trylock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_trylock")));
a61af66fc99e Initial load
duke
parents:
diff changeset
4999 os::Solaris::set_mutex_unlock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_unlock")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5000 os::Solaris::set_mutex_init(pthread_mutex_default_init);
a61af66fc99e Initial load
duke
parents:
diff changeset
5001 os::Solaris::set_mutex_destroy(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("pthread_mutex_destroy")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5002
a61af66fc99e Initial load
duke
parents:
diff changeset
5003 os::Solaris::set_cond_timedwait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP_timestruc_tP, resolve_symbol("pthread_cond_timedwait")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5004 os::Solaris::set_cond_wait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP, resolve_symbol("pthread_cond_wait")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5005 os::Solaris::set_cond_signal(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("pthread_cond_signal")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5006 os::Solaris::set_cond_broadcast(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("pthread_cond_broadcast")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5007 os::Solaris::set_cond_init(pthread_cond_default_init);
a61af66fc99e Initial load
duke
parents:
diff changeset
5008 os::Solaris::set_cond_destroy(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("pthread_cond_destroy")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5009 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5010 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5011 os::Solaris::set_mutex_lock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("mutex_lock")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5012 os::Solaris::set_mutex_trylock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("mutex_trylock")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5013 os::Solaris::set_mutex_unlock(CAST_TO_FN_PTR(int_fnP_mutex_tP, resolve_symbol("mutex_unlock")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5014 os::Solaris::set_mutex_init(::mutex_init);
a61af66fc99e Initial load
duke
parents:
diff changeset
5015 os::Solaris::set_mutex_destroy(::mutex_destroy);
a61af66fc99e Initial load
duke
parents:
diff changeset
5016
a61af66fc99e Initial load
duke
parents:
diff changeset
5017 os::Solaris::set_cond_timedwait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP_timestruc_tP, resolve_symbol("cond_timedwait")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5018 os::Solaris::set_cond_wait(CAST_TO_FN_PTR(int_fnP_cond_tP_mutex_tP, resolve_symbol("cond_wait")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5019 os::Solaris::set_cond_signal(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("cond_signal")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5020 os::Solaris::set_cond_broadcast(CAST_TO_FN_PTR(int_fnP_cond_tP, resolve_symbol("cond_broadcast")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5021 os::Solaris::set_cond_init(::cond_init);
a61af66fc99e Initial load
duke
parents:
diff changeset
5022 os::Solaris::set_cond_destroy(::cond_destroy);
a61af66fc99e Initial load
duke
parents:
diff changeset
5023 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5024 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5025 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5026
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5027 bool os::Solaris::liblgrp_init() {
267
9d6a3a6891f8 6720130: NUMA allocator: The linux version should search for libnuma.so.1
iveresov
parents: 144
diff changeset
5028 void *handle = dlopen("liblgrp.so.1", RTLD_LAZY);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5029 if (handle != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5030 os::Solaris::set_lgrp_home(CAST_TO_FN_PTR(lgrp_home_func_t, dlsym(handle, "lgrp_home")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5031 os::Solaris::set_lgrp_init(CAST_TO_FN_PTR(lgrp_init_func_t, dlsym(handle, "lgrp_init")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5032 os::Solaris::set_lgrp_fini(CAST_TO_FN_PTR(lgrp_fini_func_t, dlsym(handle, "lgrp_fini")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5033 os::Solaris::set_lgrp_root(CAST_TO_FN_PTR(lgrp_root_func_t, dlsym(handle, "lgrp_root")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5034 os::Solaris::set_lgrp_children(CAST_TO_FN_PTR(lgrp_children_func_t, dlsym(handle, "lgrp_children")));
144
e3729351c946 6697534: Premature GC and invalid lgrp selection with NUMA-aware allocator.
iveresov
parents: 141
diff changeset
5035 os::Solaris::set_lgrp_resources(CAST_TO_FN_PTR(lgrp_resources_func_t, dlsym(handle, "lgrp_resources")));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5036 os::Solaris::set_lgrp_nlgrps(CAST_TO_FN_PTR(lgrp_nlgrps_func_t, dlsym(handle, "lgrp_nlgrps")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5037 os::Solaris::set_lgrp_cookie_stale(CAST_TO_FN_PTR(lgrp_cookie_stale_func_t,
a61af66fc99e Initial load
duke
parents:
diff changeset
5038 dlsym(handle, "lgrp_cookie_stale")));
a61af66fc99e Initial load
duke
parents:
diff changeset
5039
a61af66fc99e Initial load
duke
parents:
diff changeset
5040 lgrp_cookie_t c = lgrp_init(LGRP_VIEW_CALLER);
a61af66fc99e Initial load
duke
parents:
diff changeset
5041 set_lgrp_cookie(c);
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5042 return true;
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5043 }
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5044 return false;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5045 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5046
a61af66fc99e Initial load
duke
parents:
diff changeset
5047 void os::Solaris::misc_sym_init() {
641
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
5048 address func;
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
5049
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
5050 // getisax
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
5051 func = resolve_symbol_lazy("getisax");
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
5052 if (func != NULL) {
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
5053 os::Solaris::_getisax = CAST_TO_FN_PTR(getisax_func_t, func);
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
5054 }
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
5055
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
5056 // meminfo
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
5057 func = resolve_symbol_lazy("meminfo");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5058 if (func != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5059 os::Solaris::set_meminfo(CAST_TO_FN_PTR(meminfo_func_t, func));
a61af66fc99e Initial load
duke
parents:
diff changeset
5060 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5061 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5062
641
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
5063 uint_t os::Solaris::getisax(uint32_t* array, uint_t n) {
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
5064 assert(_getisax != NULL, "_getisax not set");
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
5065 return _getisax(array, n);
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
5066 }
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
5067
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5068 // int pset_getloadavg(psetid_t pset, double loadavg[], int nelem);
a61af66fc99e Initial load
duke
parents:
diff changeset
5069 typedef long (*pset_getloadavg_type)(psetid_t pset, double loadavg[], int nelem);
a61af66fc99e Initial load
duke
parents:
diff changeset
5070 static pset_getloadavg_type pset_getloadavg_ptr = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5071
a61af66fc99e Initial load
duke
parents:
diff changeset
5072 void init_pset_getloadavg_ptr(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5073 pset_getloadavg_ptr =
a61af66fc99e Initial load
duke
parents:
diff changeset
5074 (pset_getloadavg_type)dlsym(RTLD_DEFAULT, "pset_getloadavg");
a61af66fc99e Initial load
duke
parents:
diff changeset
5075 if (PrintMiscellaneous && Verbose && pset_getloadavg_ptr == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5076 warning("pset_getloadavg function not found");
a61af66fc99e Initial load
duke
parents:
diff changeset
5077 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5078 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5079
a61af66fc99e Initial load
duke
parents:
diff changeset
5080 int os::Solaris::_dev_zero_fd = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
5081
a61af66fc99e Initial load
duke
parents:
diff changeset
5082 // this is called _before_ the global arguments have been parsed
a61af66fc99e Initial load
duke
parents:
diff changeset
5083 void os::init(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5084 _initial_pid = getpid();
a61af66fc99e Initial load
duke
parents:
diff changeset
5085
a61af66fc99e Initial load
duke
parents:
diff changeset
5086 max_hrtime = first_hrtime = gethrtime();
a61af66fc99e Initial load
duke
parents:
diff changeset
5087
a61af66fc99e Initial load
duke
parents:
diff changeset
5088 init_random(1234567);
a61af66fc99e Initial load
duke
parents:
diff changeset
5089
a61af66fc99e Initial load
duke
parents:
diff changeset
5090 page_size = sysconf(_SC_PAGESIZE);
a61af66fc99e Initial load
duke
parents:
diff changeset
5091 if (page_size == -1)
1490
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
5092 fatal(err_msg("os_solaris.cpp: os::init: sysconf failed (%s)",
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
5093 strerror(errno)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5094 init_page_sizes((size_t) page_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
5095
a61af66fc99e Initial load
duke
parents:
diff changeset
5096 Solaris::initialize_system_info();
a61af66fc99e Initial load
duke
parents:
diff changeset
5097
641
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
5098 // Initialize misc. symbols as soon as possible, so we can use them
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
5099 // if we need them.
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
5100 Solaris::misc_sym_init();
6af0a709d52b 6812587: Use auxv to determine SPARC hardware features on Solaris
twisti
parents: 548
diff changeset
5101
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5102 int fd = ::open("/dev/zero", O_RDWR);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5103 if (fd < 0) {
1490
f03d0a26bf83 6888954: argument formatting for assert() and friends
jcoomes
parents: 1353
diff changeset
5104 fatal(err_msg("os::init: cannot open /dev/zero (%s)", strerror(errno)));
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5105 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5106 Solaris::set_dev_zero_fd(fd);
a61af66fc99e Initial load
duke
parents:
diff changeset
5107
a61af66fc99e Initial load
duke
parents:
diff changeset
5108 // Close on exec, child won't inherit.
a61af66fc99e Initial load
duke
parents:
diff changeset
5109 fcntl(fd, F_SETFD, FD_CLOEXEC);
a61af66fc99e Initial load
duke
parents:
diff changeset
5110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5111
a61af66fc99e Initial load
duke
parents:
diff changeset
5112 clock_tics_per_sec = CLK_TCK;
a61af66fc99e Initial load
duke
parents:
diff changeset
5113
a61af66fc99e Initial load
duke
parents:
diff changeset
5114 // check if dladdr1() exists; dladdr1 can provide more information than
a61af66fc99e Initial load
duke
parents:
diff changeset
5115 // dladdr for os::dll_address_to_function_name. It comes with SunOS 5.9
a61af66fc99e Initial load
duke
parents:
diff changeset
5116 // and is available on linker patches for 5.7 and 5.8.
a61af66fc99e Initial load
duke
parents:
diff changeset
5117 // libdl.so must have been loaded, this call is just an entry lookup
a61af66fc99e Initial load
duke
parents:
diff changeset
5118 void * hdl = dlopen("libdl.so", RTLD_NOW);
a61af66fc99e Initial load
duke
parents:
diff changeset
5119 if (hdl)
a61af66fc99e Initial load
duke
parents:
diff changeset
5120 dladdr1_func = CAST_TO_FN_PTR(dladdr1_func_type, dlsym(hdl, "dladdr1"));
a61af66fc99e Initial load
duke
parents:
diff changeset
5121
a61af66fc99e Initial load
duke
parents:
diff changeset
5122 // (Solaris only) this switches to calls that actually do locking.
a61af66fc99e Initial load
duke
parents:
diff changeset
5123 ThreadCritical::initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
5124
a61af66fc99e Initial load
duke
parents:
diff changeset
5125 main_thread = thr_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
5126
a61af66fc99e Initial load
duke
parents:
diff changeset
5127 // Constant minimum stack size allowed. It must be at least
a61af66fc99e Initial load
duke
parents:
diff changeset
5128 // the minimum of what the OS supports (thr_min_stack()), and
a61af66fc99e Initial load
duke
parents:
diff changeset
5129 // enough to allow the thread to get to user bytecode execution.
a61af66fc99e Initial load
duke
parents:
diff changeset
5130 Solaris::min_stack_allowed = MAX2(thr_min_stack(), Solaris::min_stack_allowed);
a61af66fc99e Initial load
duke
parents:
diff changeset
5131 // If the pagesize of the VM is greater than 8K determine the appropriate
a61af66fc99e Initial load
duke
parents:
diff changeset
5132 // number of initial guard pages. The user can change this with the
a61af66fc99e Initial load
duke
parents:
diff changeset
5133 // command line arguments, if needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
5134 if (vm_page_size() > 8*K) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5135 StackYellowPages = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
5136 StackRedPages = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
5137 StackShadowPages = round_to((StackShadowPages*8*K), vm_page_size()) / vm_page_size();
a61af66fc99e Initial load
duke
parents:
diff changeset
5138 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5139 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5140
a61af66fc99e Initial load
duke
parents:
diff changeset
5141 // To install functions for atexit system call
a61af66fc99e Initial load
duke
parents:
diff changeset
5142 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
5143 static void perfMemory_exit_helper() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5144 perfMemory_exit();
a61af66fc99e Initial load
duke
parents:
diff changeset
5145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5146 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5147
a61af66fc99e Initial load
duke
parents:
diff changeset
5148 // this is called _after_ the global arguments have been parsed
a61af66fc99e Initial load
duke
parents:
diff changeset
5149 jint os::init_2(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5150 // try to enable extended file IO ASAP, see 6431278
a61af66fc99e Initial load
duke
parents:
diff changeset
5151 os::Solaris::try_enable_extended_io();
a61af66fc99e Initial load
duke
parents:
diff changeset
5152
a61af66fc99e Initial load
duke
parents:
diff changeset
5153 // Allocate a single page and mark it as readable for safepoint polling. Also
a61af66fc99e Initial load
duke
parents:
diff changeset
5154 // use this first mmap call to check support for MAP_ALIGN.
a61af66fc99e Initial load
duke
parents:
diff changeset
5155 address polling_page = (address)Solaris::mmap_chunk((char*)page_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
5156 page_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
5157 MAP_PRIVATE | MAP_ALIGN,
a61af66fc99e Initial load
duke
parents:
diff changeset
5158 PROT_READ);
a61af66fc99e Initial load
duke
parents:
diff changeset
5159 if (polling_page == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5160 has_map_align = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5161 polling_page = (address)Solaris::mmap_chunk(NULL, page_size, MAP_PRIVATE,
a61af66fc99e Initial load
duke
parents:
diff changeset
5162 PROT_READ);
a61af66fc99e Initial load
duke
parents:
diff changeset
5163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5164
a61af66fc99e Initial load
duke
parents:
diff changeset
5165 os::set_polling_page(polling_page);
a61af66fc99e Initial load
duke
parents:
diff changeset
5166
a61af66fc99e Initial load
duke
parents:
diff changeset
5167 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
5168 if( Verbose && PrintMiscellaneous )
a61af66fc99e Initial load
duke
parents:
diff changeset
5169 tty->print("[SafePoint Polling address: " INTPTR_FORMAT "]\n", (intptr_t)polling_page);
a61af66fc99e Initial load
duke
parents:
diff changeset
5170 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
5171
a61af66fc99e Initial load
duke
parents:
diff changeset
5172 if (!UseMembar) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5173 address mem_serialize_page = (address)Solaris::mmap_chunk( NULL, page_size, MAP_PRIVATE, PROT_READ | PROT_WRITE );
a61af66fc99e Initial load
duke
parents:
diff changeset
5174 guarantee( mem_serialize_page != NULL, "mmap Failed for memory serialize page");
a61af66fc99e Initial load
duke
parents:
diff changeset
5175 os::set_memory_serialize_page( mem_serialize_page );
a61af66fc99e Initial load
duke
parents:
diff changeset
5176
a61af66fc99e Initial load
duke
parents:
diff changeset
5177 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
5178 if(Verbose && PrintMiscellaneous)
a61af66fc99e Initial load
duke
parents:
diff changeset
5179 tty->print("[Memory Serialize Page address: " INTPTR_FORMAT "]\n", (intptr_t)mem_serialize_page);
a61af66fc99e Initial load
duke
parents:
diff changeset
5180 #endif
12233
40136aa2cdb1 8010722: assert: failed: heap size is too big for compressed oops
tschatzl
parents: 12110
diff changeset
5181 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5182
a61af66fc99e Initial load
duke
parents:
diff changeset
5183 // Check minimum allowable stack size for thread creation and to initialize
a61af66fc99e Initial load
duke
parents:
diff changeset
5184 // the java system classes, including StackOverflowError - depends on page
a61af66fc99e Initial load
duke
parents:
diff changeset
5185 // size. Add a page for compiler2 recursion in main thread.
1867
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
5186 // Add in 2*BytesPerWord times page size to account for VM stack during
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5187 // class initialization depending on 32 or 64 bit VM.
1867
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
5188 os::Solaris::min_stack_allowed = MAX2(os::Solaris::min_stack_allowed,
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
5189 (size_t)(StackYellowPages+StackRedPages+StackShadowPages+
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
5190 2*BytesPerWord COMPILER2_PRESENT(+1)) * page_size);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5191
a61af66fc99e Initial load
duke
parents:
diff changeset
5192 size_t threadStackSizeInBytes = ThreadStackSize * K;
a61af66fc99e Initial load
duke
parents:
diff changeset
5193 if (threadStackSizeInBytes != 0 &&
1867
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
5194 threadStackSizeInBytes < os::Solaris::min_stack_allowed) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5195 tty->print_cr("\nThe stack size specified is too small, Specify at least %dk",
1867
b6aedd1acdc0 6983240: guarantee((Solaris::min_stack_allowed >= (StackYellowPages+StackRedPages...) wrong
coleenp
parents: 1865
diff changeset
5196 os::Solaris::min_stack_allowed/K);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5197 return JNI_ERR;
a61af66fc99e Initial load
duke
parents:
diff changeset
5198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5199
a61af66fc99e Initial load
duke
parents:
diff changeset
5200 // For 64kbps there will be a 64kb page size, which makes
a61af66fc99e Initial load
duke
parents:
diff changeset
5201 // the usable default stack size quite a bit less. Increase the
a61af66fc99e Initial load
duke
parents:
diff changeset
5202 // stack for 64kb (or any > than 8kb) pages, this increases
a61af66fc99e Initial load
duke
parents:
diff changeset
5203 // virtual memory fragmentation (since we're not creating the
a61af66fc99e Initial load
duke
parents:
diff changeset
5204 // stack on a power of 2 boundary. The real fix for this
a61af66fc99e Initial load
duke
parents:
diff changeset
5205 // should be to fix the guard page mechanism.
a61af66fc99e Initial load
duke
parents:
diff changeset
5206
a61af66fc99e Initial load
duke
parents:
diff changeset
5207 if (vm_page_size() > 8*K) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5208 threadStackSizeInBytes = (threadStackSizeInBytes != 0)
a61af66fc99e Initial load
duke
parents:
diff changeset
5209 ? threadStackSizeInBytes +
a61af66fc99e Initial load
duke
parents:
diff changeset
5210 ((StackYellowPages + StackRedPages) * vm_page_size())
a61af66fc99e Initial load
duke
parents:
diff changeset
5211 : 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5212 ThreadStackSize = threadStackSizeInBytes/K;
a61af66fc99e Initial load
duke
parents:
diff changeset
5213 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5214
a61af66fc99e Initial load
duke
parents:
diff changeset
5215 // Make the stack size a multiple of the page size so that
a61af66fc99e Initial load
duke
parents:
diff changeset
5216 // the yellow/red zones can be guarded.
a61af66fc99e Initial load
duke
parents:
diff changeset
5217 JavaThread::set_stack_size_at_create(round_to(threadStackSizeInBytes,
a61af66fc99e Initial load
duke
parents:
diff changeset
5218 vm_page_size()));
a61af66fc99e Initial load
duke
parents:
diff changeset
5219
a61af66fc99e Initial load
duke
parents:
diff changeset
5220 Solaris::libthread_init();
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5221
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5222 if (UseNUMA) {
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5223 if (!Solaris::liblgrp_init()) {
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5224 UseNUMA = false;
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5225 } else {
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5226 size_t lgrp_limit = os::numa_get_groups_num();
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
5227 int *lgrp_ids = NEW_C_HEAP_ARRAY(int, lgrp_limit, mtInternal);
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5228 size_t lgrp_num = os::numa_get_leaf_groups(lgrp_ids, lgrp_limit);
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
5229 FREE_C_HEAP_ARRAY(int, lgrp_ids, mtInternal);
462
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5230 if (lgrp_num < 2) {
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5231 // There's only one locality group, disable NUMA.
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5232 UseNUMA = false;
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5233 }
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5234 }
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5235 if (!UseNUMA && ForceNUMA) {
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5236 UseNUMA = true;
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5237 }
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5238 }
85f1b9537f70 6779436: NUMA allocator: libnuma expects certain size of the buffer in numa_node_to_cpus()
iveresov
parents: 439
diff changeset
5239
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5240 Solaris::signal_sets_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
5241 Solaris::init_signal_mem();
a61af66fc99e Initial load
duke
parents:
diff changeset
5242 Solaris::install_signal_handlers();
a61af66fc99e Initial load
duke
parents:
diff changeset
5243
a61af66fc99e Initial load
duke
parents:
diff changeset
5244 if (libjsigversion < JSIG_VERSION_1_4_1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5245 Maxlibjsigsigs = OLDMAXSIGNUM;
a61af66fc99e Initial load
duke
parents:
diff changeset
5246 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5247
a61af66fc99e Initial load
duke
parents:
diff changeset
5248 // initialize synchronization primitives to use either thread or
a61af66fc99e Initial load
duke
parents:
diff changeset
5249 // lwp synchronization (controlled by UseLWPSynchronization)
a61af66fc99e Initial load
duke
parents:
diff changeset
5250 Solaris::synchronization_init();
a61af66fc99e Initial load
duke
parents:
diff changeset
5251
a61af66fc99e Initial load
duke
parents:
diff changeset
5252 if (MaxFDLimit) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5253 // set the number of file descriptors to max. print out error
a61af66fc99e Initial load
duke
parents:
diff changeset
5254 // if getrlimit/setrlimit fails but continue regardless.
a61af66fc99e Initial load
duke
parents:
diff changeset
5255 struct rlimit nbr_files;
a61af66fc99e Initial load
duke
parents:
diff changeset
5256 int status = getrlimit(RLIMIT_NOFILE, &nbr_files);
a61af66fc99e Initial load
duke
parents:
diff changeset
5257 if (status != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5258 if (PrintMiscellaneous && (Verbose || WizardMode))
a61af66fc99e Initial load
duke
parents:
diff changeset
5259 perror("os::init_2 getrlimit failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
5260 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5261 nbr_files.rlim_cur = nbr_files.rlim_max;
a61af66fc99e Initial load
duke
parents:
diff changeset
5262 status = setrlimit(RLIMIT_NOFILE, &nbr_files);
a61af66fc99e Initial load
duke
parents:
diff changeset
5263 if (status != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5264 if (PrintMiscellaneous && (Verbose || WizardMode))
a61af66fc99e Initial load
duke
parents:
diff changeset
5265 perror("os::init_2 setrlimit failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
5266 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5267 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5268 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5269
a61af66fc99e Initial load
duke
parents:
diff changeset
5270 // Calculate theoretical max. size of Threads to guard gainst
a61af66fc99e Initial load
duke
parents:
diff changeset
5271 // artifical out-of-memory situations, where all available address-
a61af66fc99e Initial load
duke
parents:
diff changeset
5272 // space has been reserved by thread stacks. Default stack size is 1Mb.
a61af66fc99e Initial load
duke
parents:
diff changeset
5273 size_t pre_thread_stack_size = (JavaThread::stack_size_at_create()) ?
a61af66fc99e Initial load
duke
parents:
diff changeset
5274 JavaThread::stack_size_at_create() : (1*K*K);
a61af66fc99e Initial load
duke
parents:
diff changeset
5275 assert(pre_thread_stack_size != 0, "Must have a stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
5276 // Solaris has a maximum of 4Gb of user programs. Calculate the thread limit when
a61af66fc99e Initial load
duke
parents:
diff changeset
5277 // we should start doing Virtual Memory banging. Currently when the threads will
a61af66fc99e Initial load
duke
parents:
diff changeset
5278 // have used all but 200Mb of space.
a61af66fc99e Initial load
duke
parents:
diff changeset
5279 size_t max_address_space = ((unsigned int)4 * K * K * K) - (200 * K * K);
a61af66fc99e Initial load
duke
parents:
diff changeset
5280 Solaris::_os_thread_limit = max_address_space / pre_thread_stack_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
5281
a61af66fc99e Initial load
duke
parents:
diff changeset
5282 // at-exit methods are called in the reverse order of their registration.
a61af66fc99e Initial load
duke
parents:
diff changeset
5283 // In Solaris 7 and earlier, atexit functions are called on return from
a61af66fc99e Initial load
duke
parents:
diff changeset
5284 // main or as a result of a call to exit(3C). There can be only 32 of
a61af66fc99e Initial load
duke
parents:
diff changeset
5285 // these functions registered and atexit() does not set errno. In Solaris
a61af66fc99e Initial load
duke
parents:
diff changeset
5286 // 8 and later, there is no limit to the number of functions registered
a61af66fc99e Initial load
duke
parents:
diff changeset
5287 // and atexit() sets errno. In addition, in Solaris 8 and later, atexit
a61af66fc99e Initial load
duke
parents:
diff changeset
5288 // functions are called upon dlclose(3DL) in addition to return from main
a61af66fc99e Initial load
duke
parents:
diff changeset
5289 // and exit(3C).
a61af66fc99e Initial load
duke
parents:
diff changeset
5290
a61af66fc99e Initial load
duke
parents:
diff changeset
5291 if (PerfAllowAtExitRegistration) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5292 // only register atexit functions if PerfAllowAtExitRegistration is set.
a61af66fc99e Initial load
duke
parents:
diff changeset
5293 // atexit functions can be delayed until process exit time, which
a61af66fc99e Initial load
duke
parents:
diff changeset
5294 // can be problematic for embedded VM situations. Embedded VMs should
a61af66fc99e Initial load
duke
parents:
diff changeset
5295 // call DestroyJavaVM() to assure that VM resources are released.
a61af66fc99e Initial load
duke
parents:
diff changeset
5296
a61af66fc99e Initial load
duke
parents:
diff changeset
5297 // note: perfMemory_exit_helper atexit function may be removed in
a61af66fc99e Initial load
duke
parents:
diff changeset
5298 // the future if the appropriate cleanup code can be added to the
a61af66fc99e Initial load
duke
parents:
diff changeset
5299 // VM_Exit VMOperation's doit method.
a61af66fc99e Initial load
duke
parents:
diff changeset
5300 if (atexit(perfMemory_exit_helper) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5301 warning("os::init2 atexit(perfMemory_exit_helper) failed");
a61af66fc99e Initial load
duke
parents:
diff changeset
5302 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5303 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5304
a61af66fc99e Initial load
duke
parents:
diff changeset
5305 // Init pset_loadavg function pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
5306 init_pset_getloadavg_ptr();
a61af66fc99e Initial load
duke
parents:
diff changeset
5307
a61af66fc99e Initial load
duke
parents:
diff changeset
5308 return JNI_OK;
a61af66fc99e Initial load
duke
parents:
diff changeset
5309 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5310
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5311 void os::init_3(void) {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5312 return;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5313 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5314
a61af66fc99e Initial load
duke
parents:
diff changeset
5315 // Mark the polling page as unreadable
a61af66fc99e Initial load
duke
parents:
diff changeset
5316 void os::make_polling_page_unreadable(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5317 if( mprotect((char *)_polling_page, page_size, PROT_NONE) != 0 )
a61af66fc99e Initial load
duke
parents:
diff changeset
5318 fatal("Could not disable polling page");
a61af66fc99e Initial load
duke
parents:
diff changeset
5319 };
a61af66fc99e Initial load
duke
parents:
diff changeset
5320
a61af66fc99e Initial load
duke
parents:
diff changeset
5321 // Mark the polling page as readable
a61af66fc99e Initial load
duke
parents:
diff changeset
5322 void os::make_polling_page_readable(void) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5323 if( mprotect((char *)_polling_page, page_size, PROT_READ) != 0 )
a61af66fc99e Initial load
duke
parents:
diff changeset
5324 fatal("Could not enable polling page");
a61af66fc99e Initial load
duke
parents:
diff changeset
5325 };
a61af66fc99e Initial load
duke
parents:
diff changeset
5326
a61af66fc99e Initial load
duke
parents:
diff changeset
5327 // OS interface.
a61af66fc99e Initial load
duke
parents:
diff changeset
5328
a61af66fc99e Initial load
duke
parents:
diff changeset
5329 bool os::check_heap(bool force) { return true; }
a61af66fc99e Initial load
duke
parents:
diff changeset
5330
a61af66fc99e Initial load
duke
parents:
diff changeset
5331 typedef int (*vsnprintf_t)(char* buf, size_t count, const char* fmt, va_list argptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
5332 static vsnprintf_t sol_vsnprintf = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5333
a61af66fc99e Initial load
duke
parents:
diff changeset
5334 int local_vsnprintf(char* buf, size_t count, const char* fmt, va_list argptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5335 if (!sol_vsnprintf) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5336 //search for the named symbol in the objects that were loaded after libjvm
a61af66fc99e Initial load
duke
parents:
diff changeset
5337 void* where = RTLD_NEXT;
a61af66fc99e Initial load
duke
parents:
diff changeset
5338 if ((sol_vsnprintf = CAST_TO_FN_PTR(vsnprintf_t, dlsym(where, "__vsnprintf"))) == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
5339 sol_vsnprintf = CAST_TO_FN_PTR(vsnprintf_t, dlsym(where, "vsnprintf"));
a61af66fc99e Initial load
duke
parents:
diff changeset
5340 if (!sol_vsnprintf){
a61af66fc99e Initial load
duke
parents:
diff changeset
5341 //search for the named symbol in the objects that were loaded before libjvm
a61af66fc99e Initial load
duke
parents:
diff changeset
5342 where = RTLD_DEFAULT;
a61af66fc99e Initial load
duke
parents:
diff changeset
5343 if ((sol_vsnprintf = CAST_TO_FN_PTR(vsnprintf_t, dlsym(where, "__vsnprintf"))) == NULL)
a61af66fc99e Initial load
duke
parents:
diff changeset
5344 sol_vsnprintf = CAST_TO_FN_PTR(vsnprintf_t, dlsym(where, "vsnprintf"));
a61af66fc99e Initial load
duke
parents:
diff changeset
5345 assert(sol_vsnprintf != NULL, "vsnprintf not found");
a61af66fc99e Initial load
duke
parents:
diff changeset
5346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5348 return (*sol_vsnprintf)(buf, count, fmt, argptr);
a61af66fc99e Initial load
duke
parents:
diff changeset
5349 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5350
a61af66fc99e Initial load
duke
parents:
diff changeset
5351
a61af66fc99e Initial load
duke
parents:
diff changeset
5352 // Is a (classpath) directory empty?
a61af66fc99e Initial load
duke
parents:
diff changeset
5353 bool os::dir_is_empty(const char* path) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5354 DIR *dir = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5355 struct dirent *ptr;
a61af66fc99e Initial load
duke
parents:
diff changeset
5356
a61af66fc99e Initial load
duke
parents:
diff changeset
5357 dir = opendir(path);
a61af66fc99e Initial load
duke
parents:
diff changeset
5358 if (dir == NULL) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
5359
a61af66fc99e Initial load
duke
parents:
diff changeset
5360 /* Scan the directory */
a61af66fc99e Initial load
duke
parents:
diff changeset
5361 bool result = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
5362 char buf[sizeof(struct dirent) + MAX_PATH];
a61af66fc99e Initial load
duke
parents:
diff changeset
5363 struct dirent *dbuf = (struct dirent *) buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
5364 while (result && (ptr = readdir(dir, dbuf)) != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5365 if (strcmp(ptr->d_name, ".") != 0 && strcmp(ptr->d_name, "..") != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5366 result = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5367 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5369 closedir(dir);
a61af66fc99e Initial load
duke
parents:
diff changeset
5370 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
5371 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5372
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5373 // This code originates from JDK's sysOpen and open64_w
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5374 // from src/solaris/hpi/src/system_md.c
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5375
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5376 #ifndef O_DELETE
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5377 #define O_DELETE 0x10000
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5378 #endif
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5379
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5380 // Open a file. Unlink the file immediately after open returns
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5381 // if the specified oflag has the O_DELETE flag set.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5382 // O_DELETE is used only in j2se/src/share/native/java/util/zip/ZipFile.c
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5383
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5384 int os::open(const char *path, int oflag, int mode) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5385 if (strlen(path) > MAX_PATH - 1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5386 errno = ENAMETOOLONG;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5387 return -1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5388 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5389 int fd;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5390 int o_delete = (oflag & O_DELETE);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5391 oflag = oflag & ~O_DELETE;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5392
2097
039eb4201e06 7009975: Large file support broken in hs20-b04
alanb
parents: 2068
diff changeset
5393 fd = ::open64(path, oflag, mode);
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5394 if (fd == -1) return -1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5395
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5396 //If the open succeeded, the file might still be a directory
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5397 {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5398 struct stat64 buf64;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5399 int ret = ::fstat64(fd, &buf64);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5400 int st_mode = buf64.st_mode;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5401
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5402 if (ret != -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5403 if ((st_mode & S_IFMT) == S_IFDIR) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5404 errno = EISDIR;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5405 ::close(fd);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5406 return -1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5407 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5408 } else {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5409 ::close(fd);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5410 return -1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5411 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5412 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5413 /*
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5414 * 32-bit Solaris systems suffer from:
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5415 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5416 * - an historical default soft limit of 256 per-process file
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5417 * descriptors that is too low for many Java programs.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5418 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5419 * - a design flaw where file descriptors created using stdio
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5420 * fopen must be less than 256, _even_ when the first limit above
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5421 * has been raised. This can cause calls to fopen (but not calls to
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5422 * open, for example) to fail mysteriously, perhaps in 3rd party
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5423 * native code (although the JDK itself uses fopen). One can hardly
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5424 * criticize them for using this most standard of all functions.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5425 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5426 * We attempt to make everything work anyways by:
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5427 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5428 * - raising the soft limit on per-process file descriptors beyond
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5429 * 256
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5430 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5431 * - As of Solaris 10u4, we can request that Solaris raise the 256
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5432 * stdio fopen limit by calling function enable_extended_FILE_stdio.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5433 * This is done in init_2 and recorded in enabled_extended_FILE_stdio
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5434 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5435 * - If we are stuck on an old (pre 10u4) Solaris system, we can
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5436 * workaround the bug by remapping non-stdio file descriptors below
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5437 * 256 to ones beyond 256, which is done below.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5438 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5439 * See:
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5440 * 1085341: 32-bit stdio routines should support file descriptors >255
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5441 * 6533291: Work around 32-bit Solaris stdio limit of 256 open files
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5442 * 6431278: Netbeans crash on 32 bit Solaris: need to call
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5443 * enable_extended_FILE_stdio() in VM initialisation
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5444 * Giri Mandalika's blog
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5445 * http://technopark02.blogspot.com/2005_05_01_archive.html
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5446 */
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5447 #ifndef _LP64
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5448 if ((!enabled_extended_FILE_stdio) && fd < 256) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5449 int newfd = ::fcntl(fd, F_DUPFD, 256);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5450 if (newfd != -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5451 ::close(fd);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5452 fd = newfd;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5453 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5454 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5455 #endif // 32-bit Solaris
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5456 /*
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5457 * All file descriptors that are opened in the JVM and not
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5458 * specifically destined for a subprocess should have the
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5459 * close-on-exec flag set. If we don't set it, then careless 3rd
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5460 * party native code might fork and exec without closing all
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5461 * appropriate file descriptors (e.g. as we do in closeDescriptors in
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5462 * UNIXProcess.c), and this in turn might:
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5463 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5464 * - cause end-of-file to fail to be detected on some file
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5465 * descriptors, resulting in mysterious hangs, or
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5466 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5467 * - might cause an fopen in the subprocess to fail on a system
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5468 * suffering from bug 1085341.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5469 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5470 * (Yes, the default setting of the close-on-exec flag is a Unix
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5471 * design flaw)
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5472 *
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5473 * See:
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5474 * 1085341: 32-bit stdio routines should support file descriptors >255
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5475 * 4843136: (process) pipe file descriptor from Runtime.exec not being closed
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5476 * 6339493: (process) Runtime.exec does not close all file descriptors on Solaris 9
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5477 */
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5478 #ifdef FD_CLOEXEC
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5479 {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5480 int flags = ::fcntl(fd, F_GETFD);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5481 if (flags != -1)
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5482 ::fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5483 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5484 #endif
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5485
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5486 if (o_delete != 0) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5487 ::unlink(path);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5488 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5489 return fd;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5490 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5491
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5492 // create binary file, rewriting existing file if required
a61af66fc99e Initial load
duke
parents:
diff changeset
5493 int os::create_binary_file(const char* path, bool rewrite_existing) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5494 int oflags = O_WRONLY | O_CREAT;
a61af66fc99e Initial load
duke
parents:
diff changeset
5495 if (!rewrite_existing) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5496 oflags |= O_EXCL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5497 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5498 return ::open64(path, oflags, S_IREAD | S_IWRITE);
a61af66fc99e Initial load
duke
parents:
diff changeset
5499 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5500
a61af66fc99e Initial load
duke
parents:
diff changeset
5501 // return current position of file pointer
a61af66fc99e Initial load
duke
parents:
diff changeset
5502 jlong os::current_file_offset(int fd) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5503 return (jlong)::lseek64(fd, (off64_t)0, SEEK_CUR);
a61af66fc99e Initial load
duke
parents:
diff changeset
5504 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5505
a61af66fc99e Initial load
duke
parents:
diff changeset
5506 // move file pointer to the specified offset
a61af66fc99e Initial load
duke
parents:
diff changeset
5507 jlong os::seek_to_file_offset(int fd, jlong offset) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5508 return (jlong)::lseek64(fd, (off64_t)offset, SEEK_SET);
a61af66fc99e Initial load
duke
parents:
diff changeset
5509 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5510
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5511 jlong os::lseek(int fd, jlong offset, int whence) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5512 return (jlong) ::lseek64(fd, offset, whence);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5513 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5514
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5515 char * os::native_path(char *path) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5516 return path;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5517 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5518
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5519 int os::ftruncate(int fd, jlong length) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5520 return ::ftruncate64(fd, length);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5521 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5522
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5523 int os::fsync(int fd) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5524 RESTARTABLE_RETURN_INT(::fsync(fd));
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5525 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5526
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5527 int os::available(int fd, jlong *bytes) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5528 jlong cur, end;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5529 int mode;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5530 struct stat64 buf64;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5531
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5532 if (::fstat64(fd, &buf64) >= 0) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5533 mode = buf64.st_mode;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5534 if (S_ISCHR(mode) || S_ISFIFO(mode) || S_ISSOCK(mode)) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5535 /*
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5536 * XXX: is the following call interruptible? If so, this might
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5537 * need to go through the INTERRUPT_IO() wrapper as for other
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5538 * blocking, interruptible calls in this file.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5539 */
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5540 int n,ioctl_return;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5541
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5542 INTERRUPTIBLE(::ioctl(fd, FIONREAD, &n),ioctl_return,os::Solaris::clear_interrupted);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5543 if (ioctl_return>= 0) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5544 *bytes = n;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5545 return 1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5546 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5547 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5548 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5549 if ((cur = ::lseek64(fd, 0L, SEEK_CUR)) == -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5550 return 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5551 } else if ((end = ::lseek64(fd, 0L, SEEK_END)) == -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5552 return 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5553 } else if (::lseek64(fd, cur, SEEK_SET) == -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5554 return 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5555 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5556 *bytes = end - cur;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5557 return 1;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5558 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5559
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5560 // Map a block of memory.
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
5561 char* os::pd_map_memory(int fd, const char* file_name, size_t file_offset,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5562 char *addr, size_t bytes, bool read_only,
a61af66fc99e Initial load
duke
parents:
diff changeset
5563 bool allow_exec) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5564 int prot;
a61af66fc99e Initial load
duke
parents:
diff changeset
5565 int flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
5566
a61af66fc99e Initial load
duke
parents:
diff changeset
5567 if (read_only) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5568 prot = PROT_READ;
a61af66fc99e Initial load
duke
parents:
diff changeset
5569 flags = MAP_SHARED;
a61af66fc99e Initial load
duke
parents:
diff changeset
5570 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5571 prot = PROT_READ | PROT_WRITE;
a61af66fc99e Initial load
duke
parents:
diff changeset
5572 flags = MAP_PRIVATE;
a61af66fc99e Initial load
duke
parents:
diff changeset
5573 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5574
a61af66fc99e Initial load
duke
parents:
diff changeset
5575 if (allow_exec) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5576 prot |= PROT_EXEC;
a61af66fc99e Initial load
duke
parents:
diff changeset
5577 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5578
a61af66fc99e Initial load
duke
parents:
diff changeset
5579 if (addr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5580 flags |= MAP_FIXED;
a61af66fc99e Initial load
duke
parents:
diff changeset
5581 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5582
a61af66fc99e Initial load
duke
parents:
diff changeset
5583 char* mapped_address = (char*)mmap(addr, (size_t)bytes, prot, flags,
a61af66fc99e Initial load
duke
parents:
diff changeset
5584 fd, file_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
5585 if (mapped_address == MAP_FAILED) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5586 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
5587 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5588 return mapped_address;
a61af66fc99e Initial load
duke
parents:
diff changeset
5589 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5590
a61af66fc99e Initial load
duke
parents:
diff changeset
5591
a61af66fc99e Initial load
duke
parents:
diff changeset
5592 // Remap a block of memory.
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
5593 char* os::pd_remap_memory(int fd, const char* file_name, size_t file_offset,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5594 char *addr, size_t bytes, bool read_only,
a61af66fc99e Initial load
duke
parents:
diff changeset
5595 bool allow_exec) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5596 // same as map_memory() on this OS
a61af66fc99e Initial load
duke
parents:
diff changeset
5597 return os::map_memory(fd, file_name, file_offset, addr, bytes, read_only,
a61af66fc99e Initial load
duke
parents:
diff changeset
5598 allow_exec);
a61af66fc99e Initial load
duke
parents:
diff changeset
5599 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5600
a61af66fc99e Initial load
duke
parents:
diff changeset
5601
a61af66fc99e Initial load
duke
parents:
diff changeset
5602 // Unmap a block of memory.
6197
d2a62e0f25eb 6995781: Native Memory Tracking (Phase 1)
zgu
parents: 6080
diff changeset
5603 bool os::pd_unmap_memory(char* addr, size_t bytes) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5604 return munmap(addr, bytes) == 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5605 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5606
a61af66fc99e Initial load
duke
parents:
diff changeset
5607 void os::pause() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5608 char filename[MAX_PATH];
a61af66fc99e Initial load
duke
parents:
diff changeset
5609 if (PauseAtStartupFile && PauseAtStartupFile[0]) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5610 jio_snprintf(filename, MAX_PATH, PauseAtStartupFile);
a61af66fc99e Initial load
duke
parents:
diff changeset
5611 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5612 jio_snprintf(filename, MAX_PATH, "./vm.paused.%d", current_process_id());
a61af66fc99e Initial load
duke
parents:
diff changeset
5613 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5614
a61af66fc99e Initial load
duke
parents:
diff changeset
5615 int fd = ::open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
a61af66fc99e Initial load
duke
parents:
diff changeset
5616 if (fd != -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5617 struct stat buf;
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5618 ::close(fd);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5619 while (::stat(filename, &buf) == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5620 (void)::poll(NULL, 0, 100);
a61af66fc99e Initial load
duke
parents:
diff changeset
5621 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5622 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5623 jio_fprintf(stderr,
a61af66fc99e Initial load
duke
parents:
diff changeset
5624 "Could not open pause file '%s', continuing immediately.\n", filename);
a61af66fc99e Initial load
duke
parents:
diff changeset
5625 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5627
a61af66fc99e Initial load
duke
parents:
diff changeset
5628 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
5629 #ifdef INTERPOSE_ON_SYSTEM_SYNCH_FUNCTIONS
a61af66fc99e Initial load
duke
parents:
diff changeset
5630 // Turn this on if you need to trace synch operations.
a61af66fc99e Initial load
duke
parents:
diff changeset
5631 // Set RECORD_SYNCH_LIMIT to a large-enough value,
a61af66fc99e Initial load
duke
parents:
diff changeset
5632 // and call record_synch_enable and record_synch_disable
a61af66fc99e Initial load
duke
parents:
diff changeset
5633 // around the computation of interest.
a61af66fc99e Initial load
duke
parents:
diff changeset
5634
a61af66fc99e Initial load
duke
parents:
diff changeset
5635 void record_synch(char* name, bool returning); // defined below
a61af66fc99e Initial load
duke
parents:
diff changeset
5636
a61af66fc99e Initial load
duke
parents:
diff changeset
5637 class RecordSynch {
a61af66fc99e Initial load
duke
parents:
diff changeset
5638 char* _name;
a61af66fc99e Initial load
duke
parents:
diff changeset
5639 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
5640 RecordSynch(char* name) :_name(name)
a61af66fc99e Initial load
duke
parents:
diff changeset
5641 { record_synch(_name, false); }
a61af66fc99e Initial load
duke
parents:
diff changeset
5642 ~RecordSynch() { record_synch(_name, true); }
a61af66fc99e Initial load
duke
parents:
diff changeset
5643 };
a61af66fc99e Initial load
duke
parents:
diff changeset
5644
a61af66fc99e Initial load
duke
parents:
diff changeset
5645 #define CHECK_SYNCH_OP(ret, name, params, args, inner) \
a61af66fc99e Initial load
duke
parents:
diff changeset
5646 extern "C" ret name params { \
a61af66fc99e Initial load
duke
parents:
diff changeset
5647 typedef ret name##_t params; \
a61af66fc99e Initial load
duke
parents:
diff changeset
5648 static name##_t* implem = NULL; \
a61af66fc99e Initial load
duke
parents:
diff changeset
5649 static int callcount = 0; \
a61af66fc99e Initial load
duke
parents:
diff changeset
5650 if (implem == NULL) { \
a61af66fc99e Initial load
duke
parents:
diff changeset
5651 implem = (name##_t*) dlsym(RTLD_NEXT, #name); \
a61af66fc99e Initial load
duke
parents:
diff changeset
5652 if (implem == NULL) fatal(dlerror()); \
a61af66fc99e Initial load
duke
parents:
diff changeset
5653 } \
a61af66fc99e Initial load
duke
parents:
diff changeset
5654 ++callcount; \
a61af66fc99e Initial load
duke
parents:
diff changeset
5655 RecordSynch _rs(#name); \
a61af66fc99e Initial load
duke
parents:
diff changeset
5656 inner; \
a61af66fc99e Initial load
duke
parents:
diff changeset
5657 return implem args; \
a61af66fc99e Initial load
duke
parents:
diff changeset
5658 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5659 // in dbx, examine callcounts this way:
a61af66fc99e Initial load
duke
parents:
diff changeset
5660 // for n in $(eval whereis callcount | awk '{print $2}'); do print $n; done
a61af66fc99e Initial load
duke
parents:
diff changeset
5661
a61af66fc99e Initial load
duke
parents:
diff changeset
5662 #define CHECK_POINTER_OK(p) \
6725
da91efe96a93 6964458: Reimplement class meta-data storage to use native memory
coleenp
parents: 6200
diff changeset
5663 (!Universe::is_fully_initialized() || !Universe::is_reserved_heap((oop)(p)))
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5664 #define CHECK_MU \
a61af66fc99e Initial load
duke
parents:
diff changeset
5665 if (!CHECK_POINTER_OK(mu)) fatal("Mutex must be in C heap only.");
a61af66fc99e Initial load
duke
parents:
diff changeset
5666 #define CHECK_CV \
a61af66fc99e Initial load
duke
parents:
diff changeset
5667 if (!CHECK_POINTER_OK(cv)) fatal("Condvar must be in C heap only.");
a61af66fc99e Initial load
duke
parents:
diff changeset
5668 #define CHECK_P(p) \
a61af66fc99e Initial load
duke
parents:
diff changeset
5669 if (!CHECK_POINTER_OK(p)) fatal(false, "Pointer must be in C heap only.");
a61af66fc99e Initial load
duke
parents:
diff changeset
5670
a61af66fc99e Initial load
duke
parents:
diff changeset
5671 #define CHECK_MUTEX(mutex_op) \
a61af66fc99e Initial load
duke
parents:
diff changeset
5672 CHECK_SYNCH_OP(int, mutex_op, (mutex_t *mu), (mu), CHECK_MU);
a61af66fc99e Initial load
duke
parents:
diff changeset
5673
a61af66fc99e Initial load
duke
parents:
diff changeset
5674 CHECK_MUTEX( mutex_lock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5675 CHECK_MUTEX( _mutex_lock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5676 CHECK_MUTEX( mutex_unlock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5677 CHECK_MUTEX(_mutex_unlock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5678 CHECK_MUTEX( mutex_trylock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5679 CHECK_MUTEX(_mutex_trylock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5680
a61af66fc99e Initial load
duke
parents:
diff changeset
5681 #define CHECK_COND(cond_op) \
a61af66fc99e Initial load
duke
parents:
diff changeset
5682 CHECK_SYNCH_OP(int, cond_op, (cond_t *cv, mutex_t *mu), (cv, mu), CHECK_MU;CHECK_CV);
a61af66fc99e Initial load
duke
parents:
diff changeset
5683
a61af66fc99e Initial load
duke
parents:
diff changeset
5684 CHECK_COND( cond_wait);
a61af66fc99e Initial load
duke
parents:
diff changeset
5685 CHECK_COND(_cond_wait);
a61af66fc99e Initial load
duke
parents:
diff changeset
5686 CHECK_COND(_cond_wait_cancel);
a61af66fc99e Initial load
duke
parents:
diff changeset
5687
a61af66fc99e Initial load
duke
parents:
diff changeset
5688 #define CHECK_COND2(cond_op) \
a61af66fc99e Initial load
duke
parents:
diff changeset
5689 CHECK_SYNCH_OP(int, cond_op, (cond_t *cv, mutex_t *mu, timestruc_t* ts), (cv, mu, ts), CHECK_MU;CHECK_CV);
a61af66fc99e Initial load
duke
parents:
diff changeset
5690
a61af66fc99e Initial load
duke
parents:
diff changeset
5691 CHECK_COND2( cond_timedwait);
a61af66fc99e Initial load
duke
parents:
diff changeset
5692 CHECK_COND2(_cond_timedwait);
a61af66fc99e Initial load
duke
parents:
diff changeset
5693 CHECK_COND2(_cond_timedwait_cancel);
a61af66fc99e Initial load
duke
parents:
diff changeset
5694
a61af66fc99e Initial load
duke
parents:
diff changeset
5695 // do the _lwp_* versions too
a61af66fc99e Initial load
duke
parents:
diff changeset
5696 #define mutex_t lwp_mutex_t
a61af66fc99e Initial load
duke
parents:
diff changeset
5697 #define cond_t lwp_cond_t
a61af66fc99e Initial load
duke
parents:
diff changeset
5698 CHECK_MUTEX( _lwp_mutex_lock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5699 CHECK_MUTEX( _lwp_mutex_unlock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5700 CHECK_MUTEX( _lwp_mutex_trylock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5701 CHECK_MUTEX( __lwp_mutex_lock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5702 CHECK_MUTEX( __lwp_mutex_unlock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5703 CHECK_MUTEX( __lwp_mutex_trylock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5704 CHECK_MUTEX(___lwp_mutex_lock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5705 CHECK_MUTEX(___lwp_mutex_unlock)
a61af66fc99e Initial load
duke
parents:
diff changeset
5706
a61af66fc99e Initial load
duke
parents:
diff changeset
5707 CHECK_COND( _lwp_cond_wait);
a61af66fc99e Initial load
duke
parents:
diff changeset
5708 CHECK_COND( __lwp_cond_wait);
a61af66fc99e Initial load
duke
parents:
diff changeset
5709 CHECK_COND(___lwp_cond_wait);
a61af66fc99e Initial load
duke
parents:
diff changeset
5710
a61af66fc99e Initial load
duke
parents:
diff changeset
5711 CHECK_COND2( _lwp_cond_timedwait);
a61af66fc99e Initial load
duke
parents:
diff changeset
5712 CHECK_COND2( __lwp_cond_timedwait);
a61af66fc99e Initial load
duke
parents:
diff changeset
5713 #undef mutex_t
a61af66fc99e Initial load
duke
parents:
diff changeset
5714 #undef cond_t
a61af66fc99e Initial load
duke
parents:
diff changeset
5715
a61af66fc99e Initial load
duke
parents:
diff changeset
5716 CHECK_SYNCH_OP(int, _lwp_suspend2, (int lwp, int *n), (lwp, n), 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5717 CHECK_SYNCH_OP(int,__lwp_suspend2, (int lwp, int *n), (lwp, n), 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5718 CHECK_SYNCH_OP(int, _lwp_kill, (int lwp, int n), (lwp, n), 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5719 CHECK_SYNCH_OP(int,__lwp_kill, (int lwp, int n), (lwp, n), 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
5720 CHECK_SYNCH_OP(int, _lwp_sema_wait, (lwp_sema_t* p), (p), CHECK_P(p));
a61af66fc99e Initial load
duke
parents:
diff changeset
5721 CHECK_SYNCH_OP(int,__lwp_sema_wait, (lwp_sema_t* p), (p), CHECK_P(p));
a61af66fc99e Initial load
duke
parents:
diff changeset
5722 CHECK_SYNCH_OP(int, _lwp_cond_broadcast, (lwp_cond_t* cv), (cv), CHECK_CV);
a61af66fc99e Initial load
duke
parents:
diff changeset
5723 CHECK_SYNCH_OP(int,__lwp_cond_broadcast, (lwp_cond_t* cv), (cv), CHECK_CV);
a61af66fc99e Initial load
duke
parents:
diff changeset
5724
a61af66fc99e Initial load
duke
parents:
diff changeset
5725
a61af66fc99e Initial load
duke
parents:
diff changeset
5726 // recording machinery:
a61af66fc99e Initial load
duke
parents:
diff changeset
5727
a61af66fc99e Initial load
duke
parents:
diff changeset
5728 enum { RECORD_SYNCH_LIMIT = 200 };
a61af66fc99e Initial load
duke
parents:
diff changeset
5729 char* record_synch_name[RECORD_SYNCH_LIMIT];
a61af66fc99e Initial load
duke
parents:
diff changeset
5730 void* record_synch_arg0ptr[RECORD_SYNCH_LIMIT];
a61af66fc99e Initial load
duke
parents:
diff changeset
5731 bool record_synch_returning[RECORD_SYNCH_LIMIT];
a61af66fc99e Initial load
duke
parents:
diff changeset
5732 thread_t record_synch_thread[RECORD_SYNCH_LIMIT];
a61af66fc99e Initial load
duke
parents:
diff changeset
5733 int record_synch_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5734 bool record_synch_enabled = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5735
a61af66fc99e Initial load
duke
parents:
diff changeset
5736 // in dbx, examine recorded data this way:
a61af66fc99e Initial load
duke
parents:
diff changeset
5737 // for n in name arg0ptr returning thread; do print record_synch_$n[0..record_synch_count-1]; done
a61af66fc99e Initial load
duke
parents:
diff changeset
5738
a61af66fc99e Initial load
duke
parents:
diff changeset
5739 void record_synch(char* name, bool returning) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5740 if (record_synch_enabled) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5741 if (record_synch_count < RECORD_SYNCH_LIMIT) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5742 record_synch_name[record_synch_count] = name;
a61af66fc99e Initial load
duke
parents:
diff changeset
5743 record_synch_returning[record_synch_count] = returning;
a61af66fc99e Initial load
duke
parents:
diff changeset
5744 record_synch_thread[record_synch_count] = thr_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
5745 record_synch_arg0ptr[record_synch_count] = &name;
a61af66fc99e Initial load
duke
parents:
diff changeset
5746 record_synch_count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
5747 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5748 // put more checking code here:
a61af66fc99e Initial load
duke
parents:
diff changeset
5749 // ...
a61af66fc99e Initial load
duke
parents:
diff changeset
5750 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5751 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5752
a61af66fc99e Initial load
duke
parents:
diff changeset
5753 void record_synch_enable() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5754 // start collecting trace data, if not already doing so
a61af66fc99e Initial load
duke
parents:
diff changeset
5755 if (!record_synch_enabled) record_synch_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
5756 record_synch_enabled = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
5757 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5758
a61af66fc99e Initial load
duke
parents:
diff changeset
5759 void record_synch_disable() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5760 // stop collecting trace data
a61af66fc99e Initial load
duke
parents:
diff changeset
5761 record_synch_enabled = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5762 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5763
a61af66fc99e Initial load
duke
parents:
diff changeset
5764 #endif // INTERPOSE_ON_SYSTEM_SYNCH_FUNCTIONS
a61af66fc99e Initial load
duke
parents:
diff changeset
5765 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
5766
a61af66fc99e Initial load
duke
parents:
diff changeset
5767 const intptr_t thr_time_off = (intptr_t)(&((prusage_t *)(NULL))->pr_utime);
a61af66fc99e Initial load
duke
parents:
diff changeset
5768 const intptr_t thr_time_size = (intptr_t)(&((prusage_t *)(NULL))->pr_ttime) -
a61af66fc99e Initial load
duke
parents:
diff changeset
5769 (intptr_t)(&((prusage_t *)(NULL))->pr_utime);
a61af66fc99e Initial load
duke
parents:
diff changeset
5770
a61af66fc99e Initial load
duke
parents:
diff changeset
5771
a61af66fc99e Initial load
duke
parents:
diff changeset
5772 // JVMTI & JVM monitoring and management support
a61af66fc99e Initial load
duke
parents:
diff changeset
5773 // The thread_cpu_time() and current_thread_cpu_time() are only
a61af66fc99e Initial load
duke
parents:
diff changeset
5774 // supported if is_thread_cpu_time_supported() returns true.
a61af66fc99e Initial load
duke
parents:
diff changeset
5775 // They are not supported on Solaris T1.
a61af66fc99e Initial load
duke
parents:
diff changeset
5776
a61af66fc99e Initial load
duke
parents:
diff changeset
5777 // current_thread_cpu_time(bool) and thread_cpu_time(Thread*, bool)
a61af66fc99e Initial load
duke
parents:
diff changeset
5778 // are used by JVM M&M and JVMTI to get user+sys or user CPU time
a61af66fc99e Initial load
duke
parents:
diff changeset
5779 // of a thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
5780 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5781 // current_thread_cpu_time() and thread_cpu_time(Thread *)
a61af66fc99e Initial load
duke
parents:
diff changeset
5782 // returns the fast estimate available on the platform.
a61af66fc99e Initial load
duke
parents:
diff changeset
5783
a61af66fc99e Initial load
duke
parents:
diff changeset
5784 // hrtime_t gethrvtime() return value includes
a61af66fc99e Initial load
duke
parents:
diff changeset
5785 // user time but does not include system time
a61af66fc99e Initial load
duke
parents:
diff changeset
5786 jlong os::current_thread_cpu_time() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5787 return (jlong) gethrvtime();
a61af66fc99e Initial load
duke
parents:
diff changeset
5788 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5789
a61af66fc99e Initial load
duke
parents:
diff changeset
5790 jlong os::thread_cpu_time(Thread *thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5791 // return user level CPU time only to be consistent with
a61af66fc99e Initial load
duke
parents:
diff changeset
5792 // what current_thread_cpu_time returns.
a61af66fc99e Initial load
duke
parents:
diff changeset
5793 // thread_cpu_time_info() must be changed if this changes
a61af66fc99e Initial load
duke
parents:
diff changeset
5794 return os::thread_cpu_time(thread, false /* user time only */);
a61af66fc99e Initial load
duke
parents:
diff changeset
5795 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5796
a61af66fc99e Initial load
duke
parents:
diff changeset
5797 jlong os::current_thread_cpu_time(bool user_sys_cpu_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5798 if (user_sys_cpu_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5799 return os::thread_cpu_time(Thread::current(), user_sys_cpu_time);
a61af66fc99e Initial load
duke
parents:
diff changeset
5800 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5801 return os::current_thread_cpu_time();
a61af66fc99e Initial load
duke
parents:
diff changeset
5802 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5803 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5804
a61af66fc99e Initial load
duke
parents:
diff changeset
5805 jlong os::thread_cpu_time(Thread *thread, bool user_sys_cpu_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5806 char proc_name[64];
a61af66fc99e Initial load
duke
parents:
diff changeset
5807 int count;
a61af66fc99e Initial load
duke
parents:
diff changeset
5808 prusage_t prusage;
a61af66fc99e Initial load
duke
parents:
diff changeset
5809 jlong lwp_time;
a61af66fc99e Initial load
duke
parents:
diff changeset
5810 int fd;
a61af66fc99e Initial load
duke
parents:
diff changeset
5811
a61af66fc99e Initial load
duke
parents:
diff changeset
5812 sprintf(proc_name, "/proc/%d/lwp/%d/lwpusage",
a61af66fc99e Initial load
duke
parents:
diff changeset
5813 getpid(),
a61af66fc99e Initial load
duke
parents:
diff changeset
5814 thread->osthread()->lwp_id());
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5815 fd = ::open(proc_name, O_RDONLY);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5816 if ( fd == -1 ) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
5817
a61af66fc99e Initial load
duke
parents:
diff changeset
5818 do {
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5819 count = ::pread(fd,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5820 (void *)&prusage.pr_utime,
a61af66fc99e Initial load
duke
parents:
diff changeset
5821 thr_time_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
5822 thr_time_off);
a61af66fc99e Initial load
duke
parents:
diff changeset
5823 } while (count < 0 && errno == EINTR);
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
5824 ::close(fd);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5825 if ( count < 0 ) return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
5826
a61af66fc99e Initial load
duke
parents:
diff changeset
5827 if (user_sys_cpu_time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5828 // user + system CPU time
a61af66fc99e Initial load
duke
parents:
diff changeset
5829 lwp_time = (((jlong)prusage.pr_stime.tv_sec +
a61af66fc99e Initial load
duke
parents:
diff changeset
5830 (jlong)prusage.pr_utime.tv_sec) * (jlong)1000000000) +
a61af66fc99e Initial load
duke
parents:
diff changeset
5831 (jlong)prusage.pr_stime.tv_nsec +
a61af66fc99e Initial load
duke
parents:
diff changeset
5832 (jlong)prusage.pr_utime.tv_nsec;
a61af66fc99e Initial load
duke
parents:
diff changeset
5833 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5834 // user level CPU time only
a61af66fc99e Initial load
duke
parents:
diff changeset
5835 lwp_time = ((jlong)prusage.pr_utime.tv_sec * (jlong)1000000000) +
a61af66fc99e Initial load
duke
parents:
diff changeset
5836 (jlong)prusage.pr_utime.tv_nsec;
a61af66fc99e Initial load
duke
parents:
diff changeset
5837 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5838
a61af66fc99e Initial load
duke
parents:
diff changeset
5839 return(lwp_time);
a61af66fc99e Initial load
duke
parents:
diff changeset
5840 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5841
a61af66fc99e Initial load
duke
parents:
diff changeset
5842 void os::current_thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5843 info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits
a61af66fc99e Initial load
duke
parents:
diff changeset
5844 info_ptr->may_skip_backward = false; // elapsed time not wall time
a61af66fc99e Initial load
duke
parents:
diff changeset
5845 info_ptr->may_skip_forward = false; // elapsed time not wall time
a61af66fc99e Initial load
duke
parents:
diff changeset
5846 info_ptr->kind = JVMTI_TIMER_USER_CPU; // only user time is returned
a61af66fc99e Initial load
duke
parents:
diff changeset
5847 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5848
a61af66fc99e Initial load
duke
parents:
diff changeset
5849 void os::thread_cpu_time_info(jvmtiTimerInfo *info_ptr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5850 info_ptr->max_value = ALL_64_BITS; // will not wrap in less than 64 bits
a61af66fc99e Initial load
duke
parents:
diff changeset
5851 info_ptr->may_skip_backward = false; // elapsed time not wall time
a61af66fc99e Initial load
duke
parents:
diff changeset
5852 info_ptr->may_skip_forward = false; // elapsed time not wall time
a61af66fc99e Initial load
duke
parents:
diff changeset
5853 info_ptr->kind = JVMTI_TIMER_USER_CPU; // only user time is returned
a61af66fc99e Initial load
duke
parents:
diff changeset
5854 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5855
a61af66fc99e Initial load
duke
parents:
diff changeset
5856 bool os::is_thread_cpu_time_supported() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5857 if ( os::Solaris::T2_libthread() || UseBoundThreads ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5858 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
5859 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5860 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5861 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5863
a61af66fc99e Initial load
duke
parents:
diff changeset
5864 // System loadavg support. Returns -1 if load average cannot be obtained.
a61af66fc99e Initial load
duke
parents:
diff changeset
5865 // Return the load average for our processor set if the primitive exists
a61af66fc99e Initial load
duke
parents:
diff changeset
5866 // (Solaris 9 and later). Otherwise just return system wide loadavg.
a61af66fc99e Initial load
duke
parents:
diff changeset
5867 int os::loadavg(double loadavg[], int nelem) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5868 if (pset_getloadavg_ptr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5869 return (*pset_getloadavg_ptr)(PS_MYID, loadavg, nelem);
a61af66fc99e Initial load
duke
parents:
diff changeset
5870 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
5871 return ::getloadavg(loadavg, nelem);
a61af66fc99e Initial load
duke
parents:
diff changeset
5872 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5873 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5874
a61af66fc99e Initial load
duke
parents:
diff changeset
5875 //---------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
5876
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5877 bool os::find(address addr, outputStream* st) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5878 Dl_info dlinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
5879 memset(&dlinfo, 0, sizeof(dlinfo));
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
5880 if (dladdr(addr, &dlinfo) != 0) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
5881 st->print(PTR_FORMAT ": ", addr);
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
5882 if (dlinfo.dli_sname != NULL && dlinfo.dli_saddr != NULL) {
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5883 st->print("%s+%#lx", dlinfo.dli_sname, addr-(intptr_t)dlinfo.dli_saddr);
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
5884 } else if (dlinfo.dli_fbase != NULL)
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5885 st->print("<offset %#lx>", addr-(intptr_t)dlinfo.dli_fbase);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5886 else
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5887 st->print("<absolute address>");
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
5888 if (dlinfo.dli_fname != NULL) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
5889 st->print(" in %s", dlinfo.dli_fname);
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
5890 }
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
5891 if (dlinfo.dli_fbase != NULL) {
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
5892 st->print(" at " PTR_FORMAT, dlinfo.dli_fbase);
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
5893 }
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5894 st->cr();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5895
a61af66fc99e Initial load
duke
parents:
diff changeset
5896 if (Verbose) {
a61af66fc99e Initial load
duke
parents:
diff changeset
5897 // decode some bytes around the PC
9060
cc32ccaaf47f 8003310: Enable -Wunused-function when compiling with gcc
mikael
parents: 9059
diff changeset
5898 address begin = clamp_address_in_page(addr-40, addr, os::vm_page_size());
cc32ccaaf47f 8003310: Enable -Wunused-function when compiling with gcc
mikael
parents: 9059
diff changeset
5899 address end = clamp_address_in_page(addr+40, addr, os::vm_page_size());
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5900 address lowest = (address) dlinfo.dli_sname;
a61af66fc99e Initial load
duke
parents:
diff changeset
5901 if (!lowest) lowest = (address) dlinfo.dli_fbase;
a61af66fc99e Initial load
duke
parents:
diff changeset
5902 if (begin < lowest) begin = lowest;
a61af66fc99e Initial load
duke
parents:
diff changeset
5903 Dl_info dlinfo2;
11092
59b052799158 8015884: runThese crashed with SIGSEGV, hs_err has an error instead of stacktrace
dcubed
parents: 10986
diff changeset
5904 if (dladdr(end, &dlinfo2) != 0 && dlinfo2.dli_saddr != dlinfo.dli_saddr
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5905 && end > dlinfo2.dli_saddr && dlinfo2.dli_saddr > begin)
a61af66fc99e Initial load
duke
parents:
diff changeset
5906 end = (address) dlinfo2.dli_saddr;
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
5907 Disassembler::decode(begin, end, st);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
5908 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5909 return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
5910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5911 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
5912 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5913
a61af66fc99e Initial load
duke
parents:
diff changeset
5914 // Following function has been added to support HotSparc's libjvm.so running
a61af66fc99e Initial load
duke
parents:
diff changeset
5915 // under Solaris production JDK 1.2.2 / 1.3.0. These came from
a61af66fc99e Initial load
duke
parents:
diff changeset
5916 // src/solaris/hpi/native_threads in the EVM codebase.
a61af66fc99e Initial load
duke
parents:
diff changeset
5917 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5918 // NOTE: This is no longer needed in the 1.3.1 and 1.4 production release
a61af66fc99e Initial load
duke
parents:
diff changeset
5919 // libraries and should thus be removed. We will leave it behind for a while
a61af66fc99e Initial load
duke
parents:
diff changeset
5920 // until we no longer want to able to run on top of 1.3.0 Solaris production
a61af66fc99e Initial load
duke
parents:
diff changeset
5921 // JDK. See 4341971.
a61af66fc99e Initial load
duke
parents:
diff changeset
5922
a61af66fc99e Initial load
duke
parents:
diff changeset
5923 #define STACK_SLACK 0x800
a61af66fc99e Initial load
duke
parents:
diff changeset
5924
a61af66fc99e Initial load
duke
parents:
diff changeset
5925 extern "C" {
a61af66fc99e Initial load
duke
parents:
diff changeset
5926 intptr_t sysThreadAvailableStackWithSlack() {
a61af66fc99e Initial load
duke
parents:
diff changeset
5927 stack_t st;
a61af66fc99e Initial load
duke
parents:
diff changeset
5928 intptr_t retval, stack_top;
a61af66fc99e Initial load
duke
parents:
diff changeset
5929 retval = thr_stksegment(&st);
a61af66fc99e Initial load
duke
parents:
diff changeset
5930 assert(retval == 0, "incorrect return value from thr_stksegment");
a61af66fc99e Initial load
duke
parents:
diff changeset
5931 assert((address)&st < (address)st.ss_sp, "Invalid stack base returned");
a61af66fc99e Initial load
duke
parents:
diff changeset
5932 assert((address)&st > (address)st.ss_sp-st.ss_size, "Invalid stack size returned");
a61af66fc99e Initial load
duke
parents:
diff changeset
5933 stack_top=(intptr_t)st.ss_sp-st.ss_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
5934 return ((intptr_t)&stack_top - stack_top - STACK_SLACK);
a61af66fc99e Initial load
duke
parents:
diff changeset
5935 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5936 }
a61af66fc99e Initial load
duke
parents:
diff changeset
5937
a61af66fc99e Initial load
duke
parents:
diff changeset
5938 // ObjectMonitor park-unpark infrastructure ...
a61af66fc99e Initial load
duke
parents:
diff changeset
5939 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5940 // We implement Solaris and Linux PlatformEvents with the
a61af66fc99e Initial load
duke
parents:
diff changeset
5941 // obvious condvar-mutex-flag triple.
a61af66fc99e Initial load
duke
parents:
diff changeset
5942 // Another alternative that works quite well is pipes:
a61af66fc99e Initial load
duke
parents:
diff changeset
5943 // Each PlatformEvent consists of a pipe-pair.
a61af66fc99e Initial load
duke
parents:
diff changeset
5944 // The thread associated with the PlatformEvent
a61af66fc99e Initial load
duke
parents:
diff changeset
5945 // calls park(), which reads from the input end of the pipe.
a61af66fc99e Initial load
duke
parents:
diff changeset
5946 // Unpark() writes into the other end of the pipe.
a61af66fc99e Initial load
duke
parents:
diff changeset
5947 // The write-side of the pipe must be set NDELAY.
a61af66fc99e Initial load
duke
parents:
diff changeset
5948 // Unfortunately pipes consume a large # of handles.
a61af66fc99e Initial load
duke
parents:
diff changeset
5949 // Native solaris lwp_park() and lwp_unpark() work nicely, too.
a61af66fc99e Initial load
duke
parents:
diff changeset
5950 // Using pipes for the 1st few threads might be workable, however.
a61af66fc99e Initial load
duke
parents:
diff changeset
5951 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5952 // park() is permitted to return spuriously.
a61af66fc99e Initial load
duke
parents:
diff changeset
5953 // Callers of park() should wrap the call to park() in
a61af66fc99e Initial load
duke
parents:
diff changeset
5954 // an appropriate loop. A litmus test for the correct
a61af66fc99e Initial load
duke
parents:
diff changeset
5955 // usage of park is the following: if park() were modified
a61af66fc99e Initial load
duke
parents:
diff changeset
5956 // to immediately return 0 your code should still work,
a61af66fc99e Initial load
duke
parents:
diff changeset
5957 // albeit degenerating to a spin loop.
a61af66fc99e Initial load
duke
parents:
diff changeset
5958 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5959 // An interesting optimization for park() is to use a trylock()
a61af66fc99e Initial load
duke
parents:
diff changeset
5960 // to attempt to acquire the mutex. If the trylock() fails
a61af66fc99e Initial load
duke
parents:
diff changeset
5961 // then we know that a concurrent unpark() operation is in-progress.
a61af66fc99e Initial load
duke
parents:
diff changeset
5962 // in that case the park() code could simply set _count to 0
a61af66fc99e Initial load
duke
parents:
diff changeset
5963 // and return immediately. The subsequent park() operation *might*
a61af66fc99e Initial load
duke
parents:
diff changeset
5964 // return immediately. That's harmless as the caller of park() is
a61af66fc99e Initial load
duke
parents:
diff changeset
5965 // expected to loop. By using trylock() we will have avoided a
a61af66fc99e Initial load
duke
parents:
diff changeset
5966 // avoided a context switch caused by contention on the per-thread mutex.
a61af66fc99e Initial load
duke
parents:
diff changeset
5967 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5968 // TODO-FIXME:
a61af66fc99e Initial load
duke
parents:
diff changeset
5969 // 1. Reconcile Doug's JSR166 j.u.c park-unpark with the
a61af66fc99e Initial load
duke
parents:
diff changeset
5970 // objectmonitor implementation.
a61af66fc99e Initial load
duke
parents:
diff changeset
5971 // 2. Collapse the JSR166 parker event, and the
a61af66fc99e Initial load
duke
parents:
diff changeset
5972 // objectmonitor ParkEvent into a single "Event" construct.
a61af66fc99e Initial load
duke
parents:
diff changeset
5973 // 3. In park() and unpark() add:
a61af66fc99e Initial load
duke
parents:
diff changeset
5974 // assert (Thread::current() == AssociatedWith).
a61af66fc99e Initial load
duke
parents:
diff changeset
5975 // 4. add spurious wakeup injection on a -XX:EarlyParkReturn=N switch.
a61af66fc99e Initial load
duke
parents:
diff changeset
5976 // 1-out-of-N park() operations will return immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
5977 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5978 // _Event transitions in park()
a61af66fc99e Initial load
duke
parents:
diff changeset
5979 // -1 => -1 : illegal
a61af66fc99e Initial load
duke
parents:
diff changeset
5980 // 1 => 0 : pass - return immediately
a61af66fc99e Initial load
duke
parents:
diff changeset
5981 // 0 => -1 : block
a61af66fc99e Initial load
duke
parents:
diff changeset
5982 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5983 // _Event serves as a restricted-range semaphore.
a61af66fc99e Initial load
duke
parents:
diff changeset
5984 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5985 // Another possible encoding of _Event would be with
a61af66fc99e Initial load
duke
parents:
diff changeset
5986 // explicit "PARKED" == 01b and "SIGNALED" == 10b bits.
a61af66fc99e Initial load
duke
parents:
diff changeset
5987 //
a61af66fc99e Initial load
duke
parents:
diff changeset
5988 // TODO-FIXME: add DTRACE probes for:
a61af66fc99e Initial load
duke
parents:
diff changeset
5989 // 1. Tx parks
a61af66fc99e Initial load
duke
parents:
diff changeset
5990 // 2. Ty unparks Tx
a61af66fc99e Initial load
duke
parents:
diff changeset
5991 // 3. Tx resumes from park
a61af66fc99e Initial load
duke
parents:
diff changeset
5992
a61af66fc99e Initial load
duke
parents:
diff changeset
5993
a61af66fc99e Initial load
duke
parents:
diff changeset
5994 // value determined through experimentation
a61af66fc99e Initial load
duke
parents:
diff changeset
5995 #define ROUNDINGFIX 11
a61af66fc99e Initial load
duke
parents:
diff changeset
5996
a61af66fc99e Initial load
duke
parents:
diff changeset
5997 // utility to compute the abstime argument to timedwait.
a61af66fc99e Initial load
duke
parents:
diff changeset
5998 // TODO-FIXME: switch from compute_abstime() to unpackTime().
a61af66fc99e Initial load
duke
parents:
diff changeset
5999
a61af66fc99e Initial load
duke
parents:
diff changeset
6000 static timestruc_t* compute_abstime(timestruc_t* abstime, jlong millis) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6001 // millis is the relative timeout time
a61af66fc99e Initial load
duke
parents:
diff changeset
6002 // abstime will be the absolute timeout time
a61af66fc99e Initial load
duke
parents:
diff changeset
6003 if (millis < 0) millis = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
6004 struct timeval now;
a61af66fc99e Initial load
duke
parents:
diff changeset
6005 int status = gettimeofday(&now, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
6006 assert(status == 0, "gettimeofday");
a61af66fc99e Initial load
duke
parents:
diff changeset
6007 jlong seconds = millis / 1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
6008 jlong max_wait_period;
a61af66fc99e Initial load
duke
parents:
diff changeset
6009
a61af66fc99e Initial load
duke
parents:
diff changeset
6010 if (UseLWPSynchronization) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6011 // forward port of fix for 4275818 (not sleeping long enough)
a61af66fc99e Initial load
duke
parents:
diff changeset
6012 // There was a bug in Solaris 6, 7 and pre-patch 5 of 8 where
a61af66fc99e Initial load
duke
parents:
diff changeset
6013 // _lwp_cond_timedwait() used a round_down algorithm rather
a61af66fc99e Initial load
duke
parents:
diff changeset
6014 // than a round_up. For millis less than our roundfactor
a61af66fc99e Initial load
duke
parents:
diff changeset
6015 // it rounded down to 0 which doesn't meet the spec.
a61af66fc99e Initial load
duke
parents:
diff changeset
6016 // For millis > roundfactor we may return a bit sooner, but
a61af66fc99e Initial load
duke
parents:
diff changeset
6017 // since we can not accurately identify the patch level and
a61af66fc99e Initial load
duke
parents:
diff changeset
6018 // this has already been fixed in Solaris 9 and 8 we will
a61af66fc99e Initial load
duke
parents:
diff changeset
6019 // leave it alone rather than always rounding down.
a61af66fc99e Initial load
duke
parents:
diff changeset
6020
a61af66fc99e Initial load
duke
parents:
diff changeset
6021 if (millis > 0 && millis < ROUNDINGFIX) millis = ROUNDINGFIX;
a61af66fc99e Initial load
duke
parents:
diff changeset
6022 // It appears that when we go directly through Solaris _lwp_cond_timedwait()
a61af66fc99e Initial load
duke
parents:
diff changeset
6023 // the acceptable max time threshold is smaller than for libthread on 2.5.1 and 2.6
a61af66fc99e Initial load
duke
parents:
diff changeset
6024 max_wait_period = 21000000;
a61af66fc99e Initial load
duke
parents:
diff changeset
6025 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6026 max_wait_period = 50000000;
a61af66fc99e Initial load
duke
parents:
diff changeset
6027 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6028 millis %= 1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
6029 if (seconds > max_wait_period) { // see man cond_timedwait(3T)
a61af66fc99e Initial load
duke
parents:
diff changeset
6030 seconds = max_wait_period;
a61af66fc99e Initial load
duke
parents:
diff changeset
6031 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6032 abstime->tv_sec = now.tv_sec + seconds;
a61af66fc99e Initial load
duke
parents:
diff changeset
6033 long usec = now.tv_usec + millis * 1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
6034 if (usec >= 1000000) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6035 abstime->tv_sec += 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
6036 usec -= 1000000;
a61af66fc99e Initial load
duke
parents:
diff changeset
6037 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6038 abstime->tv_nsec = usec * 1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
6039 return abstime;
a61af66fc99e Initial load
duke
parents:
diff changeset
6040 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6041
a61af66fc99e Initial load
duke
parents:
diff changeset
6042 // Test-and-clear _Event, always leaves _Event set to 0, returns immediately.
a61af66fc99e Initial load
duke
parents:
diff changeset
6043 // Conceptually TryPark() should be equivalent to park(0).
a61af66fc99e Initial load
duke
parents:
diff changeset
6044
a61af66fc99e Initial load
duke
parents:
diff changeset
6045 int os::PlatformEvent::TryPark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
6046 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6047 const int v = _Event ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6048 guarantee ((v == 0) || (v == 1), "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6049 if (Atomic::cmpxchg (0, &_Event, v) == v) return v ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6050 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6051 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6052
a61af66fc99e Initial load
duke
parents:
diff changeset
6053 void os::PlatformEvent::park() { // AKA: down()
a61af66fc99e Initial load
duke
parents:
diff changeset
6054 // Invariant: Only the thread associated with the Event/PlatformEvent
a61af66fc99e Initial load
duke
parents:
diff changeset
6055 // may call park().
a61af66fc99e Initial load
duke
parents:
diff changeset
6056 int v ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6057 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6058 v = _Event ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6059 if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6060 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6061 guarantee (v >= 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6062 if (v == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6063 // Do this the hard way by blocking ...
a61af66fc99e Initial load
duke
parents:
diff changeset
6064 // See http://monaco.sfbay/detail.jsf?cr=5094058.
a61af66fc99e Initial load
duke
parents:
diff changeset
6065 // TODO-FIXME: for Solaris SPARC set fprs.FEF=0 prior to parking.
a61af66fc99e Initial load
duke
parents:
diff changeset
6066 // Only for SPARC >= V8PlusA
a61af66fc99e Initial load
duke
parents:
diff changeset
6067 #if defined(__sparc) && defined(COMPILER2)
a61af66fc99e Initial load
duke
parents:
diff changeset
6068 if (ClearFPUAtPark) { _mark_fpu_nosave() ; }
a61af66fc99e Initial load
duke
parents:
diff changeset
6069 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
6070 int status = os::Solaris::mutex_lock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
6071 assert_status(status == 0, status, "mutex_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
6072 guarantee (_nParked == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6073 ++ _nParked ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6074 while (_Event < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6075 // for some reason, under 2.7 lwp_cond_wait() may return ETIME ...
a61af66fc99e Initial load
duke
parents:
diff changeset
6076 // Treat this the same as if the wait was interrupted
a61af66fc99e Initial load
duke
parents:
diff changeset
6077 // With usr/lib/lwp going to kernel, always handle ETIME
a61af66fc99e Initial load
duke
parents:
diff changeset
6078 status = os::Solaris::cond_wait(_cond, _mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
6079 if (status == ETIME) status = EINTR ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6080 assert_status(status == 0 || status == EINTR, status, "cond_wait");
a61af66fc99e Initial load
duke
parents:
diff changeset
6081 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6082 -- _nParked ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6083 _Event = 0 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6084 status = os::Solaris::mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
6085 assert_status(status == 0, status, "mutex_unlock");
7629
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6086 // Paranoia to ensure our locked and lock-free paths interact
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6087 // correctly with each other.
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6088 OrderAccess::fence();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6089 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6090 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6091
a61af66fc99e Initial load
duke
parents:
diff changeset
6092 int os::PlatformEvent::park(jlong millis) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6093 guarantee (_nParked == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6094 int v ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6095 for (;;) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6096 v = _Event ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6097 if (Atomic::cmpxchg (v-1, &_Event, v) == v) break ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6098 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6099 guarantee (v >= 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6100 if (v != 0) return OS_OK ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6101
a61af66fc99e Initial load
duke
parents:
diff changeset
6102 int ret = OS_TIMEOUT;
a61af66fc99e Initial load
duke
parents:
diff changeset
6103 timestruc_t abst;
a61af66fc99e Initial load
duke
parents:
diff changeset
6104 compute_abstime (&abst, millis);
a61af66fc99e Initial load
duke
parents:
diff changeset
6105
a61af66fc99e Initial load
duke
parents:
diff changeset
6106 // See http://monaco.sfbay/detail.jsf?cr=5094058.
a61af66fc99e Initial load
duke
parents:
diff changeset
6107 // For Solaris SPARC set fprs.FEF=0 prior to parking.
a61af66fc99e Initial load
duke
parents:
diff changeset
6108 // Only for SPARC >= V8PlusA
a61af66fc99e Initial load
duke
parents:
diff changeset
6109 #if defined(__sparc) && defined(COMPILER2)
a61af66fc99e Initial load
duke
parents:
diff changeset
6110 if (ClearFPUAtPark) { _mark_fpu_nosave() ; }
a61af66fc99e Initial load
duke
parents:
diff changeset
6111 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
6112 int status = os::Solaris::mutex_lock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
6113 assert_status(status == 0, status, "mutex_lock");
a61af66fc99e Initial load
duke
parents:
diff changeset
6114 guarantee (_nParked == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6115 ++ _nParked ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6116 while (_Event < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6117 int status = os::Solaris::cond_timedwait(_cond, _mutex, &abst);
a61af66fc99e Initial load
duke
parents:
diff changeset
6118 assert_status(status == 0 || status == EINTR ||
a61af66fc99e Initial load
duke
parents:
diff changeset
6119 status == ETIME || status == ETIMEDOUT,
a61af66fc99e Initial load
duke
parents:
diff changeset
6120 status, "cond_timedwait");
a61af66fc99e Initial load
duke
parents:
diff changeset
6121 if (!FilterSpuriousWakeups) break ; // previous semantics
a61af66fc99e Initial load
duke
parents:
diff changeset
6122 if (status == ETIME || status == ETIMEDOUT) break ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6123 // We consume and ignore EINTR and spurious wakeups.
a61af66fc99e Initial load
duke
parents:
diff changeset
6124 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6125 -- _nParked ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6126 if (_Event >= 0) ret = OS_OK ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6127 _Event = 0 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6128 status = os::Solaris::mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
6129 assert_status(status == 0, status, "mutex_unlock");
7629
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6130 // Paranoia to ensure our locked and lock-free paths interact
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6131 // correctly with each other.
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6132 OrderAccess::fence();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6133 return ret;
a61af66fc99e Initial load
duke
parents:
diff changeset
6134 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6135
a61af66fc99e Initial load
duke
parents:
diff changeset
6136 void os::PlatformEvent::unpark() {
7629
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6137 // Transitions for _Event:
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6138 // 0 :=> 1
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6139 // 1 :=> 1
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6140 // -1 :=> either 0 or 1; must signal target thread
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6141 // That is, we can safely transition _Event from -1 to either
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6142 // 0 or 1. Forcing 1 is slightly more efficient for back-to-back
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6143 // unpark() calls.
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6144 // See also: "Semaphores in Plan 9" by Mullender & Cox
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6145 //
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6146 // Note: Forcing a transition from "-1" to "1" on an unpark() means
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6147 // that it will take two back-to-back park() calls for the owning
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6148 // thread to block. This has the benefit of forcing a spurious return
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6149 // from the first park() call after an unpark() call which will help
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6150 // shake out uses of park() and unpark() without condition variables.
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6151
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6152 if (Atomic::xchg(1, &_Event) >= 0) return;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6153
a61af66fc99e Initial load
duke
parents:
diff changeset
6154 // If the thread associated with the event was parked, wake it.
7629
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6155 // Wait for the thread assoc with the PlatformEvent to vacate.
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6156 int status = os::Solaris::mutex_lock(_mutex);
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6157 assert_status(status == 0, status, "mutex_lock");
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6158 int AnyWaiters = _nParked;
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6159 status = os::Solaris::mutex_unlock(_mutex);
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6160 assert_status(status == 0, status, "mutex_unlock");
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6161 guarantee(AnyWaiters == 0 || AnyWaiters == 1, "invariant");
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6162 if (AnyWaiters != 0) {
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6163 // We intentional signal *after* dropping the lock
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6164 // to avoid a common class of futile wakeups.
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6165 status = os::Solaris::cond_signal(_cond);
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6166 assert_status(status == 0, status, "cond_signal");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6167 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6169
a61af66fc99e Initial load
duke
parents:
diff changeset
6170 // JSR166
a61af66fc99e Initial load
duke
parents:
diff changeset
6171 // -------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
6172
a61af66fc99e Initial load
duke
parents:
diff changeset
6173 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
6174 * The solaris and linux implementations of park/unpark are fairly
a61af66fc99e Initial load
duke
parents:
diff changeset
6175 * conservative for now, but can be improved. They currently use a
a61af66fc99e Initial load
duke
parents:
diff changeset
6176 * mutex/condvar pair, plus _counter.
a61af66fc99e Initial load
duke
parents:
diff changeset
6177 * Park decrements _counter if > 0, else does a condvar wait. Unpark
a61af66fc99e Initial load
duke
parents:
diff changeset
6178 * sets count to 1 and signals condvar. Only one thread ever waits
a61af66fc99e Initial load
duke
parents:
diff changeset
6179 * on the condvar. Contention seen when trying to park implies that someone
a61af66fc99e Initial load
duke
parents:
diff changeset
6180 * is unparking you, so don't wait. And spurious returns are fine, so there
a61af66fc99e Initial load
duke
parents:
diff changeset
6181 * is no need to track notifications.
a61af66fc99e Initial load
duke
parents:
diff changeset
6182 */
a61af66fc99e Initial load
duke
parents:
diff changeset
6183
a61af66fc99e Initial load
duke
parents:
diff changeset
6184 #define MAX_SECS 100000000
a61af66fc99e Initial load
duke
parents:
diff changeset
6185 /*
a61af66fc99e Initial load
duke
parents:
diff changeset
6186 * This code is common to linux and solaris and will be moved to a
a61af66fc99e Initial load
duke
parents:
diff changeset
6187 * common place in dolphin.
a61af66fc99e Initial load
duke
parents:
diff changeset
6188 *
a61af66fc99e Initial load
duke
parents:
diff changeset
6189 * The passed in time value is either a relative time in nanoseconds
a61af66fc99e Initial load
duke
parents:
diff changeset
6190 * or an absolute time in milliseconds. Either way it has to be unpacked
a61af66fc99e Initial load
duke
parents:
diff changeset
6191 * into suitable seconds and nanoseconds components and stored in the
a61af66fc99e Initial load
duke
parents:
diff changeset
6192 * given timespec structure.
a61af66fc99e Initial load
duke
parents:
diff changeset
6193 * Given time is a 64-bit value and the time_t used in the timespec is only
a61af66fc99e Initial load
duke
parents:
diff changeset
6194 * a signed-32-bit value (except on 64-bit Linux) we have to watch for
a61af66fc99e Initial load
duke
parents:
diff changeset
6195 * overflow if times way in the future are given. Further on Solaris versions
a61af66fc99e Initial load
duke
parents:
diff changeset
6196 * prior to 10 there is a restriction (see cond_timedwait) that the specified
a61af66fc99e Initial load
duke
parents:
diff changeset
6197 * number of seconds, in abstime, is less than current_time + 100,000,000.
a61af66fc99e Initial load
duke
parents:
diff changeset
6198 * As it will be 28 years before "now + 100000000" will overflow we can
a61af66fc99e Initial load
duke
parents:
diff changeset
6199 * ignore overflow and just impose a hard-limit on seconds using the value
a61af66fc99e Initial load
duke
parents:
diff changeset
6200 * of "now + 100,000,000". This places a limit on the timeout of about 3.17
a61af66fc99e Initial load
duke
parents:
diff changeset
6201 * years from "now".
a61af66fc99e Initial load
duke
parents:
diff changeset
6202 */
a61af66fc99e Initial load
duke
parents:
diff changeset
6203 static void unpackTime(timespec* absTime, bool isAbsolute, jlong time) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6204 assert (time > 0, "convertTime");
a61af66fc99e Initial load
duke
parents:
diff changeset
6205
a61af66fc99e Initial load
duke
parents:
diff changeset
6206 struct timeval now;
a61af66fc99e Initial load
duke
parents:
diff changeset
6207 int status = gettimeofday(&now, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
6208 assert(status == 0, "gettimeofday");
a61af66fc99e Initial load
duke
parents:
diff changeset
6209
a61af66fc99e Initial load
duke
parents:
diff changeset
6210 time_t max_secs = now.tv_sec + MAX_SECS;
a61af66fc99e Initial load
duke
parents:
diff changeset
6211
a61af66fc99e Initial load
duke
parents:
diff changeset
6212 if (isAbsolute) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6213 jlong secs = time / 1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
6214 if (secs > max_secs) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6215 absTime->tv_sec = max_secs;
a61af66fc99e Initial load
duke
parents:
diff changeset
6216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6217 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6218 absTime->tv_sec = secs;
a61af66fc99e Initial load
duke
parents:
diff changeset
6219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6220 absTime->tv_nsec = (time % 1000) * NANOSECS_PER_MILLISEC;
a61af66fc99e Initial load
duke
parents:
diff changeset
6221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6222 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6223 jlong secs = time / NANOSECS_PER_SEC;
a61af66fc99e Initial load
duke
parents:
diff changeset
6224 if (secs >= MAX_SECS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6225 absTime->tv_sec = max_secs;
a61af66fc99e Initial load
duke
parents:
diff changeset
6226 absTime->tv_nsec = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
6227 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6228 else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6229 absTime->tv_sec = now.tv_sec + secs;
a61af66fc99e Initial load
duke
parents:
diff changeset
6230 absTime->tv_nsec = (time % NANOSECS_PER_SEC) + now.tv_usec*1000;
a61af66fc99e Initial load
duke
parents:
diff changeset
6231 if (absTime->tv_nsec >= NANOSECS_PER_SEC) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6232 absTime->tv_nsec -= NANOSECS_PER_SEC;
a61af66fc99e Initial load
duke
parents:
diff changeset
6233 ++absTime->tv_sec; // note: this must be <= max_secs
a61af66fc99e Initial load
duke
parents:
diff changeset
6234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6235 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6237 assert(absTime->tv_sec >= 0, "tv_sec < 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
6238 assert(absTime->tv_sec <= max_secs, "tv_sec > max_secs");
a61af66fc99e Initial load
duke
parents:
diff changeset
6239 assert(absTime->tv_nsec >= 0, "tv_nsec < 0");
a61af66fc99e Initial load
duke
parents:
diff changeset
6240 assert(absTime->tv_nsec < NANOSECS_PER_SEC, "tv_nsec >= nanos_per_sec");
a61af66fc99e Initial load
duke
parents:
diff changeset
6241 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6242
a61af66fc99e Initial load
duke
parents:
diff changeset
6243 void Parker::park(bool isAbsolute, jlong time) {
7629
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6244 // Ideally we'd do something useful while spinning, such
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6245 // as calling unpackTime().
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6246
a61af66fc99e Initial load
duke
parents:
diff changeset
6247 // Optional fast-path check:
a61af66fc99e Initial load
duke
parents:
diff changeset
6248 // Return immediately if a permit is available.
7629
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6249 // We depend on Atomic::xchg() having full barrier semantics
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6250 // since we are doing a lock-free update to _counter.
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6251 if (Atomic::xchg(0, &_counter) > 0) return;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6252
a61af66fc99e Initial load
duke
parents:
diff changeset
6253 // Optional fast-exit: Check interrupt before trying to wait
a61af66fc99e Initial load
duke
parents:
diff changeset
6254 Thread* thread = Thread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
6255 assert(thread->is_Java_thread(), "Must be JavaThread");
a61af66fc99e Initial load
duke
parents:
diff changeset
6256 JavaThread *jt = (JavaThread *)thread;
a61af66fc99e Initial load
duke
parents:
diff changeset
6257 if (Thread::is_interrupted(thread, false)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6258 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
6259 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6260
a61af66fc99e Initial load
duke
parents:
diff changeset
6261 // First, demultiplex/decode time arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
6262 timespec absTime;
1865
1c352af0135d 6763959: java.util.concurrent.locks.LockSupport.parkUntil(0) blocks forever
acorn
parents: 1681
diff changeset
6263 if (time < 0 || (isAbsolute && time == 0) ) { // don't wait at all
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6264 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
6265 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6266 if (time > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6267 // Warning: this code might be exposed to the old Solaris time
a61af66fc99e Initial load
duke
parents:
diff changeset
6268 // round-down bugs. Grep "roundingFix" for details.
a61af66fc99e Initial load
duke
parents:
diff changeset
6269 unpackTime(&absTime, isAbsolute, time);
a61af66fc99e Initial load
duke
parents:
diff changeset
6270 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6271
a61af66fc99e Initial load
duke
parents:
diff changeset
6272 // Enter safepoint region
a61af66fc99e Initial load
duke
parents:
diff changeset
6273 // Beware of deadlocks such as 6317397.
a61af66fc99e Initial load
duke
parents:
diff changeset
6274 // The per-thread Parker:: _mutex is a classic leaf-lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
6275 // In particular a thread must never block on the Threads_lock while
a61af66fc99e Initial load
duke
parents:
diff changeset
6276 // holding the Parker:: mutex. If safepoints are pending both the
a61af66fc99e Initial load
duke
parents:
diff changeset
6277 // the ThreadBlockInVM() CTOR and DTOR may grab Threads_lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
6278 ThreadBlockInVM tbivm(jt);
a61af66fc99e Initial load
duke
parents:
diff changeset
6279
a61af66fc99e Initial load
duke
parents:
diff changeset
6280 // Don't wait if cannot get lock since interference arises from
a61af66fc99e Initial load
duke
parents:
diff changeset
6281 // unblocking. Also. check interrupt before trying wait
a61af66fc99e Initial load
duke
parents:
diff changeset
6282 if (Thread::is_interrupted(thread, false) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
6283 os::Solaris::mutex_trylock(_mutex) != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6284 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
6285 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6286
a61af66fc99e Initial load
duke
parents:
diff changeset
6287 int status ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6288
a61af66fc99e Initial load
duke
parents:
diff changeset
6289 if (_counter > 0) { // no wait needed
a61af66fc99e Initial load
duke
parents:
diff changeset
6290 _counter = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
6291 status = os::Solaris::mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
6292 assert (status == 0, "invariant") ;
7629
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6293 // Paranoia to ensure our locked and lock-free paths interact
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6294 // correctly with each other and Java-level accesses.
1117
95e9083cf4a7 6822370: ReentrantReadWriteLock: threads hung when there are no threads holding onto the lock (Netra x4450)
dholmes
parents: 894
diff changeset
6295 OrderAccess::fence();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6296 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
6297 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6298
a61af66fc99e Initial load
duke
parents:
diff changeset
6299 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
6300 // Don't catch signals while blocked; let the running threads have the signals.
a61af66fc99e Initial load
duke
parents:
diff changeset
6301 // (This allows a debugger to break into the running thread.)
a61af66fc99e Initial load
duke
parents:
diff changeset
6302 sigset_t oldsigs;
a61af66fc99e Initial load
duke
parents:
diff changeset
6303 sigset_t* allowdebug_blocked = os::Solaris::allowdebug_blocked_signals();
a61af66fc99e Initial load
duke
parents:
diff changeset
6304 thr_sigsetmask(SIG_BLOCK, allowdebug_blocked, &oldsigs);
a61af66fc99e Initial load
duke
parents:
diff changeset
6305 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
6306
a61af66fc99e Initial load
duke
parents:
diff changeset
6307 OSThreadWaitState osts(thread->osthread(), false /* not Object.wait() */);
a61af66fc99e Initial load
duke
parents:
diff changeset
6308 jt->set_suspend_equivalent();
a61af66fc99e Initial load
duke
parents:
diff changeset
6309 // cleared by handle_special_suspend_equivalent_condition() or java_suspend_self()
a61af66fc99e Initial load
duke
parents:
diff changeset
6310
a61af66fc99e Initial load
duke
parents:
diff changeset
6311 // Do this the hard way by blocking ...
a61af66fc99e Initial load
duke
parents:
diff changeset
6312 // See http://monaco.sfbay/detail.jsf?cr=5094058.
a61af66fc99e Initial load
duke
parents:
diff changeset
6313 // TODO-FIXME: for Solaris SPARC set fprs.FEF=0 prior to parking.
a61af66fc99e Initial load
duke
parents:
diff changeset
6314 // Only for SPARC >= V8PlusA
a61af66fc99e Initial load
duke
parents:
diff changeset
6315 #if defined(__sparc) && defined(COMPILER2)
a61af66fc99e Initial load
duke
parents:
diff changeset
6316 if (ClearFPUAtPark) { _mark_fpu_nosave() ; }
a61af66fc99e Initial load
duke
parents:
diff changeset
6317 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
6318
a61af66fc99e Initial load
duke
parents:
diff changeset
6319 if (time == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6320 status = os::Solaris::cond_wait (_cond, _mutex) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6321 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6322 status = os::Solaris::cond_timedwait (_cond, _mutex, &absTime);
a61af66fc99e Initial load
duke
parents:
diff changeset
6323 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6324 // Note that an untimed cond_wait() can sometimes return ETIME on older
a61af66fc99e Initial load
duke
parents:
diff changeset
6325 // versions of the Solaris.
a61af66fc99e Initial load
duke
parents:
diff changeset
6326 assert_status(status == 0 || status == EINTR ||
a61af66fc99e Initial load
duke
parents:
diff changeset
6327 status == ETIME || status == ETIMEDOUT,
a61af66fc99e Initial load
duke
parents:
diff changeset
6328 status, "cond_timedwait");
a61af66fc99e Initial load
duke
parents:
diff changeset
6329
a61af66fc99e Initial load
duke
parents:
diff changeset
6330 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
6331 thr_sigsetmask(SIG_SETMASK, &oldsigs, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
6332 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
6333 _counter = 0 ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6334 status = os::Solaris::mutex_unlock(_mutex);
a61af66fc99e Initial load
duke
parents:
diff changeset
6335 assert_status(status == 0, status, "mutex_unlock") ;
7629
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6336 // Paranoia to ensure our locked and lock-free paths interact
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6337 // correctly with each other and Java-level accesses.
22ba8c8ce6a6 8004902: correctness fixes motivated by contended locking work (6607129)
dcubed
parents: 7456
diff changeset
6338 OrderAccess::fence();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
6339
a61af66fc99e Initial load
duke
parents:
diff changeset
6340 // If externally suspended while waiting, re-suspend
a61af66fc99e Initial load
duke
parents:
diff changeset
6341 if (jt->handle_special_suspend_equivalent_condition()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6342 jt->java_suspend_self();
a61af66fc99e Initial load
duke
parents:
diff changeset
6343 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6344 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6345
a61af66fc99e Initial load
duke
parents:
diff changeset
6346 void Parker::unpark() {
a61af66fc99e Initial load
duke
parents:
diff changeset
6347 int s, status ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6348 status = os::Solaris::mutex_lock (_mutex) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6349 assert (status == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6350 s = _counter;
a61af66fc99e Initial load
duke
parents:
diff changeset
6351 _counter = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
6352 status = os::Solaris::mutex_unlock (_mutex) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6353 assert (status == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6354
a61af66fc99e Initial load
duke
parents:
diff changeset
6355 if (s < 1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6356 status = os::Solaris::cond_signal (_cond) ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6357 assert (status == 0, "invariant") ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6358 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6359 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6360
a61af66fc99e Initial load
duke
parents:
diff changeset
6361 extern char** environ;
a61af66fc99e Initial load
duke
parents:
diff changeset
6362
a61af66fc99e Initial load
duke
parents:
diff changeset
6363 // Run the specified command in a separate process. Return its exit value,
a61af66fc99e Initial load
duke
parents:
diff changeset
6364 // or -1 on failure (e.g. can't fork a new process).
a61af66fc99e Initial load
duke
parents:
diff changeset
6365 // Unlike system(), this function can be called from signal handler. It
a61af66fc99e Initial load
duke
parents:
diff changeset
6366 // doesn't block SIGINT et al.
a61af66fc99e Initial load
duke
parents:
diff changeset
6367 int os::fork_and_exec(char* cmd) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6368 char * argv[4];
a61af66fc99e Initial load
duke
parents:
diff changeset
6369 argv[0] = (char *)"sh";
a61af66fc99e Initial load
duke
parents:
diff changeset
6370 argv[1] = (char *)"-c";
a61af66fc99e Initial load
duke
parents:
diff changeset
6371 argv[2] = cmd;
a61af66fc99e Initial load
duke
parents:
diff changeset
6372 argv[3] = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
6373
a61af66fc99e Initial load
duke
parents:
diff changeset
6374 // fork is async-safe, fork1 is not so can't use in signal handler
a61af66fc99e Initial load
duke
parents:
diff changeset
6375 pid_t pid;
a61af66fc99e Initial load
duke
parents:
diff changeset
6376 Thread* t = ThreadLocalStorage::get_thread_slow();
a61af66fc99e Initial load
duke
parents:
diff changeset
6377 if (t != NULL && t->is_inside_signal_handler()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6378 pid = fork();
a61af66fc99e Initial load
duke
parents:
diff changeset
6379 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6380 pid = fork1();
a61af66fc99e Initial load
duke
parents:
diff changeset
6381 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6382
a61af66fc99e Initial load
duke
parents:
diff changeset
6383 if (pid < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6384 // fork failed
a61af66fc99e Initial load
duke
parents:
diff changeset
6385 warning("fork failed: %s", strerror(errno));
a61af66fc99e Initial load
duke
parents:
diff changeset
6386 return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
6387
a61af66fc99e Initial load
duke
parents:
diff changeset
6388 } else if (pid == 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6389 // child process
a61af66fc99e Initial load
duke
parents:
diff changeset
6390
a61af66fc99e Initial load
duke
parents:
diff changeset
6391 // try to be consistent with system(), which uses "/usr/bin/sh" on Solaris
a61af66fc99e Initial load
duke
parents:
diff changeset
6392 execve("/usr/bin/sh", argv, environ);
a61af66fc99e Initial load
duke
parents:
diff changeset
6393
a61af66fc99e Initial load
duke
parents:
diff changeset
6394 // execve failed
a61af66fc99e Initial load
duke
parents:
diff changeset
6395 _exit(-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
6396
a61af66fc99e Initial load
duke
parents:
diff changeset
6397 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6398 // copied from J2SE ..._waitForProcessExit() in UNIXProcess_md.c; we don't
a61af66fc99e Initial load
duke
parents:
diff changeset
6399 // care about the actual exit code, for now.
a61af66fc99e Initial load
duke
parents:
diff changeset
6400
a61af66fc99e Initial load
duke
parents:
diff changeset
6401 int status;
a61af66fc99e Initial load
duke
parents:
diff changeset
6402
a61af66fc99e Initial load
duke
parents:
diff changeset
6403 // Wait for the child process to exit. This returns immediately if
a61af66fc99e Initial load
duke
parents:
diff changeset
6404 // the child has already exited. */
a61af66fc99e Initial load
duke
parents:
diff changeset
6405 while (waitpid(pid, &status, 0) < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6406 switch (errno) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6407 case ECHILD: return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
6408 case EINTR: break;
a61af66fc99e Initial load
duke
parents:
diff changeset
6409 default: return -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
6410 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6411 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6412
a61af66fc99e Initial load
duke
parents:
diff changeset
6413 if (WIFEXITED(status)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6414 // The child exited normally; get its exit code.
a61af66fc99e Initial load
duke
parents:
diff changeset
6415 return WEXITSTATUS(status);
a61af66fc99e Initial load
duke
parents:
diff changeset
6416 } else if (WIFSIGNALED(status)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
6417 // The child exited because of a signal
a61af66fc99e Initial load
duke
parents:
diff changeset
6418 // The best value to return is 0x80 + signal number,
a61af66fc99e Initial load
duke
parents:
diff changeset
6419 // because that is what all Unix shells do, and because
a61af66fc99e Initial load
duke
parents:
diff changeset
6420 // it allows callers to distinguish between process exit and
a61af66fc99e Initial load
duke
parents:
diff changeset
6421 // process death by signal.
a61af66fc99e Initial load
duke
parents:
diff changeset
6422 return 0x80 + WTERMSIG(status);
a61af66fc99e Initial load
duke
parents:
diff changeset
6423 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
6424 // Unknown exit code; pass it through
a61af66fc99e Initial load
duke
parents:
diff changeset
6425 return status;
a61af66fc99e Initial load
duke
parents:
diff changeset
6426 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6427 }
a61af66fc99e Initial load
duke
parents:
diff changeset
6428 }
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6429
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6430 // is_headless_jre()
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6431 //
4082
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6432 // Test for the existence of xawt/libmawt.so or libawt_xawt.so
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6433 // in order to report if we are running in a headless jre
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6434 //
4082
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6435 // Since JDK8 xawt/libmawt.so was moved into the same directory
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6436 // as libawt.so, and renamed libawt_xawt.so
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6437 //
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6438 bool os::is_headless_jre() {
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6439 struct stat statbuf;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6440 char buf[MAXPATHLEN];
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6441 char libmawtpath[MAXPATHLEN];
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6442 const char *xawtstr = "/xawt/libmawt.so";
4082
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6443 const char *new_xawtstr = "/libawt_xawt.so";
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6444 char *p;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6445
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6446 // Get path to libjvm.so
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6447 os::jvm_path(buf, sizeof(buf));
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6448
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6449 // Get rid of libjvm.so
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6450 p = strrchr(buf, '/');
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6451 if (p == NULL) return false;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6452 else *p = '\0';
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6453
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6454 // Get rid of client or server
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6455 p = strrchr(buf, '/');
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6456 if (p == NULL) return false;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6457 else *p = '\0';
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6458
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6459 // check xawt/libmawt.so
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6460 strcpy(libmawtpath, buf);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6461 strcat(libmawtpath, xawtstr);
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6462 if (::stat(libmawtpath, &statbuf) == 0) return false;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6463
4082
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6464 // check libawt_xawt.so
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6465 strcpy(libmawtpath, buf);
4082
36b057451829 7110017: is_headless_jre should be updated to reflect the new location of awt toolkit libraries
dholmes
parents: 4006
diff changeset
6466 strcat(libmawtpath, new_xawtstr);
1681
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6467 if (::stat(libmawtpath, &statbuf) == 0) return false;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6468
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6469 return true;
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6470 }
126ea7725993 6953477: Increase portability and flexibility of building Hotspot
bobv
parents: 1642
diff changeset
6471
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6472 size_t os::write(int fd, const void *buf, unsigned int nBytes) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6473 INTERRUPTIBLE_RETURN_INT(::write(fd, buf, nBytes), os::Solaris::clear_interrupted);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6474 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6475
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6476 int os::close(int fd) {
10978
e95fc50106cf 7178026: os::close can restart ::close but that is not a restartable syscall
rdurbin
parents: 10969
diff changeset
6477 return ::close(fd);
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6478 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6479
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6480 int os::socket_close(int fd) {
10978
e95fc50106cf 7178026: os::close can restart ::close but that is not a restartable syscall
rdurbin
parents: 10969
diff changeset
6481 return ::close(fd);
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6482 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6483
4717
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6484 int os::recv(int fd, char* buf, size_t nBytes, uint flags) {
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6485 INTERRUPTIBLE_RETURN_INT((int)::recv(fd, buf, nBytes, flags), os::Solaris::clear_interrupted);
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6486 }
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6487
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6488 int os::send(int fd, char* buf, size_t nBytes, uint flags) {
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6489 INTERRUPTIBLE_RETURN_INT((int)::send(fd, buf, nBytes, flags), os::Solaris::clear_interrupted);
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6490 }
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6491
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6492 int os::raw_send(int fd, char* buf, size_t nBytes, uint flags) {
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6493 RESTARTABLE_RETURN_INT((int)::send(fd, buf, nBytes, flags));
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6494 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6495
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6496 // As both poll and select can be interrupted by signals, we have to be
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6497 // prepared to restart the system call after updating the timeout, unless
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6498 // a poll() is done with timeout == -1, in which case we repeat with this
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6499 // "wait forever" value.
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6500
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6501 int os::timeout(int fd, long timeout) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6502 int res;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6503 struct timeval t;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6504 julong prevtime, newtime;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6505 static const char* aNull = 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6506 struct pollfd pfd;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6507 pfd.fd = fd;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6508 pfd.events = POLLIN;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6509
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6510 gettimeofday(&t, &aNull);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6511 prevtime = ((julong)t.tv_sec * 1000) + t.tv_usec / 1000;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6512
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6513 for(;;) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6514 INTERRUPTIBLE_NORESTART(::poll(&pfd, 1, timeout), res, os::Solaris::clear_interrupted);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6515 if(res == OS_ERR && errno == EINTR) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6516 if(timeout != -1) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6517 gettimeofday(&t, &aNull);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6518 newtime = ((julong)t.tv_sec * 1000) + t.tv_usec /1000;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6519 timeout -= newtime - prevtime;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6520 if(timeout <= 0)
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6521 return OS_OK;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6522 prevtime = newtime;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6523 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6524 } else return res;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6525 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6526 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6527
4717
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6528 int os::connect(int fd, struct sockaddr *him, socklen_t len) {
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6529 int _result;
4717
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6530 INTERRUPTIBLE_NORESTART(::connect(fd, him, len), _result,\
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6531 os::Solaris::clear_interrupted);
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6532
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6533 // Depending on when thread interruption is reset, _result could be
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6534 // one of two values when errno == EINTR
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6535
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6536 if (((_result == OS_INTRPT) || (_result == OS_ERR))
4717
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6537 && (errno == EINTR)) {
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6538 /* restarting a connect() changes its errno semantics */
4717
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6539 INTERRUPTIBLE(::connect(fd, him, len), _result,\
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6540 os::Solaris::clear_interrupted);
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6541 /* undo these changes */
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6542 if (_result == OS_ERR) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6543 if (errno == EALREADY) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6544 errno = EINPROGRESS; /* fall through */
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6545 } else if (errno == EISCONN) {
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6546 errno = 0;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6547 return OS_OK;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6548 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6549 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6550 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6551 return _result;
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6552 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6553
4717
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6554 int os::accept(int fd, struct sockaddr* him, socklen_t* len) {
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6555 if (fd < 0) {
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6556 return OS_ERR;
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6557 }
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6558 INTERRUPTIBLE_RETURN_INT((int)::accept(fd, him, len),\
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6559 os::Solaris::clear_interrupted);
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6560 }
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6561
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6562 int os::recvfrom(int fd, char* buf, size_t nBytes, uint flags,
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6563 sockaddr* from, socklen_t* fromlen) {
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6564 INTERRUPTIBLE_RETURN_INT((int)::recvfrom(fd, buf, nBytes, flags, from, fromlen),\
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6565 os::Solaris::clear_interrupted);
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6566 }
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6567
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6568 int os::sendto(int fd, char* buf, size_t len, uint flags,
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6569 struct sockaddr* to, socklen_t tolen) {
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6570 INTERRUPTIBLE_RETURN_INT((int)::sendto(fd, buf, len, flags, to, tolen),\
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6571 os::Solaris::clear_interrupted);
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6572 }
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6573
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6574 int os::socket_available(int fd, jint *pbytes) {
4717
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6575 if (fd < 0) {
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6576 return OS_OK;
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6577 }
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6578 int ret;
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6579 RESTARTABLE(::ioctl(fd, FIONREAD, pbytes), ret);
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6580 // note: ioctl can return 0 when successful, JVM_SocketAvailable
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6581 // is expected to return 0 on failure and 1 on success to the jdk.
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6582 return (ret == OS_ERR) ? 0 : 1;
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6583 }
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6584
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6585 int os::bind(int fd, struct sockaddr* him, socklen_t len) {
1980
828eafbd85cc 6348631: remove the use of the HPI library from Hotspot
ikrylov
parents: 1972
diff changeset
6586 INTERRUPTIBLE_RETURN_INT_NORESTART(::bind(fd, him, len),\
4717
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6587 os::Solaris::clear_interrupted);
11c26bfcf8c7 7091417: recvfrom's 6th input should be of type socklen_t
phh
parents: 4082
diff changeset
6588 }
6200
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6589
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6590 // Get the default path to the core file
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6591 // Returns the length of the string
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6592 int os::get_core_path(char* buffer, size_t bufferSize) {
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6593 const char* p = get_current_directory(buffer, bufferSize);
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6594
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6595 if (p == NULL) {
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6596 assert(p != NULL, "failed to get current directory");
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6597 return 0;
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6598 }
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6599
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6600 return strlen(buffer);
65906dc96aa1 7129724: MAC: Core file location is wrong in crash report
mikael
parents: 6197
diff changeset
6601 }
12110
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11112
diff changeset
6602
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11112
diff changeset
6603 #ifndef PRODUCT
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11112
diff changeset
6604 void TestReserveMemorySpecial_test() {
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11112
diff changeset
6605 // No tests available for this platform
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11112
diff changeset
6606 }
4c84d351cca9 8007074: SIGSEGV at ParMarkBitMap::verify_clear()
stefank
parents: 11112
diff changeset
6607 #endif